diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index 1b020fee6e7fa85437a30b79cb12fe43922801f5..540893da05536d0e4e70d053d694925e0baf6ec6 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -170,6 +170,9 @@ export class Tree implements IDisposable { onKeyDown.filter(e => e.keyCode === KeyCode.LeftArrow).on(this.onLeftArrow, this, this.disposables); onKeyDown.filter(e => e.keyCode === KeyCode.RightArrow).on(this.onRightArrow, this, this.disposables); onKeyDown.filter(e => e.keyCode === KeyCode.Space).on(this.onSpace, this, this.disposables); + + // TODO@joao cleanup + onKeyDown.filter(e => e.keyCode === KeyCode.KEY_A).on(() => this.model.setCollapsedAll(true), null, this.disposables); } splice(location: number[], deleteCount: number, toInsert: ISequence> = Iterator.empty()): Iterator> { diff --git a/src/vs/base/browser/ui/tree/treeModel.ts b/src/vs/base/browser/ui/tree/treeModel.ts index 1116777cb90d38e99e21423649ecfa9caa5d09b8..0fbef7bf5f29b8afa3be3fdae9c5c9ca7b3b08f7 100644 --- a/src/vs/base/browser/ui/tree/treeModel.ts +++ b/src/vs/base/browser/ui/tree/treeModel.ts @@ -166,16 +166,16 @@ export class TreeModel { } setCollapsed(location: number[], collapsed: boolean): boolean { - return this._setCollapsed(location, collapsed); + const { node, listIndex, visible } = this.findNode(location); + return this._setCollapsed(node, listIndex, visible, collapsed); } toggleCollapsed(location: number[]): void { - this._setCollapsed(location); - } - - private _setCollapsed(location: number[], collapsed?: boolean | undefined): boolean { const { node, listIndex, visible } = this.findNode(location); + this._setCollapsed(node, listIndex, visible); + } + private _setCollapsed(node: IMutableTreeNode, listIndex: number, visible: boolean, collapsed?: boolean | undefined): boolean { if (!node.collapsible) { return false; } @@ -195,13 +195,29 @@ export class TreeModel { const toInsert = updateVisibleCount(node); this.list.splice(listIndex + 1, previousVisibleCount - 1, toInsert.slice(1)); + this._onDidChangeCollapseState.fire(node); } - this._onDidChangeCollapseState.fire(node); - return true; } + // TODO@joao cleanup + setCollapsedAll(collapsed: boolean): void { + if (collapsed) { + const queue = [...this.root.children]; // TODO@joao use a linked list + let listIndex = 0; + + while (queue.length > 0) { + const node = queue.shift(); + const visible = listIndex < this.root.children.length; + this._setCollapsed(node, listIndex, visible, collapsed); + + queue.push(...node.children); + listIndex++; + } + } + } + isCollapsed(location: number[]): boolean { return this.findNode(location).node.collapsed; } diff --git a/test/tree/public/index.html b/test/tree/public/index.html index 3716374c0dea4400f108f153663c6b1a461db0e3..1374fc77837bf11a7c8cbbc6c3c9411fbe560e51 100644 --- a/test/tree/public/index.html +++ b/test/tree/public/index.html @@ -44,21 +44,40 @@ const tree = new Tree(container, delegate, [renderer]); - const xhr = new XMLHttpRequest(); - xhr.open('GET', '/api/ls?path='); - xhr.send(); - xhr.onreadystatechange = function () { - if (this.readyState == 4 && this.status == 200) { - const data = JSON.parse(this.responseText); + function setModel(model) { + performance.mark('before splice'); + const start = performance.now(); + tree.splice([0], 0, model); + console.log('splice took', performance.now() - start); + performance.mark('after splice'); + } - performance.mark('before splice'); - const start = performance.now(); - tree.splice([0], 0, [data]); - console.log('splice took', performance.now() - start); - performance.mark('after splice'); + switch (location.search) { + case '?problems': { + const files = []; + for (let i = 0; i < 10000; i++) { + const errors = []; + for (let j = 1; j <= (i % 5) + 1; j++) { + errors.push({ element: `error #${j}` }); + } + + files.push({ element: `file #${i}`, children: errors }); + } + setModel(files); + break; } - }; + default: + const xhr = new XMLHttpRequest(); + xhr.open('GET', '/api/ls?path='); + xhr.send(); + xhr.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + setModel([JSON.parse(this.responseText)]); + } + }; + } + });