提交 677234a7 编写于 作者: S Sandeep Somavarapu

Proposals for Collapse, CollapseAll, Expand APIs and implementation

上级 ee6aebf5
......@@ -1132,7 +1132,37 @@ declare module 'vscode' {
}
//#endregion
//#region Tree Item Label Highlights
//#region Tree View
export namespace window {
export function createTreeView<T>(viewId: string, options: { treeDataProvider: TreeDataProvider<T> }): TreeView2<T>;
}
export interface TreeView2<T> extends TreeView<T> {
/**
* Collapses an element or several elements.
*
* @param elementOrElements element(s) to collpase.
* @param recursive Controls if elements have to be collapsed recursively or not.
*/
collapse(elementOrElements: T | T[], recursive?: boolean): Thenable<void>;
/**
* Collapse all elements.
*/
collapseAll(): Thenable<void>;
/**
* Expands an element or several elements.
*
* @param elementOrElements element(s) to expand.
* @param recursive Controls if elements have to be expanded recursively or not.
*/
expand(elementOrElements: T | T[], recursive?: boolean): Thenable<void>;
}
/**
* Label describing the [Tree item](#TreeItem)
*/
......@@ -1162,6 +1192,7 @@ declare module 'vscode' {
*/
constructor(label: TreeItemLabel, collapsibleState?: TreeItemCollapsibleState);
}
//#endregion
//#region Task
......
......@@ -57,6 +57,40 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
return TPromise.as(null);
}
$collapse(treeViewId: string, handles: undefined | string[], recursive?: boolean): Thenable<void> {
const viewer = this.getTreeViewer(treeViewId);
const dataProvider = this._dataProviders.get(treeViewId);
if (viewer && dataProvider) {
const items = handles ? [] : void 0;
if (handles) {
for (const handle of handles) {
const item = dataProvider.getItem(handle);
if (item) {
items.push(item);
}
}
}
viewer.collapse(items, recursive);
}
return Promise.resolve();
}
$expand(treeViewId: string, handles: string[], recursive?: boolean): Thenable<void> {
const viewer = this.getTreeViewer(treeViewId);
const dataProvider = this._dataProviders.get(treeViewId);
if (viewer && dataProvider) {
const items = [];
for (const handle of handles) {
const item = dataProvider.getItem(handle);
if (item) {
items.push(item);
}
}
viewer.expand(items, recursive);
}
return Promise.resolve();
}
private registerListeners(treeViewId: string, treeViewer: ITreeViewer): void {
this._register(treeViewer.onDidExpandItem(item => this._proxy.$setExpanded(treeViewId, item.handle, true)));
this._register(treeViewer.onDidCollapseItem(item => this._proxy.$setExpanded(treeViewId, item.handle, false)));
......@@ -110,7 +144,7 @@ class TreeViewDataProvider implements ITreeViewDataProvider {
const itemsToRefresh: ITreeItem[] = [];
if (itemsToRefreshByHandle) {
for (const treeItemHandle of Object.keys(itemsToRefreshByHandle)) {
const currentTreeItem = this.itemsMap.get(treeItemHandle);
const currentTreeItem = this.getItem(treeItemHandle);
if (currentTreeItem) { // Refresh only if the item exists
const treeItem = itemsToRefreshByHandle[treeItemHandle];
// Update the current item with refreshed item
......@@ -132,6 +166,10 @@ class TreeViewDataProvider implements ITreeViewDataProvider {
return itemsToRefresh;
}
getItem(handle: string): ITreeItem {
return this.itemsMap.get(handle);
}
private postGetChildren(elements: ITreeItem[]): ITreeItem[] {
const result: ITreeItem[] = [];
if (elements) {
......
......@@ -463,7 +463,7 @@ export function createApiFactory(
registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider<any>): vscode.Disposable {
return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider);
},
createTreeView(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<any> }): vscode.TreeView<any> {
createTreeView(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<any> }): vscode.TreeView2<any> {
return extHostTreeViews.createTreeView(viewId, options);
},
registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => {
......
......@@ -212,6 +212,8 @@ export interface MainThreadTextEditorsShape extends IDisposable {
export interface MainThreadTreeViewsShape extends IDisposable {
$registerTreeViewDataProvider(treeViewId: string): void;
$refresh(treeViewId: string, itemsToRefresh?: { [treeItemHandle: string]: ITreeItem }): Thenable<void>;
$collapse(treeViewId: string, handles: undefined | string[], recursive?: boolean): Thenable<void>;
$expand(treeViewId: string, handles: string[], recursive?: boolean): Thenable<void>;
$reveal(treeViewId: string, treeItem: ITreeItem, parentChain: ITreeItem[], options: { select: boolean, focus: boolean }): Thenable<void>;
}
......
......@@ -64,7 +64,7 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
return { dispose: () => treeView.dispose() };
}
createTreeView<T>(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<T> }): vscode.TreeView<T> {
createTreeView<T>(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<T> }): vscode.TreeView2<T> {
if (!options || !options.treeDataProvider) {
throw new Error('Options with treeDataProvider is mandatory');
}
......@@ -76,6 +76,15 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
get onDidChangeSelection() { return treeView.onDidChangeSelection; },
get visible() { return treeView.visible; },
get onDidChangeVisibility() { return treeView.onDidChangeVisibility; },
collapse(elementOrElements: T | T[], recursive?: boolean): Thenable<void> {
return treeView.collapse(elementOrElements, recursive);
},
collapseAll(): Thenable<void> {
return treeView.collapse();
},
expand(elementOrElements: T | T[], recursive?: boolean): Thenable<void> {
return treeView.expand(elementOrElements, recursive);
},
reveal: (element: T, options?: { select?: boolean, focus?: boolean }): Thenable<void> => {
return treeView.reveal(element, options);
},
......@@ -215,6 +224,42 @@ class ExtHostTreeView<T> extends Disposable {
.then(treeNode => this.proxy.$reveal(this.viewId, treeNode.item, parentChain.map(p => p.item), { select, focus })), error => this.logService.error(error));
}
collapse(elementOrElements?: T | T[], recursive?: boolean): Thenable<void> {
const handles: TreeItemHandle[] = elementOrElements ? [] : void 0;
if (elementOrElements) {
const elements = Array.isArray(elementOrElements) ? elementOrElements : [elementOrElements];
for (const element of elements) {
const node = this.nodes.get(element);
if (node) {
handles.push(node.item.handle);
} else {
console.error('Not found: ', element);
}
}
if (elements.length === 0) {
return Promise.resolve();
}
}
return this.proxy.$collapse(this.viewId, handles, recursive);
}
expand(elementOrElements: T | T[], recursive?: boolean): Thenable<void> {
const handles: TreeItemHandle[] = [];
const elements = Array.isArray(elementOrElements) ? elementOrElements : [elementOrElements];
for (const element of elements) {
const node = this.nodes.get(element);
if (node) {
handles.push(node.item.handle);
} else {
console.error('Not found: ', element);
}
}
if (elements.length) {
return this.proxy.$expand(this.viewId, handles, recursive);
}
return Promise.resolve();
}
setExpanded(treeItemHandle: TreeItemHandle, expanded: boolean): void {
const element = this.getExtensionElement(treeItemHandle);
if (element) {
......
......@@ -378,6 +378,33 @@ export class CustomTreeViewer extends Disposable implements ITreeViewer {
return Promise.resolve(null);
}
async collapse(treeItems: undefined | ITreeItem[], recursive?: boolean): Promise<void> {
if (this.dataProvider && this.tree) {
await this.tree.collapseAll(treeItems, recursive);
}
}
async expand(treeItems: ITreeItem[], recursive?: boolean): Promise<void> {
if (this.dataProvider && this.tree) {
const itemsToExpand: ITreeItem[] = [];
const seen: Set<string> = new Set<string>();
for (const treeItem of treeItems) {
if (!seen.has(treeItem.handle)) {
if (treeItem.collapsibleState !== TreeItemCollapsibleState.None) {
itemsToExpand.push(treeItem);
}
seen.add(treeItem.handle);
}
}
if (itemsToExpand.length) {
await this.tree.expandAll(itemsToExpand);
if (recursive) {
await this.expand(itemsToExpand.reduce((result, item) => { result.push(...(item.children ? item.children : [])); return result; }, []), recursive);
}
}
}
}
reveal(item: ITreeItem, parentChain: ITreeItem[], options?: { select?: boolean, focus?: boolean }): TPromise<void> {
if (this.dataProvider && this.tree && this.isVisible) {
options = options ? options : { select: false, focus: false };
......
......@@ -250,6 +250,10 @@ export interface ITreeViewer extends IDisposable {
refresh(treeItems?: ITreeItem[]): TPromise<void>;
collapse(treeItems: undefined | ITreeItem[], recursive?: boolean): Promise<void>;
expand(treeItems: ITreeItem[], recursive?: boolean): Promise<void>;
setVisibility(visible: boolean): void;
focus(): void;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册