noTabsTitleControl.ts 7.6 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 {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
import {IContextMenuService} from 'vs/platform/contextview/browser/contextView';
import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService';
18
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
B
Benjamin Pasero 已提交
19 20 21 22 23 24 25
import {IMessageService} from 'vs/platform/message/common/message';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
import {TitleControl} from 'vs/workbench/browser/parts/editor/titleControl';

export class NoTabsTitleControl extends TitleControl {
26 27 28 29
	private titleContainer: HTMLElement;
	private titleLabel: HTMLElement;
	private titleDecoration: HTMLElement;
	private titleDescription: HTMLElement;
B
Benjamin Pasero 已提交
30 31 32 33 34 35 36 37 38

	private editorActionsToolbar: ToolBar;

	private currentPrimaryEditorActionIds: string[];
	private currentSecondaryEditorActionIds: string[];

	constructor(
		@IContextMenuService contextMenuService: IContextMenuService,
		@IInstantiationService instantiationService: IInstantiationService,
39
		@IConfigurationService configurationService: IConfigurationService,
B
Benjamin Pasero 已提交
40 41 42 43 44 45
		@IWorkbenchEditorService editorService: IWorkbenchEditorService,
		@IEditorGroupService editorGroupService: IEditorGroupService,
		@IKeybindingService keybindingService: IKeybindingService,
		@ITelemetryService telemetryService: ITelemetryService,
		@IMessageService messageService: IMessageService
	) {
46
		super(contextMenuService, instantiationService, configurationService, editorService, editorGroupService, keybindingService, telemetryService, messageService);
B
Benjamin Pasero 已提交
47 48 49 50 51 52 53 54 55 56 57

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

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

		this.editorActionsToolbar.context = { group };
	}

58
	public create(parent: HTMLElement): void {
59
		super.create(parent);
60
		this.titleContainer = parent;
B
Benjamin Pasero 已提交
61 62

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

			this.onTitleDoubleClick();
67 68
		}));

B
Benjamin Pasero 已提交
69 70

		// Detect mouse click
71
		this.toDispose.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.MOUSE_UP, (e: MouseEvent) => {
B
Benjamin Pasero 已提交
72 73 74
			DOM.EventHelper.stop(e, false);

			this.onTitleClick(e);
75
		}));
B
Benjamin Pasero 已提交
76 77

		// Left Title Decoration
78 79 80
		this.titleDecoration = document.createElement('div');
		DOM.addClass(this.titleDecoration, 'title-decoration');
		this.titleContainer.appendChild(this.titleDecoration);
B
Benjamin Pasero 已提交
81 82

		// Left Title Label & Description
83 84 85 86 87
		const labelContainer = document.createElement('div');
		DOM.addClass(labelContainer, 'title-label');

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

89 90
		this.titleDescription = document.createElement('span');
		labelContainer.appendChild(this.titleDescription);
B
Benjamin Pasero 已提交
91

92
		this.titleContainer.appendChild(labelContainer);
B
Benjamin Pasero 已提交
93 94

		// Right Actions Container
95 96 97 98
		const actionsContainer = document.createElement('div');
		DOM.addClass(actionsContainer, 'title-actions');

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

100
		this.titleContainer.appendChild(actionsContainer);
101 102

		// Context Menu
103
		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 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
	}

	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 已提交
131
		else if (this.stacks.groups.length === 1 && !DOM.isAncestor(<any>e.target || e.srcElement, this.editorActionsToolbar.getContainer().getHTMLElement())) {
B
Benjamin Pasero 已提交
132 133 134 135
			this.editorGroupService.focusGroup(position);
		}
	}

136
	protected doRefresh(): void {
B
Benjamin Pasero 已提交
137
		const group = this.context;
138
		const editor = group && group.activeEditor;
B
Benjamin Pasero 已提交
139
		if (!editor) {
140 141 142
			this.titleLabel.innerText = '';
			this.titleDescription.innerText = '';

B
Benjamin Pasero 已提交
143 144 145 146 147 148 149 150 151 152 153 154 155
			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) {
156
			DOM.addClass(this.titleContainer, 'pinned');
B
Benjamin Pasero 已提交
157
		} else {
158
			DOM.removeClass(this.titleContainer, 'pinned');
B
Benjamin Pasero 已提交
159 160 161 162
		}

		// Activity state
		if (isActive) {
163
			DOM.addClass(this.titleContainer, 'active');
B
Benjamin Pasero 已提交
164
		} else {
165
			DOM.removeClass(this.titleContainer, 'active');
B
Benjamin Pasero 已提交
166 167 168 169 170 171 172 173 174 175
		}

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

176 177
		this.titleLabel.innerText = name;
		this.titleLabel.title = verboseDescription;
B
Benjamin Pasero 已提交
178

179 180
		this.titleDescription.innerText = description;
		this.titleDescription.title = verboseDescription;
B
Benjamin Pasero 已提交
181 182 183

		// Editor Decoration
		if (editor.isDirty()) {
184
			DOM.addClass(this.titleDecoration, 'dirty');
B
Benjamin Pasero 已提交
185
		} else {
186
			DOM.removeClass(this.titleDecoration, 'dirty');
B
Benjamin Pasero 已提交
187 188 189
		}

		// Update Editor Actions Toolbar
190
		const editorActions = this.getEditorActions({group, editor });
B
Benjamin Pasero 已提交
191
		const primaryEditorActions = prepareActions(editorActions.primary);
192
		if (isActive && editor instanceof EditorInput && editor.supportsSplitEditor()) {
193 194
			primaryEditorActions.push(this.splitEditorAction);
		}
B
Benjamin Pasero 已提交
195
		const secondaryEditorActions = prepareActions(editorActions.secondary);
196

B
Benjamin Pasero 已提交
197
		const primaryEditorActionIds = primaryEditorActions.map(a => a.id);
198
		primaryEditorActionIds.push(this.closeEditorAction.id);
B
Benjamin Pasero 已提交
199 200 201 202
		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 已提交
203
			this.editorActionsToolbar.addPrimaryAction(this.closeEditorAction)();
204

B
Benjamin Pasero 已提交
205 206 207 208 209 210 211 212 213 214 215 216
			this.currentPrimaryEditorActionIds = primaryEditorActionIds;
			this.currentSecondaryEditorActionIds = secondaryEditorActionIds;
		}
	}

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

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