tree: fix expand/collapse
This commit is contained in:
parent
5e37f92880
commit
37755faeb6
4 changed files with 41 additions and 26 deletions
|
@ -60,6 +60,7 @@ class TreeDelegate<T> implements IVirtualDelegate<ITreeNode<T>> {
|
||||||
|
|
||||||
interface ITreeListTemplateData<T> {
|
interface ITreeListTemplateData<T> {
|
||||||
twistie: HTMLElement;
|
twistie: HTMLElement;
|
||||||
|
count: HTMLElement;
|
||||||
templateData: T;
|
templateData: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,9 +90,10 @@ class TreeRenderer<T, TTemplateData> implements IRenderer<ITreeNode<T>, ITreeLis
|
||||||
const el = append(container, $('.monaco-tl-row'));
|
const el = append(container, $('.monaco-tl-row'));
|
||||||
const twistie = append(el, $('.tl-twistie'));
|
const twistie = append(el, $('.tl-twistie'));
|
||||||
const contents = append(el, $('.tl-contents'));
|
const contents = append(el, $('.tl-contents'));
|
||||||
|
const count = append(el, $('.tl-count'));
|
||||||
const templateData = this.renderer.renderTemplate(contents);
|
const templateData = this.renderer.renderTemplate(contents);
|
||||||
|
|
||||||
return { twistie, templateData };
|
return { twistie, count, templateData };
|
||||||
}
|
}
|
||||||
|
|
||||||
renderElement(node: ITreeNode<T>, index: number, templateData: ITreeListTemplateData<TTemplateData>): void {
|
renderElement(node: ITreeNode<T>, index: number, templateData: ITreeListTemplateData<TTemplateData>): void {
|
||||||
|
@ -99,6 +101,7 @@ class TreeRenderer<T, TTemplateData> implements IRenderer<ITreeNode<T>, ITreeLis
|
||||||
|
|
||||||
templateData.twistie.style.width = `${10 + node.depth * 10}px`;
|
templateData.twistie.style.width = `${10 + node.depth * 10}px`;
|
||||||
renderTwistie(node, templateData.twistie);
|
renderTwistie(node, templateData.twistie);
|
||||||
|
templateData.count.textContent = `${node.visibleCount}`;
|
||||||
|
|
||||||
this.renderer.renderElement(node.element, index, templateData.templateData);
|
this.renderer.renderElement(node.element, index, templateData.templateData);
|
||||||
}
|
}
|
||||||
|
@ -119,6 +122,7 @@ class TreeRenderer<T, TTemplateData> implements IRenderer<ITreeNode<T>, ITreeLis
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTwistie(node, templateData.twistie);
|
renderTwistie(node, templateData.twistie);
|
||||||
|
templateData.count.textContent = `${node.visibleCount}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispose(): void {
|
dispose(): void {
|
||||||
|
|
|
@ -39,13 +39,35 @@ function getVisibleCount<T>(nodes: IMutableTreeNode<T>[]): number {
|
||||||
return nodes.reduce(visibleCountReducer, 0);
|
return nodes.reduce(visibleCountReducer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVisibleNodes<T>(nodes: IMutableTreeNode<T>[], result: ITreeNode<T>[] = []): ITreeNode<T>[] {
|
/**
|
||||||
for (const node of nodes) {
|
* Recursively updates the visibleCount of a subtree, while collecting
|
||||||
|
* all the visible nodes in an array.
|
||||||
|
*/
|
||||||
|
function updateVisibleCount<T>(node: IMutableTreeNode<T>): ITreeNode<T>[] {
|
||||||
|
const previousVisibleCount = node.visibleCount;
|
||||||
|
const result: ITreeNode<T>[] = [];
|
||||||
|
|
||||||
|
function _updateVisibleCount(node: IMutableTreeNode<T>): number {
|
||||||
result.push(node);
|
result.push(node);
|
||||||
|
node.visibleCount = 1;
|
||||||
|
|
||||||
if (!node.collapsed) {
|
if (!node.collapsed) {
|
||||||
getVisibleNodes(node.children, result);
|
for (const child of node.children) {
|
||||||
|
node.visibleCount += _updateVisibleCount(child);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return node.visibleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateVisibleCount(node);
|
||||||
|
|
||||||
|
const visibleCountDiff = result.length - previousVisibleCount;
|
||||||
|
node = node.parent;
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
node.visibleCount += visibleCountDiff;
|
||||||
|
node = node.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -108,6 +130,7 @@ export class TreeModel<T> {
|
||||||
visibleCount: 1
|
visibleCount: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO@joao can't we do without this?
|
||||||
private _onDidChangeCollapseState = new Emitter<ITreeNode<T>>();
|
private _onDidChangeCollapseState = new Emitter<ITreeNode<T>>();
|
||||||
readonly onDidChangeCollapseState: Event<ITreeNode<T>> = this._onDidChangeCollapseState.event;
|
readonly onDidChangeCollapseState: Event<ITreeNode<T>> = this._onDidChangeCollapseState.event;
|
||||||
|
|
||||||
|
@ -165,30 +188,14 @@ export class TreeModel<T> {
|
||||||
node.collapsed = collapsed;
|
node.collapsed = collapsed;
|
||||||
|
|
||||||
if (visible) {
|
if (visible) {
|
||||||
this._onDidChangeCollapseState.fire(node);
|
const previousVisibleCount = node.visibleCount;
|
||||||
|
const toInsert = updateVisibleCount(node);
|
||||||
|
|
||||||
let visibleCountDiff: number;
|
this.list.splice(listIndex + 1, previousVisibleCount - 1, toInsert.slice(1));
|
||||||
|
|
||||||
if (collapsed) {
|
|
||||||
const deleteCount = getVisibleCount(node.children);
|
|
||||||
|
|
||||||
this.list.splice(listIndex + 1, deleteCount, []);
|
|
||||||
visibleCountDiff = -deleteCount;
|
|
||||||
} else {
|
|
||||||
const toInsert = getVisibleNodes(node.children);
|
|
||||||
|
|
||||||
this.list.splice(listIndex + 1, 0, toInsert);
|
|
||||||
visibleCountDiff = toInsert.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mutableNode = node;
|
|
||||||
|
|
||||||
while (mutableNode) {
|
|
||||||
mutableNode.visibleCount += visibleCountDiff;
|
|
||||||
mutableNode = mutableNode.parent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._onDidChangeCollapseState.fire(node);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
.monaco-scrollable-element>.scrollbar>.slider {
|
.monaco-scrollable-element>.scrollbar>.slider {
|
||||||
background: rgba(100, 100, 100, .4);
|
background: rgba(100, 100, 100, .4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tl-contents {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ async function getTree(fsPath, level) {
|
||||||
const element = path.basename(fsPath);
|
const element = path.basename(fsPath);
|
||||||
const stat = await fs.stat(fsPath);
|
const stat = await fs.stat(fsPath);
|
||||||
|
|
||||||
if (!stat.isDirectory() || element === '.git' || element === '.build' || level >= 3) {
|
if (!stat.isDirectory() || element === '.git' || element === '.build' || level >= 4) {
|
||||||
return { element };
|
return { element };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue