diff --git a/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts b/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts deleted file mode 100644 index b732ccd81d6..00000000000 --- a/src/vs/workbench/api/browser/viewsContainersExtensionPoint.ts +++ /dev/null @@ -1,220 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { localize } from 'vs/nls'; -import { IJSONSchema } from 'vs/base/common/jsonSchema'; -import { ExtensionMessageCollector, ExtensionsRegistry, IExtensionPoint } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import * as resources from 'vs/base/common/resources'; -import { createCSSRule } from 'vs/base/browser/dom'; -import { Registry } from 'vs/platform/registry/common/platform'; -import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; -import { ViewletDescriptor, ViewletRegistry, Extensions as ViewletExtensions, ShowViewletAction } from 'vs/workbench/browser/viewlet'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IPartService } from 'vs/workbench/services/part/common/partService'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; -import { IStorageService } from 'vs/platform/storage/common/storage'; -import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IExtensionService, IExtensionDescription } from 'vs/workbench/services/extensions/common/extensions'; -import { Extensions as ViewContainerExtensions, IViewContainersRegistry, TEST_VIEW_CONTAINER_ID } from 'vs/workbench/common/views'; -import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet'; -import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; -import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; -import { forEach } from 'vs/base/common/collections'; -import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; -import { URI } from 'vs/base/common/uri'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; - -export interface IUserFriendlyViewsContainerDescriptor { - id: string; - title: string; - icon: string; -} - -export interface IUserFriendlyViewsContainerDescriptor2 { - id: string; - title: string; - icon: URI; -} - -const viewsContainerSchema: IJSONSchema = { - type: 'object', - properties: { - id: { - description: localize({ key: 'vscode.extension.contributes.views.containers.id', comment: ['Contribution refers to those that an extension contributes to VS Code through an extension/contribution point. '] }, "Unique id used to identify the container in which views can be contributed using 'views' contribution point"), - type: 'string', - pattern: '^[a-zA-Z0-9_-]+$' - }, - title: { - description: localize('vscode.extension.contributes.views.containers.title', 'Human readable string used to render the container'), - type: 'string' - }, - icon: { - description: localize('vscode.extension.contributes.views.containers.icon', "Path to the container icon. Icons are 24x24 centered on a 50x40 block and have a fill color of 'rgb(215, 218, 224)' or '#d7dae0'. It is recommended that icons be in SVG, though any image file type is accepted."), - type: 'string' - } - } -}; - -export const viewsContainersContribution: IJSONSchema = { - description: localize('vscode.extension.contributes.viewsContainers', 'Contributes views containers to the editor'), - type: 'object', - properties: { - 'activitybar': { - description: localize('views.container.activitybar', "Contribute views containers to Activity Bar"), - type: 'array', - items: viewsContainerSchema - } - } -}; - -export const viewsContainersExtensionPoint: IExtensionPoint<{ [loc: string]: IUserFriendlyViewsContainerDescriptor[] }> = ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: IUserFriendlyViewsContainerDescriptor[] }>({ - extensionPoint: 'viewsContainers', - jsonSchema: viewsContainersContribution -}); - -const TEST_VIEW_CONTAINER_ORDER = 6; - -class ViewsContainersExtensionHandler implements IWorkbenchContribution { - - constructor() { - this.registerTestViewContainer(); - this.handleAndRegisterCustomViewContainers(); - } - - private registerTestViewContainer(): void { - const title = localize('test', "Test"); - const cssClass = `extensionViewlet-test`; - const icon = URI.parse(require.toUrl('./media/test.svg')); - - this.registerCustomViewlet({ id: TEST_VIEW_CONTAINER_ID, title, icon }, TEST_VIEW_CONTAINER_ORDER, cssClass, undefined); - } - - private handleAndRegisterCustomViewContainers() { - let order = TEST_VIEW_CONTAINER_ORDER + 1; - viewsContainersExtensionPoint.setHandler((extensions) => { - for (let extension of extensions) { - const { value, collector } = extension; - forEach(value, entry => { - if (!this.isValidViewsContainer(entry.value, collector)) { - return; - } - switch (entry.key) { - case 'activitybar': - order = this.registerCustomViewContainers(entry.value, extension.description, order); - break; - } - }); - } - }); - } - - private isValidViewsContainer(viewsContainersDescriptors: IUserFriendlyViewsContainerDescriptor[], collector: ExtensionMessageCollector): boolean { - if (!Array.isArray(viewsContainersDescriptors)) { - collector.error(localize('requirearray', "views containers must be an array")); - return false; - } - - for (let descriptor of viewsContainersDescriptors) { - if (typeof descriptor.id !== 'string') { - collector.error(localize('requireidstring', "property `{0}` is mandatory and must be of type `string`. Only alphanumeric characters, '_', and '-' are allowed.", 'id')); - return false; - } - if (!(/^[a-z0-9_-]+$/i.test(descriptor.id))) { - collector.error(localize('requireidstring', "property `{0}` is mandatory and must be of type `string`. Only alphanumeric characters, '_', and '-' are allowed.", 'id')); - return false; - } - if (typeof descriptor.title !== 'string') { - collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", 'title')); - return false; - } - if (typeof descriptor.icon !== 'string') { - collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", 'icon')); - return false; - } - } - - return true; - } - - private registerCustomViewContainers(containers: IUserFriendlyViewsContainerDescriptor[], extension: IExtensionDescription, order: number): number { - containers.forEach(descriptor => { - const cssClass = `extensionViewlet-${descriptor.id}`; - const icon = resources.joinPath(extension.extensionLocation, descriptor.icon); - this.registerCustomViewlet({ id: `workbench.view.extension.${descriptor.id}`, title: descriptor.title, icon }, order++, cssClass, extension.identifier); - }); - return order; - } - - private registerCustomViewlet(descriptor: IUserFriendlyViewsContainerDescriptor2, order: number, cssClass: string, extensionId: ExtensionIdentifier | undefined): void { - const viewContainersRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); - const viewletRegistry = Registry.as(ViewletExtensions.Viewlets); - const id = descriptor.id; - - if (!viewletRegistry.getViewlet(id)) { - - viewContainersRegistry.registerViewContainer(id, extensionId); - - // Register as viewlet - class CustomViewlet extends ViewContainerViewlet { - constructor( - @IConfigurationService configurationService: IConfigurationService, - @IPartService partService: IPartService, - @ITelemetryService telemetryService: ITelemetryService, - @IWorkspaceContextService contextService: IWorkspaceContextService, - @IStorageService storageService: IStorageService, - @IEditorService editorService: IEditorService, - @IInstantiationService instantiationService: IInstantiationService, - @IThemeService themeService: IThemeService, - @IContextMenuService contextMenuService: IContextMenuService, - @IExtensionService extensionService: IExtensionService - ) { - super(id, `${id}.state`, true, configurationService, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); - } - } - const viewletDescriptor = new ViewletDescriptor( - CustomViewlet, - id, - descriptor.title, - cssClass, - order, - descriptor.icon - ); - - viewletRegistry.registerViewlet(viewletDescriptor); - - // Register Action to Open Viewlet - class OpenCustomViewletAction extends ShowViewletAction { - constructor( - id: string, label: string, - @IViewletService viewletService: IViewletService, - @IEditorGroupsService editorGroupService: IEditorGroupsService, - @IPartService partService: IPartService - ) { - super(id, label, id, viewletService, editorGroupService, partService); - } - } - const registry = Registry.as(ActionExtensions.WorkbenchActions); - registry.registerWorkbenchAction( - new SyncActionDescriptor(OpenCustomViewletAction, id, localize('showViewlet', "Show {0}", descriptor.title)), - 'View: Show {0}', - localize('view', "View") - ); - - // Generate CSS to show the icon in the activity bar - const iconClass = `.monaco-workbench > .activitybar .monaco-action-bar .action-label.${cssClass}`; - createCSSRule(iconClass, `-webkit-mask: url('${descriptor.icon}') no-repeat 50% 50%`); - } - - } -} - -const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); -workbenchRegistry.registerWorkbenchContribution(ViewsContainersExtensionHandler, LifecyclePhase.Starting); diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 99ea9a0a611..c36f49edfb4 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -6,12 +6,12 @@ import { localize } from 'vs/nls'; import { forEach } from 'vs/base/common/collections'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; +import * as resources from 'vs/base/common/resources'; import { ExtensionMessageCollector, ExtensionsRegistry, IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { ViewContainer, ViewsRegistry, ICustomViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; +import { ViewContainer, ViewsRegistry, ITreeViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions, TEST_VIEW_CONTAINER_ID } from 'vs/workbench/common/views'; import { CustomTreeViewPanel, CustomTreeView } from 'vs/workbench/browser/parts/views/customView'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { coalesce, } from 'vs/base/common/arrays'; -import { viewsContainersExtensionPoint } from 'vs/workbench/api/browser/viewsContainersExtensionPoint'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -20,6 +20,60 @@ import { VIEWLET_ID as EXPLORER } from 'vs/workbench/parts/files/common/files'; import { VIEWLET_ID as SCM } from 'vs/workbench/parts/scm/common/scm'; import { VIEWLET_ID as DEBUG } from 'vs/workbench/parts/debug/common/debug'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { URI } from 'vs/base/common/uri'; +import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor, ShowViewletAction } from 'vs/workbench/browser/viewlet'; +import { IExtensionDescription, IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { ViewContainerViewlet } from 'vs/workbench/browser/parts/views/viewsViewlet'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IPartService } from 'vs/workbench/services/part/common/partService'; +import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { IStorageService } from 'vs/platform/storage/common/storage'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; +import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService'; +import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions'; +import { SyncActionDescriptor } from 'vs/platform/actions/common/actions'; +import { createCSSRule } from 'vs/base/browser/dom'; + +export interface IUserFriendlyViewsContainerDescriptor { + id: string; + title: string; + icon: string; +} + +const viewsContainerSchema: IJSONSchema = { + type: 'object', + properties: { + id: { + description: localize({ key: 'vscode.extension.contributes.views.containers.id', comment: ['Contribution refers to those that an extension contributes to VS Code through an extension/contribution point. '] }, "Unique id used to identify the container in which views can be contributed using 'views' contribution point"), + type: 'string', + pattern: '^[a-zA-Z0-9_-]+$' + }, + title: { + description: localize('vscode.extension.contributes.views.containers.title', 'Human readable string used to render the container'), + type: 'string' + }, + icon: { + description: localize('vscode.extension.contributes.views.containers.icon', "Path to the container icon. Icons are 24x24 centered on a 50x40 block and have a fill color of 'rgb(215, 218, 224)' or '#d7dae0'. It is recommended that icons be in SVG, though any image file type is accepted."), + type: 'string' + } + } +}; + +export const viewsContainersContribution: IJSONSchema = { + description: localize('vscode.extension.contributes.viewsContainers', 'Contributes views containers to the editor'), + type: 'object', + properties: { + 'activitybar': { + description: localize('views.container.activitybar', "Contribute views containers to Activity Bar"), + type: 'array', + items: viewsContainerSchema + } + } +}; interface IUserFriendlyViewDescriptor { id: string; @@ -82,6 +136,16 @@ const viewsContribution: IJSONSchema = { } }; +export interface ICustomViewDescriptor extends ITreeViewDescriptor { + readonly extensionId: ExtensionIdentifier; +} + +type ViewContainerExtensionPointType = { [loc: string]: IUserFriendlyViewsContainerDescriptor[] }; +const viewsContainersExtensionPoint: IExtensionPoint = ExtensionsRegistry.registerExtensionPoint({ + extensionPoint: 'viewsContainers', + jsonSchema: viewsContainersContribution +}); + type ViewExtensionPointType = { [loc: string]: IUserFriendlyViewDescriptor[] }; const viewsExtensionPoint: IExtensionPoint = ExtensionsRegistry.registerExtensionPoint({ extensionPoint: 'views', @@ -90,7 +154,8 @@ const viewsExtensionPoint: IExtensionPoint = ExtensionsR isDynamic: true }); -class ViewsContainersExtensionHandler implements IWorkbenchContribution { +const TEST_VIEW_CONTAINER_ORDER = 6; +class ViewsExtensionHandler implements IWorkbenchContribution { private viewContainersRegistry: IViewContainersRegistry; @@ -98,9 +163,137 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { @IInstantiationService private readonly instantiationService: IInstantiationService ) { this.viewContainersRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); + this.handleAndRegisterCustomViewContainers(); this.handleAndRegisterCustomViews(); } + private handleAndRegisterCustomViewContainers() { + this.registerTestViewContainer(); + + let order = TEST_VIEW_CONTAINER_ORDER + 1; + viewsContainersExtensionPoint.setHandler((extensions) => { + for (let extension of extensions) { + const { value, collector } = extension; + forEach(value, entry => { + if (!this.isValidViewsContainer(entry.value, collector)) { + return; + } + switch (entry.key) { + case 'activitybar': + order = this.registerCustomViewContainers(entry.value, extension.description, order); + break; + } + }); + } + }); + } + + private registerTestViewContainer(): void { + const title = localize('test', "Test"); + const cssClass = `extensionViewlet-test`; + const icon = URI.parse(require.toUrl('./media/test.svg')); + + this.registerCustomViewlet(TEST_VIEW_CONTAINER_ID, title, icon, TEST_VIEW_CONTAINER_ORDER, cssClass, undefined); + } + + private isValidViewsContainer(viewsContainersDescriptors: IUserFriendlyViewsContainerDescriptor[], collector: ExtensionMessageCollector): boolean { + if (!Array.isArray(viewsContainersDescriptors)) { + collector.error(localize('viewcontainer requirearray', "views containers must be an array")); + return false; + } + + for (let descriptor of viewsContainersDescriptors) { + if (typeof descriptor.id !== 'string') { + collector.error(localize('requireidstring', "property `{0}` is mandatory and must be of type `string`. Only alphanumeric characters, '_', and '-' are allowed.", 'id')); + return false; + } + if (!(/^[a-z0-9_-]+$/i.test(descriptor.id))) { + collector.error(localize('requireidstring', "property `{0}` is mandatory and must be of type `string`. Only alphanumeric characters, '_', and '-' are allowed.", 'id')); + return false; + } + if (typeof descriptor.title !== 'string') { + collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", 'title')); + return false; + } + if (typeof descriptor.icon !== 'string') { + collector.error(localize('requirestring', "property `{0}` is mandatory and must be of type `string`", 'icon')); + return false; + } + } + + return true; + } + + private registerCustomViewContainers(containers: IUserFriendlyViewsContainerDescriptor[], extension: IExtensionDescription, order: number): number { + containers.forEach(descriptor => { + const cssClass = `extensionViewlet-${descriptor.id}`; + const icon = resources.joinPath(extension.extensionLocation, descriptor.icon); + this.registerCustomViewlet(`workbench.view.extension.${descriptor.id}`, descriptor.title, icon, order++, cssClass, extension.identifier); + }); + return order; + } + + private registerCustomViewlet(id: string, title: string, icon: URI, order: number, cssClass: string, extensionId: ExtensionIdentifier | undefined): void { + const viewContainersRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); + const viewletRegistry = Registry.as(ViewletExtensions.Viewlets); + + if (!viewletRegistry.getViewlet(id)) { + + viewContainersRegistry.registerViewContainer(id, extensionId); + + // Register as viewlet + class CustomViewlet extends ViewContainerViewlet { + constructor( + @IConfigurationService configurationService: IConfigurationService, + @IPartService partService: IPartService, + @ITelemetryService telemetryService: ITelemetryService, + @IWorkspaceContextService contextService: IWorkspaceContextService, + @IStorageService storageService: IStorageService, + @IEditorService editorService: IEditorService, + @IInstantiationService instantiationService: IInstantiationService, + @IThemeService themeService: IThemeService, + @IContextMenuService contextMenuService: IContextMenuService, + @IExtensionService extensionService: IExtensionService + ) { + super(id, `${id}.state`, true, configurationService, partService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); + } + } + const viewletDescriptor = new ViewletDescriptor( + CustomViewlet, + id, + title, + cssClass, + order, + icon + ); + + viewletRegistry.registerViewlet(viewletDescriptor); + + // Register Action to Open Viewlet + class OpenCustomViewletAction extends ShowViewletAction { + constructor( + id: string, label: string, + @IViewletService viewletService: IViewletService, + @IEditorGroupsService editorGroupService: IEditorGroupsService, + @IPartService partService: IPartService + ) { + super(id, label, id, viewletService, editorGroupService, partService); + } + } + const registry = Registry.as(ActionExtensions.WorkbenchActions); + registry.registerWorkbenchAction( + new SyncActionDescriptor(OpenCustomViewletAction, id, localize('showViewlet', "Show {0}", title)), + 'View: Show {0}', + localize('view', "View") + ); + + // Generate CSS to show the icon in the activity bar + const iconClass = `.monaco-workbench > .activitybar .monaco-action-bar .action-label.${cssClass}`; + createCSSRule(iconClass, `-webkit-mask: url('${icon}') no-repeat 50% 50%`); + } + + } + private handleAndRegisterCustomViews() { viewsExtensionPoint.setHandler((extensions, { added, removed }) => { if (removed.length) { @@ -139,7 +332,7 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { return null; } - const viewDescriptor = { + const viewDescriptor = { id: item.id, name: item.name, ctor: CustomTreeViewPanel, @@ -215,4 +408,4 @@ class ViewsContainersExtensionHandler implements IWorkbenchContribution { } const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); -workbenchRegistry.registerWorkbenchContribution(ViewsContainersExtensionHandler, LifecyclePhase.Starting); \ No newline at end of file +workbenchRegistry.registerWorkbenchContribution(ViewsExtensionHandler, LifecyclePhase.Starting); \ No newline at end of file diff --git a/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts b/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts index a2237755d84..c3617f2bb85 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadTreeViews.ts @@ -5,7 +5,7 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { ExtHostContext, MainThreadTreeViewsShape, ExtHostTreeViewsShape, MainContext, IExtHostContext } from '../node/extHost.protocol'; -import { ITreeViewDataProvider, ITreeItem, IViewsService, ITreeView, ViewsRegistry, ICustomViewDescriptor, IRevealOptions } from 'vs/workbench/common/views'; +import { ITreeViewDataProvider, ITreeItem, IViewsService, ITreeView, ViewsRegistry, ITreeViewDescriptor, IRevealOptions } from 'vs/workbench/common/views'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import { distinct } from 'vs/base/common/arrays'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -110,7 +110,7 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie } private getTreeView(treeViewId: string): ITreeView { - const viewDescriptor: ICustomViewDescriptor = ViewsRegistry.getView(treeViewId); + const viewDescriptor: ITreeViewDescriptor = ViewsRegistry.getView(treeViewId); return viewDescriptor ? viewDescriptor.treeView : null; } diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 456eb50130b..daebf0af817 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -13,7 +13,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions'; import { ContextAwareMenuItemActionItem, fillInActionBarActions, fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IViewsService, ITreeView, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ICustomViewDescriptor, ViewsRegistry, ViewContainer, ITreeItemLabel } from 'vs/workbench/common/views'; +import { IViewsService, ITreeView, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ITreeViewDescriptor, ViewsRegistry, ViewContainer, ITreeItemLabel } from 'vs/workbench/common/views'; import { IViewletViewOptions, FileIconThemableWorkbenchTree } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -58,7 +58,7 @@ export class CustomTreeViewPanel extends ViewletPanel { @IViewsService viewsService: IViewsService, ) { super({ ...(options as IViewletPanelOptions), ariaHeaderLabel: options.title }, keybindingService, contextMenuService, configurationService); - const { treeView } = (ViewsRegistry.getView(options.id)); + const { treeView } = (ViewsRegistry.getView(options.id)); this.treeView = treeView; this.treeView.onDidChangeActions(() => this.updateActions(), this, this.disposables); this.disposables.push(toDisposable(() => this.treeView.setVisibility(false))); @@ -210,7 +210,7 @@ export class CustomTreeView extends Disposable implements ITreeView { constructor( private id: string, - private container: ViewContainer, + private viewContainer: ViewContainer, @IExtensionService private readonly extensionService: IExtensionService, @IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService, @IInstantiationService private readonly instantiationService: IInstantiationService, @@ -376,7 +376,7 @@ export class CustomTreeView extends Disposable implements ITreeView { const actionItemProvider = (action: IAction) => action instanceof MenuItemAction ? this.instantiationService.createInstance(ContextAwareMenuItemActionItem, action) : undefined; const menus = this._register(this.instantiationService.createInstance(TreeMenus, this.id)); this.treeLabels = this._register(this.instantiationService.createInstance(ResourceLabels, this)); - const dataSource = this.instantiationService.createInstance(TreeDataSource, this, this.container); + const dataSource = this.instantiationService.createInstance(TreeDataSource, this, (task: Promise) => this.progressService.withProgress({ location: this.viewContainer.id }, () => task)); const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, menus, this.treeLabels, actionItemProvider); const controller = this.instantiationService.createInstance(TreeController, this.id, menus); this.tree = this._register(this.instantiationService.createInstance(FileIconThemableWorkbenchTree, this.treeContainer, { dataSource, renderer, controller }, {})); @@ -509,7 +509,7 @@ export class CustomTreeView extends Disposable implements ITreeView { private activate() { if (!this.activated) { this.createTree(); - this.progressService.withProgress({ location: this.container.id }, () => this.extensionService.activateByEvent(`onView:${this.id}`)) + this.progressService.withProgress({ location: this.viewContainer.id }, () => this.extensionService.activateByEvent(`onView:${this.id}`)) .then(() => timeout(2000)) .then(() => { this.updateMessage(); @@ -569,8 +569,7 @@ class TreeDataSource implements IDataSource { constructor( private treeView: ITreeView, - private container: ViewContainer, - @IProgressService2 private readonly progressService: IProgressService2 + private withProgress: (task: Promise) => Promise ) { } @@ -584,7 +583,7 @@ class TreeDataSource implements IDataSource { getChildren(tree: ITree, node: ITreeItem): Promise { if (this.treeView.dataProvider) { - return this.progressService.withProgress({ location: this.container.id }, () => this.treeView.dataProvider.getChildren(node)); + return this.withProgress(this.treeView.dataProvider.getChildren(node)); } return Promise.resolve([]); } diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 7b36e2170b5..6ae178230c2 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -294,7 +294,7 @@ export interface IRevealOptions { } -export interface ICustomViewDescriptor extends IViewDescriptor { +export interface ITreeViewDescriptor extends IViewDescriptor { readonly treeView: ITreeView; readonly extensionId: ExtensionIdentifier; diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index dc6ef56c636..1cb536f7767 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -20,7 +20,6 @@ import 'vs/platform/widget/browser/contextScopedHistoryWidget'; import 'vs/workbench/services/actions/electron-browser/menusExtensionPoint'; // Views -import 'vs/workbench/api/browser/viewsContainersExtensionPoint'; import 'vs/workbench/api/browser/viewsExtensionPoint'; // Localizations