dockview
Version:
Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support
145 lines (144 loc) • 4.95 kB
JavaScript
import { Splitview, Orientation, } from '../splitview/core/splitview';
import { CompositeDisposable } from '../lifecycle';
import { Emitter } from '../events';
import { addClasses, removeClasses } from '../dom';
export class Paneview extends CompositeDisposable {
constructor(container, options) {
var _a;
super();
this.paneItems = [];
this._onDidChange = new Emitter();
this.onDidChange = this._onDidChange.event;
this.skipAnimation = false;
this._orientation = (_a = options.orientation) !== null && _a !== void 0 ? _a : Orientation.VERTICAL;
this.element = document.createElement('div');
this.element.className = 'pane-container';
container.appendChild(this.element);
this.splitview = new Splitview(this.element, {
orientation: this._orientation,
proportionalLayout: false,
descriptor: options.descriptor,
});
// if we've added views from the descriptor we need to
// add the panes to our Pane array and setup animation
this.getPanes().forEach((pane, index) => {
const disposable = new CompositeDisposable(pane.onDidChangeExpansionState(() => {
this.setupAnimation();
this._onDidChange.fire(undefined);
}));
const paneItem = {
pane,
disposable: {
dispose: () => {
disposable.dispose();
},
},
};
this.paneItems.push(paneItem);
pane.orthogonalSize = this.splitview.orthogonalSize;
});
this.addDisposables(this.splitview.onDidSashEnd(() => {
this._onDidChange.fire(undefined);
}), this.splitview.onDidAddView(() => {
this._onDidChange.fire();
}), this.splitview.onDidRemoveView(() => {
this._onDidChange.fire();
}));
}
get onDidAddView() {
return this.splitview.onDidAddView;
}
get onDidRemoveView() {
return this.splitview.onDidRemoveView;
}
get minimumSize() {
return this.splitview.minimumSize;
}
get maximumSize() {
return this.splitview.maximumSize;
}
get orientation() {
return this.splitview.orientation;
}
get size() {
return this.splitview.size;
}
get orthogonalSize() {
return this.splitview.orthogonalSize;
}
addPane(pane, size, index = this.splitview.length, skipLayout = false) {
const disposable = pane.onDidChangeExpansionState(() => {
this.setupAnimation();
this._onDidChange.fire(undefined);
});
const paneItem = {
pane,
disposable: {
dispose: () => {
disposable.dispose();
},
},
};
this.paneItems.splice(index, 0, paneItem);
pane.orthogonalSize = this.splitview.orthogonalSize;
this.splitview.addView(pane, size, index, skipLayout);
}
getViewSize(index) {
return this.splitview.getViewSize(index);
}
getPanes() {
return this.splitview.getViews();
}
removePane(index) {
const paneItem = this.paneItems.splice(index, 1)[0];
this.splitview.removeView(index);
paneItem.disposable.dispose();
return paneItem;
}
moveView(from, to) {
if (from === to) {
return;
}
const view = this.removePane(from);
this.skipAnimation = true;
try {
this.addPane(view.pane, view.pane.size, to, false);
}
finally {
this.skipAnimation = false;
}
}
layout(size, orthogonalSize) {
// for (const paneItem of this.paneItems) {
// paneItem.pane.orthogonalSize = orthogonalSize;
// }
this.splitview.layout(size, orthogonalSize);
}
setupAnimation() {
if (this.skipAnimation) {
return;
}
if (this.animationTimer) {
clearTimeout(this.animationTimer);
this.animationTimer = undefined;
}
addClasses(this.element, 'animated');
this.animationTimer = setTimeout(() => {
this.animationTimer = undefined;
removeClasses(this.element, 'animated');
}, 200);
}
dispose() {
super.dispose();
this.splitview.dispose();
if (this.animationTimer) {
clearTimeout(this.animationTimer);
this.animationTimer = undefined;
}
this.paneItems.forEach((paneItem) => {
paneItem.disposable.dispose();
});
this.paneItems = [];
this.element.remove();
}
}