views.ts 7.8 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
import { Registry } from 'vs/platform/registry/common/platform';
S
Sandeep Somavarapu 已提交
19

20
export const TEST_VIEW_CONTAINER_ID = 'workbench.view.extension.test';
S
Sandeep Somavarapu 已提交
21

S
Sandeep Somavarapu 已提交
22 23 24
export namespace Extensions {
	export const ViewContainersRegistry = 'workbench.registry.view.containers';
}
S
Sandeep Somavarapu 已提交
25

S
Sandeep Somavarapu 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
export interface IViewContainersRegistry {
	/**
	 * An event that is triggerred when a view container is registered.
	 */
	readonly onDidRegister: Event<ViewContainer>;

	/**
	 * All registered view containers
	 */
	readonly all: ViewContainer[];

	/**
	 * Registers a view container with given id
	 * No op if a view container is already registered with the given id.
	 *
	 * @param id of the view container.
	 *
	 * @returns the registered ViewContainer.
	 */
45
	registerViewContainer(id: string, extensionId?: string): ViewContainer;
S
Sandeep Somavarapu 已提交
46 47 48 49 50 51 52 53 54

	/**
	 * Returns the view container with given id.
	 *
	 * @param id
	 * @returns the view container with given id.
	 */
	get(id: string): ViewContainer;
}
55

S
Sandeep Somavarapu 已提交
56
export class ViewContainer {
57
	protected constructor(readonly id: string, readonly extensionId: string) { }
S
Sandeep Somavarapu 已提交
58 59 60 61 62 63
}

class ViewContainersRegistryImpl implements IViewContainersRegistry {

	private readonly _onDidRegister: Emitter<ViewContainer> = new Emitter<ViewContainer>();
	readonly onDidRegister: Event<ViewContainer> = this._onDidRegister.event;
64

S
Sandeep Somavarapu 已提交
65 66 67 68 69 70
	private viewContainers: Map<string, ViewContainer> = new Map<string, ViewContainer>();

	get all(): ViewContainer[] {
		return values(this.viewContainers);
	}

71
	registerViewContainer(id: string, extensionId: string): ViewContainer {
S
Sandeep Somavarapu 已提交
72 73 74
		if (!this.viewContainers.has(id)) {
			const viewContainer = new class extends ViewContainer {
				constructor() {
75
					super(id, extensionId);
S
Sandeep Somavarapu 已提交
76 77 78 79 80 81 82 83 84 85 86
				}
			};
			this.viewContainers.set(id, viewContainer);
			this._onDidRegister.fire(viewContainer);
		}
		return this.get(id);
	}

	get(id: string): ViewContainer {
		return this.viewContainers.get(id);
	}
S
Sandeep Somavarapu 已提交
87 88
}

S
Sandeep Somavarapu 已提交
89 90
Registry.add(Extensions.ViewContainersRegistry, new ViewContainersRegistryImpl());

S
Sandeep Somavarapu 已提交
91 92 93 94 95 96
export interface IViewDescriptor {

	readonly id: string;

	readonly name: string;

S
Sandeep Somavarapu 已提交
97
	readonly container: ViewContainer;
S
Sandeep Somavarapu 已提交
98

B
Benjamin Pasero 已提交
99
	// TODO@Sandeep do we really need this?!
S
Sandeep Somavarapu 已提交
100 101 102 103 104 105 106 107 108 109 110
	readonly ctor: any;

	readonly when?: ContextKeyExpr;

	readonly order?: number;

	readonly weight?: number;

	readonly collapsed?: boolean;

	readonly canToggleVisibility?: boolean;
111

112
	// Applies only to newly created views
113
	readonly hideByDefault?: boolean;
S
Sandeep Somavarapu 已提交
114 115
}

116 117 118 119 120
export interface IViewDescriptorCollection {
	readonly onDidChange: Event<void>;
	readonly viewDescriptors: IViewDescriptor[];
}

S
Sandeep Somavarapu 已提交
121 122 123 124 125 126 127 128
export interface IViewsRegistry {

	readonly onViewsRegistered: Event<IViewDescriptor[]>;

	readonly onViewsDeregistered: Event<IViewDescriptor[]>;

	registerViews(views: IViewDescriptor[]): void;

S
Sandeep Somavarapu 已提交
129
	deregisterViews(ids: string[], container: ViewContainer): void;
S
Sandeep Somavarapu 已提交
130

S
Sandeep Somavarapu 已提交
131
	getViews(loc: ViewContainer): IViewDescriptor[];
S
Sandeep Somavarapu 已提交
132

S
Sandeep Somavarapu 已提交
133
	getView(id: string): IViewDescriptor;
S
Sandeep Somavarapu 已提交
134 135 136 137 138

}

export const ViewsRegistry: IViewsRegistry = new class implements IViewsRegistry {

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

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

S
Sandeep Somavarapu 已提交
145 146
	private _viewContainer: ViewContainer[] = [];
	private _views: Map<ViewContainer, IViewDescriptor[]> = new Map<ViewContainer, IViewDescriptor[]>();
S
Sandeep Somavarapu 已提交
147 148 149 150

	registerViews(viewDescriptors: IViewDescriptor[]): void {
		if (viewDescriptors.length) {
			for (const viewDescriptor of viewDescriptors) {
S
Sandeep Somavarapu 已提交
151
				let views = this._views.get(viewDescriptor.container);
S
Sandeep Somavarapu 已提交
152 153
				if (!views) {
					views = [];
S
Sandeep Somavarapu 已提交
154 155
					this._views.set(viewDescriptor.container, views);
					this._viewContainer.push(viewDescriptor.container);
S
Sandeep Somavarapu 已提交
156 157
				}
				if (views.some(v => v.id === viewDescriptor.id)) {
S
Sandeep Somavarapu 已提交
158
					throw new Error(localize('duplicateId', "A view with id '{0}' is already registered in the container '{1}'", viewDescriptor.id, viewDescriptor.container.id));
S
Sandeep Somavarapu 已提交
159 160 161 162 163 164 165
				}
				views.push(viewDescriptor);
			}
			this._onViewsRegistered.fire(viewDescriptors);
		}
	}

S
Sandeep Somavarapu 已提交
166 167
	deregisterViews(ids: string[], container: ViewContainer): void {
		const views = this._views.get(container);
S
Sandeep Somavarapu 已提交
168 169 170 171 172 173 174 175

		if (!views) {
			return;
		}

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

		if (viewsToDeregister.length) {
S
Sandeep Somavarapu 已提交
176 177
			const remaningViews = views.filter(view => ids.indexOf(view.id) === -1);
			if (remaningViews.length) {
S
Sandeep Somavarapu 已提交
178
				this._views.set(container, remaningViews);
S
Sandeep Somavarapu 已提交
179
			} else {
S
Sandeep Somavarapu 已提交
180 181
				this._views.delete(container);
				this._viewContainer.splice(this._viewContainer.indexOf(container), 1);
S
Sandeep Somavarapu 已提交
182
			}
183
			this._onViewsDeregistered.fire(viewsToDeregister);
S
Sandeep Somavarapu 已提交
184 185 186 187
		}

	}

S
Sandeep Somavarapu 已提交
188
	getViews(loc: ViewContainer): IViewDescriptor[] {
S
Sandeep Somavarapu 已提交
189 190 191
		return this._views.get(loc) || [];
	}

S
Sandeep Somavarapu 已提交
192
	getView(id: string): IViewDescriptor {
S
Sandeep Somavarapu 已提交
193 194
		for (const viewContainer of this._viewContainer) {
			const viewDescriptor = (this._views.get(viewContainer) || []).filter(v => v.id === id)[0];
S
Sandeep Somavarapu 已提交
195 196 197 198 199
			if (viewDescriptor) {
				return viewDescriptor;
			}
		}
		return null;
S
Sandeep Somavarapu 已提交
200 201 202
	}
};

S
Sandeep Somavarapu 已提交
203 204 205 206 207 208
export interface IView {

	readonly id: string;

}

S
Sandeep Somavarapu 已提交
209 210
export interface IViewsViewlet extends IViewlet {

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

}

215 216 217 218 219
export const IViewsService = createDecorator<IViewsService>('viewsService');

export interface IViewsService {
	_serviceBrand: any;

S
Sandeep Somavarapu 已提交
220
	openView(id: string, focus?: boolean): TPromise<IView>;
221 222

	getViewDescriptors(container: ViewContainer): IViewDescriptorCollection;
223 224
}

S
Sandeep Somavarapu 已提交
225 226
// Custom views

227 228
export interface ITreeViewer extends IDisposable {

229
	dataProvider: ITreeViewDataProvider;
S
Sandeep Somavarapu 已提交
230

231 232 233 234
	readonly onDidExpandItem: Event<ITreeItem>;

	readonly onDidCollapseItem: Event<ITreeItem>;

235 236
	readonly onDidChangeSelection: Event<ITreeItem[]>;

237 238
	readonly onDidChangeVisibility: Event<boolean>;

S
Sandeep Somavarapu 已提交
239 240
	readonly visible: boolean;

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

243
	setVisibility(visible: boolean): void;
S
Sandeep Somavarapu 已提交
244

245 246 247 248
	focus(): void;

	layout(height: number): void;

S
Sandeep Somavarapu 已提交
249
	show(container: HTMLElement);
250 251

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

S
Sandeep Somavarapu 已提交
253
	reveal(item: ITreeItem, parentChain: ITreeItem[], options: { select?: boolean }): TPromise<void>;
S
Sandeep Somavarapu 已提交
254 255 256 257
}

export interface ICustomViewDescriptor extends IViewDescriptor {

S
Sandeep Somavarapu 已提交
258
	readonly treeViewer: ITreeViewer;
S
Sandeep Somavarapu 已提交
259 260

}
S
Sandeep Somavarapu 已提交
261 262 263

export type TreeViewItemHandleArg = {
	$treeViewId: string,
S
Sandeep Somavarapu 已提交
264
	$treeItemHandle: string
S
Sandeep Somavarapu 已提交
265 266 267 268 269 270 271 272 273 274
};

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

export interface ITreeItem {

S
Sandeep Somavarapu 已提交
275
	handle: string;
S
Sandeep Somavarapu 已提交
276

S
Sandeep Somavarapu 已提交
277 278
	parentHandle: string;

S
Sandeep Somavarapu 已提交
279 280
	collapsibleState: TreeItemCollapsibleState;

S
Sandeep Somavarapu 已提交
281
	label?: string;
S
Sandeep Somavarapu 已提交
282

283
	icon?: UriComponents;
S
Sandeep Somavarapu 已提交
284

285
	iconDark?: UriComponents;
S
Sandeep Somavarapu 已提交
286

S
Sandeep Somavarapu 已提交
287
	themeIcon?: ThemeIcon;
S
Sandeep Somavarapu 已提交
288

S
Sandeep Somavarapu 已提交
289 290
	resourceUri?: UriComponents;

S
Sandeep Somavarapu 已提交
291 292
	tooltip?: string;

S
Sandeep Somavarapu 已提交
293 294 295 296 297 298 299 300 301
	contextValue?: string;

	command?: Command;

	children?: ITreeItem[];
}

export interface ITreeViewDataProvider {

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

S
Sandeep Somavarapu 已提交
304
}