layout.ts 18.9 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

J
Johannes Rieken 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19
import { Dimension, Builder, Box } from 'vs/base/browser/builder';
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 } from 'vs/workbench/services/part/common/partService';
import { IViewletService } from 'vs/workbench/services/viewlet/common/viewletService';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IEventService } from 'vs/platform/event/common/event';
import { IThemeService } from 'vs/workbench/services/themes/common/themeService';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
E
Erich Gamma 已提交
20 21

const DEFAULT_MIN_PART_WIDTH = 170;
I
isidor 已提交
22
const DEFAULT_MIN_PANEL_PART_HEIGHT = 77;
I
isidor 已提交
23
const DEFAULT_MIN_EDITOR_PART_HEIGHT = 170;
E
Erich Gamma 已提交
24
const HIDE_SIDEBAR_WIDTH_THRESHOLD = 50;
I
isidor 已提交
25
const HIDE_PANEL_HEIGHT_THRESHOLD = 50;
E
Erich Gamma 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

export class LayoutOptions {
	public margin: Box;

	constructor() {
		this.margin = new Box(0, 0, 0, 0);
	}

	public setMargin(margin: Box): LayoutOptions {
		this.margin = margin;

		return this;
	}
}

interface ComputedStyles {
	activitybar: { minWidth: number; };
	sidebar: { minWidth: number; };
B
Benjamin Pasero 已提交
44
	panel: { minHeight: number; };
E
Erich Gamma 已提交
45 46 47 48 49
	editor: { minWidth: number; };
	statusbar: { height: number; };
}

/**
B
Benjamin Pasero 已提交
50
 * The workbench layout is responsible to lay out all parts that make the Workbench.
E
Erich Gamma 已提交
51
 */
I
isidor 已提交
52
export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontalSashLayoutProvider {
E
Erich Gamma 已提交
53

I
isidor 已提交
54
	private static sashXWidthSettingsKey = 'workbench.sidebar.width';
I
isidor 已提交
55
	private static sashYHeightSettingsKey = 'workbench.panel.height';
E
Erich Gamma 已提交
56 57 58 59 60 61

	private parent: Builder;
	private workbenchContainer: Builder;
	private activitybar: Part;
	private editor: Part;
	private sidebar: Part;
B
Benjamin Pasero 已提交
62
	private panel: Part;
E
Erich Gamma 已提交
63 64 65
	private statusbar: Part;
	private quickopen: QuickOpenController;
	private options: LayoutOptions;
M
Martin Aeschlimann 已提交
66
	private toUnbind: IDisposable[];
E
Erich Gamma 已提交
67 68
	private computedStyles: ComputedStyles;
	private workbenchSize: Dimension;
I
isidor 已提交
69 70
	private sashX: Sash;
	private sashY: Sash;
E
Erich Gamma 已提交
71 72
	private startSidebarWidth: number;
	private sidebarWidth: number;
I
isidor 已提交
73
	private sidebarHeight: number;
I
isidor 已提交
74 75 76
	private startPanelHeight: number;
	private panelHeight: number;
	private panelWidth: number;
E
Erich Gamma 已提交
77

I
isidor 已提交
78
	// Take parts as an object bag since instatation service does not have typings for constructors with 9+ arguments
E
Erich Gamma 已提交
79 80 81
	constructor(
		parent: Builder,
		workbenchContainer: Builder,
I
isidor 已提交
82 83 84 85 86 87 88
		parts: {
			activitybar: Part,
			editor: Part,
			sidebar: Part,
			panel: Part,
			statusbar: Part
		},
E
Erich Gamma 已提交
89 90 91
		quickopen: QuickOpenController,
		options: LayoutOptions,
		@IStorageService private storageService: IStorageService,
M
Martin Aeschlimann 已提交
92
		@IEventService eventService: IEventService,
E
Erich Gamma 已提交
93 94
		@IContextViewService private contextViewService: IContextViewService,
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
95
		@IEditorGroupService editorGroupService: IEditorGroupService,
M
Martin Aeschlimann 已提交
96
		@IPartService private partService: IPartService,
M
Maxime Quandalle 已提交
97
		@IViewletService private viewletService: IViewletService,
M
Martin Aeschlimann 已提交
98
		@IThemeService themeService: IThemeService
E
Erich Gamma 已提交
99 100 101
	) {
		this.parent = parent;
		this.workbenchContainer = workbenchContainer;
I
isidor 已提交
102 103 104
		this.activitybar = parts.activitybar;
		this.editor = parts.editor;
		this.sidebar = parts.sidebar;
B
Benjamin Pasero 已提交
105
		this.panel = parts.panel;
I
isidor 已提交
106
		this.statusbar = parts.statusbar;
E
Erich Gamma 已提交
107 108 109 110
		this.quickopen = quickopen;
		this.options = options || new LayoutOptions();
		this.toUnbind = [];
		this.computedStyles = null;
I
isidor 已提交
111
		this.sashX = new Sash(this.workbenchContainer.getHTMLElement(), this, {
E
Erich Gamma 已提交
112 113
			baseSize: 5
		});
I
isidor 已提交
114
		this.sashY = new Sash(this.workbenchContainer.getHTMLElement(), this, {
I
isidor 已提交
115
			baseSize: 4,
I
isidor 已提交
116 117
			orientation: Orientation.HORIZONTAL
		});
E
Erich Gamma 已提交
118

I
isidor 已提交
119
		this.sidebarWidth = this.storageService.getInteger(WorkbenchLayout.sashXWidthSettingsKey, StorageScope.GLOBAL, -1);
I
isidor 已提交
120
		this.panelHeight = this.storageService.getInteger(WorkbenchLayout.sashYHeightSettingsKey, StorageScope.GLOBAL, 0);
E
Erich Gamma 已提交
121

M
Martin Aeschlimann 已提交
122
		this.toUnbind.push(themeService.onDidColorThemeChange(_ => this.relayout()));
123
		this.toUnbind.push(editorGroupService.onEditorsChanged(() => this.onEditorsChanged()));
M
Martin Aeschlimann 已提交
124

E
Erich Gamma 已提交
125 126 127 128 129 130
		this.registerSashListeners();
	}


	private registerSashListeners(): void {
		let startX: number = 0;
I
isidor 已提交
131
		let startY: number = 0;
E
Erich Gamma 已提交
132

A
Alex Dima 已提交
133
		this.sashX.addListener2('start', (e: ISashEvent) => {
E
Erich Gamma 已提交
134 135 136 137
			this.startSidebarWidth = this.sidebarWidth;
			startX = e.startX;
		});

A
Alex Dima 已提交
138
		this.sashY.addListener2('start', (e: ISashEvent) => {
I
isidor 已提交
139
			this.startPanelHeight = this.panelHeight;
I
isidor 已提交
140 141 142
			startY = e.startY;
		});

A
Alex Dima 已提交
143
		this.sashX.addListener2('change', (e: ISashEvent) => {
E
Erich Gamma 已提交
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
			let doLayout = false;
			let sidebarPosition = this.partService.getSideBarPosition();
			let isSidebarHidden = this.partService.isSideBarHidden();
			let newSashWidth = (sidebarPosition === Position.LEFT) ? this.startSidebarWidth + e.currentX - startX : this.startSidebarWidth - e.currentX + startX;

			// Sidebar visible
			if (!isSidebarHidden) {

				// Automatically hide side bar when a certain threshold is met
				if (newSashWidth + HIDE_SIDEBAR_WIDTH_THRESHOLD < this.computedStyles.sidebar.minWidth) {
					let dragCompensation = DEFAULT_MIN_PART_WIDTH - HIDE_SIDEBAR_WIDTH_THRESHOLD;
					this.partService.setSideBarHidden(true);
					startX = (sidebarPosition === Position.LEFT) ? Math.max(this.computedStyles.activitybar.minWidth, e.currentX - dragCompensation) : Math.min(e.currentX + dragCompensation, this.workbenchSize.width - this.computedStyles.activitybar.minWidth);
					this.sidebarWidth = this.startSidebarWidth; // when restoring sidebar, restore to the sidebar width we started from
				}

				// Otherwise size the sidebar accordingly
				else {
					this.sidebarWidth = Math.max(this.computedStyles.sidebar.minWidth, newSashWidth); // Sidebar can not become smaller than MIN_PART_WIDTH
					doLayout = newSashWidth >= this.computedStyles.sidebar.minWidth;
				}
			}

			// Sidebar hidden
			else {
				if ((sidebarPosition === Position.LEFT && e.currentX - startX >= this.computedStyles.sidebar.minWidth) ||
					(sidebarPosition === Position.RIGHT && startX - e.currentX >= this.computedStyles.sidebar.minWidth)) {
					this.startSidebarWidth = this.computedStyles.sidebar.minWidth - (sidebarPosition === Position.LEFT ? e.currentX - startX : startX - e.currentX);
					this.sidebarWidth = this.computedStyles.sidebar.minWidth;
					this.partService.setSideBarHidden(false);
				}
			}

			if (doLayout) {
				this.layout();
			}
		});

A
Alex Dima 已提交
182
		this.sashY.addListener2('change', (e: ISashEvent) => {
I
isidor 已提交
183
			let doLayout = false;
I
isidor 已提交
184
			let isPanelHidden = this.partService.isPanelHidden();
185
			let isStatusbarHidden = this.partService.isStatusBarHidden();
I
isidor 已提交
186
			let newSashHeight = this.startPanelHeight - (e.currentY - startY);
I
isidor 已提交
187 188

			// Panel visible
I
isidor 已提交
189
			if (!isPanelHidden) {
190 191 192 193
				// Automatically hide panel when a certain threshold is met
				if (newSashHeight + HIDE_PANEL_HEIGHT_THRESHOLD < this.computedStyles.panel.minHeight) {
					let dragCompensation = DEFAULT_MIN_PANEL_PART_HEIGHT - HIDE_PANEL_HEIGHT_THRESHOLD;
					this.partService.setPanelHidden(true);
194 195
					let statusbarHeight = isStatusbarHidden ? 0 : this.computedStyles.statusbar.height;
					startY = Math.min(this.sidebarHeight - statusbarHeight, e.currentY + dragCompensation);
M
Maxime Quandalle 已提交
196
					this.panelHeight = this.startPanelHeight; // when restoring panel, restore to the panel height we started from
197 198 199 200 201 202 203 204
				}

				// Otherwise size the panel accordingly
				else {
					this.panelHeight = Math.max(this.computedStyles.panel.minHeight, newSashHeight); // Panel can not become smaller than MIN_PART_HEIGHT
					doLayout = newSashHeight >= this.computedStyles.panel.minHeight;
				}
			}
I
isidor 已提交
205

206 207 208 209 210 211 212
			// Panel hidden
			else {
				if (startY - e.currentY >= this.computedStyles.panel.minHeight) {
					this.startPanelHeight = 0;
					this.panelHeight = this.computedStyles.panel.minHeight;
					this.partService.setPanelHidden(false);
				}
I
isidor 已提交
213
			}
214

I
isidor 已提交
215 216 217 218 219
			if (doLayout) {
				this.layout();
			}
		});

A
Alex Dima 已提交
220
		this.sashX.addListener2('end', () => {
I
isidor 已提交
221 222
			this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL);
		});
M
Maxime Quandalle 已提交
223

A
Alex Dima 已提交
224
		this.sashY.addListener2('end', () => {
I
isidor 已提交
225
			this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL);
E
Erich Gamma 已提交
226
		});
M
Maxime Quandalle 已提交
227

A
Alex Dima 已提交
228
		this.sashY.addListener2('reset', () => {
M
Maxime Quandalle 已提交
229 230 231 232 233 234
			this.panelHeight = DEFAULT_MIN_PANEL_PART_HEIGHT;
			this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL);
			this.partService.setPanelHidden(false);
			this.layout();
		});

A
Alex Dima 已提交
235
		this.sashX.addListener2('reset', () => {
M
Maxime Quandalle 已提交
236 237 238 239 240 241 242
			let activeViewlet = this.viewletService.getActiveViewlet();
			let optimalWidth = activeViewlet && activeViewlet.getOptimalWidth();
			this.sidebarWidth = Math.max(DEFAULT_MIN_PART_WIDTH, optimalWidth || 0);
			this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL);
			this.partService.setSideBarHidden(false);
			this.layout();
		});
E
Erich Gamma 已提交
243 244
	}

245
	private onEditorsChanged(): void {
E
Erich Gamma 已提交
246 247 248 249 250 251 252 253 254 255 256 257

		// Make sure that we layout properly in case we detect that the sidebar is large enought to cause
		// multiple opened editors to go below minimal size. The fix is to trigger a layout for any editor
		// input change that falls into this category.
		if (this.workbenchSize && this.sidebarWidth) {
			let visibleEditors = this.editorService.getVisibleEditors().length;
			if (visibleEditors > 1 && this.workbenchSize.width - this.sidebarWidth < visibleEditors * DEFAULT_MIN_PART_WIDTH) {
				this.layout();
			}
		}
	}

M
Martin Aeschlimann 已提交
258
	private relayout(): void {
E
Erich Gamma 已提交
259

M
Martin Aeschlimann 已提交
260 261 262 263 264
		// Recompute Styles
		this.computeStyle();
		this.editor.getLayout().computeStyle();
		this.sidebar.getLayout().computeStyle();
		this.panel.getLayout().computeStyle();
E
Erich Gamma 已提交
265

M
Martin Aeschlimann 已提交
266 267
		// Trigger Layout
		this.layout();
E
Erich Gamma 已提交
268 269 270
	}

	private computeStyle(): void {
I
isidor 已提交
271
		const sidebarStyle = this.sidebar.getContainer().getComputedStyle();
B
Benjamin Pasero 已提交
272
		const panelStyle = this.panel.getContainer().getComputedStyle();
I
isidor 已提交
273 274
		const editorStyle = this.editor.getContainer().getComputedStyle();
		const activitybarStyle = this.activitybar.getContainer().getComputedStyle();
B
Benjamin Pasero 已提交
275
		const statusbarStyle = this.statusbar.getContainer().getComputedStyle();
E
Erich Gamma 已提交
276 277 278 279 280 281 282 283 284 285

		this.computedStyles = {
			activitybar: {
				minWidth: parseInt(activitybarStyle.getPropertyValue('min-width'), 10) || 0
			},

			sidebar: {
				minWidth: parseInt(sidebarStyle.getPropertyValue('min-width'), 10) || DEFAULT_MIN_PART_WIDTH
			},

I
isidor 已提交
286
			panel: {
B
Benjamin Pasero 已提交
287
				minHeight: parseInt(panelStyle.getPropertyValue('min-height'), 10) || DEFAULT_MIN_PANEL_PART_HEIGHT
I
isidor 已提交
288 289
			},

E
Erich Gamma 已提交
290 291 292 293 294
			editor: {
				minWidth: parseInt(editorStyle.getPropertyValue('min-width'), 10) || DEFAULT_MIN_PART_WIDTH
			},

			statusbar: {
B
Benjamin Pasero 已提交
295
				height: parseInt(statusbarStyle.getPropertyValue('height'), 10) || 18
E
Erich Gamma 已提交
296 297 298 299 300 301 302 303 304
			}
		};
	}

	public layout(forceStyleReCompute?: boolean): void {
		if (forceStyleReCompute) {
			this.computeStyle();
			this.editor.getLayout().computeStyle();
			this.sidebar.getLayout().computeStyle();
B
Benjamin Pasero 已提交
305
			this.panel.getLayout().computeStyle();
E
Erich Gamma 已提交
306 307 308 309 310 311 312 313
		}

		if (!this.computedStyles) {
			this.computeStyle();
		}

		this.workbenchSize = this.getWorkbenchArea();

I
isidor 已提交
314
		const isSidebarHidden = this.partService.isSideBarHidden();
I
isidor 已提交
315
		const isPanelHidden = this.partService.isPanelHidden();
I
isidor 已提交
316
		const sidebarPosition = this.partService.getSideBarPosition();
317
		const isStatusbarHidden = this.partService.isStatusBarHidden();
E
Erich Gamma 已提交
318 319 320 321 322 323 324 325 326 327 328

		// Sidebar
		let sidebarWidth: number;
		if (isSidebarHidden) {
			sidebarWidth = 0;
		} else if (this.sidebarWidth !== -1) {
			sidebarWidth = Math.max(this.computedStyles.sidebar.minWidth, this.sidebarWidth);
		} else {
			sidebarWidth = this.workbenchSize.width / 5;
			this.sidebarWidth = sidebarWidth;
		}
B
Benjamin Pasero 已提交
329

330
		let statusbarHeight = isStatusbarHidden ? 0 : this.computedStyles.statusbar.height;
E
Erich Gamma 已提交
331

332
		this.sidebarHeight = this.workbenchSize.height - statusbarHeight;
I
isidor 已提交
333
		let sidebarSize = new Dimension(sidebarWidth, this.sidebarHeight);
E
Erich Gamma 已提交
334 335 336 337 338

		// Activity Bar
		let activityBarMinWidth = this.computedStyles.activitybar.minWidth;
		let activityBarSize = new Dimension(activityBarMinWidth, sidebarSize.height);

I
isidor 已提交
339 340
		// Panel part
		let panelHeight: number;
I
isidor 已提交
341
		if (isPanelHidden) {
I
isidor 已提交
342
			panelHeight = 0;
I
isidor 已提交
343
		} else if (this.panelHeight > 0) {
I
isidor 已提交
344
			panelHeight = Math.min(sidebarSize.height - DEFAULT_MIN_EDITOR_PART_HEIGHT, Math.max(this.computedStyles.panel.minHeight, this.panelHeight));
I
isidor 已提交
345 346 347 348
		} else {
			panelHeight = sidebarSize.height * 0.4;
		}
		const panelDimension = new Dimension(this.workbenchSize.width - sidebarSize.width - activityBarSize.width, panelHeight);
I
isidor 已提交
349
		this.panelWidth = panelDimension.width;
I
isidor 已提交
350

E
Erich Gamma 已提交
351 352 353 354 355 356 357 358
		// Editor
		let editorSize = {
			width: 0,
			height: 0,
			remainderLeft: 0,
			remainderRight: 0
		};

I
isidor 已提交
359
		let editorDimension = new Dimension(panelDimension.width, sidebarSize.height - panelDimension.height);
E
Erich Gamma 已提交
360
		editorSize.width = editorDimension.width;
I
isidor 已提交
361
		editorSize.height = editorDimension.height;
E
Erich Gamma 已提交
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381

		// Sidebar hidden
		if (isSidebarHidden) {
			editorSize.width = Math.min(this.workbenchSize.width - activityBarSize.width, this.workbenchSize.width - activityBarMinWidth);

			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
		let editorMinWidth = this.computedStyles.editor.minWidth;
		let visibleEditorCount = this.editorService.getVisibleEditors().length;
		if (visibleEditorCount > 1) {
			editorMinWidth *= visibleEditorCount;
		}
B
Benjamin Pasero 已提交
382

E
Erich Gamma 已提交
383 384 385
		if (editorSize.width < editorMinWidth) {
			let diff = editorMinWidth - editorSize.width;
			editorSize.width = editorMinWidth;
386
			panelDimension.width = editorMinWidth;
E
Erich Gamma 已提交
387 388 389 390 391 392
			sidebarSize.width -= diff;
			sidebarSize.width = Math.max(DEFAULT_MIN_PART_WIDTH, sidebarSize.width);
		}

		if (!isSidebarHidden) {
			this.sidebarWidth = sidebarSize.width;
I
isidor 已提交
393
			this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL);
E
Erich Gamma 已提交
394 395
		}

I
isidor 已提交
396 397 398
		if (!isPanelHidden) {
			this.panelHeight = panelDimension.height;
			this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL);
I
isidor 已提交
399 400
		}

E
Erich Gamma 已提交
401 402 403 404 405 406 407 408 409 410
		// Workbench
		this.workbenchContainer
			.position(this.options.margin.top, this.options.margin.right, this.options.margin.bottom, this.options.margin.left, 'relative')
			.size(this.workbenchSize.width, this.workbenchSize.height);

		// Bug on Chrome: Sometimes Chrome wants to scroll the workbench container on layout changes. The fix is to reset scrollTop in this case.
		if (this.workbenchContainer.getHTMLElement().scrollTop > 0) {
			this.workbenchContainer.getHTMLElement().scrollTop = 0;
		}

I
isidor 已提交
411
		// Editor Part and Panel part
E
Erich Gamma 已提交
412
		this.editor.getContainer().size(editorSize.width, editorSize.height);
B
Benjamin Pasero 已提交
413
		this.panel.getContainer().size(panelDimension.width, panelDimension.height);
E
Erich Gamma 已提交
414

415
		const editorBottom = statusbarHeight + panelDimension.height;
E
Erich Gamma 已提交
416
		if (isSidebarHidden) {
417
			this.editor.getContainer().position(0, editorSize.remainderRight, editorBottom, editorSize.remainderLeft);
418
			this.panel.getContainer().position(editorDimension.height, editorSize.remainderRight, statusbarHeight, editorSize.remainderLeft);
E
Erich Gamma 已提交
419
		} else if (sidebarPosition === Position.LEFT) {
420
			this.editor.getContainer().position(0, 0, editorBottom, sidebarSize.width + activityBarSize.width);
421
			this.panel.getContainer().position(editorDimension.height, 0, statusbarHeight, sidebarSize.width + activityBarSize.width);
E
Erich Gamma 已提交
422
		} else {
423
			this.editor.getContainer().position(0, sidebarSize.width, editorBottom, 0);
424
			this.panel.getContainer().position(editorDimension.height, sidebarSize.width, statusbarHeight, 0);
E
Erich Gamma 已提交
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
		}

		// Activity Bar Part
		this.activitybar.getContainer().size(null, activityBarSize.height);
		if (sidebarPosition === Position.LEFT) {
			this.activitybar.getContainer().getHTMLElement().style.right = '';
			this.activitybar.getContainer().position(0, null, 0, 0);
		} else {
			this.activitybar.getContainer().getHTMLElement().style.left = '';
			this.activitybar.getContainer().position(0, 0, 0, null);
		}

		// Sidebar Part
		this.sidebar.getContainer().size(sidebarSize.width, sidebarSize.height);

		if (sidebarPosition === Position.LEFT) {
			this.sidebar.getContainer().position(0, editorSize.width, 0, activityBarSize.width);
		} else {
			this.sidebar.getContainer().position(0, null, 0, editorSize.width);
		}

		// Statusbar Part
B
Benjamin Pasero 已提交
447
		this.statusbar.getContainer().position(this.workbenchSize.height - statusbarHeight);
E
Erich Gamma 已提交
448 449 450 451

		// Quick open
		this.quickopen.layout(this.workbenchSize);

I
isidor 已提交
452 453 454
		// Sashes
		this.sashX.layout();
		this.sashY.layout();
E
Erich Gamma 已提交
455 456 457 458

		// Propagate to Part Layouts
		this.editor.layout(new Dimension(editorSize.width, editorSize.height));
		this.sidebar.layout(sidebarSize);
B
Benjamin Pasero 已提交
459
		this.panel.layout(panelDimension);
E
Erich Gamma 已提交
460 461

		// Propagate to Context View
B
Benjamin Pasero 已提交
462
		this.contextViewService.layout();
E
Erich Gamma 已提交
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
	}

	private getWorkbenchArea(): Dimension {

		// Client Area: Parent
		let clientArea = this.parent.getClientArea();

		// Workbench: Client Area - Margins
		return clientArea.substract(this.options.margin);
	}

	public getVerticalSashTop(sash: Sash): number {
		return 0;
	}

	public getVerticalSashLeft(sash: Sash): number {
		let isSidebarHidden = this.partService.isSideBarHidden();
		let sidebarPosition = this.partService.getSideBarPosition();
		let activitybarWidth = this.computedStyles.activitybar.minWidth;

		if (sidebarPosition === Position.LEFT) {
			return !isSidebarHidden ? this.sidebarWidth + activitybarWidth : activitybarWidth;
		}

		return !isSidebarHidden ? this.workbenchSize.width - this.sidebarWidth - activitybarWidth : this.workbenchSize.width - activitybarWidth;
	}

	public getVerticalSashHeight(sash: Sash): number {
I
isidor 已提交
491
		return this.sidebarHeight;
E
Erich Gamma 已提交
492 493
	}

I
isidor 已提交
494
	public getHorizontalSashTop(sash: Sash): number {
B
Benjamin Pasero 已提交
495
		return 2 + (this.partService.isPanelHidden() ? this.sidebarHeight : this.sidebarHeight - this.panelHeight); // Horizontal sash should be a bit lower than the editor area, thus add 2px #5524
I
isidor 已提交
496 497 498
	}

	public getHorizontalSashLeft(sash: Sash): number {
499
		return this.partService.getSideBarPosition() === Position.LEFT ? this.getVerticalSashLeft(sash) : 0;
I
isidor 已提交
500 501 502
	}

	public getHorizontalSashWidth(sash: Sash): number {
I
isidor 已提交
503
		return this.panelWidth;
I
isidor 已提交
504 505
	}

E
Erich Gamma 已提交
506
	public dispose(): void {
M
Martin Aeschlimann 已提交
507 508 509
		if (this.toUnbind) {
			dispose(this.toUnbind);
			this.toUnbind = null;
E
Erich Gamma 已提交
510 511
		}
	}
B
Benjamin Pasero 已提交
512
}