noTabsTitleControl.ts 6.2 KB
Newer Older
B
Benjamin Pasero 已提交
1 2 3 4 5 6 7 8 9 10 11
/*---------------------------------------------------------------------------------------------
 *  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 'vs/css!./media/notabstitle';
import {prepareActions} from 'vs/workbench/browser/actionBarRegistry';
import errors = require('vs/base/common/errors');
import arrays = require('vs/base/common/arrays');
12
import {IEditorGroup, EditorInput} from 'vs/workbench/common/editor';
B
Benjamin Pasero 已提交
13 14 15 16 17
import DOM = require('vs/base/browser/dom');
import {ToolBar} from 'vs/base/browser/ui/toolbar/toolbar';
import {TitleControl} from 'vs/workbench/browser/parts/editor/titleControl';

export class NoTabsTitleControl extends TitleControl {
18 19 20 21
	private titleContainer: HTMLElement;
	private titleLabel: HTMLElement;
	private titleDecoration: HTMLElement;
	private titleDescription: HTMLElement;
B
Benjamin Pasero 已提交
22 23 24

	private editorActionsToolbar: ToolBar;

25 26 27
	private currentPrimaryEditorActionIds: string[] = [];
	private currentSecondaryEditorActionIds: string[] = [];

B
Benjamin Pasero 已提交
28 29 30 31 32 33 34

	public setContext(group: IEditorGroup): void {
		super.setContext(group);

		this.editorActionsToolbar.context = { group };
	}

35 36
	public create(parent: HTMLElement): void {
		this.titleContainer = parent;
B
Benjamin Pasero 已提交
37 38

		// Pin on double click
39
		this.toDispose.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.DBLCLICK, (e: MouseEvent) => {
B
Benjamin Pasero 已提交
40 41 42
			DOM.EventHelper.stop(e);

			this.onTitleDoubleClick();
43 44
		}));

B
Benjamin Pasero 已提交
45
		// Detect mouse click
46
		this.toDispose.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.MOUSE_UP, (e: MouseEvent) => {
B
Benjamin Pasero 已提交
47 48 49
			DOM.EventHelper.stop(e, false);

			this.onTitleClick(e);
50
		}));
B
Benjamin Pasero 已提交
51 52

		// Left Title Decoration
53 54 55
		this.titleDecoration = document.createElement('div');
		DOM.addClass(this.titleDecoration, 'title-decoration');
		this.titleContainer.appendChild(this.titleDecoration);
B
Benjamin Pasero 已提交
56 57

		// Left Title Label & Description
58 59 60 61 62
		const labelContainer = document.createElement('div');
		DOM.addClass(labelContainer, 'title-label');

		this.titleLabel = document.createElement('a');
		labelContainer.appendChild(this.titleLabel);
B
Benjamin Pasero 已提交
63

64 65
		this.titleDescription = document.createElement('span');
		labelContainer.appendChild(this.titleDescription);
B
Benjamin Pasero 已提交
66

67
		this.titleContainer.appendChild(labelContainer);
B
Benjamin Pasero 已提交
68 69

		// Right Actions Container
70 71 72 73
		const actionsContainer = document.createElement('div');
		DOM.addClass(actionsContainer, 'title-actions');

		this.editorActionsToolbar = this.doCreateToolbar(actionsContainer);
B
Benjamin Pasero 已提交
74

75
		this.titleContainer.appendChild(actionsContainer);
76 77

		// Context Menu
78
		this.toDispose.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.CONTEXT_MENU, (e: Event) => this.onContextMenu({ group: this.context, editor: this.context.activeEditor }, e, this.titleContainer)));
B
Benjamin Pasero 已提交
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
	}

	private onTitleDoubleClick(): void {
		if (!this.context) {
			return;
		}

		const group = this.context;
		const position = this.stacks.positionOfGroup(group);

		this.editorGroupService.pinEditor(position, group.activeEditor);
	}

	private onTitleClick(e: MouseEvent): void {
		if (!this.context) {
			return;
		}

		const group = this.context;
		const position = this.stacks.positionOfGroup(group);

		// Close editor on middle mouse click
		if (e.button === 1 /* Middle Button */) {
			this.editorService.closeEditor(position, group.activeEditor).done(null, errors.onUnexpectedError);
		}

		// Focus editor group unless click on toolbar
B
Benjamin Pasero 已提交
106
		else if (this.stacks.groups.length === 1 && !DOM.isAncestor(<any>e.target || e.srcElement, this.editorActionsToolbar.getContainer().getHTMLElement())) {
B
Benjamin Pasero 已提交
107 108 109 110
			this.editorGroupService.focusGroup(position);
		}
	}

111
	protected doRefresh(): void {
B
Benjamin Pasero 已提交
112
		const group = this.context;
113
		const editor = group && group.activeEditor;
B
Benjamin Pasero 已提交
114
		if (!editor) {
115 116 117
			this.titleLabel.innerText = '';
			this.titleDescription.innerText = '';

B
Benjamin Pasero 已提交
118 119 120 121 122 123 124 125 126 127 128 129 130
			this.editorActionsToolbar.setActions([], [])();

			this.currentPrimaryEditorActionIds = [];
			this.currentSecondaryEditorActionIds = [];

			return; // return early if we are being closed
		}

		const isPinned = group.isPinned(group.activeEditor);
		const isActive = this.stacks.isActive(group);

		// Pinned state
		if (isPinned) {
131
			DOM.addClass(this.titleContainer, 'pinned');
B
Benjamin Pasero 已提交
132
		} else {
133
			DOM.removeClass(this.titleContainer, 'pinned');
B
Benjamin Pasero 已提交
134 135 136 137
		}

		// Activity state
		if (isActive) {
138
			DOM.addClass(this.titleContainer, 'active');
B
Benjamin Pasero 已提交
139
		} else {
140
			DOM.removeClass(this.titleContainer, 'active');
B
Benjamin Pasero 已提交
141 142 143 144 145 146 147 148 149 150
		}

		// Editor Title
		let name = editor.getName() || '';
		let description = isActive ? (editor.getDescription() || '') : '';
		let verboseDescription = editor.getDescription(true) || '';
		if (description === verboseDescription) {
			verboseDescription = ''; // dont repeat what is already shown
		}

151 152
		this.titleLabel.innerText = name;
		this.titleLabel.title = verboseDescription;
B
Benjamin Pasero 已提交
153

154 155
		this.titleDescription.innerText = description;
		this.titleDescription.title = verboseDescription;
B
Benjamin Pasero 已提交
156 157 158

		// Editor Decoration
		if (editor.isDirty()) {
159
			DOM.addClass(this.titleDecoration, 'dirty');
B
Benjamin Pasero 已提交
160
		} else {
161
			DOM.removeClass(this.titleDecoration, 'dirty');
B
Benjamin Pasero 已提交
162 163 164
		}

		// Update Editor Actions Toolbar
B
Benjamin Pasero 已提交
165
		const editorActions = this.getEditorActions({ group, editor });
B
Benjamin Pasero 已提交
166
		const primaryEditorActions = prepareActions(editorActions.primary);
167
		if (isActive && editor instanceof EditorInput && editor.supportsSplitEditor()) {
168 169
			primaryEditorActions.push(this.splitEditorAction);
		}
B
Benjamin Pasero 已提交
170
		const secondaryEditorActions = prepareActions(editorActions.secondary);
171

B
Benjamin Pasero 已提交
172
		const primaryEditorActionIds = primaryEditorActions.map(a => a.id);
173
		primaryEditorActionIds.push(this.closeEditorAction.id);
B
Benjamin Pasero 已提交
174 175 176 177
		const secondaryEditorActionIds = secondaryEditorActions.map(a => a.id);

		if (!arrays.equals(primaryEditorActionIds, this.currentPrimaryEditorActionIds) || !arrays.equals(secondaryEditorActionIds, this.currentSecondaryEditorActionIds)) {
			this.editorActionsToolbar.setActions(primaryEditorActions, secondaryEditorActions)();
B
Benjamin Pasero 已提交
178
			this.editorActionsToolbar.addPrimaryAction(this.closeEditorAction)();
179

B
Benjamin Pasero 已提交
180 181 182 183 184 185 186 187 188 189 190 191
			this.currentPrimaryEditorActionIds = primaryEditorActionIds;
			this.currentSecondaryEditorActionIds = secondaryEditorActionIds;
		}
	}

	public dispose(): void {
		super.dispose();

		// Toolbars
		this.editorActionsToolbar.dispose();
	}
}