提交 6fee1f6e 编写于 作者: J Joao Moreno

tree: more filter testing

上级 0bdfc259
......@@ -6,7 +6,7 @@
import 'vs/css!./tree';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IListOptions, List, IIdentityProvider, IMultipleSelectionController } from 'vs/base/browser/ui/list/listWidget';
import { TreeModel, ITreeNode, ITreeElement, getNodeLocation } from 'vs/base/browser/ui/tree/treeModel';
import { TreeModel, ITreeNode, ITreeElement, getNodeLocation, ITreeModelOptions } from 'vs/base/browser/ui/tree/treeModel';
import { Iterator, ISequence } from 'vs/base/common/iterator';
import { IVirtualDelegate, IRenderer, IListMouseEvent } from 'vs/base/browser/ui/list/list';
import { append, $ } from 'vs/base/browser/dom';
......@@ -135,7 +135,7 @@ function isInputElement(e: HTMLElement): boolean {
return e.tagName === 'INPUT' || e.tagName === 'TEXTAREA';
}
export interface ITreeOptions<T> extends IListOptions<T> { }
export interface ITreeOptions<T, TFilterData = void> extends IListOptions<T>, ITreeModelOptions<T, TFilterData> { }
export class Tree<T, TFilterData = void> implements IDisposable {
......@@ -147,7 +147,7 @@ export class Tree<T, TFilterData = void> implements IDisposable {
container: HTMLElement,
delegate: IVirtualDelegate<T>,
renderers: IRenderer<T, any>[],
options?: ITreeOptions<T>
options?: ITreeOptions<T, TFilterData>
) {
const treeDelegate = new TreeDelegate(delegate);
......@@ -155,10 +155,8 @@ export class Tree<T, TFilterData = void> implements IDisposable {
const treeRenderers = renderers.map(r => new TreeRenderer(r, onDidChangeCollapseStateRelay.event));
this.disposables.push(...treeRenderers);
const treeOptions = toTreeListOptions(options);
this.view = new List(container, treeDelegate, treeRenderers, treeOptions);
this.model = new TreeModel<T, TFilterData>(this.view);
this.view = new List(container, treeDelegate, treeRenderers, toTreeListOptions(options));
this.model = new TreeModel<T, TFilterData>(this.view, options);
onDidChangeCollapseStateRelay.input = this.model.onDidChangeCollapseState;
this.view.onMouseClick(this.onMouseClick, this, this.disposables);
......@@ -176,6 +174,10 @@ export class Tree<T, TFilterData = void> implements IDisposable {
return this.model.splice(location, deleteCount, toInsert);
}
refilter(location?: number[]): void {
this.model.refilter(location);
}
private onMouseClick(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
const node = e.element;
const location = getNodeLocation(node);
......
......@@ -54,7 +54,7 @@ function isFilterResult<T>(obj: any): obj is IFilterResult<T> {
}
export interface ITreeFilter<T, TFilterData = void> {
getVisibility(element: T): Visibility | IFilterResult<TFilterData>;
filter(element: T): boolean | Visibility | IFilterResult<TFilterData>;
}
function revealedCountReducer<T>(result: number, node: IMutableTreeNode<T, any>): number {
......@@ -93,7 +93,7 @@ export function getNodeLocation<T>(node: ITreeNode<T, any>): number[] {
return location.reverse();
}
export interface ITreeOptions<T, TFilterData = void> {
export interface ITreeModelOptions<T, TFilterData = void> {
filter?: ITreeFilter<T, TFilterData>;
}
......@@ -116,7 +116,7 @@ export class TreeModel<T, TFilterData = void> {
private filter?: ITreeFilter<T, TFilterData>;
constructor(private list: ISpliceable<ITreeNode<T, TFilterData>>, options: ITreeOptions<T, TFilterData> = {}) {
constructor(private list: ISpliceable<ITreeNode<T, TFilterData>>, options: ITreeModelOptions<T, TFilterData> = {}) {
this.filter = options.filter;
}
......@@ -299,9 +299,12 @@ export class TreeModel<T, TFilterData = void> {
}
private filterNode(node: IMutableTreeNode<T, TFilterData>): void {
const visibility = this.filter ? this.filter.getVisibility(node.element) : Visibility.Visible;
const visibility = this.filter ? this.filter.filter(node.element) : Visibility.Visible;
if (isFilterResult(visibility)) {
if (typeof visibility === 'boolean') {
node.visible = visibility;
node.filterData = undefined;
} else if (isFilterResult<TFilterData>(visibility)) {
node.visible = visibility.visibility === Visibility.Visible;
node.filterData = visibility.data;
} else {
......
......@@ -335,7 +335,7 @@ suite('TreeModel2', function () {
test('simple filter', function () {
const list = [] as ITreeNode<number>[];
const filter = new class implements ITreeFilter<number> {
getVisibility(element: number): Visibility {
filter(element: number): Visibility {
return element % 2 === 0 ? Visibility.Visible : Visibility.Hidden;
}
};
......@@ -370,7 +370,7 @@ suite('TreeModel2', function () {
const list = [] as ITreeNode<number>[];
let shouldFilter = false;
const filter = new class implements ITreeFilter<number> {
getVisibility(element: number): Visibility {
filter(element: number): Visibility {
return (!shouldFilter || element % 2 === 0) ? Visibility.Visible : Visibility.Hidden;
}
};
......@@ -405,7 +405,7 @@ suite('TreeModel2', function () {
const list = [] as ITreeNode<number>[];
let shouldFilter = false;
const filter = new class implements ITreeFilter<number> {
getVisibility(element: number): Visibility {
filter(element: number): Visibility {
return (!shouldFilter || element % 2 === 0) ? Visibility.Visible : Visibility.Hidden;
}
};
......
......@@ -21,6 +21,7 @@
</head>
<body>
<input type="text" id="filter" />
<div id="container"></div>
<script src="/static/vs/loader.js"></script>
......@@ -42,7 +43,30 @@
disposeTemplate() { }
};
const tree = new Tree(container, delegate, [renderer]);
const tree = new Tree(container, delegate, [renderer], {
filter: new class {
constructor() {
this.pattern = null;
let timeout;
filter.oninput = () => {
clearTimeout(timeout);
timeout = setTimeout(() => this.updatePattern(), 300);
};
}
updatePattern() {
if (!filter.value) {
this.pattern = null;
} else {
this.pattern = new RegExp(filter.value, 'i');
}
tree.refilter();
}
filter(el) {
return this.pattern ? this.pattern.test(el) : true;
}
}
});
function setModel(model) {
performance.mark('before splice');
......@@ -77,7 +101,6 @@
}
};
}
});
</script>
</body>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册