From 0585cef42cd4f9677552508c90c73291e698b073 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Oct 2017 10:22:18 +0200 Subject: [PATCH 01/13] vertical panel: action to toggle --- .../parts/panel/media/panel-bottom.svg | 1 + .../browser/parts/panel/media/panel-right.svg | 1 + .../browser/parts/panel/media/panelpart.css | 18 ++++++++ .../browser/parts/panel/panelActions.ts | 44 ++++++++++++++++++- .../browser/parts/panel/panelPart.ts | 5 ++- .../electron-browser/main.contribution.ts | 6 +++ .../workbench/electron-browser/workbench.ts | 36 +++++++++++++++ .../services/part/common/partService.ts | 8 +++- .../workbench/test/workbenchTestServices.ts | 4 ++ 9 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 src/vs/workbench/browser/parts/panel/media/panel-bottom.svg create mode 100644 src/vs/workbench/browser/parts/panel/media/panel-right.svg diff --git a/src/vs/workbench/browser/parts/panel/media/panel-bottom.svg b/src/vs/workbench/browser/parts/panel/media/panel-bottom.svg new file mode 100644 index 0000000000000..4750174b6c1ce --- /dev/null +++ b/src/vs/workbench/browser/parts/panel/media/panel-bottom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/media/panel-right.svg b/src/vs/workbench/browser/parts/panel/media/panel-right.svg new file mode 100644 index 0000000000000..35cf0a522c3ed --- /dev/null +++ b/src/vs/workbench/browser/parts/panel/media/panel-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/media/panelpart.css b/src/vs/workbench/browser/parts/panel/media/panelpart.css index 042d150e84fb9..21bcd398c08d3 100644 --- a/src/vs/workbench/browser/parts/panel/media/panelpart.css +++ b/src/vs/workbench/browser/parts/panel/media/panelpart.css @@ -106,6 +106,24 @@ background: url('down-inverse.svg') center center no-repeat; } +.monaco-workbench .move-panel-to-right { + background: url('panel-right.svg') center center no-repeat; +} + +.vs-dark .monaco-workbench .move-panel-to-right, +.hc-black .monaco-workbench .move-panel-to-right { + background: url('panel-right-inverse.svg') center center no-repeat; +} + +.monaco-workbench .move-panel-to-bottom { + background: url('panel-bottom.svg') center center no-repeat; +} + +.vs-dark .monaco-workbench .move-panel-to-bottom, +.hc-black .monaco-workbench .move-panel-to-bottom { + background: url('panel-bottom-inverse.svg') center center no-repeat; +} + .vs-dark .monaco-workbench .hide-panel-action, .hc-black .monaco-workbench .hide-panel-action { background: url('close-inverse.svg') center center no-repeat; diff --git a/src/vs/workbench/browser/parts/panel/panelActions.ts b/src/vs/workbench/browser/parts/panel/panelActions.ts index 759cb22cbf670..bccf5ec0f75d0 100644 --- a/src/vs/workbench/browser/parts/panel/panelActions.ts +++ b/src/vs/workbench/browser/parts/panel/panelActions.ts @@ -13,10 +13,11 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; import { IWorkbenchActionRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/actions'; import { IPanelService, IPanelIdentifier } from 'vs/workbench/services/panel/common/panelService'; -import { IPartService, Parts } from 'vs/workbench/services/part/common/partService'; +import { IPartService, Parts, Position } from 'vs/workbench/services/part/common/partService'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { ActivityAction } from 'vs/workbench/browser/parts/compositebar/compositeBarActions'; import { IActivity } from 'vs/workbench/common/activity'; +import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; export class OpenPanelAction extends Action { @@ -117,6 +118,44 @@ class FocusPanelAction extends Action { } } +export class TogglePanelPositionAction extends Action { + + public static ID = 'workbench.action.togglePanelPosition'; + public static LABEL = nls.localize('toggledPanelPosition', "Toggle Panel Position"); + private static MOVE_TO_RIGHT_LABEL = nls.localize('moveToRight', "Move to Right"); + private static MOVE_TO_BOTTOM_LABEL = nls.localize('moveToBottom', "Move to Bottom"); + private static panelPositionConfigurationKey = 'workbench.panel.location'; + private toDispose: IDisposable[]; + + constructor( + id: string, + label: string, + @IPartService private partService: IPartService, + @IConfigurationService private configurationService: IConfigurationService + + ) { + super(id, label, partService.getPanelPosition() === Position.RIGHT ? 'move-panel-to-bottom' : 'move-panel-to-right'); + this.toDispose = []; + this.toDispose.push(partService.onEditorLayout(() => { + const positionRight = this.partService.getPanelPosition() === Position.RIGHT; + this.class = positionRight ? 'move-panel-to-bottom' : 'move-panel-to-right'; + this.label = positionRight ? TogglePanelPositionAction.MOVE_TO_BOTTOM_LABEL : TogglePanelPositionAction.MOVE_TO_RIGHT_LABEL; + })); + } + + public run(): TPromise { + const position = this.partService.getPanelPosition(); + const newPositionValue = (position === Position.BOTTOM) ? 'right' : 'bottom'; + + return this.configurationService.updateValue(TogglePanelPositionAction.panelPositionConfigurationKey, newPositionValue, ConfigurationTarget.USER); + } + + public dispose(): void { + super.dispose(); + this.toDispose = dispose(this.toDispose); + } +} + export class ToggleMaximizedPanelAction extends Action { public static ID = 'workbench.action.toggleMaximizedPanel'; @@ -169,4 +208,5 @@ const actionRegistry = Registry.as(WorkbenchExtensions actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TogglePanelAction, TogglePanelAction.ID, TogglePanelAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_J }), 'View: Toggle Panel', nls.localize('view', "View")); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPanelAction, FocusPanelAction.ID, FocusPanelAction.LABEL), 'View: Focus into Panel', nls.localize('view', "View")); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleMaximizedPanelAction, ToggleMaximizedPanelAction.ID, ToggleMaximizedPanelAction.LABEL), 'View: Toggle Maximized Panel', nls.localize('view', "View")); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClosePanelAction, ClosePanelAction.ID, ClosePanelAction.LABEL), 'View: Close Panel', nls.localize('view', "View")); \ No newline at end of file +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClosePanelAction, ClosePanelAction.ID, ClosePanelAction.LABEL), 'View: Close Panel', nls.localize('view', "View")); +actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TogglePanelPositionAction, TogglePanelPositionAction.ID, TogglePanelPositionAction.LABEL), 'View: Toggle Panel Position', nls.localize('view', "View")); diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 66485230cdf57..337df2cbcaeb1 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -22,7 +22,7 @@ import { IMessageService } from 'vs/platform/message/common/message'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ClosePanelAction, ToggleMaximizedPanelAction, PanelActivityAction, OpenPanelAction } from 'vs/workbench/browser/parts/panel/panelActions'; +import { ClosePanelAction, ToggleMaximizedPanelAction, TogglePanelPositionAction, PanelActivityAction, OpenPanelAction } from 'vs/workbench/browser/parts/panel/panelActions'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { PANEL_BACKGROUND, PANEL_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER, PANEL_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme'; import { activeContrastBorder, focusBorder, contrastBorder, editorBackground, badgeBackground, badgeForeground } from 'vs/platform/theme/common/colorRegistry'; @@ -120,7 +120,7 @@ export class PanelPart extends CompositePart implements IPanelService { return this._onDidCompositeClose.event; } - protected updateStyles(): void { + public updateStyles(): void { super.updateStyles(); const container = this.getContainer(); @@ -176,6 +176,7 @@ export class PanelPart extends CompositePart implements IPanelService { protected getActions(): IAction[] { return [ this.instantiationService.createInstance(ToggleMaximizedPanelAction, ToggleMaximizedPanelAction.ID, ToggleMaximizedPanelAction.LABEL), + this.instantiationService.createInstance(TogglePanelPositionAction, TogglePanelPositionAction.ID, TogglePanelPositionAction.LABEL), this.instantiationService.createInstance(ClosePanelAction, ClosePanelAction.ID, ClosePanelAction.LABEL) ]; } diff --git a/src/vs/workbench/electron-browser/main.contribution.ts b/src/vs/workbench/electron-browser/main.contribution.ts index 63aed0c15c133..3f29706e8d8ca 100644 --- a/src/vs/workbench/electron-browser/main.contribution.ts +++ b/src/vs/workbench/electron-browser/main.contribution.ts @@ -222,6 +222,12 @@ let workbenchProperties: { [path: string]: IJSONSchema; } = { 'default': 'left', 'description': nls.localize('sideBarLocation', "Controls the location of the sidebar. It can either show on the left or right of the workbench.") }, + 'workbench.panel.location': { + 'type': 'string', + 'enum': ['bottom', 'right'], + 'default': 'bottom', + 'description': nls.localize('panelLocation', "Controls the location of the panel. It can either show on the bottom or right of the workbench.") + }, 'workbench.statusBar.visible': { 'type': 'boolean', 'default': true, diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index f2d871d7eb69c..c74e12ff25206 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -152,6 +152,7 @@ export class Workbench implements IPartService { private static zenModeActiveSettingKey = 'workbench.zenmode.active'; private static sidebarPositionConfigurationKey = 'workbench.sideBar.location'; + private static panelPositionConfigurationKey = 'workbench.panel.location'; private static statusbarVisibleConfigurationKey = 'workbench.statusBar.visible'; private static activityBarVisibleConfigurationKey = 'workbench.activityBar.visible'; @@ -194,6 +195,7 @@ export class Workbench implements IPartService { private statusBarHidden: boolean; private activityBarHidden: boolean; private sideBarPosition: Position; + private panelPosition: Position; private panelHidden: boolean; private editorBackgroundDelayer: Delayer; private closeEmptyWindowScheduler: RunOnceScheduler; @@ -643,6 +645,10 @@ export class Workbench implements IPartService { const sideBarPosition = this.configurationService.getValue(Workbench.sidebarPositionConfigurationKey); this.sideBarPosition = (sideBarPosition === 'right') ? Position.RIGHT : Position.LEFT; + // Panel position + const panelPosition = this.configurationService.getValue(Workbench.panelPositionConfigurationKey); + this.panelPosition = (panelPosition === 'right') ? Position.RIGHT : Position.BOTTOM; + // Statusbar visibility const statusBarVisible = this.configurationService.getValue(Workbench.statusbarVisibleConfigurationKey); this.statusBarHidden = !statusBarVisible; @@ -921,6 +927,30 @@ export class Workbench implements IPartService { this.workbenchLayout.layout(); } + public getPanelPosition(): Position { + return this.panelPosition; + } + + private setPanelPosition(position: Position): void { + if (this.panelHidden) { + this.setPanelHidden(false, true /* Skip Layout */).done(undefined, errors.onUnexpectedError); + } + + const newPositionValue = (position === Position.BOTTOM) ? 'bottom' : 'right'; + const oldPositionValue = (this.panelPosition === Position.BOTTOM) ? 'bottom' : 'right'; + this.panelPosition = position; + + // Adjust CSS + this.panelPart.getContainer().removeClass(oldPositionValue); + this.panelPart.getContainer().addClass(newPositionValue); + + // Update Styles + this.panelPart.updateStyles(); + + // Layout + this.workbenchLayout.layout(); + } + private setFontAliasing(aliasing: string) { this.fontAliasing = aliasing; @@ -1076,6 +1106,12 @@ export class Workbench implements IPartService { this.setSideBarPosition(newSidebarPosition); } + const newPanelPositionValue = this.configurationService.getValue(Workbench.panelPositionConfigurationKey); + const newPanelPosition = (newPanelPositionValue === 'right') ? Position.RIGHT : Position.BOTTOM; + if (newPanelPosition !== this.getSideBarPosition()) { + this.setPanelPosition(newPanelPosition); + } + const fontAliasing = this.configurationService.getValue(Workbench.fontAliasingConfigurationKey); if (fontAliasing !== this.fontAliasing) { this.setFontAliasing(fontAliasing); diff --git a/src/vs/workbench/services/part/common/partService.ts b/src/vs/workbench/services/part/common/partService.ts index 4e41c5df51c4f..ed98549afb00a 100644 --- a/src/vs/workbench/services/part/common/partService.ts +++ b/src/vs/workbench/services/part/common/partService.ts @@ -19,7 +19,8 @@ export enum Parts { export enum Position { LEFT, - RIGHT + RIGHT, + BOTTOM } export interface ILayoutOptions { @@ -107,6 +108,11 @@ export interface IPartService { */ getSideBarPosition(): Position; + /** + * Gets the current panel position. Note that the panel can be hidden too. + */ + getPanelPosition(): Position; + /** * Returns the identifier of the element that contains the workbench. */ diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 262634df4a6eb..89c2c2de9862c 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -426,6 +426,10 @@ export class TestPartService implements IPartService { return 0; } + public getPanelPosition() { + return 0; + } + public addClass(clazz: string): void { } public removeClass(clazz: string): void { } public getWorkbenchElementId(): string { return ''; } From 80f355596b49547f294ba347a4770834e6310c46 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Oct 2017 10:54:40 +0200 Subject: [PATCH 02/13] vertical panel: add a secondary x sash to the workbench layout --- src/vs/workbench/browser/layout.ts | 120 ++++++++++++------ .../workbench/electron-browser/workbench.ts | 2 +- 2 files changed, 82 insertions(+), 40 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 7b4676fee99b0..4e712356d8915 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -45,7 +45,8 @@ interface PartLayoutInfo { */ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontalSashLayoutProvider { - private static sashXWidthSettingsKey = 'workbench.sidebar.width'; + private static sashXOneWidthSettingsKey = 'workbench.sidebar.width'; + private static sashXTwoWidthSettingsKey = 'workbench.panel.width'; private static sashYHeightSettingsKey = 'workbench.panel.height'; private parent: Builder; @@ -60,15 +61,14 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal private toUnbind: IDisposable[]; private partLayoutInfo: PartLayoutInfo; private workbenchSize: Dimension; - private sashX: Sash; + private sashXOne: Sash; + private sashXTwo: Sash; private sashY: Sash; - private startSidebarWidth: number; private sidebarWidth: number; private sidebarHeight: number; private titlebarHeight: number; private activitybarWidth: number; private statusbarHeight: number; - private startPanelHeight: number; private panelHeight: number; private panelHeightBeforeMaximized: number; private panelMaximized: boolean; @@ -110,7 +110,11 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal this.panelHeightBeforeMaximized = 0; this.panelMaximized = false; - this.sashX = new Sash(this.workbenchContainer.getHTMLElement(), this, { + this.sashXOne = new Sash(this.workbenchContainer.getHTMLElement(), this, { + baseSize: 5 + }); + + this.sashXTwo = new Sash(this.workbenchContainer.getHTMLElement(), this, { baseSize: 5 }); @@ -119,8 +123,9 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal orientation: Orientation.HORIZONTAL }); - this.sidebarWidth = this.storageService.getInteger(WorkbenchLayout.sashXWidthSettingsKey, StorageScope.GLOBAL, -1); + this.sidebarWidth = this.storageService.getInteger(WorkbenchLayout.sashXOneWidthSettingsKey, StorageScope.GLOBAL, -1); this.panelHeight = this.storageService.getInteger(WorkbenchLayout.sashYHeightSettingsKey, StorageScope.GLOBAL, 0); + this.panelWidth = this.storageService.getInteger(WorkbenchLayout.sashXTwoWidthSettingsKey, StorageScope.GLOBAL, 0); this.layoutEditorGroupsVertically = (this.editorGroupService.getGroupOrientation() !== 'horizontal'); @@ -158,22 +163,31 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal private registerSashListeners(): void { let startX: number = 0; let startY: number = 0; + let startX2: number = 0; + let startSidebarWidth: number; + let startPanelHeight: number; + let startPanelWidth: number; - this.sashX.addListener('start', (e: ISashEvent) => { - this.startSidebarWidth = this.sidebarWidth; + this.toUnbind.push(this.sashXOne.addListener('start', (e: ISashEvent) => { + startSidebarWidth = this.sidebarWidth; startX = e.startX; - }); + })); - this.sashY.addListener('start', (e: ISashEvent) => { - this.startPanelHeight = this.panelHeight; + this.toUnbind.push(this.sashY.addListener('start', (e: ISashEvent) => { + startPanelHeight = this.panelHeight; startY = e.startY; - }); + })); + + this.toUnbind.push(this.sashXTwo.addListener('start', (e: ISashEvent) => { + startPanelWidth = this.panelWidth; + startX2 = e.startX; + })); - this.sashX.addListener('change', (e: ISashEvent) => { + this.toUnbind.push(this.sashXOne.addListener('change', (e: ISashEvent) => { let doLayout = false; let sidebarPosition = this.partService.getSideBarPosition(); let isSidebarVisible = this.partService.isVisible(Parts.SIDEBAR_PART); - let newSashWidth = (sidebarPosition === Position.LEFT) ? this.startSidebarWidth + e.currentX - startX : this.startSidebarWidth - e.currentX + startX; + let newSashWidth = (sidebarPosition === Position.LEFT) ? startSidebarWidth + e.currentX - startX : startSidebarWidth - e.currentX + startX; let promise = TPromise.as(null); // Sidebar visible @@ -184,7 +198,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal let dragCompensation = MIN_SIDEBAR_PART_WIDTH - HIDE_SIDEBAR_WIDTH_THRESHOLD; promise = this.partService.setSideBarHidden(true); startX = (sidebarPosition === Position.LEFT) ? Math.max(this.activitybarWidth, e.currentX - dragCompensation) : Math.min(e.currentX + dragCompensation, this.workbenchSize.width - this.activitybarWidth); - this.sidebarWidth = this.startSidebarWidth; // when restoring sidebar, restore to the sidebar width we started from + this.sidebarWidth = startSidebarWidth; // when restoring sidebar, restore to the sidebar width we started from } // Otherwise size the sidebar accordingly @@ -198,7 +212,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal else { if ((sidebarPosition === Position.LEFT && e.currentX - startX >= this.partLayoutInfo.sidebar.minWidth) || (sidebarPosition === Position.RIGHT && startX - e.currentX >= this.partLayoutInfo.sidebar.minWidth)) { - this.startSidebarWidth = this.partLayoutInfo.sidebar.minWidth - (sidebarPosition === Position.LEFT ? e.currentX - startX : startX - e.currentX); + startSidebarWidth = this.partLayoutInfo.sidebar.minWidth - (sidebarPosition === Position.LEFT ? e.currentX - startX : startX - e.currentX); this.sidebarWidth = this.partLayoutInfo.sidebar.minWidth; promise = this.partService.setSideBarHidden(false); } @@ -207,12 +221,12 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal if (doLayout) { promise.done(() => this.layout(), errors.onUnexpectedError); } - }); + })); - this.sashY.addListener('change', (e: ISashEvent) => { + this.toUnbind.push(this.sashY.addListener('change', (e: ISashEvent) => { let doLayout = false; let isPanelVisible = this.partService.isVisible(Parts.PANEL_PART); - let newSashHeight = this.startPanelHeight - (e.currentY - startY); + let newSashHeight = startPanelHeight - (e.currentY - startY); let promise = TPromise.as(null); // Panel visible @@ -223,7 +237,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal let dragCompensation = MIN_PANEL_PART_HEIGHT - HIDE_PANEL_HEIGHT_THRESHOLD; promise = this.partService.setPanelHidden(true); startY = Math.min(this.sidebarHeight - this.statusbarHeight - this.titlebarHeight, e.currentY + dragCompensation); - this.panelHeight = this.startPanelHeight; // when restoring panel, restore to the panel height we started from + this.panelHeight = startPanelHeight; // when restoring panel, restore to the panel height we started from } // Otherwise size the panel accordingly @@ -236,7 +250,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal // Panel hidden else { if (startY - e.currentY >= this.partLayoutInfo.panel.minHeight) { - this.startPanelHeight = 0; + startPanelHeight = 0; this.panelHeight = this.partLayoutInfo.panel.minHeight; promise = this.partService.setPanelHidden(false); } @@ -245,29 +259,44 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal if (doLayout) { promise.done(() => this.layout(), errors.onUnexpectedError); } - }); + })); - this.sashX.addListener('end', () => { - this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); - }); + this.toUnbind.push(this.sashXTwo.addListener('change', (e: ISashEvent) => { + console.log('change'); + // TODO@Isidor + })); - this.sashY.addListener('end', () => { + this.toUnbind.push(this.sashXOne.addListener('end', () => { + this.storageService.store(WorkbenchLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); + })); + + this.toUnbind.push(this.sashY.addListener('end', () => { this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); - }); + })); + + this.toUnbind.push(this.sashXTwo.addListener('end', () => { + this.storageService.store(WorkbenchLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); + })); - this.sashY.addListener('reset', () => { + this.toUnbind.push(this.sashY.addListener('reset', () => { this.panelHeight = this.sidebarHeight * DEFAULT_PANEL_HEIGHT_COEFFICIENT; this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); - this.partService.setPanelHidden(false).done(() => this.layout(), errors.onUnexpectedError); - }); + this.layout(); + })); - this.sashX.addListener('reset', () => { + this.toUnbind.push(this.sashXOne.addListener('reset', () => { let activeViewlet = this.viewletService.getActiveViewlet(); let optimalWidth = activeViewlet && activeViewlet.getOptimalWidth(); this.sidebarWidth = Math.max(MIN_SIDEBAR_PART_WIDTH, optimalWidth || 0); - this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); this.partService.setSideBarHidden(false).done(() => this.layout(), errors.onUnexpectedError); - }); + })); + + this.toUnbind.push(this.sashXTwo.addListener('reset', () => { + this.panelWidth = 0; // TODO@ISIDOR + this.storageService.store(WorkbenchLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); + this.layout(); + })); } private onEditorsChanged(): void { @@ -308,6 +337,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal const isStatusbarHidden = !this.partService.isVisible(Parts.STATUSBAR_PART); const isSidebarHidden = !this.partService.isVisible(Parts.SIDEBAR_PART); const sidebarPosition = this.partService.getSideBarPosition(); + const panelPosition = this.partService.getPanelPosition(); // Sidebar let sidebarWidth: number; @@ -409,12 +439,14 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal if (!isSidebarHidden) { this.sidebarWidth = sidebarSize.width; - this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); } if (!isPanelHidden) { this.panelHeight = panelDimension.height; + this.panelWidth = panelDimension.width; this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); + this.storageService.store(WorkbenchLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); } // Workbench @@ -490,8 +522,14 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal this.quickopen.layout(this.workbenchSize); // Sashes - this.sashX.layout(); - this.sashY.layout(); + this.sashXOne.layout(); + if (panelPosition === Position.BOTTOM) { + this.sashY.layout(); + this.sashXTwo.hide(); + } else { + this.sashY.hide(); + this.sashXTwo.layout(); + } // Propagate to Part Layouts this.titlebar.layout(new Dimension(this.workbenchSize.width, this.titlebarHeight)); @@ -511,12 +549,16 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal public getVerticalSashLeft(sash: Sash): number { let isSidebarVisible = this.partService.isVisible(Parts.SIDEBAR_PART); let sidebarPosition = this.partService.getSideBarPosition(); + if (sash === this.sashXOne) { - if (sidebarPosition === Position.LEFT) { - return isSidebarVisible ? this.sidebarWidth + this.activitybarWidth : this.activitybarWidth; + if (sidebarPosition === Position.LEFT) { + return isSidebarVisible ? this.sidebarWidth + this.activitybarWidth : this.activitybarWidth; + } + + return isSidebarVisible ? this.workbenchSize.width - this.sidebarWidth - this.activitybarWidth : this.workbenchSize.width - this.activitybarWidth; } - return isSidebarVisible ? this.workbenchSize.width - this.sidebarWidth - this.activitybarWidth : this.workbenchSize.width - this.activitybarWidth; + return this.workbenchSize.width - this.panelWidth - (sidebarPosition === Position.RIGHT && isSidebarVisible ? this.sidebarWidth + this.activitybarWidth : 0); } public getVerticalSashHeight(sash: Sash): number { diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index c74e12ff25206..53658654eb0a0 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -1226,7 +1226,7 @@ export class Workbench implements IPartService { private createPanelPart(): void { const panelPartContainer = $(this.workbench) .div({ - 'class': ['part', 'panel'], + 'class': ['part', 'panel', this.panelPosition === Position.BOTTOM ? 'bottom' : 'right'], id: Identifiers.PANEL_PART, role: 'complementary' }); From 7975b74757be328c2c12b7947067ef497dbd2821 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Oct 2017 12:02:20 +0200 Subject: [PATCH 03/13] Vertical panel: initial layout --- src/vs/workbench/browser/layout.ts | 126 ++++++++++++++++------------- 1 file changed, 70 insertions(+), 56 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 4e712356d8915..540b7b213735b 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -24,7 +24,8 @@ const MIN_SIDEBAR_PART_WIDTH = 170; const MIN_EDITOR_PART_HEIGHT = 70; const MIN_EDITOR_PART_WIDTH = 220; const MIN_PANEL_PART_HEIGHT = 77; -const DEFAULT_PANEL_HEIGHT_COEFFICIENT = 0.4; +const MIN_PANEL_PART_WIDTH = 150; +const DEFAULT_PANEL_SIZE_COEFFICIENT = 0.4; const HIDE_SIDEBAR_WIDTH_THRESHOLD = 50; const HIDE_PANEL_HEIGHT_THRESHOLD = 50; const TITLE_BAR_HEIGHT = 22; @@ -35,7 +36,7 @@ interface PartLayoutInfo { titlebar: { height: number; }; activitybar: { width: number; }; sidebar: { minWidth: number; }; - panel: { minHeight: number; }; + panel: { minHeight: number; minWidth: number; }; editor: { minWidth: number; minHeight: number; }; statusbar: { height: number; }; } @@ -148,7 +149,8 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal minWidth: MIN_SIDEBAR_PART_WIDTH }, panel: { - minHeight: MIN_PANEL_PART_HEIGHT + minHeight: MIN_PANEL_PART_HEIGHT, + minWidth: MIN_PANEL_PART_WIDTH }, editor: { minWidth: MIN_EDITOR_PART_WIDTH, @@ -279,7 +281,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal })); this.toUnbind.push(this.sashY.addListener('reset', () => { - this.panelHeight = this.sidebarHeight * DEFAULT_PANEL_HEIGHT_COEFFICIENT; + this.panelHeight = this.sidebarHeight * DEFAULT_PANEL_SIZE_COEFFICIENT; this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); this.layout(); })); @@ -363,51 +365,56 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal // Panel part let panelHeight: number; + let panelWidth: number; const editorCountForHeight = this.editorGroupService.getGroupOrientation() === 'horizontal' ? this.editorGroupService.getStacksModel().groups.length : 1; const maxPanelHeight = sidebarSize.height - editorCountForHeight * MIN_EDITOR_PART_HEIGHT; + const maxPanelWidth = this.workbenchSize.width - activityBarSize.width - sidebarSize.width - editorCountForHeight * MIN_EDITOR_PART_WIDTH; + if (isPanelHidden) { panelHeight = 0; - } else if (this.panelHeight === previousMaxPanelHeight) { - panelHeight = maxPanelHeight; - } else if (this.panelHeight > 0) { - panelHeight = Math.min(maxPanelHeight, Math.max(this.partLayoutInfo.panel.minHeight, this.panelHeight)); + panelWidth = 0; + } else if (panelPosition === Position.BOTTOM) { + if (this.panelHeight === previousMaxPanelHeight) { + panelHeight = maxPanelHeight; + } else if (this.panelHeight > 0) { + panelHeight = Math.min(maxPanelHeight, Math.max(this.partLayoutInfo.panel.minHeight, this.panelHeight)); + } else { + panelHeight = sidebarSize.height * DEFAULT_PANEL_SIZE_COEFFICIENT; + } + if (options && options.toggleMaximizedPanel) { + panelHeight = this.panelMaximized ? Math.max(this.partLayoutInfo.panel.minHeight, Math.min(this.panelHeightBeforeMaximized, maxPanelHeight)) : maxPanelHeight; + } + + this.panelMaximized = panelHeight === maxPanelHeight; + if (panelHeight / maxPanelHeight < 0.7) { + // Remember the previous height only if the panel size is not too large. + // To get a nice minimize effect even if a user dragged the panel sash to maximum. + this.panelHeightBeforeMaximized = panelHeight; + } + + panelWidth = this.workbenchSize.width - sidebarSize.width - activityBarSize.width; } else { - panelHeight = sidebarSize.height * DEFAULT_PANEL_HEIGHT_COEFFICIENT; - } - if (options && options.toggleMaximizedPanel) { - panelHeight = this.panelMaximized ? Math.max(this.partLayoutInfo.panel.minHeight, Math.min(this.panelHeightBeforeMaximized, maxPanelHeight)) : maxPanelHeight; - } - this.panelMaximized = panelHeight === maxPanelHeight; - if (panelHeight / maxPanelHeight < 0.7) { - // Remember the previous height only if the panel size is not too large. - // To get a nice minimize effect even if a user dragged the panel sash to maximum. - this.panelHeightBeforeMaximized = panelHeight; + panelHeight = sidebarSize.height; + if (this.panelWidth > 0) { + panelWidth = Math.min(maxPanelWidth, Math.max(this.partLayoutInfo.panel.minWidth, this.panelWidth)); + } else { + panelWidth = (this.workbenchSize.width - activityBarSize.width - sidebarSize.width) * DEFAULT_PANEL_SIZE_COEFFICIENT; + } } - const panelDimension = new Dimension(this.workbenchSize.width - sidebarSize.width - activityBarSize.width, panelHeight); - this.panelWidth = panelDimension.width; + const panelDimension = new Dimension(panelWidth, panelHeight); // Editor let editorSize = { width: 0, - height: 0, - remainderLeft: 0, - remainderRight: 0 + height: 0 }; - editorSize.width = panelDimension.width; - editorSize.height = sidebarSize.height - panelDimension.height; + editorSize.width = this.workbenchSize.width - sidebarSize.width - activityBarSize.width - (panelPosition === Position.RIGHT ? panelDimension.width : 0); + editorSize.height = sidebarSize.height - (panelPosition === Position.BOTTOM ? panelDimension.height : 0); // Sidebar hidden if (isSidebarHidden) { editorSize.width = this.workbenchSize.width - activityBarSize.width; - - if (sidebarPosition === Position.LEFT) { - editorSize.remainderLeft = Math.round((this.workbenchSize.width - editorSize.width + activityBarSize.width) / 2); - editorSize.remainderRight = this.workbenchSize.width - editorSize.width - editorSize.remainderLeft; - } else { - editorSize.remainderRight = Math.round((this.workbenchSize.width - editorSize.width + activityBarSize.width) / 2); - editorSize.remainderLeft = this.workbenchSize.width - editorSize.width - editorSize.remainderRight; - } } // Assert Sidebar and Editor Size to not overflow @@ -422,20 +429,21 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } } - if (editorSize.width < editorMinWidth) { - let diff = editorMinWidth - editorSize.width; - editorSize.width = editorMinWidth; - panelDimension.width = editorMinWidth; - sidebarSize.width -= diff; - sidebarSize.width = Math.max(MIN_SIDEBAR_PART_WIDTH, sidebarSize.width); - } - - if (editorSize.height < editorMinHeight) { - let diff = editorMinHeight - editorSize.height; - editorSize.height = editorMinHeight; - panelDimension.height -= diff; - panelDimension.height = Math.max(MIN_PANEL_PART_HEIGHT, panelDimension.height); - } + // TODO@Isidor + // if (editorSize.width < editorMinWidth) { + // let diff = editorMinWidth - editorSize.width; + // editorSize.width = editorMinWidth; + // panelDimension.width = editorMinWidth; + // sidebarSize.width -= diff; + // sidebarSize.width = Math.max(MIN_SIDEBAR_PART_WIDTH, sidebarSize.width); + // } + + // if (editorSize.height < editorMinHeight) { + // let diff = editorMinHeight - editorSize.height; + // editorSize.height = editorMinHeight; + // panelDimension.height -= diff; + // panelDimension.height = Math.max(MIN_PANEL_PART_HEIGHT, panelDimension.height); + // } if (!isSidebarHidden) { this.sidebarWidth = sidebarSize.width; @@ -474,16 +482,22 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal this.editor.getContainer().size(editorSize.width, editorSize.height); this.panel.getContainer().size(panelDimension.width, panelDimension.height); - const editorBottom = this.statusbarHeight + panelDimension.height; - if (isSidebarHidden) { - this.editor.getContainer().position(this.titlebarHeight, editorSize.remainderRight, editorBottom, editorSize.remainderLeft); - this.panel.getContainer().position(editorSize.height + this.titlebarHeight, editorSize.remainderRight, this.statusbarHeight, editorSize.remainderLeft); - } else if (sidebarPosition === Position.LEFT) { - this.editor.getContainer().position(this.titlebarHeight, 0, editorBottom, sidebarSize.width + activityBarSize.width); - this.panel.getContainer().position(editorSize.height + this.titlebarHeight, 0, this.statusbarHeight, sidebarSize.width + activityBarSize.width); + if (panelPosition === Position.BOTTOM) { + if (sidebarPosition === Position.LEFT) { + this.editor.getContainer().position(this.titlebarHeight, 0, this.statusbarHeight + panelDimension.height, sidebarSize.width + activityBarSize.width); + this.panel.getContainer().position(editorSize.height + this.titlebarHeight, 0, this.statusbarHeight, sidebarSize.width + activityBarSize.width); + } else { + this.editor.getContainer().position(this.titlebarHeight, sidebarSize.width, this.statusbarHeight + panelDimension.height, 0); + this.panel.getContainer().position(editorSize.height + this.titlebarHeight, sidebarSize.width, this.statusbarHeight, 0); + } } else { - this.editor.getContainer().position(this.titlebarHeight, sidebarSize.width, editorBottom, 0); - this.panel.getContainer().position(editorSize.height + this.titlebarHeight, sidebarSize.width, this.statusbarHeight, 0); + if (sidebarPosition === Position.LEFT) { + this.editor.getContainer().position(this.titlebarHeight, panelDimension.width, this.statusbarHeight, sidebarSize.width + activityBarSize.width); + this.panel.getContainer().position(this.titlebarHeight, 0, this.statusbarHeight, sidebarSize.width + activityBarSize.width + editorSize.width); + } else { + this.editor.getContainer().position(this.titlebarHeight, sidebarSize.width + activityBarSize.width + panelWidth, this.statusbarHeight, 0); + this.panel.getContainer().position(this.titlebarHeight, sidebarSize.width + activityBarSize.width, this.statusbarHeight, editorSize.width); + } } // Activity Bar Part From 2aff0adfd127f0325e18100c5df1c343b8bf2971 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Oct 2017 12:16:09 +0200 Subject: [PATCH 04/13] remove ToggleMaxmizedPanelAction --- src/vs/workbench/browser/layout.ts | 15 ++------ .../parts/panel/media/down-inverse.svg | 1 - .../browser/parts/panel/media/down.svg | 1 - .../browser/parts/panel/media/panelpart.css | 18 ---------- .../browser/parts/panel/media/up-inverse.svg | 1 - .../browser/parts/panel/media/up.svg | 1 - .../browser/parts/panel/panelActions.ts | 35 ------------------- .../browser/parts/panel/panelPart.ts | 3 +- .../workbench/electron-browser/workbench.ts | 14 ++------ .../services/part/common/partService.ts | 17 +-------- 10 files changed, 7 insertions(+), 99 deletions(-) delete mode 100755 src/vs/workbench/browser/parts/panel/media/down-inverse.svg delete mode 100755 src/vs/workbench/browser/parts/panel/media/down.svg delete mode 100755 src/vs/workbench/browser/parts/panel/media/up-inverse.svg delete mode 100755 src/vs/workbench/browser/parts/panel/media/up.svg diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 540b7b213735b..0739db695508c 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -11,7 +11,7 @@ import { Part } from 'vs/workbench/browser/part'; import { QuickOpenController } from 'vs/workbench/browser/parts/quickopen/quickOpenController'; import { Sash, ISashEvent, IVerticalSashLayoutProvider, IHorizontalSashLayoutProvider, Orientation } from 'vs/base/browser/ui/sash/sash'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IPartService, Position, ILayoutOptions, Parts } from 'vs/workbench/services/part/common/partService'; +import { IPartService, Position, Parts } from 'vs/workbench/services/part/common/partService'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; @@ -72,7 +72,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal private statusbarHeight: number; private panelHeight: number; private panelHeightBeforeMaximized: number; - private panelMaximized: boolean; private panelWidth: number; private layoutEditorGroupsVertically: boolean; @@ -109,7 +108,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal this.toUnbind = []; this.partLayoutInfo = this.getPartLayoutInfo(); this.panelHeightBeforeMaximized = 0; - this.panelMaximized = false; this.sashXOne = new Sash(this.workbenchContainer.getHTMLElement(), this, { baseSize: 5 @@ -330,7 +328,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } } - public layout(options?: ILayoutOptions): void { + public layout(): void { this.workbenchSize = this.parent.getClientArea(); const isActivityBarHidden = !this.partService.isVisible(Parts.ACTIVITYBAR_PART); @@ -381,11 +379,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } else { panelHeight = sidebarSize.height * DEFAULT_PANEL_SIZE_COEFFICIENT; } - if (options && options.toggleMaximizedPanel) { - panelHeight = this.panelMaximized ? Math.max(this.partLayoutInfo.panel.minHeight, Math.min(this.panelHeightBeforeMaximized, maxPanelHeight)) : maxPanelHeight; - } - - this.panelMaximized = panelHeight === maxPanelHeight; if (panelHeight / maxPanelHeight < 0.7) { // Remember the previous height only if the panel size is not too large. // To get a nice minimize effect even if a user dragged the panel sash to maximum. @@ -592,10 +585,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal return this.panelWidth; } - public isPanelMaximized(): boolean { - return this.panelMaximized; - } - // change part size along the main axis public resizePart(part: Parts, sizeChange: number): void { const visibleEditors = this.editorService.getVisibleEditors().length; diff --git a/src/vs/workbench/browser/parts/panel/media/down-inverse.svg b/src/vs/workbench/browser/parts/panel/media/down-inverse.svg deleted file mode 100755 index d436c7e273547..0000000000000 --- a/src/vs/workbench/browser/parts/panel/media/down-inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/media/down.svg b/src/vs/workbench/browser/parts/panel/media/down.svg deleted file mode 100755 index 279f3570dc8b7..0000000000000 --- a/src/vs/workbench/browser/parts/panel/media/down.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/media/panelpart.css b/src/vs/workbench/browser/parts/panel/media/panelpart.css index 21bcd398c08d3..554d8cd04f6cb 100644 --- a/src/vs/workbench/browser/parts/panel/media/panelpart.css +++ b/src/vs/workbench/browser/parts/panel/media/panelpart.css @@ -88,24 +88,6 @@ background: url('close.svg') center center no-repeat; } -.monaco-workbench .maximize-panel-action { - background: url('up.svg') center center no-repeat; -} - -.vs-dark .monaco-workbench .maximize-panel-action, -.hc-black .monaco-workbench .maximize-panel-action { - background: url('up-inverse.svg') center center no-repeat; -} - -.monaco-workbench .minimize-panel-action { - background: url('down.svg') center center no-repeat; -} - -.vs-dark .monaco-workbench .minimize-panel-action, -.hc-black .monaco-workbench .minimize-panel-action { - background: url('down-inverse.svg') center center no-repeat; -} - .monaco-workbench .move-panel-to-right { background: url('panel-right.svg') center center no-repeat; } diff --git a/src/vs/workbench/browser/parts/panel/media/up-inverse.svg b/src/vs/workbench/browser/parts/panel/media/up-inverse.svg deleted file mode 100755 index 33b7f7c65f6c6..0000000000000 --- a/src/vs/workbench/browser/parts/panel/media/up-inverse.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/media/up.svg b/src/vs/workbench/browser/parts/panel/media/up.svg deleted file mode 100755 index 0033a32716389..0000000000000 --- a/src/vs/workbench/browser/parts/panel/media/up.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/panelActions.ts b/src/vs/workbench/browser/parts/panel/panelActions.ts index bccf5ec0f75d0..866321889e320 100644 --- a/src/vs/workbench/browser/parts/panel/panelActions.ts +++ b/src/vs/workbench/browser/parts/panel/panelActions.ts @@ -156,40 +156,6 @@ export class TogglePanelPositionAction extends Action { } } -export class ToggleMaximizedPanelAction extends Action { - - public static ID = 'workbench.action.toggleMaximizedPanel'; - public static LABEL = nls.localize('toggleMaximizedPanel', "Toggle Maximized Panel"); - private static MAXIMIZE_LABEL = nls.localize('maximizePanel', "Maximize Panel Size"); - private static RESTORE_LABEL = nls.localize('minimizePanel', "Restore Panel Size"); - private toDispose: IDisposable[]; - - constructor( - id: string, - label: string, - @IPartService private partService: IPartService - ) { - super(id, label, partService.isPanelMaximized() ? 'minimize-panel-action' : 'maximize-panel-action'); - this.toDispose = []; - this.toDispose.push(partService.onEditorLayout(() => { - const maximized = this.partService.isPanelMaximized(); - this.class = maximized ? 'minimize-panel-action' : 'maximize-panel-action'; - this.label = maximized ? ToggleMaximizedPanelAction.RESTORE_LABEL : ToggleMaximizedPanelAction.MAXIMIZE_LABEL; - })); - } - - public run(): TPromise { - // Show panel - return this.partService.setPanelHidden(false) - .then(() => this.partService.toggleMaximizedPanel()); - } - - public dispose(): void { - super.dispose(); - this.toDispose = dispose(this.toDispose); - } -} - export class PanelActivityAction extends ActivityAction { constructor( @@ -207,6 +173,5 @@ export class PanelActivityAction extends ActivityAction { const actionRegistry = Registry.as(WorkbenchExtensions.WorkbenchActions); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TogglePanelAction, TogglePanelAction.ID, TogglePanelAction.LABEL, { primary: KeyMod.CtrlCmd | KeyCode.KEY_J }), 'View: Toggle Panel', nls.localize('view', "View")); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(FocusPanelAction, FocusPanelAction.ID, FocusPanelAction.LABEL), 'View: Focus into Panel', nls.localize('view', "View")); -actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleMaximizedPanelAction, ToggleMaximizedPanelAction.ID, ToggleMaximizedPanelAction.LABEL), 'View: Toggle Maximized Panel', nls.localize('view', "View")); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClosePanelAction, ClosePanelAction.ID, ClosePanelAction.LABEL), 'View: Close Panel', nls.localize('view', "View")); actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(TogglePanelPositionAction, TogglePanelPositionAction.ID, TogglePanelPositionAction.LABEL), 'View: Toggle Panel Position', nls.localize('view', "View")); diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 337df2cbcaeb1..b2ec9634027aa 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -22,7 +22,7 @@ import { IMessageService } from 'vs/platform/message/common/message'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ClosePanelAction, ToggleMaximizedPanelAction, TogglePanelPositionAction, PanelActivityAction, OpenPanelAction } from 'vs/workbench/browser/parts/panel/panelActions'; +import { ClosePanelAction, TogglePanelPositionAction, PanelActivityAction, OpenPanelAction } from 'vs/workbench/browser/parts/panel/panelActions'; import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService'; import { PANEL_BACKGROUND, PANEL_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER, PANEL_DRAG_AND_DROP_BACKGROUND } from 'vs/workbench/common/theme'; import { activeContrastBorder, focusBorder, contrastBorder, editorBackground, badgeBackground, badgeForeground } from 'vs/platform/theme/common/colorRegistry'; @@ -175,7 +175,6 @@ export class PanelPart extends CompositePart implements IPanelService { protected getActions(): IAction[] { return [ - this.instantiationService.createInstance(ToggleMaximizedPanelAction, ToggleMaximizedPanelAction.ID, ToggleMaximizedPanelAction.LABEL), this.instantiationService.createInstance(TogglePanelPositionAction, TogglePanelPositionAction.ID, TogglePanelPositionAction.LABEL), this.instantiationService.createInstance(ClosePanelAction, ClosePanelAction.ID, ClosePanelAction.LABEL) ]; diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 53658654eb0a0..d37f4acba1412 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -38,7 +38,7 @@ import { IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs/workbe import { PanelRegistry, Extensions as PanelExtensions } from 'vs/workbench/browser/panel'; import { QuickOpenController } from 'vs/workbench/browser/parts/quickopen/quickOpenController'; import { getServices } from 'vs/platform/instantiation/common/extensions'; -import { Position, Parts, IPartService, ILayoutOptions } from 'vs/workbench/services/part/common/partService'; +import { Position, Parts, IPartService } from 'vs/workbench/services/part/common/partService'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ContextMenuService } from 'vs/workbench/services/contextview/electron-browser/contextmenuService'; @@ -892,14 +892,6 @@ export class Workbench implements IPartService { }); } - public toggleMaximizedPanel(): void { - this.workbenchLayout.layout({ toggleMaximizedPanel: true }); - } - - public isPanelMaximized(): boolean { - return this.workbenchLayout.isPanelMaximized(); - } - public getSideBarPosition(): Position { return this.sideBarPosition; } @@ -970,9 +962,9 @@ export class Workbench implements IPartService { * Asks the workbench and all its UI components inside to lay out according to * the containers dimension the workbench is living in. */ - public layout(options?: ILayoutOptions): void { + public layout(): void { if (this.isStarted()) { - this.workbenchLayout.layout(options); + this.workbenchLayout.layout(); } } diff --git a/src/vs/workbench/services/part/common/partService.ts b/src/vs/workbench/services/part/common/partService.ts index ed98549afb00a..47a45649559b7 100644 --- a/src/vs/workbench/services/part/common/partService.ts +++ b/src/vs/workbench/services/part/common/partService.ts @@ -23,10 +23,6 @@ export enum Position { BOTTOM } -export interface ILayoutOptions { - toggleMaximizedPanel?: boolean; -} - export const IPartService = createDecorator('partService'); export interface IPartService { @@ -45,7 +41,7 @@ export interface IPartService { /** * Asks the part service to layout all parts. */ - layout(options?: ILayoutOptions): void; + layout(): void; /** * Asks the part service to if all parts have been created. @@ -92,17 +88,6 @@ export interface IPartService { */ setPanelHidden(hidden: boolean): TPromise; - /** - * Maximizes the panel height if the panel is not already maximized. - * Shrinks the panel to the default starting size if the panel is maximized. - */ - toggleMaximizedPanel(): void; - - /** - * Returns true if the panel is maximized. - */ - isPanelMaximized(): boolean; - /** * Gets the current side bar position. Note that the sidebar can be hidden too. */ From 1bbc6bc805384b64b28a509087034aa1e36c8186 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Oct 2017 12:55:55 +0200 Subject: [PATCH 05/13] vertical panel: react on changes from second X sash --- src/vs/workbench/browser/layout.ts | 84 +++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 0739db695508c..d0f9a4e4c009e 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -28,6 +28,7 @@ const MIN_PANEL_PART_WIDTH = 150; const DEFAULT_PANEL_SIZE_COEFFICIENT = 0.4; const HIDE_SIDEBAR_WIDTH_THRESHOLD = 50; const HIDE_PANEL_HEIGHT_THRESHOLD = 50; +const HIDE_PANEL_WIDTH_THRESHOLD = 100; const TITLE_BAR_HEIGHT = 22; const STATUS_BAR_HEIGHT = 22; const ACTIVITY_BAR_WIDTH = 50; @@ -163,7 +164,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal private registerSashListeners(): void { let startX: number = 0; let startY: number = 0; - let startX2: number = 0; + let startXTwo: number = 0; let startSidebarWidth: number; let startPanelHeight: number; let startPanelWidth: number; @@ -180,7 +181,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal this.toUnbind.push(this.sashXTwo.addListener('start', (e: ISashEvent) => { startPanelWidth = this.panelWidth; - startX2 = e.startX; + startXTwo = e.startX; })); this.toUnbind.push(this.sashXOne.addListener('change', (e: ISashEvent) => { @@ -262,8 +263,41 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal })); this.toUnbind.push(this.sashXTwo.addListener('change', (e: ISashEvent) => { - console.log('change'); - // TODO@Isidor + let doLayout = false; + let isPanelVisible = this.partService.isVisible(Parts.PANEL_PART); + let newSashWidth = startPanelWidth - (e.currentX - startXTwo); + let promise = TPromise.as(null); + + // Panel visible + if (isPanelVisible) { + + // Automatically hide panel when a certain threshold is met + if (newSashWidth + HIDE_PANEL_WIDTH_THRESHOLD < this.partLayoutInfo.panel.minWidth) { + let dragCompensation = MIN_PANEL_PART_WIDTH - HIDE_PANEL_WIDTH_THRESHOLD; + promise = this.partService.setPanelHidden(true); + startXTwo = Math.min(this.workbenchSize.width - this.activitybarWidth, e.currentX + dragCompensation); + this.panelWidth = startPanelWidth; // when restoring panel, restore to the panel height we started from + } + + // Otherwise size the panel accordingly + else { + this.panelWidth = Math.max(this.partLayoutInfo.panel.minWidth, newSashWidth); // Panel can not become smaller than MIN_PART_HEIGHT + doLayout = newSashWidth >= this.partLayoutInfo.panel.minWidth; + } + } + + // Panel hidden + else { + if (startXTwo - e.currentX >= this.partLayoutInfo.panel.minWidth) { + startPanelWidth = 0; + this.panelWidth = this.partLayoutInfo.panel.minWidth; + promise = this.partService.setPanelHidden(false); + } + } + + if (doLayout) { + promise.done(() => this.layout(), errors.onUnexpectedError); + } })); this.toUnbind.push(this.sashXOne.addListener('end', () => { @@ -293,7 +327,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal })); this.toUnbind.push(this.sashXTwo.addListener('reset', () => { - this.panelWidth = 0; // TODO@ISIDOR + this.panelWidth = (this.workbenchSize.width - this.sidebarWidth - this.activitybarWidth) * DEFAULT_PANEL_SIZE_COEFFICIENT; this.storageService.store(WorkbenchLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); this.layout(); })); @@ -405,11 +439,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal editorSize.width = this.workbenchSize.width - sidebarSize.width - activityBarSize.width - (panelPosition === Position.RIGHT ? panelDimension.width : 0); editorSize.height = sidebarSize.height - (panelPosition === Position.BOTTOM ? panelDimension.height : 0); - // Sidebar hidden - if (isSidebarHidden) { - editorSize.width = this.workbenchSize.width - activityBarSize.width; - } - // Assert Sidebar and Editor Size to not overflow let editorMinWidth = this.partLayoutInfo.editor.minWidth; let editorMinHeight = this.partLayoutInfo.editor.minHeight; @@ -422,21 +451,26 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } } - // TODO@Isidor - // if (editorSize.width < editorMinWidth) { - // let diff = editorMinWidth - editorSize.width; - // editorSize.width = editorMinWidth; - // panelDimension.width = editorMinWidth; - // sidebarSize.width -= diff; - // sidebarSize.width = Math.max(MIN_SIDEBAR_PART_WIDTH, sidebarSize.width); - // } - - // if (editorSize.height < editorMinHeight) { - // let diff = editorMinHeight - editorSize.height; - // editorSize.height = editorMinHeight; - // panelDimension.height -= diff; - // panelDimension.height = Math.max(MIN_PANEL_PART_HEIGHT, panelDimension.height); - // } + if (editorSize.width < editorMinWidth) { + let diff = editorMinWidth - editorSize.width; + editorSize.width = editorMinWidth; + if (panelPosition === Position.BOTTOM) { + panelDimension.width = editorMinWidth; + } else { + // TODO@Isidor might need to reduce panel size and only then recude sidebar size + } + + sidebarSize.width -= diff; + sidebarSize.width = Math.max(MIN_SIDEBAR_PART_WIDTH, sidebarSize.width); + } + + if (editorSize.height < editorMinHeight && panelPosition === Position.BOTTOM) { + let diff = editorMinHeight - editorSize.height; + editorSize.height = editorMinHeight; + + panelDimension.height -= diff; + panelDimension.height = Math.max(MIN_PANEL_PART_HEIGHT, panelDimension.height); + } if (!isSidebarHidden) { this.sidebarWidth = sidebarSize.width; From c18a3fd5185a829ce58501efcd9d852bcfb1189e Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Oct 2017 16:21:50 +0200 Subject: [PATCH 06/13] vertical panel: fix borders --- .../browser/parts/panel/media/panelpart.css | 12 ++++++++++-- src/vs/workbench/browser/parts/panel/panelPart.ts | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/panel/media/panelpart.css b/src/vs/workbench/browser/parts/panel/media/panelpart.css index 554d8cd04f6cb..821ae39094534 100644 --- a/src/vs/workbench/browser/parts/panel/media/panelpart.css +++ b/src/vs/workbench/browser/parts/panel/media/panelpart.css @@ -13,8 +13,6 @@ } .monaco-workbench > .part.panel .title { - border-top-width: 1px; - border-top-style: solid; padding-right: 0px; height: 35px; display: flex; @@ -22,6 +20,16 @@ justify-content: space-between; } +.monaco-workbench > .part.panel.bottom .title { + border-top-width: 1px; + border-top-style: solid; +} + +.monaco-workbench > .part.panel.right { + border-left-width: 1px; + border-left-style: solid; +} + .monaco-workbench > .part.panel > .composite.title > .title-actions { flex: 0; } diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index b2ec9634027aa..6de483e3d2368 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -125,6 +125,7 @@ export class PanelPart extends CompositePart implements IPanelService { const container = this.getContainer(); container.style('background-color', this.getColor(PANEL_BACKGROUND)); + container.style('border-left-color', this.getColor(PANEL_BORDER) || this.getColor(contrastBorder)); const title = this.getTitleArea(); title.style('border-top-color', this.getColor(PANEL_BORDER) || this.getColor(contrastBorder)); From d7020488d5e90361e919154f69b450cb2396c592 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Oct 2017 16:24:41 +0200 Subject: [PATCH 07/13] layout: better min and max boundary computations --- src/vs/workbench/browser/layout.ts | 113 +++++++++++++++++++---------- 1 file changed, 75 insertions(+), 38 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index d0f9a4e4c009e..591c40f024e9b 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -66,14 +66,13 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal private sashXOne: Sash; private sashXTwo: Sash; private sashY: Sash; - private sidebarWidth: number; + private _sidebarWidth: number; private sidebarHeight: number; private titlebarHeight: number; private activitybarWidth: number; private statusbarHeight: number; - private panelHeight: number; - private panelHeightBeforeMaximized: number; - private panelWidth: number; + private _panelHeight: number; + private _panelWidth: number; private layoutEditorGroupsVertically: boolean; // Take parts as an object bag since instatation service does not have typings for constructors with 9+ arguments @@ -108,7 +107,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal this.quickopen = quickopen; this.toUnbind = []; this.partLayoutInfo = this.getPartLayoutInfo(); - this.panelHeightBeforeMaximized = 0; this.sashXOne = new Sash(this.workbenchContainer.getHTMLElement(), this, { baseSize: 5 @@ -123,9 +121,9 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal orientation: Orientation.HORIZONTAL }); - this.sidebarWidth = this.storageService.getInteger(WorkbenchLayout.sashXOneWidthSettingsKey, StorageScope.GLOBAL, -1); - this.panelHeight = this.storageService.getInteger(WorkbenchLayout.sashYHeightSettingsKey, StorageScope.GLOBAL, 0); - this.panelWidth = this.storageService.getInteger(WorkbenchLayout.sashXTwoWidthSettingsKey, StorageScope.GLOBAL, 0); + this._sidebarWidth = this.storageService.getInteger(WorkbenchLayout.sashXOneWidthSettingsKey, StorageScope.GLOBAL, -1); + this._panelHeight = this.storageService.getInteger(WorkbenchLayout.sashYHeightSettingsKey, StorageScope.GLOBAL, 0); + this._panelWidth = this.storageService.getInteger(WorkbenchLayout.sashXTwoWidthSettingsKey, StorageScope.GLOBAL, 0); this.layoutEditorGroupsVertically = (this.editorGroupService.getGroupOrientation() !== 'horizontal'); @@ -136,6 +134,48 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal this.registerSashListeners(); } + private get panelHeight(): number { + const panelPosition = this.partService.getPanelPosition(); + if (panelPosition === Position.RIGHT) { + return this.sidebarHeight; + } + + return this._panelHeight; + } + + private set panelHeight(value: number) { + const editorCountForHeight = this.editorGroupService.getGroupOrientation() === 'horizontal' ? this.editorGroupService.getStacksModel().groups.length : 1; + const maxPanelHeight = this.sidebarHeight - editorCountForHeight * MIN_EDITOR_PART_HEIGHT; + this._panelHeight = Math.min(maxPanelHeight, Math.max(this.partLayoutInfo.panel.minHeight, value)); + } + + private get panelWidth(): number { + const panelPosition = this.partService.getPanelPosition(); + if (panelPosition === Position.BOTTOM) { + return this.workbenchSize.width - this.activitybarWidth - this.sidebarWidth; + } + + return this._panelWidth; + } + + private set panelWidth(value: number) { + const editorCountForWidth = this.editorGroupService.getGroupOrientation() === 'vertical' ? this.editorGroupService.getStacksModel().groups.length : 1; + const maxPanelWidth = this.workbenchSize.width - editorCountForWidth * MIN_EDITOR_PART_WIDTH - this.sidebarWidth - this.activitybarWidth; + this._panelWidth = Math.min(maxPanelWidth, Math.max(this.partLayoutInfo.panel.minWidth, value)); + } + + private get sidebarWidth(): number { + if (this.partService.isVisible(Parts.SIDEBAR_PART)) { + return this._sidebarWidth; + } + + return 0; + } + + private set sidebarWidth(value: number) { + this._sidebarWidth = Math.max(this.partLayoutInfo.sidebar.minWidth, value); + } + private getPartLayoutInfo(): PartLayoutInfo { return { titlebar: { @@ -281,7 +321,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal // Otherwise size the panel accordingly else { - this.panelWidth = Math.max(this.partLayoutInfo.panel.minWidth, newSashWidth); // Panel can not become smaller than MIN_PART_HEIGHT + this.panelWidth = newSashWidth; doLayout = newSashWidth >= this.partLayoutInfo.panel.minWidth; } } @@ -321,7 +361,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal this.toUnbind.push(this.sashXOne.addListener('reset', () => { let activeViewlet = this.viewletService.getActiveViewlet(); let optimalWidth = activeViewlet && activeViewlet.getOptimalWidth(); - this.sidebarWidth = Math.max(MIN_SIDEBAR_PART_WIDTH, optimalWidth || 0); + this.sidebarWidth = optimalWidth || 0; this.storageService.store(WorkbenchLayout.sashXOneWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); this.partService.setSideBarHidden(false).done(() => this.layout(), errors.onUnexpectedError); })); @@ -374,14 +414,10 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal const panelPosition = this.partService.getPanelPosition(); // Sidebar - let sidebarWidth: number; - if (isSidebarHidden) { - sidebarWidth = 0; - } else if (this.sidebarWidth !== -1) { - sidebarWidth = Math.max(this.partLayoutInfo.sidebar.minWidth, this.sidebarWidth); + if (this.sidebarWidth !== -1) { + this.sidebarWidth = Math.max(this.partLayoutInfo.sidebar.minWidth, this.sidebarWidth); } else { - sidebarWidth = this.workbenchSize.width / 5; - this.sidebarWidth = sidebarWidth; + this.sidebarWidth = this.workbenchSize.width / 5; } this.statusbarHeight = isStatusbarHidden ? 0 : this.partLayoutInfo.statusbar.height; @@ -389,7 +425,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal const previousMaxPanelHeight = this.sidebarHeight - MIN_EDITOR_PART_HEIGHT; this.sidebarHeight = this.workbenchSize.height - this.statusbarHeight - this.titlebarHeight; - let sidebarSize = new Dimension(sidebarWidth, this.sidebarHeight); + let sidebarSize = new Dimension(this.sidebarWidth, this.sidebarHeight); // Activity Bar this.activitybarWidth = isActivityBarHidden ? 0 : this.partLayoutInfo.activitybar.width; @@ -413,11 +449,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } else { panelHeight = sidebarSize.height * DEFAULT_PANEL_SIZE_COEFFICIENT; } - if (panelHeight / maxPanelHeight < 0.7) { - // Remember the previous height only if the panel size is not too large. - // To get a nice minimize effect even if a user dragged the panel sash to maximum. - this.panelHeightBeforeMaximized = panelHeight; - } panelWidth = this.workbenchSize.width - sidebarSize.width - activityBarSize.width; } else { @@ -478,10 +509,13 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } if (!isPanelHidden) { - this.panelHeight = panelDimension.height; - this.panelWidth = panelDimension.width; - this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); - this.storageService.store(WorkbenchLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); + if (panelPosition === Position.BOTTOM) { + this.panelHeight = panelDimension.height; + this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); + } else { + this.panelWidth = panelDimension.width; + this.storageService.store(WorkbenchLayout.sashXTwoWidthSettingsKey, this.panelWidth, StorageScope.GLOBAL); + } } // Workbench @@ -565,11 +599,13 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal // Sashes this.sashXOne.layout(); if (panelPosition === Position.BOTTOM) { - this.sashY.layout(); this.sashXTwo.hide(); + this.sashY.layout(); + this.sashY.show(); } else { this.sashY.hide(); this.sashXTwo.layout(); + this.sashXTwo.show(); } // Propagate to Part Layouts @@ -588,18 +624,17 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } public getVerticalSashLeft(sash: Sash): number { - let isSidebarVisible = this.partService.isVisible(Parts.SIDEBAR_PART); let sidebarPosition = this.partService.getSideBarPosition(); if (sash === this.sashXOne) { if (sidebarPosition === Position.LEFT) { - return isSidebarVisible ? this.sidebarWidth + this.activitybarWidth : this.activitybarWidth; + return this.sidebarWidth + this.activitybarWidth; } - return isSidebarVisible ? this.workbenchSize.width - this.sidebarWidth - this.activitybarWidth : this.workbenchSize.width - this.activitybarWidth; + return this.workbenchSize.width - this.sidebarWidth - this.activitybarWidth; } - return this.workbenchSize.width - this.panelWidth - (sidebarPosition === Position.RIGHT && isSidebarVisible ? this.sidebarWidth + this.activitybarWidth : 0); + return this.workbenchSize.width - this.panelWidth - (sidebarPosition === Position.RIGHT ? this.sidebarWidth + this.activitybarWidth : 0); } public getVerticalSashHeight(sash: Sash): number { @@ -612,7 +647,11 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } public getHorizontalSashLeft(sash: Sash): number { - return this.partService.getSideBarPosition() === Position.LEFT ? this.getVerticalSashLeft(sash) : 0; + if (this.partService.getSideBarPosition() === Position.RIGHT) { + return 0; + } + + return this.sidebarWidth + this.activitybarWidth; } public getHorizontalSashWidth(sash: Sash): number { @@ -626,12 +665,10 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal const sizeChangePxHeight = this.workbenchSize.height * (sizeChange / 100); let doLayout = false; - let newSashSize: number = 0; switch (part) { case Parts.SIDEBAR_PART: - newSashSize = this.sidebarWidth + sizeChangePxWidth; - this.sidebarWidth = Math.max(this.partLayoutInfo.sidebar.minWidth, newSashSize); // Sidebar can not become smaller than MIN_PART_WIDTH + this.sidebarWidth = this.sidebarWidth + sizeChangePxWidth; // Sidebar can not become smaller than MIN_PART_WIDTH if (this.layoutEditorGroupsVertically && (this.workbenchSize.width - this.sidebarWidth < visibleEditors * MIN_EDITOR_PART_WIDTH)) { this.sidebarWidth = (this.workbenchSize.width - visibleEditors * MIN_EDITOR_PART_WIDTH); @@ -640,8 +677,8 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal doLayout = true; break; case Parts.PANEL_PART: - newSashSize = this.panelHeight + sizeChangePxHeight; - this.panelHeight = Math.max(this.partLayoutInfo.panel.minHeight, newSashSize); + this.panelHeight = this.panelHeight + sizeChangePxHeight; + this.panelWidth = this.panelWidth + sizeChangePxWidth; doLayout = true; break; case Parts.EDITOR_PART: From 1ffcfc3ae479204a52047b2e86a47cdbe1f927ff Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Oct 2017 16:26:31 +0200 Subject: [PATCH 08/13] layout: remove unneeded todo --- src/vs/workbench/browser/layout.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 591c40f024e9b..b17221162b8f9 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -487,8 +487,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal editorSize.width = editorMinWidth; if (panelPosition === Position.BOTTOM) { panelDimension.width = editorMinWidth; - } else { - // TODO@Isidor might need to reduce panel size and only then recude sidebar size } sidebarSize.width -= diff; From 42e690c8f99c6a562223903b6cf6d4aa97e2189a Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Oct 2017 16:30:34 +0200 Subject: [PATCH 09/13] vertical panel: use tmp hacky transform to get a inverse icon --- src/vs/workbench/browser/parts/panel/media/panelpart.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/panel/media/panelpart.css b/src/vs/workbench/browser/parts/panel/media/panelpart.css index 821ae39094534..7a3ac428ca337 100644 --- a/src/vs/workbench/browser/parts/panel/media/panelpart.css +++ b/src/vs/workbench/browser/parts/panel/media/panelpart.css @@ -102,7 +102,8 @@ .vs-dark .monaco-workbench .move-panel-to-right, .hc-black .monaco-workbench .move-panel-to-right { - background: url('panel-right-inverse.svg') center center no-repeat; + background: url('panel-right.svg') center center no-repeat; + transform: rotate(180deg) } .monaco-workbench .move-panel-to-bottom { @@ -111,7 +112,8 @@ .vs-dark .monaco-workbench .move-panel-to-bottom, .hc-black .monaco-workbench .move-panel-to-bottom { - background: url('panel-bottom-inverse.svg') center center no-repeat; + background: url('panel-bottom.svg') center center no-repeat; + transform: rotate(180deg) } .vs-dark .monaco-workbench .hide-panel-action, From 757bf29c93f3434e224d093558d64b054928d277 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 24 Oct 2017 16:42:20 +0200 Subject: [PATCH 10/13] composite bar fix min width issue --- src/vs/workbench/browser/layout.ts | 2 +- src/vs/workbench/browser/parts/compositebar/compositeBar.ts | 2 +- src/vs/workbench/browser/parts/panel/panelPart.ts | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index b17221162b8f9..d298147bd8ea6 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -24,7 +24,7 @@ const MIN_SIDEBAR_PART_WIDTH = 170; const MIN_EDITOR_PART_HEIGHT = 70; const MIN_EDITOR_PART_WIDTH = 220; const MIN_PANEL_PART_HEIGHT = 77; -const MIN_PANEL_PART_WIDTH = 150; +const MIN_PANEL_PART_WIDTH = 220; const DEFAULT_PANEL_SIZE_COEFFICIENT = 0.4; const HIDE_SIDEBAR_WIDTH_THRESHOLD = 50; const HIDE_PANEL_HEIGHT_THRESHOLD = 50; diff --git a/src/vs/workbench/browser/parts/compositebar/compositeBar.ts b/src/vs/workbench/browser/parts/compositebar/compositeBar.ts index bbc336984018e..2a1a311acfee0 100644 --- a/src/vs/workbench/browser/parts/compositebar/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositebar/compositeBar.ts @@ -281,7 +281,7 @@ export class CompositeBar implements ICompositeBar { } // Add overflow action as needed - if (visibleCompositesChange && overflows) { + if ((visibleCompositesChange && overflows) || this.compositeSwitcherBar.length() === 0) { this.compositeOverflowAction = this.instantiationService.createInstance(CompositeOverflowActivityAction, () => this.compositeOverflowActionItem.showMenu()); this.compositeOverflowActionItem = this.instantiationService.createInstance( CompositeOverflowActivityActionItem, diff --git a/src/vs/workbench/browser/parts/panel/panelPart.ts b/src/vs/workbench/browser/parts/panel/panelPart.ts index 6de483e3d2368..949d3135c5272 100644 --- a/src/vs/workbench/browser/parts/panel/panelPart.ts +++ b/src/vs/workbench/browser/parts/panel/panelPart.ts @@ -36,6 +36,7 @@ export class PanelPart extends CompositePart implements IPanelService { public static activePanelSettingsKey = 'workbench.panelpart.activepanelid'; private static readonly PINNED_PANELS = 'workbench.panel.pinnedPanels'; + private static readonly MIN_COMPOSITE_BAR_WIDTH = 50; public _serviceBrand: any; @@ -225,7 +226,7 @@ export class PanelPart extends CompositePart implements IPanelService { let availableWidth = this.dimension.width - 8; // take padding into account if (this.toolBar) { // adjust height for global actions showing - availableWidth -= this.toolBar.getContainer().getHTMLElement().offsetWidth; + availableWidth = Math.max(PanelPart.MIN_COMPOSITE_BAR_WIDTH, availableWidth - this.toolBar.getContainer().getHTMLElement().offsetWidth); } this.compositeBar.layout(new Dimension(availableWidth, this.dimension.height)); } From 88e780aa6a5e200a9cf926628286dad8f6cf32a7 Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 25 Oct 2017 11:07:00 +0200 Subject: [PATCH 11/13] vertical panel: proper icons --- .../browser/parts/panel/media/panel-bottom-inverse.svg | 1 + src/vs/workbench/browser/parts/panel/media/panel-bottom.svg | 2 +- .../browser/parts/panel/media/panel-right-inverse.svg | 1 + src/vs/workbench/browser/parts/panel/media/panel-right.svg | 2 +- src/vs/workbench/browser/parts/panel/media/panelpart.css | 6 ++---- 5 files changed, 6 insertions(+), 6 deletions(-) create mode 100755 src/vs/workbench/browser/parts/panel/media/panel-bottom-inverse.svg mode change 100644 => 100755 src/vs/workbench/browser/parts/panel/media/panel-bottom.svg create mode 100755 src/vs/workbench/browser/parts/panel/media/panel-right-inverse.svg mode change 100644 => 100755 src/vs/workbench/browser/parts/panel/media/panel-right.svg diff --git a/src/vs/workbench/browser/parts/panel/media/panel-bottom-inverse.svg b/src/vs/workbench/browser/parts/panel/media/panel-bottom-inverse.svg new file mode 100755 index 0000000000000..f9aa418241a0e --- /dev/null +++ b/src/vs/workbench/browser/parts/panel/media/panel-bottom-inverse.svg @@ -0,0 +1 @@ +BottomRowOfTwoRows_16x \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/media/panel-bottom.svg b/src/vs/workbench/browser/parts/panel/media/panel-bottom.svg old mode 100644 new mode 100755 index 4750174b6c1ce..780681f19e5f8 --- a/src/vs/workbench/browser/parts/panel/media/panel-bottom.svg +++ b/src/vs/workbench/browser/parts/panel/media/panel-bottom.svg @@ -1 +1 @@ - \ No newline at end of file +BottomRowOfTwoRows_16x \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/media/panel-right-inverse.svg b/src/vs/workbench/browser/parts/panel/media/panel-right-inverse.svg new file mode 100755 index 0000000000000..428206fb117ee --- /dev/null +++ b/src/vs/workbench/browser/parts/panel/media/panel-right-inverse.svg @@ -0,0 +1 @@ +RightColumnOfTwoColumns_16x \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/media/panel-right.svg b/src/vs/workbench/browser/parts/panel/media/panel-right.svg old mode 100644 new mode 100755 index 35cf0a522c3ed..3b7b808f9ab9c --- a/src/vs/workbench/browser/parts/panel/media/panel-right.svg +++ b/src/vs/workbench/browser/parts/panel/media/panel-right.svg @@ -1 +1 @@ - \ No newline at end of file +RightColumnOfTwoColumns_16x \ No newline at end of file diff --git a/src/vs/workbench/browser/parts/panel/media/panelpart.css b/src/vs/workbench/browser/parts/panel/media/panelpart.css index 7a3ac428ca337..821ae39094534 100644 --- a/src/vs/workbench/browser/parts/panel/media/panelpart.css +++ b/src/vs/workbench/browser/parts/panel/media/panelpart.css @@ -102,8 +102,7 @@ .vs-dark .monaco-workbench .move-panel-to-right, .hc-black .monaco-workbench .move-panel-to-right { - background: url('panel-right.svg') center center no-repeat; - transform: rotate(180deg) + background: url('panel-right-inverse.svg') center center no-repeat; } .monaco-workbench .move-panel-to-bottom { @@ -112,8 +111,7 @@ .vs-dark .monaco-workbench .move-panel-to-bottom, .hc-black .monaco-workbench .move-panel-to-bottom { - background: url('panel-bottom.svg') center center no-repeat; - transform: rotate(180deg) + background: url('panel-bottom-inverse.svg') center center no-repeat; } .vs-dark .monaco-workbench .hide-panel-action, From fb9f0a6594d32155d9984d47a315de3a8a50d47e Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 25 Oct 2017 11:32:31 +0200 Subject: [PATCH 12/13] vertical panel: fix sidebar max value --- src/vs/workbench/browser/layout.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index d298147bd8ea6..04f77dd11bb3b 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -69,7 +69,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal private _sidebarWidth: number; private sidebarHeight: number; private titlebarHeight: number; - private activitybarWidth: number; private statusbarHeight: number; private _panelHeight: number; private _panelWidth: number; @@ -134,6 +133,14 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal this.registerSashListeners(); } + private get activitybarWidth(): number { + if (this.partService.isVisible(Parts.ACTIVITYBAR_PART)) { + return this.partLayoutInfo.activitybar.width; + } + + return 0; + } + private get panelHeight(): number { const panelPosition = this.partService.getPanelPosition(); if (panelPosition === Position.RIGHT) { @@ -173,7 +180,10 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } private set sidebarWidth(value: number) { - this._sidebarWidth = Math.max(this.partLayoutInfo.sidebar.minWidth, value); + const editorCountForWidth = this.editorGroupService.getGroupOrientation() === 'vertical' ? this.editorGroupService.getStacksModel().groups.length : 1; + const panelMinWidth = this.partService.getPanelPosition() === Position.RIGHT && this.partService.isVisible(Parts.PANEL_PART) ? MIN_PANEL_PART_WIDTH : 0; + const maxSidebarWidth = this.workbenchSize.width - this.activitybarWidth - editorCountForWidth * MIN_EDITOR_PART_WIDTH - panelMinWidth; + this._sidebarWidth = Math.min(maxSidebarWidth, Math.max(this.partLayoutInfo.sidebar.minWidth, value)); } private getPartLayoutInfo(): PartLayoutInfo { @@ -428,7 +438,6 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal let sidebarSize = new Dimension(this.sidebarWidth, this.sidebarHeight); // Activity Bar - this.activitybarWidth = isActivityBarHidden ? 0 : this.partLayoutInfo.activitybar.width; let activityBarSize = new Dimension(this.activitybarWidth, sidebarSize.height); // Panel part From ce2893322ce67fc9312a98b7c4b60daf49af3c4c Mon Sep 17 00:00:00 2001 From: isidor Date: Wed, 25 Oct 2017 11:45:55 +0200 Subject: [PATCH 13/13] vertical panel: fix sidebar right layouting --- src/vs/workbench/browser/layout.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 04f77dd11bb3b..e4e8166b56eff 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -585,11 +585,11 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal // Sidebar Part this.sidebar.getContainer().size(sidebarSize.width, sidebarSize.height); - + const editorAndPanelWidth = editorSize.width + (panelPosition === Position.RIGHT ? panelWidth : 0); if (sidebarPosition === Position.LEFT) { - this.sidebar.getContainer().position(this.titlebarHeight, editorSize.width, 0, activityBarSize.width); + this.sidebar.getContainer().position(this.titlebarHeight, editorAndPanelWidth, this.statusbarHeight, activityBarSize.width); } else { - this.sidebar.getContainer().position(this.titlebarHeight, null, 0, editorSize.width); + this.sidebar.getContainer().position(this.titlebarHeight, activityBarSize.width, this.statusbarHeight, editorAndPanelWidth); } // Statusbar Part