noTabsTitleControl.ts 5.8 KB
Newer Older
B
Benjamin Pasero 已提交
1 2 3 4 5 6 7 8 9
/*---------------------------------------------------------------------------------------------
 *  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 errors = require('vs/base/common/errors');
B
Benjamin Pasero 已提交
10
import { toResource } from 'vs/workbench/common/editor';
B
Benjamin Pasero 已提交
11
import DOM = require('vs/base/browser/dom');
J
Johannes Rieken 已提交
12
import { TitleControl } from 'vs/workbench/browser/parts/editor/titleControl';
B
Benjamin Pasero 已提交
13
import { ResourceLabel } from 'vs/workbench/browser/labels';
14
import { Verbosity } from 'vs/platform/editor/common/editor';
15
import { TAB_ACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND } from 'vs/workbench/common/theme';
16
import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
B
Benjamin Pasero 已提交
17 18

export class NoTabsTitleControl extends TitleControl {
19
	private titleContainer: HTMLElement;
B
Benjamin Pasero 已提交
20
	private editorLabel: ResourceLabel;
B
Benjamin Pasero 已提交
21

22
	public create(parent: HTMLElement): void {
23
		super.create(parent);
24

25
		this.titleContainer = parent;
B
Benjamin Pasero 已提交
26

27
		// Gesture Support
28
		Gesture.addTarget(this.titleContainer);
29

B
Benjamin Pasero 已提交
30
		// Pin on double click
31
		this.toUnbind.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.DBLCLICK, (e: MouseEvent) => this.onTitleDoubleClick(e)));
32

B
Benjamin Pasero 已提交
33
		// Detect mouse click
34
		this.toUnbind.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.CLICK, (e: MouseEvent) => this.onTitleClick(e)));
B
Benjamin Pasero 已提交
35

36 37 38
		// Detect touch
		this.toUnbind.push(DOM.addDisposableListener(this.titleContainer, TouchEventType.Tap, (e: GestureEvent) => this.onTitleClick(e)));

39
		// Editor Label
B
Benjamin Pasero 已提交
40
		this.editorLabel = this.instantiationService.createInstance(ResourceLabel, this.titleContainer, void 0);
41
		this.toUnbind.push(this.editorLabel);
B
Benjamin Pasero 已提交
42
		this.toUnbind.push(this.editorLabel.onClick(e => this.onTitleLabelClick(e)));
B
Benjamin Pasero 已提交
43 44

		// Right Actions Container
45 46 47
		const actionsContainer = document.createElement('div');
		DOM.addClass(actionsContainer, 'title-actions');
		this.titleContainer.appendChild(actionsContainer);
48

49 50 51
		// Editor actions toolbar
		this.createEditorActionsToolBar(actionsContainer);

52
		// Context Menu
53
		this.toUnbind.push(DOM.addDisposableListener(this.titleContainer, DOM.EventType.CONTEXT_MENU, (e: Event) => this.onContextMenu({ group: this.context, editor: this.context.activeEditor }, e, this.titleContainer)));
54
		this.toUnbind.push(DOM.addDisposableListener(this.titleContainer, TouchEventType.Contextmenu, (e: Event) => this.onContextMenu({ group: this.context, editor: this.context.activeEditor }, e, this.titleContainer)));
B
Benjamin Pasero 已提交
55 56
	}

57 58 59
	private onTitleLabelClick(e: MouseEvent): void {
		DOM.EventHelper.stop(e, false);
		if (!this.dragged) {
60
			setTimeout(() => this.quickOpenService.show()); // delayed to let the onTitleClick() come first which can cause a focus change which can close quick open
61 62 63 64 65
		}
	}

	private onTitleDoubleClick(e: MouseEvent): void {
		DOM.EventHelper.stop(e);
B
Benjamin Pasero 已提交
66 67 68 69 70 71
		if (!this.context) {
			return;
		}

		const group = this.context;

72
		this.editorGroupService.pinEditor(group, group.activeEditor);
B
Benjamin Pasero 已提交
73 74
	}

75
	private onTitleClick(e: MouseEvent | GestureEvent): void {
B
Benjamin Pasero 已提交
76 77 78 79 80 81 82
		if (!this.context) {
			return;
		}

		const group = this.context;

		// Close editor on middle mouse click
83
		if (e instanceof MouseEvent && e.button === 1 /* Middle Button */) {
84
			this.closeOneEditorAction.run({ groupId: group.id, editorIndex: group.indexOf(group.activeEditor) }).done(null, errors.onUnexpectedError);
B
Benjamin Pasero 已提交
85 86
		}

87 88 89 90
		// Focus editor group unless:
		// - click on toolbar: should trigger actions within
		// - mouse click: do not focus group if there are more than one as it otherwise makes group DND funky
		// - touch: always focus
91
		else if ((this.stacks.groups.length === 1 || !(e instanceof MouseEvent)) && !DOM.isAncestor(((e as GestureEvent).initialTarget || e.target || e.srcElement) as HTMLElement, this.editorActionsToolbar.getContainer().getHTMLElement())) {
92
			this.editorGroupService.focusGroup(group);
B
Benjamin Pasero 已提交
93 94 95
		}
	}

96
	protected doRefresh(): void {
B
Benjamin Pasero 已提交
97
		const group = this.context;
98
		const editor = group && group.activeEditor;
B
Benjamin Pasero 已提交
99
		if (!editor) {
100
			this.editorLabel.clear();
101
			this.clearEditorActionsToolbar();
B
Benjamin Pasero 已提交
102 103 104 105 106 107 108 109 110

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

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

		// Activity state
		if (isActive) {
111
			DOM.addClass(this.titleContainer, 'active');
B
Benjamin Pasero 已提交
112
		} else {
113
			DOM.removeClass(this.titleContainer, 'active');
B
Benjamin Pasero 已提交
114 115
		}

116 117 118 119 120 121 122
		// Dirty state
		if (editor.isDirty()) {
			DOM.addClass(this.titleContainer, 'dirty');
		} else {
			DOM.removeClass(this.titleContainer, 'dirty');
		}

123
		// Editor Label
124
		const resource = toResource(editor, { supportSideBySide: true });
B
Benjamin Pasero 已提交
125
		const name = editor.getName() || '';
126 127 128 129 130 131 132 133 134

		const labelFormat = this.editorGroupService.getTabOptions().labelFormat;
		let description: string;
		if (labelFormat === 'default' && !isActive) {
			description = ''; // hide description when group is not active and style is 'default'
		} else {
			description = editor.getDescription(this.getVerbosity(labelFormat)) || '';
		}

135 136 137
		let title = editor.getTitle(Verbosity.LONG);
		if (description === title) {
			title = ''; // dont repeat what is already shown
B
Benjamin Pasero 已提交
138 139
		}

140
		this.editorLabel.setLabel({ name, description, resource }, { title, italic: !isPinned, extraClasses: ['title-label'] });
141 142 143 144 145
		if (isActive) {
			this.editorLabel.element.style.color = this.getColor(TAB_ACTIVE_FOREGROUND);
		} else {
			this.editorLabel.element.style.color = this.getColor(TAB_UNFOCUSED_ACTIVE_FOREGROUND);
		}
B
Benjamin Pasero 已提交
146 147

		// Update Editor Actions Toolbar
148
		this.updateEditorActionsToolbar();
B
Benjamin Pasero 已提交
149
	}
150 151 152 153 154 155 156 157

	private getVerbosity(style: string): Verbosity {
		switch (style) {
			case 'short': return Verbosity.SHORT;
			case 'long': return Verbosity.LONG;
			default: return Verbosity.MEDIUM;
		}
	}
I
isidor 已提交
158
}