提交 d462d332 编写于 作者: J Joao Moreno

tree options: collapse by default

上级 0e0fbf98
......@@ -11,10 +11,10 @@ import { append, $, toggleClass } from 'vs/base/browser/dom';
import { Event, Relay, chain, mapEvent } from 'vs/base/common/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { ITreeModel, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeOptions } from 'vs/base/browser/ui/tree/tree';
import { ITreeModel, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeFilter } from 'vs/base/browser/ui/tree/tree';
import { ISpliceable } from 'vs/base/common/sequence';
export function createComposedTreeListOptions<T, R extends { element: T }>(options?: IListOptions<T>): IListOptions<R> | undefined {
export function createComposedTreeListOptions<T, R extends { element: T }, O extends IListOptions<R>>(options?: IListOptions<T>): O | undefined {
if (!options) {
return undefined;
}
......@@ -60,7 +60,7 @@ export function createComposedTreeListOptions<T, R extends { element: T }>(optio
identityProvider,
multipleSelectionController,
accessibilityProvider
};
} as O;
}
export class ComposedTreeDelegate<T, N extends { element: T }> implements IListVirtualDelegate<N> {
......@@ -196,6 +196,10 @@ function asTreeContextMenuEvent<T>(event: IListContextMenuEvent<ITreeNode<T, any
};
}
export interface IAbstractTreeOptions<T, TFilterData = void> extends IListOptions<T> {
filter?: ITreeFilter<T, TFilterData>;
}
export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable {
private view: List<ITreeNode<T, TFilterData>>;
......@@ -220,7 +224,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
container: HTMLElement,
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
options: ITreeOptions<T, TFilterData> = {}
options: IAbstractTreeOptions<T, TFilterData> = {}
) {
const treeDelegate = new ComposedTreeDelegate<T, ITreeNode<T, TFilterData>>(delegate);
......@@ -480,7 +484,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
this.model.toggleCollapsed(location);
}
protected abstract createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: ITreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, TRef>;
protected abstract createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: IAbstractTreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, TRef>;
dispose(): void {
this.disposables = dispose(this.disposables);
......
......@@ -3,10 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ComposedTreeDelegate, createComposedTreeListOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { ComposedTreeDelegate, createComposedTreeListOptions, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { ObjectTree, IObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeOptions } from 'vs/base/browser/ui/tree/tree';
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Emitter, Event, mapEvent } from 'vs/base/common/event';
import { timeout, always } from 'vs/base/common/async';
......@@ -123,6 +123,8 @@ export interface IChildrenResolutionEvent<T> {
readonly reason: ChildrenResolutionReason;
}
export interface IAsyncDataTreeOptions<T, TFilterData = void> extends IAbstractTreeOptions<T, TFilterData> { }
export class AsyncDataTree<T extends NonNullable<any>, TFilterData = void> implements IDisposable {
private tree: ObjectTree<IAsyncDataTreeNode<T>, TFilterData>;
......@@ -154,11 +156,12 @@ export class AsyncDataTree<T extends NonNullable<any>, TFilterData = void> imple
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
private dataSource: IDataSource<T>,
options?: ITreeOptions<T, TFilterData>
options?: IAsyncDataTreeOptions<T, TFilterData>
) {
const objectTreeDelegate = new ComposedTreeDelegate<T | null, IAsyncDataTreeNode<T>>(delegate);
const objectTreeRenderers = renderers.map(r => new DataTreeRenderer(r, this._onDidChangeNodeState.event));
const objectTreeOptions = createComposedTreeListOptions<T | null, IAsyncDataTreeNode<T>>(options);
const objectTreeOptions = createComposedTreeListOptions<T | null, IAsyncDataTreeNode<T>, IObjectTreeOptions<IAsyncDataTreeNode<T>, TFilterData>>(options);
objectTreeOptions.collapseByDefault = true;
this.tree = new ObjectTree(container, objectTreeDelegate, objectTreeRenderers, objectTreeOptions);
this.root = {
......@@ -395,8 +398,7 @@ export class AsyncDataTree<T extends NonNullable<any>, TFilterData = void> imple
state: AsyncDataTreeNodeState.Uninitialized,
parent: node
},
collapsible,
collapsed: true
collapsible
};
};
......
......@@ -5,20 +5,34 @@
import 'vs/css!./media/tree';
import { Iterator, ISequence } from 'vs/base/common/iterator';
import { AbstractTree } from 'vs/base/browser/ui/tree/abstractTree';
import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { ISpliceable } from 'vs/base/common/sequence';
import { IndexTreeModel } from 'vs/base/browser/ui/tree/indexTreeModel';
import { ITreeElement, ITreeModel, ITreeNode, ITreeOptions } from 'vs/base/browser/ui/tree/tree';
import { ITreeElement, ITreeModel, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
export interface IIndexTreeOptions<T, TFilterData = void> extends IAbstractTreeOptions<T, TFilterData> {
collapseByDefault?: boolean; // defaults to false
}
export class IndexTree<T, TFilterData = void> extends AbstractTree<T, TFilterData, number[]> {
protected model: IndexTreeModel<T, TFilterData>;
constructor(
container: HTMLElement,
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
options: IIndexTreeOptions<T, TFilterData> = {}
) {
super(container, delegate, renderers, options);
}
splice(location: number[], deleteCount: number, toInsert: ISequence<ITreeElement<T>> = Iterator.empty()): Iterator<ITreeElement<T>> {
return this.model.splice(location, deleteCount, toInsert);
}
protected createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: ITreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, number[]> {
protected createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: IIndexTreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, number[]> {
return new IndexTreeModel(view, options);
}
}
\ No newline at end of file
......@@ -39,6 +39,7 @@ function getVisibleState(visibility: boolean | TreeVisibility): TreeVisibility {
}
export interface IIndexTreeModelOptions<T, TFilterData> {
collapseByDefault?: boolean; // defaults to false
filter?: ITreeFilter<T, TFilterData>;
}
......@@ -64,9 +65,11 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
private _onDidChangeRenderNodeCount = new Emitter<ITreeNode<T, TFilterData>>();
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>> = this.eventBufferer.wrapEvent(this._onDidChangeRenderNodeCount.event);
private collapseByDefault: boolean;
private filter?: ITreeFilter<T, TFilterData>;
constructor(private list: ISpliceable<ITreeNode<T, TFilterData>>, options: IIndexTreeModelOptions<T, TFilterData> = {}) {
this.collapseByDefault = typeof options.collapseByDefault === 'undefined' ? false : options.collapseByDefault;
this.filter = options.filter;
}
......@@ -194,8 +197,8 @@ export class IndexTreeModel<T, TFilterData = void> implements ITreeModel<T, TFil
element: treeElement.element,
children: [],
depth: parent.depth + 1,
collapsible: typeof treeElement.collapsible === 'boolean' ? treeElement.collapsible : (typeof treeElement.collapsed === 'boolean'),
collapsed: !!treeElement.collapsed,
collapsible: typeof treeElement.collapsible === 'boolean' ? treeElement.collapsible : (typeof treeElement.collapsed !== 'undefined'),
collapsed: typeof treeElement.collapsed === 'undefined' ? this.collapseByDefault : treeElement.collapsed,
renderNodeCount: 1,
visible: true,
filterData: undefined
......
......@@ -4,15 +4,29 @@
*--------------------------------------------------------------------------------------------*/
import { Iterator, ISequence } from 'vs/base/common/iterator';
import { AbstractTree } from 'vs/base/browser/ui/tree/abstractTree';
import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { ISpliceable } from 'vs/base/common/sequence';
import { ITreeNode, ITreeModel, ITreeElement, ITreeOptions } from 'vs/base/browser/ui/tree/tree';
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
export interface IObjectTreeOptions<T, TFilterData = void> extends IAbstractTreeOptions<T, TFilterData> {
collapseByDefault?: boolean; // defaults to false
}
export class ObjectTree<T extends NonNullable<any>, TFilterData = void> extends AbstractTree<T | null, TFilterData, T | null> {
protected model: ObjectTreeModel<T, TFilterData>;
constructor(
container: HTMLElement,
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
options: IObjectTreeOptions<T, TFilterData> = {}
) {
super(container, delegate, renderers, options);
}
setChildren(
element: T | null,
children?: ISequence<ITreeElement<T>>,
......@@ -22,7 +36,7 @@ export class ObjectTree<T extends NonNullable<any>, TFilterData = void> extends
return this.model.setChildren(element, children, onDidCreateNode, onDidDeleteNode);
}
protected createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: ITreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, T> {
protected createModel(view: ISpliceable<ITreeNode<T, TFilterData>>, options: IObjectTreeOptions<T, TFilterData>): ITreeModel<T, TFilterData, T> {
return new ObjectTreeModel(view, options);
}
}
\ No newline at end of file
......@@ -9,6 +9,8 @@ import { IndexTreeModel, IIndexTreeModelOptions } from 'vs/base/browser/ui/tree/
import { Event } from 'vs/base/common/event';
import { ITreeModel, ITreeNode, ITreeElement } from 'vs/base/browser/ui/tree/tree';
export interface IObjectTreeModelOptions<T, TFilterData> extends IIndexTreeModelOptions<T, TFilterData> { }
export class ObjectTreeModel<T extends NonNullable<any>, TFilterData = void> implements ITreeModel<T, TFilterData, T> {
private model: IndexTreeModel<T, TFilterData>;
......@@ -19,7 +21,7 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData = void> imp
get size(): number { return this.nodes.size; }
constructor(list: ISpliceable<ITreeNode<T, TFilterData>>, options: IIndexTreeModelOptions<T, TFilterData> = {}) {
constructor(list: ISpliceable<ITreeNode<T, TFilterData>>, options: IObjectTreeModelOptions<T, TFilterData> = {}) {
this.model = new IndexTreeModel(list, options);
this.onDidChangeCollapseState = this.model.onDidChangeCollapseState;
this.onDidChangeRenderNodeCount = this.model.onDidChangeRenderNodeCount;
......
......@@ -6,7 +6,6 @@
import { Event } from 'vs/base/common/event';
import { Iterator } from 'vs/base/common/iterator';
import { IListRenderer } from 'vs/base/browser/ui/list/list';
import { IListOptions } from 'vs/base/browser/ui/list/listWidget';
export const enum TreeVisibility {
......@@ -112,10 +111,6 @@ export interface ITreeRenderer<T, TFilterData, TTemplateData> extends IListRende
onDidChangeTwistieState?: Event<T>;
}
export interface ITreeOptions<T, TFilterData = void> extends IListOptions<T> {
filter?: ITreeFilter<T, TFilterData>;
}
export interface ITreeEvent<T> {
elements: T[];
browserEvent?: UIEvent;
......
......@@ -32,9 +32,9 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { attachInputBoxStyler, attachListStyler, computeStyles, defaultListStyles } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { InputFocusedContextKey } from 'vs/platform/workbench/common/contextkeys';
import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { ITreeOptions as ITreeOptions2, ITreeEvent, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { AsyncDataTree, IDataSource } from 'vs/base/browser/ui/tree/asyncDataTree';
import { ObjectTree, IObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree';
import { ITreeEvent, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { AsyncDataTree, IDataSource, IAsyncDataTreeOptions } from 'vs/base/browser/ui/tree/asyncDataTree';
export type ListWidget = List<any> | PagedList<any> | ITree | ObjectTree<any, any> | AsyncDataTree<any, any>;
......@@ -881,7 +881,7 @@ export class WorkbenchObjectTree<T extends NonNullable<any>, TFilterData = void>
container: HTMLElement,
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
options: ITreeOptions2<T, TFilterData>,
options: IObjectTreeOptions<T, TFilterData>,
@IContextKeyService contextKeyService: IContextKeyService,
@IListService listService: IListService,
@IThemeService themeService: IThemeService,
......@@ -944,7 +944,7 @@ export class WorkbenchAsyncDataTree<T extends NonNullable<any>, TFilterData = vo
delegate: IListVirtualDelegate<T>,
renderers: ITreeRenderer<any /* TODO@joao */, TFilterData, any>[],
dataSource: IDataSource<T>,
options: ITreeOptions2<T, TFilterData>,
options: IAsyncDataTreeOptions<T, TFilterData>,
@IContextKeyService contextKeyService: IContextKeyService,
@IListService listService: IListService,
@IThemeService themeService: IThemeService,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册