sussudio
Version:
An unofficial VS Code Internal API
156 lines (155 loc) • 6.33 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { $ } from "../../dom.mjs";
import { SplitView } from "../splitview/splitview.mjs";
import { Event } from "../../../common/event.mjs";
import { DisposableStore } from "../../../common/lifecycle.mjs";
const GOLDEN_RATIO = {
leftMarginRatio: 0.1909,
rightMarginRatio: 0.1909
};
function createEmptyView(background) {
const element = $('.centered-layout-margin');
element.style.height = '100%';
if (background) {
element.style.backgroundColor = background.toString();
}
return {
element,
layout: () => undefined,
minimumSize: 60,
maximumSize: Number.POSITIVE_INFINITY,
onDidChange: Event.None
};
}
function toSplitViewView(view, getHeight) {
return {
element: view.element,
get maximumSize() { return view.maximumWidth; },
get minimumSize() { return view.minimumWidth; },
onDidChange: Event.map(view.onDidChange, e => e && e.width),
layout: (size, offset, ctx) => view.layout(size, getHeight(), ctx?.top ?? 0, (ctx?.left ?? 0) + offset)
};
}
export class CenteredViewLayout {
container;
view;
state;
splitView;
width = 0;
height = 0;
style;
didLayout = false;
emptyViews;
splitViewDisposables = new DisposableStore();
constructor(container, view, state = { leftMarginRatio: GOLDEN_RATIO.leftMarginRatio, rightMarginRatio: GOLDEN_RATIO.rightMarginRatio }) {
this.container = container;
this.view = view;
this.state = state;
this.container.appendChild(this.view.element);
// Make sure to hide the split view overflow like sashes #52892
this.container.style.overflow = 'hidden';
}
get minimumWidth() { return this.splitView ? this.splitView.minimumSize : this.view.minimumWidth; }
get maximumWidth() { return this.splitView ? this.splitView.maximumSize : this.view.maximumWidth; }
get minimumHeight() { return this.view.minimumHeight; }
get maximumHeight() { return this.view.maximumHeight; }
get onDidChange() { return this.view.onDidChange; }
_boundarySashes = {};
get boundarySashes() { return this._boundarySashes; }
set boundarySashes(boundarySashes) {
this._boundarySashes = boundarySashes;
if (!this.splitView) {
return;
}
this.splitView.orthogonalStartSash = boundarySashes.top;
this.splitView.orthogonalEndSash = boundarySashes.bottom;
}
layout(width, height, top, left) {
this.width = width;
this.height = height;
if (this.splitView) {
this.splitView.layout(width);
if (!this.didLayout) {
this.resizeMargins();
}
}
else {
this.view.layout(width, height, top, left);
}
this.didLayout = true;
}
resizeMargins() {
if (!this.splitView) {
return;
}
this.splitView.resizeView(0, this.state.leftMarginRatio * this.width);
this.splitView.resizeView(2, this.state.rightMarginRatio * this.width);
}
isActive() {
return !!this.splitView;
}
styles(style) {
this.style = style;
if (this.splitView && this.emptyViews) {
this.splitView.style(this.style);
this.emptyViews[0].element.style.backgroundColor = this.style.background.toString();
this.emptyViews[1].element.style.backgroundColor = this.style.background.toString();
}
}
activate(active) {
if (active === this.isActive()) {
return;
}
if (active) {
this.container.removeChild(this.view.element);
this.splitView = new SplitView(this.container, {
inverseAltBehavior: true,
orientation: 1 /* Orientation.HORIZONTAL */,
styles: this.style
});
this.splitView.orthogonalStartSash = this.boundarySashes.top;
this.splitView.orthogonalEndSash = this.boundarySashes.bottom;
this.splitViewDisposables.add(this.splitView.onDidSashChange(() => {
if (this.splitView) {
this.state.leftMarginRatio = this.splitView.getViewSize(0) / this.width;
this.state.rightMarginRatio = this.splitView.getViewSize(2) / this.width;
}
}));
this.splitViewDisposables.add(this.splitView.onDidSashReset(() => {
this.state.leftMarginRatio = GOLDEN_RATIO.leftMarginRatio;
this.state.rightMarginRatio = GOLDEN_RATIO.rightMarginRatio;
this.resizeMargins();
}));
this.splitView.layout(this.width);
this.splitView.addView(toSplitViewView(this.view, () => this.height), 0);
const backgroundColor = this.style ? this.style.background : undefined;
this.emptyViews = [createEmptyView(backgroundColor), createEmptyView(backgroundColor)];
this.splitView.addView(this.emptyViews[0], this.state.leftMarginRatio * this.width, 0);
this.splitView.addView(this.emptyViews[1], this.state.rightMarginRatio * this.width, 2);
}
else {
if (this.splitView) {
this.container.removeChild(this.splitView.el);
}
this.splitViewDisposables.clear();
this.splitView?.dispose();
this.splitView = undefined;
this.emptyViews = undefined;
this.container.appendChild(this.view.element);
this.view.layout(this.width, this.height, 0, 0);
}
}
isDefault(state) {
return state.leftMarginRatio === GOLDEN_RATIO.leftMarginRatio && state.rightMarginRatio === GOLDEN_RATIO.rightMarginRatio;
}
dispose() {
this.splitViewDisposables.dispose();
if (this.splitView) {
this.splitView.dispose();
this.splitView = undefined;
}
}
}