sideBySideEditor.ts 7.2 KB
Newer Older
S
Sandeep Somavarapu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import 'vs/css!./media/sidebysideEditor';
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';
15
import { IEditorControl, Position, IEditor } from 'vs/platform/editor/common/editor';
S
Sandeep Somavarapu 已提交
16
import { VSash } from 'vs/base/browser/ui/sash/sash';
S
Sandeep Somavarapu 已提交
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';

export class SideBySideEditor extends BaseEditor {

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

	private dimension: Dimension;

	private masterEditor: BaseEditor;
	private masterEditorContainer: HTMLElement;

	private detailsEditor: BaseEditor;
	private detailsEditorContainer: HTMLElement;

	private sash: VSash;

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

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

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

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

B
Benjamin Pasero 已提交
64 65 66 67 68 69 70 71 72 73
	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 已提交
74
	public clearInput(): void {
B
Benjamin Pasero 已提交
75 76 77 78 79 80
		if (this.masterEditor) {
			this.masterEditor.clearInput();
		}
		if (this.detailsEditor) {
			this.detailsEditor.clearInput();
		}
S
Sandeep Somavarapu 已提交
81 82 83 84
		this.disposeEditors();
		super.clearInput();
	}

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

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

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

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

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

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

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

S
Sandeep Somavarapu 已提交
131
	private _createEditor(editorInput: EditorInput, container: HTMLElement): TPromise<BaseEditor> {
S
Sandeep Somavarapu 已提交
132 133 134 135 136 137 138
		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 已提交
139
				editor.setVisible(this.isVisible(), this.position);
S
Sandeep Somavarapu 已提交
140
				return editor;
S
Sandeep Somavarapu 已提交
141 142 143
			});
	}

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

S
Sandeep Somavarapu 已提交
151
	private createEditorContainers(): void {
S
Sandeep Somavarapu 已提交
152 153 154 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';
	}

	private createSash(parentElement: HTMLElement): void {
S
Sandeep Somavarapu 已提交
160
		this.sash = this._register(new VSash(parentElement, 220));
S
Sandeep Somavarapu 已提交
161 162 163
		this._register(this.sash.onPositionChange(position => this.dolayout(position)));
	}

S
Sandeep Somavarapu 已提交
164
	private dolayout(splitPoint: number): void {
S
Sandeep Somavarapu 已提交
165
		if (!this.detailsEditor || !this.masterEditor || !this.dimension) {
S
Sandeep Somavarapu 已提交
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
			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 已提交
183
	private disposeEditors(): void {
S
Sandeep Somavarapu 已提交
184 185 186 187 188 189 190
		const parentContainer = this.getContainer().getHTMLElement();
		if (this.detailsEditor) {
			this.detailsEditor.dispose();
			this.detailsEditor = null;
		}
		if (this.masterEditor) {
			this.masterEditor.dispose();
S
Sandeep Somavarapu 已提交
191
			this.masterEditor = null;
S
Sandeep Somavarapu 已提交
192 193 194 195 196 197 198 199 200 201
		}
		if (this.detailsEditorContainer) {
			parentContainer.removeChild(this.detailsEditorContainer);
			this.detailsEditorContainer = null;
		}
		if (this.masterEditorContainer) {
			parentContainer.removeChild(this.masterEditorContainer);
			this.masterEditorContainer = null;
		}
	}
S
Sandeep Somavarapu 已提交
202 203 204 205 206

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