From a32307e7656b3559c3f978612ce79480ca83540e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 30 May 2018 11:35:54 +0200 Subject: [PATCH] fixes #50609 --- src/vs/base/browser/ui/grid/gridview.ts | 62 +++++++++++++------ src/vs/base/test/browser/ui/grid/grid.test.ts | 28 +++++++++ 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index dcd38e84f3cc0..fe4464334cfcb 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -293,7 +293,7 @@ class LeafNode implements ISplitView, IDisposable { type Node = BranchNode | LeafNode; -function flipNode(node: Node, size: number, orthogonalSize: number): Node { +function flipNode(node: T, size: number, orthogonalSize: number): T { if (node instanceof BranchNode) { const result = new BranchNode(orthogonal(node.orientation), size, orthogonalSize); @@ -314,39 +314,50 @@ function flipNode(node: Node, size: number, orthogonalSize: number): Node { result.addChild(flipNode(child, orthogonalSize, newSize), newSize, 0); } - return result; + return result as T; } else { - return new LeafNode(node.view, orthogonal(node.orientation), orthogonalSize); + return new LeafNode((node as LeafNode).view, orthogonal(node.orientation), orthogonalSize) as T; } } export class GridView implements IDisposable { private element: HTMLElement; - private root: BranchNode; + + private _root: BranchNode; private onDidSashResetRelay = new Relay(); readonly onDidSashReset: Event = this.onDidSashResetRelay.event; - get orientation(): Orientation { - return this.root.orientation; + private get root(): BranchNode { + return this._root; } - set orientation(orientation: Orientation) { - if (this.root.orientation === orientation) { - return; + private set root(root: BranchNode) { + const oldRoot = this._root; + + if (oldRoot) { + this.element.removeChild(oldRoot.element); + oldRoot.dispose(); } - const oldRoot = this.root; - this.element.removeChild(oldRoot.element); + this._root = root; + this.element.appendChild(root.element); + this.onDidSashResetRelay.input = root.onDidSashReset; + } - this.root = flipNode(oldRoot, oldRoot.orthogonalSize, oldRoot.size) as BranchNode; - this.element.appendChild(this.root.element); - this.onDidSashResetRelay.input = this.root.onDidSashReset; + get orientation(): Orientation { + return this._root.orientation; + } - this.root.layout(oldRoot.size); - this.root.orthogonalLayout(oldRoot.orthogonalSize); + set orientation(orientation: Orientation) { + if (this._root.orientation === orientation) { + return; + } - oldRoot.dispose(); + const { size, orthogonalSize } = this._root; + this.root = flipNode(this._root, orthogonalSize, size); + this.root.layout(size); + this.root.orthogonalLayout(orthogonalSize); } get width(): number { @@ -376,8 +387,6 @@ export class GridView implements IDisposable { constructor(container: HTMLElement) { this.element = append(container, $('.monaco-grid-view')); this.root = new BranchNode(Orientation.VERTICAL); - this.element.appendChild(this.root.element); - this.onDidSashResetRelay.input = this.root.onDidSashReset; } layout(width: number, height: number): void { @@ -435,7 +444,20 @@ export class GridView implements IDisposable { throw new Error('Invalid grid state'); } - if (parent.children.length > 1 || pathToParent.length === 0) { + if (parent.children.length > 1) { + return node.view; + } + + if (pathToParent.length === 0) { // parent is root + const sibling = parent.children[0]; + + if (sibling instanceof LeafNode) { + return node.view; + } + + // we must promote sibling to be the new root + parent.removeChild(0); + this.root = sibling; return node.view; } diff --git a/src/vs/base/test/browser/ui/grid/grid.test.ts b/src/vs/base/test/browser/ui/grid/grid.test.ts index 16ccee9832773..810b5eea25daa 100644 --- a/src/vs/base/test/browser/ui/grid/grid.test.ts +++ b/src/vs/base/test/browser/ui/grid/grid.test.ts @@ -527,4 +527,32 @@ suite('SerializableGrid', function () { assert.deepEqual(view1Copy.size, [400, 600]); assert.deepEqual(view2Copy.size, [400, 600]); }); + + test('deserialize simple view layout #50609', function () { + const view1 = new TestSerializableView('view1', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE); + const grid = new SerializableGrid(container, view1); + grid.layout(800, 600); + + const view2 = new TestSerializableView('view2', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE); + grid.addView(view2, Sizing.Split, view1, Direction.Right); + + const view3 = new TestSerializableView('view3', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE); + grid.addView(view3, Sizing.Split, view2, Direction.Down); + + grid.removeView(view1, Sizing.Split); + + const json = grid.serialize(); + grid.dispose(); + + const deserializer = new TestViewDeserializer(); + const grid2 = SerializableGrid.deserialize(container, json, deserializer); + + const view2Copy = deserializer.getView('view2'); + const view3Copy = deserializer.getView('view3'); + + grid2.layout(800, 600); + + assert.deepEqual(view2Copy.size, [800, 300]); + assert.deepEqual(view3Copy.size, [800, 300]); + }); }); \ No newline at end of file