sideBySideEditor.ts 7.6 KB
Newer Older
S
Sandeep Somavarapu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*---------------------------------------------------------------------------------------------
 *  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 strings from 'vs/base/common/strings';
import * as DOM from 'vs/base/browser/dom';
import { Dimension, Builder } from 'vs/base/browser/builder';

import { Registry } from 'vs/platform/platform';
import { IEditorRegistry, Extensions as EditorExtensions, EditorInput, EditorOptions, SideBySideEditorInput } from 'vs/workbench/common/editor';
import { BaseEditor, EditorDescriptor } from 'vs/workbench/browser/parts/editor/baseEditor';
14
import { IEditorControl, Position, IEditor } from 'vs/platform/editor/common/editor';
S
Sandeep Somavarapu 已提交
15
import { VSash } from 'vs/base/browser/ui/sash/sash';
S
Sandeep Somavarapu 已提交
16 17 18

import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
B
Benjamin Pasero 已提交
19
import { IThemeService } from 'vs/platform/theme/common/themeService';
20
import { EDITOR_SIDE_BY_SIDE_BORDER } from 'vs/workbench/common/theme';
S
Sandeep Somavarapu 已提交
21 22 23 24 25 26 27

export class SideBySideEditor extends BaseEditor {

	public static ID: string = 'workbench.editor.sidebysideEditor';

	private dimension: Dimension;

28
	protected masterEditor: BaseEditor;
S
Sandeep Somavarapu 已提交
29 30
	private masterEditorContainer: HTMLElement;

31
	protected detailsEditor: BaseEditor;
S
Sandeep Somavarapu 已提交
32 33 34 35 36 37
	private detailsEditorContainer: HTMLElement;

	private sash: VSash;

	constructor(
		@ITelemetryService telemetryService: ITelemetryService,
B
Benjamin Pasero 已提交
38 39
		@IInstantiationService private instantiationService: IInstantiationService,
		@IThemeService themeService: IThemeService
S
Sandeep Somavarapu 已提交
40
	) {
B
Benjamin Pasero 已提交
41
		super(SideBySideEditor.ID, telemetryService, themeService);
S
Sandeep Somavarapu 已提交
42 43
	}

B
Benjamin Pasero 已提交
44
	protected createEditor(parent: Builder): void {
S
Sandeep Somavarapu 已提交
45 46 47 48 49
		const parentElement = parent.getHTMLElement();
		DOM.addClass(parentElement, 'side-by-side-editor');
		this.createSash(parentElement);
	}

B
Benjamin Pasero 已提交
50
	public setInput(newInput: SideBySideEditorInput, options?: EditorOptions): TPromise<void> {
B
Benjamin Pasero 已提交
51
		const oldInput = <SideBySideEditorInput>this.input;
S
Sandeep Somavarapu 已提交
52 53 54 55
		return super.setInput(newInput, options)
			.then(() => this.updateInput(oldInput, newInput, options));
	}

B
Benjamin Pasero 已提交
56
	protected setEditorVisible(visible: boolean, position: Position): void {
S
Sandeep Somavarapu 已提交
57
		if (this.masterEditor) {
B
Benjamin Pasero 已提交
58
			this.masterEditor.setVisible(visible, position);
S
Sandeep Somavarapu 已提交
59 60
		}
		if (this.detailsEditor) {
B
Benjamin Pasero 已提交
61
			this.detailsEditor.setVisible(visible, position);
S
Sandeep Somavarapu 已提交
62 63 64 65
		}
		super.setEditorVisible(visible, position);
	}

B
Benjamin Pasero 已提交
66 67 68 69 70 71 72 73 74 75
	public changePosition(position: Position): void {
		if (this.masterEditor) {
			this.masterEditor.changePosition(position);
		}
		if (this.detailsEditor) {
			this.detailsEditor.changePosition(position);
		}
		super.changePosition(position);
	}

S
Sandeep Somavarapu 已提交
76
	public clearInput(): void {
B
Benjamin Pasero 已提交
77 78 79 80 81 82
		if (this.masterEditor) {
			this.masterEditor.clearInput();
		}
		if (this.detailsEditor) {
			this.detailsEditor.clearInput();
		}
S
Sandeep Somavarapu 已提交
83 84 85 86
		this.disposeEditors();
		super.clearInput();
	}

S
Sandeep Somavarapu 已提交
87
	public focus(): void {
S
Sandeep Somavarapu 已提交
88 89 90 91 92
		if (this.masterEditor) {
			this.masterEditor.focus();
		}
	}

S
Sandeep Somavarapu 已提交
93
	public layout(dimension: Dimension): void {
S
Sandeep Somavarapu 已提交
94 95 96 97 98
		this.dimension = dimension;
		this.sash.setDimenesion(this.dimension);
	}

	public getControl(): IEditorControl {
S
Sandeep Somavarapu 已提交
99 100 101 102
		if (this.masterEditor) {
			return this.masterEditor.getControl();
		}
		return null;
S
Sandeep Somavarapu 已提交
103 104
	}

105 106 107 108 109 110 111 112
	public getMasterEditor(): IEditor {
		return this.masterEditor;
	}

	public getDetailsEditor(): IEditor {
		return this.detailsEditor;
	}

B
Benjamin Pasero 已提交
113
	private updateInput(oldInput: SideBySideEditorInput, newInput: SideBySideEditorInput, options?: EditorOptions): TPromise<void> {
S
Sandeep Somavarapu 已提交
114 115 116 117 118 119 120
		if (!newInput.matches(oldInput)) {
			if (oldInput) {
				this.disposeEditors();
			}
			this.createEditorContainers();
			return this.setNewInput(newInput, options);
		} else {
B
Benjamin Pasero 已提交
121
			this.detailsEditor.setInput(newInput.details);
S
Sandeep Somavarapu 已提交
122
			this.masterEditor.setInput(newInput.master, options);
M
Matt Bierner 已提交
123
			return undefined;
S
Sandeep Somavarapu 已提交
124 125 126
		}
	}

B
Benjamin Pasero 已提交
127
	private setNewInput(newInput: SideBySideEditorInput, options?: EditorOptions): TPromise<void> {
S
Sandeep Somavarapu 已提交
128
		return TPromise.join([
B
Benjamin Pasero 已提交
129
			this._createEditor(<EditorInput>newInput.details, this.detailsEditorContainer),
S
Sandeep Somavarapu 已提交
130 131
			this._createEditor(<EditorInput>newInput.master, this.masterEditorContainer)
		]).then(result => this.onEditorsCreated(result[0], result[1], newInput.details, newInput.master, options));
S
Sandeep Somavarapu 已提交
132 133
	}

S
Sandeep Somavarapu 已提交
134
	private _createEditor(editorInput: EditorInput, container: HTMLElement): TPromise<BaseEditor> {
S
Sandeep Somavarapu 已提交
135 136 137 138 139 140 141
		const descriptor = Registry.as<IEditorRegistry>(EditorExtensions.Editors).getEditor(editorInput);
		if (!descriptor) {
			return TPromise.wrapError(new Error(strings.format('Can not find a registered editor for the input {0}', editorInput)));
		}
		return this.instantiationService.createInstance(<EditorDescriptor>descriptor)
			.then((editor: BaseEditor) => {
				editor.create(new Builder(container));
B
Benjamin Pasero 已提交
142
				editor.setVisible(this.isVisible(), this.position);
S
Sandeep Somavarapu 已提交
143
				return editor;
S
Sandeep Somavarapu 已提交
144 145 146
			});
	}

S
Sandeep Somavarapu 已提交
147
	private onEditorsCreated(details: BaseEditor, master: BaseEditor, detailsInput: EditorInput, masterInput: EditorInput, options: EditorOptions): TPromise<void> {
S
Sandeep Somavarapu 已提交
148 149 150
		this.detailsEditor = details;
		this.masterEditor = master;
		this.dolayout(this.sash.getVerticalSashLeft());
S
Sandeep Somavarapu 已提交
151
		return TPromise.join([this.detailsEditor.setInput(detailsInput), this.masterEditor.setInput(masterInput, options)]).then(() => this.focus());
S
Sandeep Somavarapu 已提交
152 153
	}

S
Sandeep Somavarapu 已提交
154
	private createEditorContainers(): void {
S
Sandeep Somavarapu 已提交
155 156 157 158 159
		const parentElement = this.getContainer().getHTMLElement();
		this.detailsEditorContainer = DOM.append(parentElement, DOM.$('.details-editor-container'));
		this.detailsEditorContainer.style.position = 'absolute';
		this.masterEditorContainer = DOM.append(parentElement, DOM.$('.master-editor-container'));
		this.masterEditorContainer.style.position = 'absolute';
160 161 162 163 164 165 166 167 168 169

		this.updateStyles();
	}

	protected updateStyles(): void {
		super.updateStyles();

		if (this.masterEditorContainer) {
			this.masterEditorContainer.style.boxShadow = `-6px 0 5px -5px ${this.getColor(EDITOR_SIDE_BY_SIDE_BORDER)}`;
		}
S
Sandeep Somavarapu 已提交
170 171 172
	}

	private createSash(parentElement: HTMLElement): void {
S
Sandeep Somavarapu 已提交
173
		this.sash = this._register(new VSash(parentElement, 220));
S
Sandeep Somavarapu 已提交
174 175 176
		this._register(this.sash.onPositionChange(position => this.dolayout(position)));
	}

S
Sandeep Somavarapu 已提交
177
	private dolayout(splitPoint: number): void {
S
Sandeep Somavarapu 已提交
178
		if (!this.detailsEditor || !this.masterEditor || !this.dimension) {
S
Sandeep Somavarapu 已提交
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
			return;
		}
		const masterEditorWidth = this.dimension.width - splitPoint;
		const detailsEditorWidth = this.dimension.width - masterEditorWidth;

		this.detailsEditorContainer.style.width = `${detailsEditorWidth}px`;
		this.detailsEditorContainer.style.height = `${this.dimension.height}px`;
		this.detailsEditorContainer.style.left = '0px';

		this.masterEditorContainer.style.width = `${masterEditorWidth}px`;
		this.masterEditorContainer.style.height = `${this.dimension.height}px`;
		this.masterEditorContainer.style.left = `${splitPoint}px`;

		this.detailsEditor.layout(new Dimension(detailsEditorWidth, this.dimension.height));
		this.masterEditor.layout(new Dimension(masterEditorWidth, this.dimension.height));
	}

S
Sandeep Somavarapu 已提交
196
	private disposeEditors(): void {
S
Sandeep Somavarapu 已提交
197 198 199 200 201 202 203
		const parentContainer = this.getContainer().getHTMLElement();
		if (this.detailsEditor) {
			this.detailsEditor.dispose();
			this.detailsEditor = null;
		}
		if (this.masterEditor) {
			this.masterEditor.dispose();
S
Sandeep Somavarapu 已提交
204
			this.masterEditor = null;
S
Sandeep Somavarapu 已提交
205 206 207 208 209 210 211 212 213 214
		}
		if (this.detailsEditorContainer) {
			parentContainer.removeChild(this.detailsEditorContainer);
			this.detailsEditorContainer = null;
		}
		if (this.masterEditorContainer) {
			parentContainer.removeChild(this.masterEditorContainer);
			this.masterEditorContainer = null;
		}
	}
S
Sandeep Somavarapu 已提交
215 216 217 218 219

	public dispose(): void {
		this.disposeEditors();
		super.dispose();
	}
S
Sandeep Somavarapu 已提交
220
}