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

import {Dimension, Builder, Box} from 'vs/base/browser/builder';
8
import {EditorEvent, EventType} from 'vs/workbench/common/events';
E
Erich Gamma 已提交
9 10
import {Part} from 'vs/workbench/browser/part';
import {QuickOpenController} from 'vs/workbench/browser/parts/quickopen/quickOpenController';
I
isidor 已提交
11
import {Sash, ISashEvent, IVerticalSashLayoutProvider, IHorizontalSashLayoutProvider, Orientation} from 'vs/base/browser/ui/sash/sash';
E
Erich Gamma 已提交
12 13 14
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
import {IPartService, Position} from 'vs/workbench/services/part/common/partService';
import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService';
M
Maxime Quandalle 已提交
15
import {IViewletService} from 'vs/workbench/services/viewlet/common/viewletService';
M
Martin Aeschlimann 已提交
16
import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage';
B
Benjamin Pasero 已提交
17
import {IContextViewService} from 'vs/platform/contextview/browser/contextView';
E
Erich Gamma 已提交
18
import {IEventService} from 'vs/platform/event/common/event';
M
Martin Aeschlimann 已提交
19 20
import {IThemeService} from 'vs/workbench/services/themes/common/themeService';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
E
Erich Gamma 已提交
21 22

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

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 已提交
45
	panel: { minHeight: number; };
E
Erich Gamma 已提交
46 47 48 49 50 51 52
	editor: { minWidth: number; };
	statusbar: { height: number; };
}

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

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

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

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

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

M
Martin Aeschlimann 已提交
123 124 125
		this.toUnbind.push(themeService.onDidThemeChange(_ => this.relayout()));
		this.toUnbind.push(eventService.addListener2(EventType.EDITOR_INPUT_CHANGING, (e: EditorEvent) => this.onEditorInputChanging(e)));

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


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

I
isidor 已提交
134
		this.sashX.addListener('start', (e: ISashEvent) => {
E
Erich Gamma 已提交
135 136 137 138
			this.startSidebarWidth = this.sidebarWidth;
			startX = e.startX;
		});

I
isidor 已提交
139
		this.sashY.addListener('start', (e: ISashEvent) => {
I
isidor 已提交
140
			this.startPanelHeight = this.panelHeight;
I
isidor 已提交
141 142 143 144
			startY = e.startY;
		});

		this.sashX.addListener('change', (e: ISashEvent) => {
E
Erich Gamma 已提交
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 182
			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();
			}
		});

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

			// Panel visible
I
isidor 已提交
189
			if (!isPanelHidden) {
190 191 192 193 194
				// 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);
					startY = Math.min(this.sidebarHeight - this.computedStyles.statusbar.height, e.currentY + dragCompensation);
M
Maxime Quandalle 已提交
195
					this.panelHeight = this.startPanelHeight; // when restoring panel, restore to the panel height we started from
196 197 198 199 200 201 202 203
				}

				// 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 已提交
204

205 206 207 208 209 210 211
			// 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 已提交
212
			}
213

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

		this.sashX.addListener('end', () => {
			this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL);
		});
M
Maxime Quandalle 已提交
222

I
isidor 已提交
223
		this.sashY.addListener('end', () => {
I
isidor 已提交
224
			this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL);
E
Erich Gamma 已提交
225
		});
M
Maxime Quandalle 已提交
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241

		this.sashY.addListener('reset', () => {
			this.panelHeight = DEFAULT_MIN_PANEL_PART_HEIGHT;
			this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL);
			this.partService.setPanelHidden(false);
			this.layout();
		});

		this.sashX.addListener('reset', () => {
			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 已提交
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
	}

	private onEditorInputChanging(e: EditorEvent): void {

		// 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 已提交
257
	private relayout(): void {
E
Erich Gamma 已提交
258

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

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

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

		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 已提交
284
			panel: {
B
Benjamin Pasero 已提交
285
				minHeight: parseInt(panelStyle.getPropertyValue('min-height'), 10) || DEFAULT_MIN_PANEL_PART_HEIGHT
I
isidor 已提交
286 287
			},

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

			statusbar: {
				height: 0
			}
		};

		if (this.statusbar) {
I
isidor 已提交
298
			const statusbarStyle = this.statusbar.getContainer().getComputedStyle();
E
Erich Gamma 已提交
299 300 301 302 303 304 305 306 307
			this.computedStyles.statusbar.height = parseInt(statusbarStyle.getPropertyValue('height'), 10) || 18;
		}
	}

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

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

		this.workbenchSize = this.getWorkbenchArea();

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

		// 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;
		}

I
isidor 已提交
332 333
		this.sidebarHeight = this.workbenchSize.height - this.computedStyles.statusbar.height;
		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 382 383 384

		// 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;
		}
		if (editorSize.width < editorMinWidth) {
			let diff = editorMinWidth - editorSize.width;
			editorSize.width = editorMinWidth;
385
			panelDimension.width = editorMinWidth;
E
Erich Gamma 已提交
386 387 388 389 390 391
			sidebarSize.width -= diff;
			sidebarSize.width = Math.max(DEFAULT_MIN_PART_WIDTH, sidebarSize.width);
		}

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

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

E
Erich Gamma 已提交
400 401 402 403 404 405 406 407 408 409
		// 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 已提交
410
		// Editor Part and Panel part
E
Erich Gamma 已提交
411
		this.editor.getContainer().size(editorSize.width, editorSize.height);
B
Benjamin Pasero 已提交
412
		this.panel.getContainer().size(panelDimension.width, panelDimension.height);
E
Erich Gamma 已提交
413

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

		// 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
		if (this.statusbar) {
			this.statusbar.getContainer().position(this.workbenchSize.height - this.computedStyles.statusbar.height);
		}

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

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

		// Propagate to Part Layouts
		this.editor.layout(new Dimension(editorSize.width, editorSize.height));
		this.sidebar.layout(sidebarSize);
B
Benjamin Pasero 已提交
460
		this.panel.layout(panelDimension);
E
Erich Gamma 已提交
461 462 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 491 492 493

		// Propagate to Context View
		if (this.contextViewService) {
			this.contextViewService.layout();
		}
	}

	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 已提交
494
		return this.sidebarHeight;
E
Erich Gamma 已提交
495 496
	}

I
isidor 已提交
497
	public getHorizontalSashTop(sash: Sash): number {
498
		return this.partService.isPanelHidden() ? this.sidebarHeight : this.sidebarHeight - this.panelHeight;
I
isidor 已提交
499 500 501
	}

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

	public getHorizontalSashWidth(sash: Sash): number {
I
isidor 已提交
506
		return this.panelWidth;
I
isidor 已提交
507 508
	}

E
Erich Gamma 已提交
509
	public dispose(): void {
M
Martin Aeschlimann 已提交
510 511 512
		if (this.toUnbind) {
			dispose(this.toUnbind);
			this.toUnbind = null;
E
Erich Gamma 已提交
513 514 515
		}
	}
}