diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 97e1ac32a48..2f4b56a8a87 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -1350,12 +1350,14 @@ declare module 'vscode' { export interface TreeContentProvider { provideTreeContent(): Thenable; + resolveChildren(node: ITreeNode): Thenable; } export interface ITreeNode { label: string; isExpanded: boolean; - children: ITreeNode[] + children: ITreeNode[]; + isChildrenResolved: boolean; } /** diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 43ab9e5fbd2..f84739f296f 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -264,6 +264,7 @@ export abstract class ExtHostEditorsShape { export abstract class ExtHostExplorersShape { $provideTreeContent(treeContentProviderId: string): TPromise { throw ni(); }; + $resolveChildren(treeContentProviderId: string, node: vscode.ITreeNode): TPromise { throw ni(); } } export abstract class ExtHostExtensionServiceShape { diff --git a/src/vs/workbench/api/node/extHostExplorers.ts b/src/vs/workbench/api/node/extHostExplorers.ts index f0be05d4693..4cdd46858d6 100644 --- a/src/vs/workbench/api/node/extHostExplorers.ts +++ b/src/vs/workbench/api/node/extHostExplorers.ts @@ -46,4 +46,15 @@ export class ExtHostExplorers extends ExtHostExplorersShape { return JSON.stringify(treeContent); })); } + + $resolveChildren(treeContentProviderId: string, node: vscode.ITreeNode): TPromise { + const provider = this._treeContentProviders[treeContentProviderId]; + if (!provider) { + throw new Error(`no TreeContentProvider registered with id '${treeContentProviderId}'`); + } + + return TPromise.wrap(provider.resolveChildren(node).then(children => { + return JSON.stringify(children); + })); + } } diff --git a/src/vs/workbench/api/node/mainThreadExplorers.ts b/src/vs/workbench/api/node/mainThreadExplorers.ts index 3e31c82261e..04e0c080600 100644 --- a/src/vs/workbench/api/node/mainThreadExplorers.ts +++ b/src/vs/workbench/api/node/mainThreadExplorers.ts @@ -28,6 +28,11 @@ export class MainThreadExplorers extends MainThreadExplorersShape { return this._proxy.$provideTreeContent(providerId).then(jsonTree => { return JSON.parse(jsonTree); }) + }, + resolveChildren: (node: ITreeNode): TPromise => { + return this._proxy.$resolveChildren(providerId, node).then(jsonChildren => { + return JSON.parse(jsonChildren); + }) } }); } diff --git a/src/vs/workbench/parts/explorers/browser/treeExplorerViewletService.ts b/src/vs/workbench/parts/explorers/browser/treeExplorerViewletService.ts index f899fc22680..b9171622480 100644 --- a/src/vs/workbench/parts/explorers/browser/treeExplorerViewletService.ts +++ b/src/vs/workbench/parts/explorers/browser/treeExplorerViewletService.ts @@ -4,7 +4,6 @@ import { ITreeNode, TreeContentProvider } from 'vscode'; import { TPromise } from 'vs/base/common/winjs.base'; import Event, {Emitter} from 'vs/base/common/event'; import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { TreeViewNode } from 'vs/workbench/parts/explorers/common/treeViewModel'; export const ITreeExplorerViewletService = createDecorator('customViewletService'); @@ -13,6 +12,7 @@ export interface ITreeExplorerViewletService { registerTreeContentProvider(providerId: string, provider: TreeContentProvider): void; provideTreeContent(providerId: string): TPromise; + resolveChildren(providerId: string, node: ITreeNode): TPromise; } export class TreeExplorerViewletService implements ITreeExplorerViewletService { @@ -21,7 +21,7 @@ export class TreeExplorerViewletService implements ITreeExplorerViewletService { private _treeContentProviders: { [providerId: string]: TreeContentProvider; }; constructor( - @IInstantiationService private _instantiationService: IInstantiationService, + @IInstantiationService private _instantiationService: IInstantiationService ) { this._treeContentProviders = Object.create(null); } @@ -33,4 +33,8 @@ export class TreeExplorerViewletService implements ITreeExplorerViewletService { provideTreeContent(providerId: string): TPromise { return TPromise.wrap(this._treeContentProviders[providerId].provideTreeContent()); } + + resolveChildren(providerId: string, node: ITreeNode): TPromise { + return TPromise.wrap(this._treeContentProviders[providerId].resolveChildren(node)); + } } diff --git a/src/vs/workbench/parts/explorers/browser/views/treeViewer.ts b/src/vs/workbench/parts/explorers/browser/views/treeViewer.ts index 0ba9f357861..69634812c3a 100644 --- a/src/vs/workbench/parts/explorers/browser/views/treeViewer.ts +++ b/src/vs/workbench/parts/explorers/browser/views/treeViewer.ts @@ -14,23 +14,41 @@ import { ContributableActionProvider } from 'vs/workbench/browser/actionBarRegis import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IExtensionService } from 'vs/platform/extensions/common/extensions'; import { IModeService } from 'vs/editor/common/services/modeService'; +import { ITreeExplorerViewletService } from 'vs/workbench/parts/explorers/browser/treeExplorerViewletService'; + +const providerId = 'pineTree'; export class TreeDataSource implements IDataSource { - - constructor() { + constructor( + @ITreeExplorerViewletService private treeExplorerViewletService: ITreeExplorerViewletService + ) { } - public getId(tree: ITree, node: TreeViewNode): string { + public getId(tree: ITree, node: vscode.ITreeNode): string { return node.label; } - public hasChildren(tree: ITree, node: TreeViewNode): boolean { - return node.children && node.children.length > 0; + public hasChildren(tree: ITree, node: vscode.ITreeNode): boolean { + if (node.isChildrenResolved) { + return node.children && node.children.length > 0; + } else { + return true; + } } - public getChildren(tree: ITree, node: TreeViewNode): TPromise { - return TPromise.as(node.children); + public getChildren(tree: ITree, node: vscode.ITreeNode): TPromise { + if (node.isChildrenResolved) { + return TPromise.as(node.children); + } else { + return this.treeExplorerViewletService.resolveChildren(providerId, node).then(children => { + children.forEach(child => { + node.children.push(child); + }); + node.isChildrenResolved = true; + return node.children; + }); + } } public getParent(tree: ITree, node: TreeViewNode): TPromise { @@ -79,7 +97,7 @@ export class TreeController extends DefaultController { super.onLeftClick(tree, node, event, origin); console.log(node.label); - + return true; } } diff --git a/src/vs/workbench/parts/explorers/common/treeViewModel.ts b/src/vs/workbench/parts/explorers/common/treeViewModel.ts index 540a57a395f..0457c25afcd 100644 --- a/src/vs/workbench/parts/explorers/common/treeViewModel.ts +++ b/src/vs/workbench/parts/explorers/common/treeViewModel.ts @@ -4,7 +4,8 @@ export class TreeViewNode implements vscode.ITreeNode { public label: string, public isExpanded: boolean = true, public parent: TreeViewNode = null, - public children: TreeViewNode[] = []) { + public children: TreeViewNode[] = [], + public isChildrenResolved: boolean = true) { } addChild(child: TreeViewNode) {