提交 4b3c04ec 编写于 作者: J Joao Moreno

tree: expand/collapse on click

上级 323bbc57
......@@ -4,19 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./tree';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IListOptions, List, IIdentityProvider, IMultipleSelectionController } from 'vs/base/browser/ui/list/listWidget';
import { TreeModel, ITreeNode, ITreeElement } from 'vs/base/browser/ui/tree/treeModel';
import { IIterator, empty } from 'vs/base/common/iterator';
import { IDelegate, IRenderer } from 'vs/base/browser/ui/list/list';
import { IDelegate, IRenderer, IListMouseEvent } from 'vs/base/browser/ui/list/list';
import { append, $ } from 'vs/base/browser/dom';
/**
* Remove ITreeNode and just use ITreeNode instead.
* We need ITreeNode live objects to associate them with the respective rendered
* HTMLElement. That way we can find the right node when DOM events happen, eg click.
*/
function toTreeListOptions<T>(options?: IListOptions<T>): IListOptions<ITreeNode<T>> {
if (!options) {
return undefined;
......@@ -95,10 +89,22 @@ class TreeRenderer<T, TTemplateData> implements IRenderer<ITreeNode<T>, ITreeLis
}
}
function getLocation<T>(node: ITreeNode<T>): number[] {
const location = [];
while (node.parent) {
location.push(node.parent.children.indexOf(node));
node = node.parent;
}
return location.reverse();
}
export class Tree<T> implements IDisposable {
private view: List<ITreeNode<T>>;
private model: TreeModel<T>;
private disposables: IDisposable[] = [];
constructor(
container: HTMLElement,
......@@ -112,13 +118,24 @@ export class Tree<T> implements IDisposable {
this.view = new List(container, treeDelegate, treeRenderers, treeOptions);
this.model = new TreeModel<T>(this.view);
this.view.onMouseClick(this.onMouseClick, this, this.disposables);
}
splice(location: number[], deleteCount: number, toInsert: IIterator<ITreeElement<T>> = empty()): IIterator<ITreeElement<T>> {
return this.model.splice(location, deleteCount, toInsert);
}
private onMouseClick(e: IListMouseEvent<ITreeNode<T>>): void {
const node = e.element;
const location = getLocation(node);
this.model.toggleCollapsed(location);
}
dispose(): void {
this.disposables = dispose(this.disposables);
this.view.dispose();
this.view = null;
this.model = null;
}
}
\ No newline at end of file
......@@ -16,7 +16,7 @@ export interface ITreeElement<T> {
}
export interface ITreeNode<T> {
readonly parent: IMutableTreeNode<T>;
readonly parent: IMutableTreeNode<T> | undefined;
readonly element: T;
readonly children: IMutableTreeNode<T>[];
readonly depth: number;
......@@ -52,7 +52,7 @@ function getVisibleNodes<T>(nodes: IMutableTreeNode<T>[], result: ITreeNode<T>[]
function treeElementToNode<T>(treeElement: ITreeElement<T>, parent: IMutableTreeNode<T>, visible: boolean, treeListElements: ITreeNode<T>[]): IMutableTreeNode<T> {
const depth = parent.depth + 1;
const { element, collapsed } = treeElement;
const node = { parent: undefined, element, children: [], depth, collapsed, visibleCount: 0 };
const node = { parent, element, children: [], depth, collapsed, visibleCount: 0 };
if (visible) {
treeListElements.push(node);
......@@ -105,8 +105,20 @@ export class TreeModel<T> {
}
setCollapsed(location: number[], collapsed: boolean): void {
this._setCollapsed(location, collapsed);
}
toggleCollapsed(location: number[]): void {
this._setCollapsed(location);
}
private _setCollapsed(location: number[], collapsed?: boolean | undefined): void {
const { node, listIndex, visible } = this.findNode(location);
if (typeof collapsed === 'undefined') {
collapsed = !node.collapsed;
}
if (node.collapsed === collapsed) {
return;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册