Skip to content

Commit 5fd4be9

Browse files
committed
tree: node.collapsible
1 parent 47e4319 commit 5fd4be9

3 files changed

Lines changed: 21 additions & 5 deletions

File tree

src/vs/base/browser/ui/tree/tree.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ interface ITreeListTemplateData<T> {
6363
templateData: T;
6464
}
6565

66+
function renderTwistie<T>(node: ITreeNode<T>, twistie: HTMLElement): void {
67+
if (node.children.length === 0 && !node.collapsible) {
68+
twistie.innerText = '';
69+
} else {
70+
twistie.innerText = node.collapsed ? '▹' : '◢';
71+
}
72+
}
73+
6674
class TreeRenderer<T, TTemplateData> implements IRenderer<ITreeNode<T>, ITreeListTemplateData<TTemplateData>> {
6775

6876
readonly templateId: string;
@@ -92,8 +100,8 @@ class TreeRenderer<T, TTemplateData> implements IRenderer<ITreeNode<T>, ITreeLis
92100
this.renderedNodes.set(node, templateData);
93101
templateData.elementDisposable = toDisposable(() => this.renderedNodes.delete(node));
94102

95-
templateData.twistie.innerText = node.children.length === 0 ? '' : (node.collapsed ? '▹' : '◢');
96103
templateData.twistie.style.width = `${10 + node.depth * 10}px`;
104+
renderTwistie(node, templateData.twistie);
97105

98106
this.renderer.renderElement(node.element, index, templateData.templateData);
99107
}
@@ -109,7 +117,7 @@ class TreeRenderer<T, TTemplateData> implements IRenderer<ITreeNode<T>, ITreeLis
109117
return;
110118
}
111119

112-
templateData.twistie.innerText = node.children.length === 0 ? '' : (node.collapsed ? '▹' : '◢');
120+
renderTwistie(node, templateData.twistie);
113121
}
114122

115123
dispose(): void {

src/vs/base/browser/ui/tree/treeModel.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Emitter, Event } from 'vs/base/common/event';
1212
export interface ITreeElement<T> {
1313
readonly element: T;
1414
readonly children?: IIterator<ITreeElement<T>> | ITreeElement<T>[];
15+
readonly collapsible?: boolean;
1516
readonly collapsed?: boolean;
1617
}
1718

@@ -20,6 +21,7 @@ export interface ITreeNode<T> {
2021
readonly element: T;
2122
readonly children: IMutableTreeNode<T>[];
2223
readonly depth: number;
24+
readonly collapsible: boolean;
2325
readonly collapsed: boolean;
2426
readonly visibleCount: number;
2527
}
@@ -61,15 +63,16 @@ function getTreeElementIterator<T>(elements: IIterator<ITreeElement<T>> | ITreeE
6163

6264
function treeElementToNode<T>(treeElement: ITreeElement<T>, parent: IMutableTreeNode<T>, visible: boolean, treeListElements: ITreeNode<T>[]): IMutableTreeNode<T> {
6365
const depth = parent.depth + 1;
64-
const { element, collapsed } = treeElement;
65-
const node = { parent, element, children: [], depth, collapsed: !!collapsed, visibleCount: 0 };
66+
const { element, collapsible, collapsed } = treeElement;
67+
const node = { parent, element, children: [], depth, collapsible: !!collapsible, collapsed: !!collapsed, visibleCount: 0 };
6668

6769
if (visible) {
6870
treeListElements.push(node);
6971
}
7072

7173
const children = getTreeElementIterator(treeElement.children);
7274
node.children = collect(map(children, el => treeElementToNode(el, node, visible && !treeElement.collapsed, treeListElements)));
75+
node.collapsible = node.collapsible || node.children.length > 0;
7376
node.visibleCount = 1 + getVisibleCount(node.children);
7477

7578
return node;
@@ -89,6 +92,7 @@ export class TreeModel<T> {
8992
element: undefined,
9093
children: [],
9194
depth: 0,
95+
collapsible: false,
9296
collapsed: false,
9397
visibleCount: 1
9498
};
@@ -131,6 +135,10 @@ export class TreeModel<T> {
131135
private _setCollapsed(location: number[], collapsed?: boolean | undefined): boolean {
132136
const { node, listIndex, visible } = this.findNode(location);
133137

138+
if (!node.collapsible) {
139+
return false;
140+
}
141+
134142
if (typeof collapsed === 'undefined') {
135143
collapsed = !node.collapsed;
136144
}

test/tree/server.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ async function getTree(fsPath, level) {
2323

2424
const childNames = await fs.readdir(fsPath);
2525
const children = await Promise.all(childNames.map(async childName => await getTree(path.join(fsPath, childName), level + 1)));
26-
return { element, collapsed: false, children };
26+
return { element, collapsible: true, collapsed: false, children };
2727
}
2828

2929
app.use(serve('public'));

0 commit comments

Comments
 (0)