From 65ce6d874d4a45a1889a15b5579b27ad74fed98b Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 11 Jul 2019 18:18:24 +0200 Subject: [PATCH] grid: support resizing both dimensions fixes #77226 fixes #67366 --- src/vs/base/browser/ui/grid/grid.ts | 36 ++++++------------- src/vs/base/browser/ui/grid/gridview.ts | 32 +++++++++++++---- src/vs/workbench/browser/layout.ts | 9 ++--- src/vs/workbench/browser/legacyLayout.ts | 4 +-- .../browser/parts/editor/editorPart.ts | 4 +-- .../editor/common/editorGroupsService.ts | 4 +-- .../workbench/test/workbenchTestServices.ts | 6 ++-- 7 files changed, 51 insertions(+), 44 deletions(-) diff --git a/src/vs/base/browser/ui/grid/grid.ts b/src/vs/base/browser/ui/grid/grid.ts index 4178efc9e98..8297b231ced 100644 --- a/src/vs/base/browser/ui/grid/grid.ts +++ b/src/vs/base/browser/ui/grid/grid.ts @@ -7,7 +7,7 @@ import 'vs/css!./gridview'; import { Orientation } from 'vs/base/browser/ui/sash/sash'; import { Disposable } from 'vs/base/common/lifecycle'; import { tail2 as tail, equals } from 'vs/base/common/arrays'; -import { orthogonal, IView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles } from './gridview'; +import { orthogonal, IView, GridView, Sizing as GridViewSizing, Box, IGridViewStyles, IViewSize } from './gridview'; import { Event, Emitter } from 'vs/base/common/event'; import { $ } from 'vs/base/browser/dom'; import { LayoutPriority } from 'vs/base/browser/ui/splitview/splitview'; @@ -117,10 +117,6 @@ function getDirectionOrientation(direction: Direction): Orientation { return direction === Direction.Up || direction === Direction.Down ? Orientation.VERTICAL : Orientation.HORIZONTAL; } -function getSize(dimensions: { width: number; height: number; }, orientation: Orientation) { - return orientation === Orientation.HORIZONTAL ? dimensions.width : dimensions.height; -} - export function getRelativeLocation(rootOrientation: Orientation, location: number[], direction: Direction): number[] { const orientation = getLocationOrientation(rootOrientation, location); const directionOrientation = getDirectionOrientation(direction); @@ -209,8 +205,6 @@ export class Grid extends Disposable { get element(): HTMLElement { return this.gridview.element; } - sashResetSizing: Sizing = Sizing.Distribute; - constructor(view: T, options: IGridOptions = {}) { super(); this.gridview = new GridView(options); @@ -298,15 +292,14 @@ export class Grid extends Disposable { return this.gridview.swapViews(fromLocation, toLocation); } - resizeView(view: T, size: number): void { + resizeView(view: T, size: IViewSize): void { const location = this.getViewLocation(view); return this.gridview.resizeView(location, size); } - getViewSize(view: T): number { + getViewSize(view: T): IViewSize { const location = this.getViewLocation(view); - const viewSize = this.gridview.getViewSize(location); - return getLocationOrientation(this.orientation, location) === Orientation.HORIZONTAL ? viewSize.width : viewSize.height; + return this.gridview.getViewSize(location); } // TODO@joao cleanup @@ -361,18 +354,8 @@ export class Grid extends Disposable { } private doResetViewSize(location: number[]): void { - if (this.sashResetSizing === Sizing.Split) { - const orientation = getLocationOrientation(this.orientation, location); - const firstViewSize = getSize(this.gridview.getViewSize(location), orientation); - const [parentLocation, index] = tail(location); - const secondViewSize = getSize(this.gridview.getViewSize([...parentLocation, index + 1]), orientation); - const totalSize = firstViewSize + secondViewSize; - this.gridview.resizeView(location, Math.floor(totalSize / 2)); - - } else { - const [parentLocation,] = tail(location); - this.gridview.distributeViewSizes(parentLocation); - } + const [parentLocation,] = tail(location); + this.gridview.distributeViewSizes(parentLocation); } } @@ -563,8 +546,11 @@ export class SerializableGrid extends Grid { const childLocation = [...location, i]; if (i < node.children.length - 1) { - const size = orientation === Orientation.VERTICAL ? child.box.height : child.box.width; - this.gridview.resizeView(childLocation, Math.floor(size * scale)); + const size = orientation === Orientation.VERTICAL + ? { height: Math.floor(child.box.height * scale) } + : { width: Math.floor(child.box.width * scale) }; + + this.gridview.resizeView(childLocation, size); } this.restoreViewsSize(childLocation, child, orthogonal(orientation), widthScale, heightScale); diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index e4e6f8909ad..8b1a39d02d9 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -15,13 +15,18 @@ import { Color } from 'vs/base/common/color'; export { Sizing, LayoutPriority } from 'vs/base/browser/ui/splitview/splitview'; export { Orientation } from 'vs/base/browser/ui/sash/sash'; +export interface IViewSize { + readonly width: number; + readonly height: number; +} + export interface IView { readonly element: HTMLElement; readonly minimumWidth: number; readonly maximumWidth: number; readonly minimumHeight: number; readonly maximumHeight: number; - readonly onDidChange: Event<{ width: number; height: number; } | undefined>; + readonly onDidChange: Event; readonly priority?: LayoutPriority; readonly snapSize?: number; layout(width: number, height: number, orientation: Orientation): void; @@ -573,7 +578,7 @@ export class GridView implements IDisposable { get maximumWidth(): number { return this.root.maximumHeight; } get maximumHeight(): number { return this.root.maximumHeight; } - private _onDidChange = new Relay<{ width: number; height: number; } | undefined>(); + private _onDidChange = new Relay(); readonly onDidChange = this._onDidChange.event; constructor(options: IGridViewOptions = {}) { @@ -747,18 +752,33 @@ export class GridView implements IDisposable { } } - resizeView(location: number[], size: number): void { + resizeView(location: number[], { width, height }: Partial): void { const [rest, index] = tail(location); - const [, parent] = this.getNode(rest); + const [pathToParent, parent] = this.getNode(rest); if (!(parent instanceof BranchNode)) { throw new Error('Invalid location'); } - parent.resizeChild(index, size); + if (!width && !height) { + return; + } + + const [parentSize, grandParentSize] = parent.orientation === Orientation.HORIZONTAL ? [width, height] : [height, width]; + + if (typeof grandParentSize === 'number' && pathToParent.length > 0) { + const [, grandParent] = tail(pathToParent); + const [, parentIndex] = tail(rest); + + grandParent.resizeChild(parentIndex, grandParentSize); + } + + if (typeof parentSize === 'number') { + parent.resizeChild(index, parentSize); + } } - getViewSize(location: number[]): { width: number; height: number; } { + getViewSize(location: number[]): IViewSize { const [, node] = this.getNode(location); return { width: node.width, height: node.height }; } diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 7e6bfaa4a30..72d13ef9aa4 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -317,7 +317,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi // Layout if (this.workbenchGrid instanceof Grid) { if (!wasHidden) { - this.state.sideBar.width = this.workbenchGrid.getViewSize(this.sideBarPartView); + this.state.sideBar.width = this.workbenchGrid.getViewSize(this.sideBarPartView).width; } this.workbenchGrid.removeView(this.sideBarPartView); @@ -878,7 +878,8 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi case Parts.EDITOR_PART: view = this.editorPartView; if (this.workbenchGrid instanceof Grid) { - this.workbenchGrid.resizeView(view, this.workbenchGrid.getViewSize(view) + sizeChange); + const { width, height } = this.workbenchGrid.getViewSize(view); + this.workbenchGrid.resizeView(view, { width: width + sizeChange, height: height + sizeChange }); } else { this.workbenchGrid.resizePart(part, sizeChange); } @@ -1117,9 +1118,9 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi } if (this.state.panel.position === Position.BOTTOM) { - this.state.panel.height = this.workbenchGrid.getViewSize(this.panelPartView); + this.state.panel.height = this.workbenchGrid.getViewSize(this.panelPartView).height; } else { - this.state.panel.width = this.workbenchGrid.getViewSize(this.panelPartView); + this.state.panel.width = this.workbenchGrid.getViewSize(this.panelPartView).width; } } diff --git a/src/vs/workbench/browser/legacyLayout.ts b/src/vs/workbench/browser/legacyLayout.ts index a1d936c0f1e..d936e13f1b2 100644 --- a/src/vs/workbench/browser/legacyLayout.ts +++ b/src/vs/workbench/browser/legacyLayout.ts @@ -726,8 +726,8 @@ export class WorkbenchLegacyLayout extends Disposable implements IVerticalSashLa } else { const activeGroup = this.editorGroupService.activeGroup; - const activeGroupSize = this.editorGroupService.getSize(activeGroup); - this.editorGroupService.setSize(activeGroup, activeGroupSize + sizeChangePxWidth); + const { width, height } = this.editorGroupService.getSize(activeGroup); + this.editorGroupService.setSize(activeGroup, { width: width + sizeChangePxWidth, height: height + sizeChangePxHeight }); } } diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 810b2aa3ab7..5bb777ae85f 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -326,13 +326,13 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro return groupView; } - getSize(group: IEditorGroupView | GroupIdentifier): number { + getSize(group: IEditorGroupView | GroupIdentifier): { width: number, height: number } { const groupView = this.assertGroupView(group); return this.gridWidget.getViewSize(groupView); } - setSize(group: IEditorGroupView | GroupIdentifier, size: number): void { + setSize(group: IEditorGroupView | GroupIdentifier, size: { width: number, height: number }): void { const groupView = this.assertGroupView(group); this.gridWidget.resizeView(groupView, size); diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index 91b2ea587f3..ac6ff2b537c 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -232,12 +232,12 @@ export interface IEditorGroupsService { /** * Returns the size of a group. */ - getSize(group: IEditorGroup | GroupIdentifier): number; + getSize(group: IEditorGroup | GroupIdentifier): { width: number, height: number }; /** * Sets the size of a group. */ - setSize(group: IEditorGroup | GroupIdentifier, size: number): void; + setSize(group: IEditorGroup | GroupIdentifier, size: { width: number, height: number }): void; /** * Arrange all groups according to the provided arrangement. diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 32f5ec8248d..9e9e0d739e8 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -703,11 +703,11 @@ export class TestEditorGroupsService implements IEditorGroupsService { throw new Error('not implemented'); } - getSize(_group: number | IEditorGroup): number { - return 100; + getSize(_group: number | IEditorGroup): { width: number, height: number } { + return { width: 100, height: 100 }; } - setSize(_group: number | IEditorGroup, _size: number): void { } + setSize(_group: number | IEditorGroup, _size: { width: number, height: number }): void { } arrangeGroups(_arrangement: GroupsArrangement): void { } -- GitLab