mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 09:08:48 +01:00
@@ -179,6 +179,7 @@ function asTreeContextMenuEvent<T>(event: IListContextMenuEvent<ITreeNode<T, any
|
||||
}
|
||||
|
||||
export interface IAbstractTreeOptions<T, TFilterData = void> extends IListOptions<T> {
|
||||
collapseByDefault?: boolean; // defaults to false
|
||||
filter?: ITreeFilter<T, TFilterData>;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { ComposedTreeDelegate, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { ObjectTree, IObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree';
|
||||
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { timeout, always } from 'vs/base/common/async';
|
||||
@@ -157,6 +157,11 @@ function asObjectTreeOptions<T, TFilterData>(options?: IAsyncDataTreeOptions<T,
|
||||
getKeyboardNavigationLabel(e) {
|
||||
return options.keyboardNavigationLabelProvider!.getKeyboardNavigationLabel(e.element!);
|
||||
}
|
||||
},
|
||||
sorter: options.sorter && {
|
||||
compare(a, b) {
|
||||
return options.sorter!.compare(a.element!, b.element!);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -170,6 +175,7 @@ function asTreeElement<T>(node: IAsyncDataTreeNode<T>): ITreeElement<IAsyncDataT
|
||||
|
||||
export interface IAsyncDataTreeOptions<T, TFilterData = void> extends IAbstractTreeOptions<T, TFilterData> {
|
||||
identityProvider?: IIdentityProvider<T>;
|
||||
sorter?: ITreeSorter<T>;
|
||||
}
|
||||
|
||||
export class AsyncDataTree<T extends NonNullable<any>, TFilterData = void> implements IDisposable {
|
||||
|
||||
@@ -11,9 +11,7 @@ import { IndexTreeModel } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
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 interface IIndexTreeOptions<T, TFilterData = void> extends IAbstractTreeOptions<T, TFilterData> { }
|
||||
|
||||
export class IndexTree<T, TFilterData = void> extends AbstractTree<T, TFilterData, number[]> {
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
import { Iterator, ISequence } from 'vs/base/common/iterator';
|
||||
import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { ISpliceable } from 'vs/base/common/sequence';
|
||||
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter } 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
|
||||
sorter?: ITreeSorter<T>;
|
||||
}
|
||||
|
||||
export class ObjectTree<T extends NonNullable<any>, TFilterData = void> extends AbstractTree<T | null, TFilterData, T | null> {
|
||||
|
||||
@@ -7,9 +7,11 @@ import { ISpliceable } from 'vs/base/common/sequence';
|
||||
import { Iterator, ISequence, getSequenceIterator } from 'vs/base/common/iterator';
|
||||
import { IndexTreeModel, IIndexTreeModelOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { ITreeModel, ITreeNode, ITreeElement } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ITreeModel, ITreeNode, ITreeElement, ITreeSorter } from 'vs/base/browser/ui/tree/tree';
|
||||
|
||||
export interface IObjectTreeModelOptions<T, TFilterData> extends IIndexTreeModelOptions<T, TFilterData> { }
|
||||
export interface IObjectTreeModelOptions<T, TFilterData> extends IIndexTreeModelOptions<T, TFilterData> {
|
||||
sorter?: ITreeSorter<T>;
|
||||
}
|
||||
|
||||
export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends NonNullable<any> = void> implements ITreeModel<T | null, TFilterData, T | null> {
|
||||
|
||||
@@ -17,6 +19,7 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
|
||||
private model: IndexTreeModel<T | null, TFilterData>;
|
||||
private nodes = new Map<T | null, ITreeNode<T, TFilterData>>();
|
||||
private sorter?: ITreeSorter<ITreeElement<T>>;
|
||||
|
||||
readonly onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>;
|
||||
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>>;
|
||||
@@ -27,6 +30,14 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
this.model = new IndexTreeModel(list, null, options);
|
||||
this.onDidChangeCollapseState = this.model.onDidChangeCollapseState as Event<ITreeNode<T, TFilterData>>;
|
||||
this.onDidChangeRenderNodeCount = this.model.onDidChangeRenderNodeCount as Event<ITreeNode<T, TFilterData>>;
|
||||
|
||||
if (options.sorter) {
|
||||
this.sorter = {
|
||||
compare(a, b) {
|
||||
return options.sorter!.compare(a.element, b.element);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
setChildren(
|
||||
@@ -67,7 +78,11 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
|
||||
}
|
||||
|
||||
private preserveCollapseState(elements: ISequence<ITreeElement<T | null>> | undefined): ISequence<ITreeElement<T | null>> {
|
||||
const iterator = elements ? getSequenceIterator(elements) : Iterator.empty<ITreeElement<T>>();
|
||||
let iterator = elements ? getSequenceIterator(elements) : Iterator.empty<ITreeElement<T>>();
|
||||
|
||||
if (this.sorter) {
|
||||
iterator = Iterator.fromArray(Iterator.collect(iterator).sort(this.sorter.compare.bind(this.sorter)));
|
||||
}
|
||||
|
||||
return Iterator.map(iterator, treeElement => {
|
||||
const node = this.nodes.get(treeElement.element);
|
||||
|
||||
@@ -67,6 +67,10 @@ export interface ITreeFilter<T, TFilterData = void> {
|
||||
filter(element: T, parentVisibility: TreeVisibility): TreeFilterResult<TFilterData>;
|
||||
}
|
||||
|
||||
export interface ITreeSorter<T> {
|
||||
compare(element: T, otherElement: T): number;
|
||||
}
|
||||
|
||||
export interface ITreeElement<T> {
|
||||
readonly element: T;
|
||||
readonly children?: Iterator<ITreeElement<T>> | ITreeElement<T>[];
|
||||
|
||||
@@ -138,6 +138,16 @@
|
||||
}
|
||||
};
|
||||
|
||||
const sorter = new class {
|
||||
compare(a, b) {
|
||||
if (a.collapsible === b.collapsible) {
|
||||
return a.name < b.name ? -1 : 1;
|
||||
}
|
||||
|
||||
return a.collapsible ? -1 : 1;
|
||||
}
|
||||
};
|
||||
|
||||
const dataSource = new class {
|
||||
hasChildren(element) {
|
||||
return element === null || element.element.type === 'dir';
|
||||
@@ -154,11 +164,7 @@
|
||||
collapsible: element.type === 'dir'
|
||||
}));
|
||||
|
||||
if (element) {
|
||||
setTimeout(() => c(els), 2500);
|
||||
} else {
|
||||
c(els);
|
||||
}
|
||||
c(els);
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -171,7 +177,7 @@
|
||||
}
|
||||
};
|
||||
|
||||
const tree = new AsyncDataTree(container, delegate, [renderer], dataSource, { filter: treeFilter, identityProvider });
|
||||
const tree = new AsyncDataTree(container, delegate, [renderer], dataSource, { filter: treeFilter, sorter, identityProvider });
|
||||
|
||||
return { tree, treeFilter };
|
||||
}
|
||||
|
||||
@@ -46,14 +46,6 @@ async function readdir(relativePath) {
|
||||
}
|
||||
}
|
||||
|
||||
result.sort((a, b) => {
|
||||
if (a.type === b.type) {
|
||||
return a.name < b.name ? -1 : 1;
|
||||
}
|
||||
|
||||
return a.type === 'dir' ? -1 : 1;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user