Skip to content
This repository has been archived by the owner on Nov 30, 2021. It is now read-only.

Clehner/maximize views #50

Merged
merged 20 commits into from
Feb 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/layout/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export class LayoutContainerEvents {
static readonly EVENT_CHANGE_SPLIT_RATIOS = 'changeRatios';
static readonly EVENT_TAB_REORDED = 'tabReorded';
static readonly EVENT_CHANGE_ACTIVE_TAB = 'changeActiveTab';
static readonly EVENT_MAXIMIZE = 'maximize';
static readonly EVENT_RESTORE_SIZE = 'restoreSize';
}
/**
* base interface for the container
Expand Down
44 changes: 44 additions & 0 deletions src/layout/internal/ALayoutContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ export abstract class ALayoutContainer<T extends ILayoutContainerOption> extends

readonly id = uniqueId(ALayoutContainer.MIME_TYPE);

private readonly keyDownListener = (evt: KeyboardEvent) => {
if (evt.keyCode === 27) { // Escape
this.toggleMaximizedView();
}
}

protected isMaximized: boolean = false;

constructor(document: Document, options: Partial<T>) {
super();
console.assert(document != null);
Expand Down Expand Up @@ -156,6 +164,42 @@ export abstract class ALayoutContainer<T extends ILayoutContainerOption> extends
}
return parent.closest(id);
}

protected toggleMaximizedView() {
const sizeToggle = <HTMLElement>this.header.querySelector('.size-toggle');
const sizeToggleIcon = sizeToggle.querySelector('i');
const closeButton = this.header.querySelector('.close');
this.isMaximized = !this.isMaximized;

if (this.isMaximized) {
closeButton.classList.add('hidden');
sizeToggle.title = 'Restore default size';
sizeToggleIcon.classList.remove('fa-expand');
sizeToggleIcon.classList.add('fa-compress');

this.header.ownerDocument.addEventListener('keydown', this.keyDownListener);

this.fire(LayoutContainerEvents.EVENT_MAXIMIZE, this);
} else {
if (!this.options.fixedLayout) {
closeButton.classList.remove('hidden');
}

sizeToggle.title = 'Expand view';
sizeToggleIcon.classList.add('fa-expand');
sizeToggleIcon.classList.remove('fa-compress');

this.header.ownerDocument.removeEventListener('keydown', this.keyDownListener);

this.fire(LayoutContainerEvents.EVENT_RESTORE_SIZE, this);
}

this.updateTitle();
}

protected updateTitle() {
this.header.title = `Double click to ${this.isMaximized? 'restore default size' : 'expand view'}`;
}
}

export default ALayoutContainer;
4 changes: 2 additions & 2 deletions src/layout/internal/AParentLayoutContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export abstract class AParentLayoutContainer<T extends ILayoutContainerOption> e

protected addedChild(child: ILayoutContainer, index: number) {
child.resized();
this.propagate(child, LayoutContainerEvents.EVENT_LAYOUT_CHANGED);
this.propagate(child, LayoutContainerEvents.EVENT_LAYOUT_CHANGED, LayoutContainerEvents.EVENT_MAXIMIZE, LayoutContainerEvents.EVENT_RESTORE_SIZE);
this.fire(withChanged(LayoutContainerEvents.EVENT_CHILD_ADDED), child, index);
}

Expand Down Expand Up @@ -133,7 +133,7 @@ export abstract class AParentLayoutContainer<T extends ILayoutContainerOption> e
}

protected takeDownChild(child: ILayoutContainer) {
this.stopPropagation(child, LayoutContainerEvents.EVENT_LAYOUT_CHANGED);
this.stopPropagation(child, LayoutContainerEvents.EVENT_LAYOUT_CHANGED, LayoutContainerEvents.EVENT_MAXIMIZE, LayoutContainerEvents.EVENT_RESTORE_SIZE);
child.visible = false;
(<any>child).parent = null;
}
Expand Down
42 changes: 41 additions & 1 deletion src/layout/internal/RootLayoutContainer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {AParentLayoutContainer} from './AParentLayoutContainer';
import {ILayoutContainer, ILayoutDump, IRootLayoutContainer} from '../interfaces';
import {ILayoutContainer, ILayoutDump, IRootLayoutContainer, LayoutContainerEvents} from '../interfaces';
import TabbingLayoutContainer from './TabbingLayoutContainer';
import {ILayoutContainerOption} from './ALayoutContainer';
import {IDropArea} from './interfaces';
Expand All @@ -10,13 +10,53 @@ export default class RootLayoutContainer extends AParentLayoutContainer<ILayoutC
readonly minChildCount = 0;
readonly type = 'root';

private viewDump: {
parent: {
viewParent: HTMLElement,
headerParent: HTMLElement
},
sibling: {
viewSibling: HTMLElement,
headerSibling: HTMLElement
}
};

constructor(document: Document, public readonly build: (layout: IBuildAbleOrViewLike)=> ILayoutContainer, private readonly restorer: (dump: ILayoutDump, restoreView: (referenceId: number) => IView) => ILayoutContainer) {
super(document, {
name: '',
fixed: true
});
this.node.dataset.layout = 'root';
this.visible = true;

this.on(LayoutContainerEvents.EVENT_MAXIMIZE, (_evt, view) => {
const section = this.node.ownerDocument.createElement('section');
section.classList.add('maximized-view');

this.viewDump = {
parent: {
viewParent: view.node.parentNode,
headerParent: view.header.parentNode
},
sibling: {
viewSibling: view.node.nextElementSibling,
headerSibling: view.header.nextElementSibling
}
};

section.appendChild(view.header);
section.appendChild(view.node);
this.node.insertAdjacentElement('afterbegin', section);
});

this.on(LayoutContainerEvents.EVENT_RESTORE_SIZE, (_evt, view) => {
const parent = view.parent;

this.viewDump.parent.viewParent.insertBefore(view.node, this.viewDump.sibling.viewSibling);
this.viewDump.parent.headerParent.insertBefore(view.header, this.viewDump.sibling.headerSibling);

this.node.querySelector('.maximized-view').remove();
});
}

set root(root: ILayoutContainer) {
Expand Down
7 changes: 7 additions & 0 deletions src/layout/internal/ViewLayoutContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export default class ViewLayoutContainer extends ALayoutContainer<IViewLayoutCon
this.node.dataset.layout = 'view';
this.node.appendChild(view.node);

this.header.insertAdjacentHTML('beforeend', `<button type="button" title="Expand view" class="size-toggle" aria-label="Toggle View Size"><span><i class="fa fa-expand"></i></span></button>`);

const min = this.minSize;
if (min[0] > 0) {
view.node.style.minWidth = `${min[0]}px`;
Expand All @@ -29,6 +31,11 @@ export default class ViewLayoutContainer extends ALayoutContainer<IViewLayoutCon
if (!this.options.fixedLayout) {
dropViews(this.node, this);
}

this.updateTitle();

this.header.querySelector('.size-toggle').addEventListener('click', () => this.toggleMaximizedView());
this.header.addEventListener('dblclick', () => this.toggleMaximizedView());
}

protected defaultOptions() {
Expand Down
17 changes: 14 additions & 3 deletions src/layout/styles/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,19 @@ header {
opacity: 0.2;
}

> button.close {
margin: 0 3px;
cursor: pointer;
> button {
&.close,
&.size-toggle {
margin: 0 3px;
cursor: pointer;
}

&.size-toggle {
padding: 0;
background: transparent;
border: 0;
opacity: .2;
float: right;
}
}
}
21 changes: 21 additions & 0 deletions src/layout/styles/_root.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
display: flex;
align-items: stretch;
flex-direction: column;
position: relative;

> header {
flex: 0 0 auto;
Expand All @@ -15,4 +16,24 @@
flex: 1 1 auto;
position: relative;
}

> section.maximized-view {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 100;
display: flex;
flex-direction: column;
background-color: #fff;

> header {
background-color: $phovea_layout_view_header;
}

> article {
flex: 1 1 auto;
}
}
}