actions.ts 5.6 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

J
Johannes Rieken 已提交
7
import { TPromise } from 'vs/base/common/winjs.base';
8
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
M
Matt Bierner 已提交
9
import { Event, Emitter } from 'vs/base/common/event';
10
import { isThenable } from 'vs/base/common/async';
11 12 13 14 15 16

export interface ITelemetryData {
	from?: string;
	target?: string;
	[key: string]: any;
}
E
Erich Gamma 已提交
17

J
Johannes Rieken 已提交
18
export interface IAction extends IDisposable {
E
Erich Gamma 已提交
19 20 21 22 23 24
	id: string;
	label: string;
	tooltip: string;
	class: string;
	enabled: boolean;
	checked: boolean;
25
	radio: boolean;
A
Alex Dima 已提交
26
	run(event?: any): TPromise<any>;
E
Erich Gamma 已提交
27 28
}

I
isidor 已提交
29
export interface IActionRunner extends IDisposable {
A
Alex Dima 已提交
30
	run(action: IAction, context?: any): TPromise<any>;
I
isidor 已提交
31 32
	onDidRun: Event<IRunEvent>;
	onDidBeforeRun: Event<IRunEvent>;
E
Erich Gamma 已提交
33 34
}

I
isidor 已提交
35
export interface IActionItem {
E
Erich Gamma 已提交
36 37 38 39 40 41 42 43 44
	actionRunner: IActionRunner;
	setActionContext(context: any): void;
	render(element: any /* HTMLElement */): void;
	isEnabled(): boolean;
	focus(): void;
	blur(): void;
	dispose(): void;
}

45 46 47 48 49 50
export interface IActionChangeEvent {
	label?: string;
	tooltip?: string;
	class?: string;
	enabled?: boolean;
	checked?: boolean;
51
	radio?: boolean;
52
}
E
Erich Gamma 已提交
53

54
export class Action implements IAction {
E
Erich Gamma 已提交
55

56
	protected _onDidChange = new Emitter<IActionChangeEvent>();
57 58 59 60 61 62
	protected _id: string;
	protected _label: string;
	protected _tooltip: string;
	protected _cssClass: string;
	protected _enabled: boolean;
	protected _checked: boolean;
63
	protected _radio: boolean;
64
	protected _actionCallback: (event?: any) => TPromise<any>;
65

66
	constructor(id: string, label: string = '', cssClass: string = '', enabled: boolean = true, actionCallback?: (event?: any) => TPromise<any>) {
E
Erich Gamma 已提交
67 68 69 70 71 72 73
		this._id = id;
		this._label = label;
		this._cssClass = cssClass;
		this._enabled = enabled;
		this._actionCallback = actionCallback;
	}

74 75 76 77 78 79 80 81
	public dispose() {
		this._onDidChange.dispose();
	}

	public get onDidChange(): Event<IActionChangeEvent> {
		return this._onDidChange.event;
	}

E
Erich Gamma 已提交
82 83 84 85 86 87 88 89 90 91 92 93
	public get id(): string {
		return this._id;
	}

	public get label(): string {
		return this._label;
	}

	public set label(value: string) {
		this._setLabel(value);
	}

94
	protected _setLabel(value: string): void {
E
Erich Gamma 已提交
95 96
		if (this._label !== value) {
			this._label = value;
97
			this._onDidChange.fire({ label: value });
E
Erich Gamma 已提交
98 99 100 101 102 103 104 105 106 107 108
		}
	}

	public get tooltip(): string {
		return this._tooltip;
	}

	public set tooltip(value: string) {
		this._setTooltip(value);
	}

109
	protected _setTooltip(value: string): void {
E
Erich Gamma 已提交
110 111
		if (this._tooltip !== value) {
			this._tooltip = value;
112
			this._onDidChange.fire({ tooltip: value });
E
Erich Gamma 已提交
113 114 115 116 117 118 119 120 121 122 123
		}
	}

	public get class(): string {
		return this._cssClass;
	}

	public set class(value: string) {
		this._setClass(value);
	}

124
	protected _setClass(value: string): void {
E
Erich Gamma 已提交
125 126
		if (this._cssClass !== value) {
			this._cssClass = value;
127
			this._onDidChange.fire({ class: value });
E
Erich Gamma 已提交
128 129 130 131 132 133 134 135 136 137 138
		}
	}

	public get enabled(): boolean {
		return this._enabled;
	}

	public set enabled(value: boolean) {
		this._setEnabled(value);
	}

139
	protected _setEnabled(value: boolean): void {
E
Erich Gamma 已提交
140 141
		if (this._enabled !== value) {
			this._enabled = value;
142
			this._onDidChange.fire({ enabled: value });
E
Erich Gamma 已提交
143 144 145 146 147 148 149 150 151 152 153
		}
	}

	public get checked(): boolean {
		return this._checked;
	}

	public set checked(value: boolean) {
		this._setChecked(value);
	}

154 155 156 157 158 159 160 161
	public get radio(): boolean {
		return this._radio;
	}

	public set radio(value: boolean) {
		this._setRadio(value);
	}

162
	protected _setChecked(value: boolean): void {
E
Erich Gamma 已提交
163 164
		if (this._checked !== value) {
			this._checked = value;
165
			this._onDidChange.fire({ checked: value });
E
Erich Gamma 已提交
166 167 168
		}
	}

169 170 171 172 173 174 175
	protected _setRadio(value: boolean): void {
		if (this._radio !== value) {
			this._radio = value;
			this._onDidChange.fire({ radio: value });
		}
	}

176
	public run(event?: any, data?: ITelemetryData): TPromise<any> {
177
		if (this._actionCallback !== void 0) {
E
Erich Gamma 已提交
178 179
			return this._actionCallback(event);
		}
180
		return TPromise.as(true);
E
Erich Gamma 已提交
181 182 183 184 185 186 187 188 189
	}
}

export interface IRunEvent {
	action: IAction;
	result?: any;
	error?: any;
}

I
isidor 已提交
190 191 192 193 194 195 196 197 198 199 200 201
export class ActionRunner implements IActionRunner {

	private _onDidBeforeRun = new Emitter<IRunEvent>();
	private _onDidRun = new Emitter<IRunEvent>();

	public get onDidRun(): Event<IRunEvent> {
		return this._onDidRun.event;
	}

	public get onDidBeforeRun(): Event<IRunEvent> {
		return this._onDidBeforeRun.event;
	}
E
Erich Gamma 已提交
202

A
Alex Dima 已提交
203
	public run(action: IAction, context?: any): TPromise<any> {
E
Erich Gamma 已提交
204
		if (!action.enabled) {
A
Alex Dima 已提交
205
			return TPromise.as(null);
E
Erich Gamma 已提交
206 207
		}

I
isidor 已提交
208
		this._onDidBeforeRun.fire({ action: action });
E
Erich Gamma 已提交
209

210
		return this.runAction(action, context).then((result: any) => {
I
isidor 已提交
211
			this._onDidRun.fire({ action: action, result: result });
E
Erich Gamma 已提交
212
		}, (error: any) => {
I
isidor 已提交
213
			this._onDidRun.fire({ action: action, error: error });
E
Erich Gamma 已提交
214 215
		});
	}
216 217

	protected runAction(action: IAction, context?: any): TPromise<any> {
218 219
		const res = context ? action.run(context) : action.run();

220
		if (isThenable(res)) {
221 222 223 224
			return res;
		}

		return TPromise.wrap(res);
225
	}
I
isidor 已提交
226 227

	public dispose(): void {
228 229
		this._onDidBeforeRun.dispose();
		this._onDidRun.dispose();
I
isidor 已提交
230
	}
E
Erich Gamma 已提交
231
}
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254

export class RadioGroup {

	private _disposable: IDisposable;

	constructor(readonly actions: Action[]) {
		this._disposable = combinedDisposable(actions.map(action => {
			return action.onDidChange(e => {
				if (e.checked && action.checked) {
					for (const candidate of actions) {
						if (candidate !== action) {
							candidate.checked = false;
						}
					}
				}
			});
		}));
	}

	dispose(): void {
		this._disposable.dispose();
	}
}