terminalPanel.ts 5.0 KB
Newer Older
D
Daniel Imms 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

6
import lifecycle = require('vs/base/common/lifecycle');
7
import platform = require('vs/base/common/platform');
D
Daniel Imms 已提交
8 9
import {TPromise} from 'vs/base/common/winjs.base';
import {Builder, Dimension} from 'vs/base/browser/builder';
10
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
D
Daniel Imms 已提交
11
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
12
import {IThemeService} from 'vs/workbench/services/themes/common/themeService';
13
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
14
import {ITerminalService, TERMINAL_PANEL_ID} from 'vs/workbench/parts/terminal/electron-browser/terminal';
D
Daniel Imms 已提交
15
import {Panel} from 'vs/workbench/browser/panel';
16 17
import {TerminalConfigHelper} from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper';
import {TerminalInstance} from 'vs/workbench/parts/terminal/electron-browser/terminalInstance';
D
Daniel Imms 已提交
18 19 20

export class TerminalPanel extends Panel {

21
	private toDispose: lifecycle.IDisposable[];
D
Daniel Imms 已提交
22
	private parentDomElement: HTMLElement;
23
	private themeStyleElement: HTMLElement;
24
	private configurationHelper: TerminalConfigHelper;
25
	private terminalInstance: TerminalInstance;
D
Daniel Imms 已提交
26 27

	constructor(
28
		@IConfigurationService private configurationService: IConfigurationService,
29
		@ITelemetryService telemetryService: ITelemetryService,
30
		@IWorkspaceContextService private contextService: IWorkspaceContextService,
31 32
		@ITerminalService private terminalService: ITerminalService,
		@IThemeService private themeService: IThemeService
D
Daniel Imms 已提交
33 34
	) {
		super(TERMINAL_PANEL_ID, telemetryService);
35
		this.toDispose = [];
D
Daniel Imms 已提交
36 37
	}

38 39 40
	public layout(dimension?: Dimension): void {
		if (this.terminalInstance) {
			this.terminalInstance.layout(dimension);
41
		}
D
Daniel Imms 已提交
42 43 44 45
	}

	public create(parent: Builder): TPromise<void> {
		super.create(parent);
46
		this.parentDomElement = parent.getHTMLElement();
47 48
		this.themeStyleElement = document.createElement('style');
		this.parentDomElement.appendChild(this.themeStyleElement);
49 50
		this.configurationHelper = new TerminalConfigHelper(platform.platform, this.configurationService, this.parentDomElement);

51
		return this.createTerminal();
52 53
	}

54
	public setVisible(visible: boolean): TPromise<void> {
55 56 57 58 59 60 61 62 63 64 65 66
		if (visible) {
			if (this.terminalInstance) {
				this.updateFont();
				this.updateTheme();
			} else {
				return super.setVisible(visible).then(() => {
					this.createTerminal();
					this.updateFont();
					this.updateTheme();
					return Promise.resolve(void 0);
				});
			}
67 68 69 70
		}
		return super.setVisible(visible);
	}

71 72
	private createTerminal(): TPromise<void> {
		return new TPromise<void>(resolve => {
73 74 75
			this.terminalInstance = new TerminalInstance(this.configurationHelper.getShell(), this.parentDomElement, this.contextService, this.terminalService, this.onTerminalInstanceExit.bind(this));
			this.toDispose.push(this.themeService.onDidThemeChange(this.updateTheme.bind(this)));
			this.toDispose.push(this.configurationService.onDidUpdateConfiguration(this.updateFont.bind(this)));
76
			resolve(void 0);
D
Daniel Imms 已提交
77 78
		});
	}
79

80 81 82 83 84 85 86 87 88
	private onTerminalInstanceExit(terminalInstance: TerminalInstance): void {
		if (this.terminalInstance === terminalInstance) {
			this.terminalInstance = null;
		}
		this.terminalService.toggle();
	}

	private updateTheme(themeId?: string): void {
		if (!this.terminalInstance) {
89 90
			return;
		}
91 92 93
		if (!themeId) {
			themeId = this.themeService.getTheme();
		}
D
Daniel Imms 已提交
94 95 96 97 98 99 100 101 102 103 104
		let theme = this.configurationHelper.getTheme(themeId);

		let css = '';
		theme.forEach((color: string, index: number) => {
			let rgba = this.convertHexCssColorToRgba(color, 0.996);
			css += `.terminal .xterm-color-${index} { color: ${color}; }` +
				`.terminal .xterm-color-${index}::selection { background-color: ${rgba}; }` +
				`.terminal .xterm-bg-color-${index} { background-color: ${color}; }` +
				`.terminal .xterm-bg-color-${index}::selection { color: ${color}; }`;
		});

105
		this.themeStyleElement.innerHTML = css;
D
Daniel Imms 已提交
106 107 108 109 110 111 112
	}

	private convertHexCssColorToRgba(hex: string, alpha: number): string {
		let r = parseInt(hex.substr(1, 2), 16);
		let g = parseInt(hex.substr(3, 2), 16);
		let b = parseInt(hex.substr(5, 2), 16);
		return `rgba(${r}, ${g}, ${b}, ${alpha})`;
113 114
	}

115
	private updateFont(): void {
116 117 118 119
		if (!this.terminalInstance) {
			return;
		}
		this.terminalInstance.setFont(this.configurationHelper.getFont());
120
		this.layout(new Dimension(this.parentDomElement.offsetWidth, this.parentDomElement.offsetHeight));
121 122
	}

123

124
	public focus(): void {
125 126
		if (this.terminalInstance) {
			this.terminalInstance.focus(true);
127 128 129
		}
	}

130 131
	public dispose(): void {
		this.toDispose = lifecycle.dispose(this.toDispose);
132 133 134 135
		if (this.terminalInstance) {
			this.terminalInstance.dispose();
			this.terminalInstance = null;
		}
136 137
		super.dispose();
	}
D
Daniel Imms 已提交
138
}