sideBySideEditor.ts 8.8 KB
Newer Older
S
Sandeep Somavarapu 已提交
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.
 *--------------------------------------------------------------------------------------------*/

import { TPromise } from 'vs/base/common/winjs.base';
import * as DOM from 'vs/base/browser/dom';
8
import { Registry } from 'vs/platform/registry/common/platform';
9
import { EditorInput, EditorOptions, SideBySideEditorInput, IEditorControl, IEditor } from 'vs/workbench/common/editor';
10
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
S
Sandeep Somavarapu 已提交
11 12
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
B
Benjamin Pasero 已提交
13
import { IThemeService } from 'vs/platform/theme/common/themeService';
14
import { scrollbarShadow } from 'vs/platform/theme/common/colorRegistry';
15
import { IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/browser/editor';
16
import { CancellationToken } from 'vs/base/common/cancellation';
17
import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService';
18
import { SplitView, Sizing, Orientation } from 'vs/base/browser/ui/splitview/splitview';
19
import { Event, Relay, anyEvent, mapEvent, Emitter } from 'vs/base/common/event';
B
Benjamin Pasero 已提交
20
import { INextStorage2Service } from 'vs/platform/storage2/common/storage2';
S
Sandeep Somavarapu 已提交
21 22 23

export class SideBySideEditor extends BaseEditor {

B
Benjamin Pasero 已提交
24
	static readonly ID: string = 'workbench.editor.sidebysideEditor';
S
Sandeep Somavarapu 已提交
25

B
Benjamin Pasero 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
	get minimumMasterWidth() { return this.masterEditor ? this.masterEditor.minimumWidth : 0; }
	get maximumMasterWidth() { return this.masterEditor ? this.masterEditor.maximumWidth : Number.POSITIVE_INFINITY; }
	get minimumMasterHeight() { return this.masterEditor ? this.masterEditor.minimumHeight : 0; }
	get maximumMasterHeight() { return this.masterEditor ? this.masterEditor.maximumHeight : Number.POSITIVE_INFINITY; }

	get minimumDetailsWidth() { return this.detailsEditor ? this.detailsEditor.minimumWidth : 0; }
	get maximumDetailsWidth() { return this.detailsEditor ? this.detailsEditor.maximumWidth : Number.POSITIVE_INFINITY; }
	get minimumDetailsHeight() { return this.detailsEditor ? this.detailsEditor.minimumHeight : 0; }
	get maximumDetailsHeight() { return this.detailsEditor ? this.detailsEditor.maximumHeight : Number.POSITIVE_INFINITY; }

	// these setters need to exist because this extends from BaseEditor
	set minimumWidth(value: number) { /* noop */ }
	set maximumWidth(value: number) { /* noop */ }
	set minimumHeight(value: number) { /* noop */ }
	set maximumHeight(value: number) { /* noop */ }

	get minimumWidth() { return this.minimumMasterWidth + this.minimumDetailsWidth; }
	get maximumWidth() { return this.maximumMasterWidth + this.maximumDetailsWidth; }
	get minimumHeight() { return this.minimumMasterHeight + this.minimumDetailsHeight; }
	get maximumHeight() { return this.maximumMasterHeight + this.maximumDetailsHeight; }
S
Sandeep Somavarapu 已提交
46

47 48
	protected masterEditor: BaseEditor;
	protected detailsEditor: BaseEditor;
B
Benjamin Pasero 已提交
49 50

	private masterEditorContainer: HTMLElement;
S
Sandeep Somavarapu 已提交
51 52
	private detailsEditorContainer: HTMLElement;

53
	private splitview: SplitView;
B
Benjamin Pasero 已提交
54
	private dimension: DOM.Dimension = new DOM.Dimension(0, 0);
S
Sandeep Somavarapu 已提交
55

B
Benjamin Pasero 已提交
56 57
	private onDidCreateEditors = this._register(new Emitter<{ width: number; height: number; }>());
	private _onDidSizeConstraintsChange = this._register(new Relay<{ width: number; height: number; }>());
J
Joao Moreno 已提交
58
	readonly onDidSizeConstraintsChange: Event<{ width: number; height: number; }> = anyEvent(this.onDidCreateEditors.event, this._onDidSizeConstraintsChange.event);
59

S
Sandeep Somavarapu 已提交
60 61
	constructor(
		@ITelemetryService telemetryService: ITelemetryService,
B
Benjamin Pasero 已提交
62
		@IInstantiationService private instantiationService: IInstantiationService,
B
Benjamin Pasero 已提交
63 64
		@IThemeService themeService: IThemeService,
		@INextStorage2Service nextStorage2Service: INextStorage2Service
S
Sandeep Somavarapu 已提交
65
	) {
B
Benjamin Pasero 已提交
66
		super(SideBySideEditor.ID, telemetryService, themeService, nextStorage2Service);
S
Sandeep Somavarapu 已提交
67 68
	}

69 70
	protected createEditor(parent: HTMLElement): void {
		DOM.addClass(parent, 'side-by-side-editor');
71

B
Benjamin Pasero 已提交
72
		this.splitview = this._register(new SplitView(parent, { orientation: Orientation.HORIZONTAL }));
73
		this._register(this.splitview.onDidSashReset(() => this.splitview.distributeViewSizes()));
74 75 76 77

		this.detailsEditorContainer = DOM.$('.details-editor-container');
		this.splitview.addView({
			element: this.detailsEditorContainer,
J
Joao Moreno 已提交
78
			layout: size => this.detailsEditor && this.detailsEditor.layout(new DOM.Dimension(size, this.dimension.height)),
79 80 81 82 83 84 85 86
			minimumSize: 220,
			maximumSize: Number.POSITIVE_INFINITY,
			onDidChange: Event.None
		}, Sizing.Distribute);

		this.masterEditorContainer = DOM.$('.master-editor-container');
		this.splitview.addView({
			element: this.masterEditorContainer,
J
Joao Moreno 已提交
87
			layout: size => this.masterEditor && this.masterEditor.layout(new DOM.Dimension(size, this.dimension.height)),
88 89 90 91 92 93
			minimumSize: 220,
			maximumSize: Number.POSITIVE_INFINITY,
			onDidChange: Event.None
		}, Sizing.Distribute);

		this.updateStyles();
S
Sandeep Somavarapu 已提交
94 95
	}

B
Benjamin Pasero 已提交
96
	setInput(newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
B
Benjamin Pasero 已提交
97
		const oldInput = <SideBySideEditorInput>this.input;
98 99 100 101
		return super.setInput(newInput, options, token)
			.then(() => this.updateInput(oldInput, newInput, options, token));
	}

B
Benjamin Pasero 已提交
102
	setOptions(options: EditorOptions): void {
103 104 105
		if (this.masterEditor) {
			this.masterEditor.setOptions(options);
		}
S
Sandeep Somavarapu 已提交
106 107
	}

108
	protected setEditorVisible(visible: boolean, group: IEditorGroup): void {
S
Sandeep Somavarapu 已提交
109
		if (this.masterEditor) {
110
			this.masterEditor.setVisible(visible, group);
S
Sandeep Somavarapu 已提交
111 112
		}
		if (this.detailsEditor) {
113
			this.detailsEditor.setVisible(visible, group);
S
Sandeep Somavarapu 已提交
114
		}
115
		super.setEditorVisible(visible, group);
B
Benjamin Pasero 已提交
116 117
	}

B
Benjamin Pasero 已提交
118
	clearInput(): void {
B
Benjamin Pasero 已提交
119 120 121 122 123 124
		if (this.masterEditor) {
			this.masterEditor.clearInput();
		}
		if (this.detailsEditor) {
			this.detailsEditor.clearInput();
		}
S
Sandeep Somavarapu 已提交
125 126 127 128
		this.disposeEditors();
		super.clearInput();
	}

B
Benjamin Pasero 已提交
129
	focus(): void {
S
Sandeep Somavarapu 已提交
130 131 132 133 134
		if (this.masterEditor) {
			this.masterEditor.focus();
		}
	}

B
Benjamin Pasero 已提交
135
	layout(dimension: DOM.Dimension): void {
S
Sandeep Somavarapu 已提交
136
		this.dimension = dimension;
137
		this.splitview.layout(dimension.width);
S
Sandeep Somavarapu 已提交
138 139
	}

B
Benjamin Pasero 已提交
140
	getControl(): IEditorControl {
S
Sandeep Somavarapu 已提交
141 142 143 144
		if (this.masterEditor) {
			return this.masterEditor.getControl();
		}
		return null;
S
Sandeep Somavarapu 已提交
145 146
	}

B
Benjamin Pasero 已提交
147
	getMasterEditor(): IEditor {
148 149 150
		return this.masterEditor;
	}

B
Benjamin Pasero 已提交
151
	getDetailsEditor(): IEditor {
152 153 154
		return this.detailsEditor;
	}

155
	private updateInput(oldInput: SideBySideEditorInput, newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
S
Sandeep Somavarapu 已提交
156 157 158 159
		if (!newInput.matches(oldInput)) {
			if (oldInput) {
				this.disposeEditors();
			}
160

161
			return this.setNewInput(newInput, options, token);
S
Sandeep Somavarapu 已提交
162
		}
B
Benjamin Pasero 已提交
163

I
isidor 已提交
164
		return Promise.all([this.detailsEditor.setInput(newInput.details, null, token), this.masterEditor.setInput(newInput.master, options, token)]).then(() => void 0);
S
Sandeep Somavarapu 已提交
165 166
	}

167
	private setNewInput(newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Thenable<void> {
168 169 170
		const detailsEditor = this._createEditor(<EditorInput>newInput.details, this.detailsEditorContainer);
		const masterEditor = this._createEditor(<EditorInput>newInput.master, this.masterEditorContainer);

171
		return this.onEditorsCreated(detailsEditor, masterEditor, newInput.details, newInput.master, options, token);
S
Sandeep Somavarapu 已提交
172 173
	}

174
	private _createEditor(editorInput: EditorInput, container: HTMLElement): BaseEditor {
S
Sandeep Somavarapu 已提交
175
		const descriptor = Registry.as<IEditorRegistry>(EditorExtensions.Editors).getEditor(editorInput);
176 177

		const editor = descriptor.instantiate(this.instantiationService);
178
		editor.create(container);
179
		editor.setVisible(this.isVisible(), this.group);
180 181

		return editor;
S
Sandeep Somavarapu 已提交
182 183
	}

184
	private onEditorsCreated(details: BaseEditor, master: BaseEditor, detailsInput: EditorInput, masterInput: EditorInput, options: EditorOptions, token: CancellationToken): TPromise<void> {
S
Sandeep Somavarapu 已提交
185 186
		this.detailsEditor = details;
		this.masterEditor = master;
187

B
Benjamin Pasero 已提交
188
		this._onDidSizeConstraintsChange.input = anyEvent(
B
Benjamin Pasero 已提交
189 190
			mapEvent(details.onDidSizeConstraintsChange, () => undefined),
			mapEvent(master.onDidSizeConstraintsChange, () => undefined)
191 192
		);

B
Benjamin Pasero 已提交
193
		this.onDidCreateEditors.fire();
194

I
isidor 已提交
195
		return Promise.all([this.detailsEditor.setInput(detailsInput, null, token), this.masterEditor.setInput(masterInput, options, token)]).then(() => this.focus());
S
Sandeep Somavarapu 已提交
196 197
	}

B
Benjamin Pasero 已提交
198
	updateStyles(): void {
199 200 201
		super.updateStyles();

		if (this.masterEditorContainer) {
202
			this.masterEditorContainer.style.boxShadow = `-6px 0 5px -5px ${this.getColor(scrollbarShadow)}`;
203
		}
S
Sandeep Somavarapu 已提交
204 205
	}

S
Sandeep Somavarapu 已提交
206
	private disposeEditors(): void {
S
Sandeep Somavarapu 已提交
207 208 209 210
		if (this.detailsEditor) {
			this.detailsEditor.dispose();
			this.detailsEditor = null;
		}
B
Benjamin Pasero 已提交
211

S
Sandeep Somavarapu 已提交
212 213
		if (this.masterEditor) {
			this.masterEditor.dispose();
S
Sandeep Somavarapu 已提交
214
			this.masterEditor = null;
S
Sandeep Somavarapu 已提交
215
		}
B
Benjamin Pasero 已提交
216

217 218
		this.detailsEditorContainer.innerHTML = '';
		this.masterEditorContainer.innerHTML = '';
S
Sandeep Somavarapu 已提交
219
	}
S
Sandeep Somavarapu 已提交
220

B
Benjamin Pasero 已提交
221
	dispose(): void {
S
Sandeep Somavarapu 已提交
222
		this.disposeEditors();
B
Benjamin Pasero 已提交
223

S
Sandeep Somavarapu 已提交
224 225
		super.dispose();
	}
I
isidor 已提交
226
}