views.ts 6.9 KB
Newer Older
S
Sandeep Somavarapu 已提交
1 2 3 4 5 6 7
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import { TPromise } from 'vs/base/common/winjs.base';
import { Command } from 'vs/editor/common/modes';
S
Sandeep Somavarapu 已提交
8
import { UriComponents } from 'vs/base/common/uri';
M
Matt Bierner 已提交
9
import { Event, Emitter } from 'vs/base/common/event';
S
Sandeep Somavarapu 已提交
10 11 12 13
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { ITreeViewDataProvider } from 'vs/workbench/common/views';
import { localize } from 'vs/nls';
import { IViewlet } from 'vs/workbench/common/viewlet';
S
Sandeep Somavarapu 已提交
14
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
15
import { IDisposable } from 'vs/base/common/lifecycle';
S
Sandeep Somavarapu 已提交
16
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
S
Sandeep Somavarapu 已提交
17
import { values } from 'vs/base/common/map';
S
Sandeep Somavarapu 已提交
18 19 20

export class ViewLocation {

S
Sandeep Somavarapu 已提交
21 22 23
	private static readonly _onDidRegister: Emitter<ViewLocation> = new Emitter<ViewLocation>();
	static readonly onDidRegister: Event<ViewLocation> = ViewLocation._onDidRegister.event;

24 25
	private static locations: Map<string, ViewLocation> = new Map<string, ViewLocation>();
	static register(id: string): ViewLocation {
S
Sandeep Somavarapu 已提交
26 27 28 29 30 31
		if (!ViewLocation.locations.has(id)) {
			const viewLocation = new ViewLocation(id);
			ViewLocation.locations.set(id, viewLocation);
			ViewLocation._onDidRegister.fire(viewLocation);
		}
		return ViewLocation.get(id);
S
Sandeep Somavarapu 已提交
32
	}
33 34
	static get(value: string): ViewLocation {
		return ViewLocation.locations.get(value);
S
Sandeep Somavarapu 已提交
35
	}
S
Sandeep Somavarapu 已提交
36 37 38
	static get all(): ViewLocation[] {
		return values(ViewLocation.locations);
	}
S
Sandeep Somavarapu 已提交
39

40 41 42
	static readonly Explorer: ViewLocation = ViewLocation.register('workbench.view.explorer');
	static readonly Debug: ViewLocation = ViewLocation.register('workbench.view.debug');
	static readonly Extensions: ViewLocation = ViewLocation.register('workbench.view.extensions');
43
	static readonly SCM: ViewLocation = ViewLocation.register('workbench.view.scm.views.contributed');
S
Sandeep Somavarapu 已提交
44
	static readonly TEST: ViewLocation = ViewLocation.register('workbench.view.extension.test');
45 46 47 48

	private constructor(private _id: string) { }
	get id(): string { return this._id; }

S
Sandeep Somavarapu 已提交
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
}

export interface IViewDescriptor {

	readonly id: string;

	readonly name: string;

	readonly location: ViewLocation;

	// TODO do we really need this?!
	readonly ctor: any;

	readonly when?: ContextKeyExpr;

	readonly order?: number;

	readonly weight?: number;

	readonly collapsed?: boolean;

	readonly canToggleVisibility?: boolean;
71 72

	readonly hideByDefault?: boolean;
S
Sandeep Somavarapu 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86
}

export interface IViewsRegistry {

	readonly onViewsRegistered: Event<IViewDescriptor[]>;

	readonly onViewsDeregistered: Event<IViewDescriptor[]>;

	registerViews(views: IViewDescriptor[]): void;

	deregisterViews(ids: string[], location: ViewLocation): void;

	getViews(loc: ViewLocation): IViewDescriptor[];

87 88
	getAllViews(): IViewDescriptor[];

S
Sandeep Somavarapu 已提交
89
	getView(id: string): IViewDescriptor;
S
Sandeep Somavarapu 已提交
90 91 92 93 94

}

export const ViewsRegistry: IViewsRegistry = new class implements IViewsRegistry {

M
Matt Bierner 已提交
95
	private readonly _onViewsRegistered: Emitter<IViewDescriptor[]> = new Emitter<IViewDescriptor[]>();
S
Sandeep Somavarapu 已提交
96 97
	readonly onViewsRegistered: Event<IViewDescriptor[]> = this._onViewsRegistered.event;

M
Matt Bierner 已提交
98
	private readonly _onViewsDeregistered: Emitter<IViewDescriptor[]> = new Emitter<IViewDescriptor[]>();
S
Sandeep Somavarapu 已提交
99 100
	readonly onViewsDeregistered: Event<IViewDescriptor[]> = this._onViewsDeregistered.event;

S
Sandeep Somavarapu 已提交
101
	private _viewLocations: ViewLocation[] = [];
S
Sandeep Somavarapu 已提交
102 103 104 105 106 107 108 109 110
	private _views: Map<ViewLocation, IViewDescriptor[]> = new Map<ViewLocation, IViewDescriptor[]>();

	registerViews(viewDescriptors: IViewDescriptor[]): void {
		if (viewDescriptors.length) {
			for (const viewDescriptor of viewDescriptors) {
				let views = this._views.get(viewDescriptor.location);
				if (!views) {
					views = [];
					this._views.set(viewDescriptor.location, views);
S
Sandeep Somavarapu 已提交
111
					this._viewLocations.push(viewDescriptor.location);
S
Sandeep Somavarapu 已提交
112 113
				}
				if (views.some(v => v.id === viewDescriptor.id)) {
114
					throw new Error(localize('duplicateId', "A view with id '{0}' is already registered in the location '{1}'", viewDescriptor.id, viewDescriptor.location.id));
S
Sandeep Somavarapu 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
				}
				views.push(viewDescriptor);
			}
			this._onViewsRegistered.fire(viewDescriptors);
		}
	}

	deregisterViews(ids: string[], location: ViewLocation): void {
		const views = this._views.get(location);

		if (!views) {
			return;
		}

		const viewsToDeregister = views.filter(view => ids.indexOf(view.id) !== -1);

		if (viewsToDeregister.length) {
S
Sandeep Somavarapu 已提交
132 133 134 135 136 137 138
			const remaningViews = views.filter(view => ids.indexOf(view.id) === -1);
			if (remaningViews.length) {
				this._views.set(location, remaningViews);
			} else {
				this._views.delete(location);
				this._viewLocations.splice(this._viewLocations.indexOf(location), 1);
			}
139
			this._onViewsDeregistered.fire(viewsToDeregister);
S
Sandeep Somavarapu 已提交
140 141 142 143 144 145 146 147
		}

	}

	getViews(loc: ViewLocation): IViewDescriptor[] {
		return this._views.get(loc) || [];
	}

148 149 150 151 152 153
	getAllViews(): IViewDescriptor[] {
		const result: IViewDescriptor[] = [];
		this._views.forEach(views => result.push(...views));
		return result;
	}

S
Sandeep Somavarapu 已提交
154 155 156 157 158 159 160 161
	getView(id: string): IViewDescriptor {
		for (const viewLocation of this._viewLocations) {
			const viewDescriptor = (this._views.get(viewLocation) || []).filter(v => v.id === id)[0];
			if (viewDescriptor) {
				return viewDescriptor;
			}
		}
		return null;
S
Sandeep Somavarapu 已提交
162 163 164 165 166
	}
};

export interface IViewsViewlet extends IViewlet {

S
Sandeep Somavarapu 已提交
167
	openView(id: string, focus?: boolean): TPromise<void>;
S
Sandeep Somavarapu 已提交
168 169 170

}

S
Sandeep Somavarapu 已提交
171 172
// Custom views

173 174
export interface ITreeViewer extends IDisposable {

175
	dataProvider: ITreeViewDataProvider;
S
Sandeep Somavarapu 已提交
176

177 178 179 180
	readonly onDidExpandItem: Event<ITreeItem>;

	readonly onDidCollapseItem: Event<ITreeItem>;

181 182
	readonly onDidChangeSelection: Event<ITreeItem[]>;

183
	refresh(treeItems?: ITreeItem[]): TPromise<void>;
S
Sandeep Somavarapu 已提交
184

185
	setVisibility(visible: boolean): void;
S
Sandeep Somavarapu 已提交
186

187 188 189 190
	focus(): void;

	layout(height: number): void;

S
Sandeep Somavarapu 已提交
191
	show(container: HTMLElement);
192 193

	getOptimalWidth(): number;
S
Sandeep Somavarapu 已提交
194

S
Sandeep Somavarapu 已提交
195
	reveal(item: ITreeItem, parentChain: ITreeItem[], options: { select?: boolean }): TPromise<void>;
S
Sandeep Somavarapu 已提交
196 197 198 199
}

export interface ICustomViewDescriptor extends IViewDescriptor {

200
	treeView?: boolean;
S
Sandeep Somavarapu 已提交
201 202 203

}

204
export const IViewsService = createDecorator<IViewsService>('viewsService');
S
Sandeep Somavarapu 已提交
205

206
export interface IViewsService {
S
Sandeep Somavarapu 已提交
207 208
	_serviceBrand: any;

209
	getTreeViewer(id: string): ITreeViewer;
S
Sandeep Somavarapu 已提交
210 211

	openView(id: string, focus?: boolean): TPromise<void>;
S
Sandeep Somavarapu 已提交
212
}
S
Sandeep Somavarapu 已提交
213 214 215

export type TreeViewItemHandleArg = {
	$treeViewId: string,
S
Sandeep Somavarapu 已提交
216
	$treeItemHandle: string
S
Sandeep Somavarapu 已提交
217 218 219 220 221 222 223 224 225 226
};

export enum TreeItemCollapsibleState {
	None = 0,
	Collapsed = 1,
	Expanded = 2
}

export interface ITreeItem {

S
Sandeep Somavarapu 已提交
227
	handle: string;
S
Sandeep Somavarapu 已提交
228

S
Sandeep Somavarapu 已提交
229 230
	parentHandle: string;

S
Sandeep Somavarapu 已提交
231 232
	collapsibleState: TreeItemCollapsibleState;

S
Sandeep Somavarapu 已提交
233
	label?: string;
S
Sandeep Somavarapu 已提交
234

S
Sandeep Somavarapu 已提交
235 236 237
	icon?: string;

	iconDark?: string;
S
Sandeep Somavarapu 已提交
238

S
Sandeep Somavarapu 已提交
239
	themeIcon?: ThemeIcon;
S
Sandeep Somavarapu 已提交
240

S
Sandeep Somavarapu 已提交
241 242
	resourceUri?: UriComponents;

S
Sandeep Somavarapu 已提交
243 244
	tooltip?: string;

S
Sandeep Somavarapu 已提交
245 246 247 248 249 250 251 252 253 254
	contextValue?: string;

	command?: Command;

	children?: ITreeItem[];

}

export interface ITreeViewDataProvider {

255
	getChildren(element?: ITreeItem): TPromise<ITreeItem[]>;
S
Sandeep Somavarapu 已提交
256

S
Sandeep Somavarapu 已提交
257
}