watermark.ts 7.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*---------------------------------------------------------------------------------------------
 *  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!./watermark';
import { $ } from 'vs/base/browser/builder';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { assign } from 'vs/base/common/objects';
import { isMacintosh } from 'vs/base/common/platform';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import * as nls from 'vs/nls';
import { Registry } from 'vs/platform/platform';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchContribution, IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
C
Christof Marti 已提交
19 20 21
import { GlobalQuickOpenAction } from 'vs/workbench/browser/parts/quickopen/quickopen.contribution';
import { KeybindingsReferenceAction, OpenRecentAction } from 'vs/workbench/electron-browser/actions';
import { ShowRecommendedKeymapExtensionsAction } from 'vs/workbench/parts/extensions/browser/extensionsActions';
22
import { GlobalNewUntitledFileAction, OpenFileAction } from 'vs/workbench/parts/files/browser/fileActions';
23
import { OpenFolderAction, OpenFileFolderAction } from 'vs/workbench/browser/actions/fileActions';
C
Christof Marti 已提交
24 25 26 27
import { ShowAllCommandsAction } from 'vs/workbench/parts/quickopen/browser/commandsHandler';
import { Parts, IPartService } from 'vs/workbench/services/part/common/partService';
import { StartAction } from 'vs/workbench/parts/debug/browser/debugActions';
import { FindInFilesActionId } from 'vs/workbench/parts/search/common/constants';
28
import { OpenGlobalKeybindingsAction } from 'vs/workbench/parts/preferences/browser/preferencesActions';
C
Christof Marti 已提交
29 30
import { ToggleTerminalAction } from 'vs/workbench/parts/terminal/electron-browser/terminalActions';
import { SelectColorThemeAction } from 'vs/workbench/parts/themes/electron-browser/themes.contribution';
31 32 33 34 35 36 37 38 39

interface WatermarkEntry {
	text: string;
	ids: string[];
	mac?: boolean;
}

const showCommands: WatermarkEntry = {
	text: nls.localize('watermark.showCommands', "Show All Commands"),
C
Christof Marti 已提交
40
	ids: [ShowAllCommandsAction.ID]
41 42 43
};
const quickOpen: WatermarkEntry = {
	text: nls.localize('watermark.quickOpen', "Go to File"),
C
Christof Marti 已提交
44
	ids: [GlobalQuickOpenAction.ID]
45 46 47
};
const openFileNonMacOnly: WatermarkEntry = {
	text: nls.localize('watermark.openFile', "Open File"),
C
Christof Marti 已提交
48
	ids: [OpenFileAction.ID],
49 50 51 52
	mac: false
};
const openFolderNonMacOnly: WatermarkEntry = {
	text: nls.localize('watermark.openFolder', "Open Folder"),
C
Christof Marti 已提交
53
	ids: [OpenFolderAction.ID],
54 55 56 57
	mac: false
};
const openFileOrFolderMacOnly: WatermarkEntry = {
	text: nls.localize('watermark.openFileFolder', "Open File or Folder"),
C
Christof Marti 已提交
58
	ids: [OpenFileFolderAction.ID],
59 60 61 62
	mac: true
};
const openRecent: WatermarkEntry = {
	text: nls.localize('watermark.openRecent', "Open Recent"),
C
Christof Marti 已提交
63
	ids: [OpenRecentAction.ID]
64 65 66
};
const newUntitledFile: WatermarkEntry = {
	text: nls.localize('watermark.newUntitledFile', "New Untitled File"),
C
Christof Marti 已提交
67
	ids: [GlobalNewUntitledFileAction.ID]
68 69 70 71
};
const newUntitledFileMacOnly: WatermarkEntry = assign({ mac: true }, newUntitledFile);
const toggleTerminal: WatermarkEntry = {
	text: nls.localize({ key: 'watermark.toggleTerminal', comment: ['toggle is a verb here'] }, "Toggle Terminal"),
C
Christof Marti 已提交
72
	ids: [ToggleTerminalAction.ID]
73 74 75 76
};

const findInFiles: WatermarkEntry = {
	text: nls.localize('watermark.findInFiles', "Find in Files"),
C
Christof Marti 已提交
77
	ids: [FindInFilesActionId]
78 79 80
};
const startDebugging: WatermarkEntry = {
	text: nls.localize('watermark.startDebugging', "Start Debugging"),
C
Christof Marti 已提交
81
	ids: [StartAction.ID]
82 83 84
};

const selectTheme: WatermarkEntry = {
C
Christof Marti 已提交
85 86
	text: nls.localize('watermark.selectTheme', "Change Theme"),
	ids: [SelectColorThemeAction.ID]
87 88 89
};
const selectKeymap: WatermarkEntry = {
	text: nls.localize('watermark.selectKeymap', "Change Keymap"),
C
Christof Marti 已提交
90
	ids: [ShowRecommendedKeymapExtensionsAction.ID]
91 92 93
};
const keybindingsReference: WatermarkEntry = {
	text: nls.localize('watermark.keybindingsReference', "Keyboard Reference"),
C
Christof Marti 已提交
94
	ids: [KeybindingsReferenceAction.ID]
95 96 97
};
const openGlobalKeybindings: WatermarkEntry = {
	text: nls.localize('watermark.openGlobalKeybindings', "Keyboard Shortcuts"),
C
Christof Marti 已提交
98
	ids: [OpenGlobalKeybindingsAction.ID]
99 100
};

101
const newUserEntries = [
102 103 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 131 132 133 134 135 136 137 138
	showCommands,
	selectTheme,
	selectKeymap,
	openFolderNonMacOnly,
	openFileOrFolderMacOnly,
	KeybindingsReferenceAction.AVAILABLE ? keybindingsReference : openGlobalKeybindings
];

const noFolderEntries = [
	showCommands,
	openFileNonMacOnly,
	openFolderNonMacOnly,
	openFileOrFolderMacOnly,
	openRecent,
	newUntitledFileMacOnly,
	toggleTerminal
];

const folderEntries = [
	showCommands,
	quickOpen,
	findInFiles,
	startDebugging,
	toggleTerminal
];

const UNBOUND = nls.localize('watermark.unboundCommand', "unbound");

export class WatermarkContribution implements IWorkbenchContribution {

	private toDispose: IDisposable[] = [];

	constructor(
		@ILifecycleService lifecycleService: ILifecycleService,
		@IPartService private partService: IPartService,
		@IKeybindingService private keybindingService: IKeybindingService,
		@IWorkspaceContextService private contextService: IWorkspaceContextService,
139
		@ITelemetryService private telemetryService: ITelemetryService
140
	) {
141 142 143 144
		lifecycleService.onShutdown(this.dispose, this);
		this.partService.joinCreation().then(() => {
			this.create();
		});
145 146 147 148 149 150 151 152
	}

	public getId() {
		return 'vs.watermark';
	}

	private create(): void {
		const container = this.partService.getContainer(Parts.EDITOR_PART);
153

154 155 156 157
		const watermark = $()
			.div({ 'class': 'watermark' });
		const box = $(watermark)
			.div({ 'class': 'watermark-box' });
B
Benjamin Pasero 已提交
158
		const folder = this.contextService.hasWorkspace();
159 160
		const newUser = this.telemetryService.getExperiments().showNewUserWatermark;
		const selected = (newUser ? newUserEntries : (folder ? folderEntries : noFolderEntries))
161 162 163 164 165 166 167 168 169 170 171
			.filter(entry => !('mac' in entry) || entry.mac === isMacintosh);
		const update = () => {
			const builder = $(box);
			builder.clearChildren();
			selected.map(entry => {
				builder.element('dl', {}, dl => {
					dl.element('dt', {}, dt => dt.text(entry.text));
					dl.element('dd', {}, dd => dd.innerHtml(
						entry.ids
							.map(id => this.keybindingService.lookupKeybindings(id).slice(0, 1)
								.map(k => `<span class="shortcuts">${this.keybindingService.getLabelFor(k)}</span>`)
172
								.join('') || `<span class="unbound">${UNBOUND}</span>`)
173 174 175 176 177
							.join(' / ')
					));
				});
			});
		};
178 179 180 181
		const layout = () => {
			const { height } = container.getBoundingClientRect();
			container.classList[height <= 478 ? 'add' : 'remove']('max-height-478px');
		};
182
		update();
183 184
		watermark.build(container.firstElementChild as HTMLElement, 0);
		layout();
185
		this.toDispose.push(this.keybindingService.onDidUpdateKeybindings(update));
186
		this.toDispose.push(this.partService.onEditorLayout(layout));
187 188 189 190 191 192 193 194 195
	}

	public dispose(): void {
		this.toDispose = dispose(this.toDispose);
	}
}

Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
	.registerWorkbenchContribution(WatermarkContribution);