Skip to content

Commit

Permalink
Introduce CompressibleObjectTree (#77876)
Browse files Browse the repository at this point in the history
Introduce `CompressibleObjectTree`
  • Loading branch information
joaomoreno authored Sep 13, 2019
2 parents c05a0af + 3d93cac commit 4f39995
Show file tree
Hide file tree
Showing 18 changed files with 747 additions and 344 deletions.
2 changes: 1 addition & 1 deletion src/vs/base/browser/ui/list/listWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ export interface IListStyles {
}

const defaultStyles: IListStyles = {
listFocusBackground: Color.fromHex('#073655'),
listFocusBackground: Color.fromHex('#7FB0D0'),
listActiveSelectionBackground: Color.fromHex('#0E639C'),
listActiveSelectionForeground: Color.fromHex('#FFFFFF'),
listFocusAndSelectionBackground: Color.fromHex('#094771'),
Expand Down
63 changes: 35 additions & 28 deletions src/vs/base/browser/ui/tree/abstractTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ class TreeNodeListDragAndDrop<T, TFilterData, TRef> implements IListDragAndDrop<
}

if (result.bubble === TreeDragOverBubble.Up) {
const parentNode = targetNode.parent;
const model = this.modelProvider();
const parentIndex = parentNode && model.getListIndex(model.getNodeLocation(parentNode));
const ref = model.getNodeLocation(targetNode);
const parentRef = model.getParentNodeLocation(ref);
const parentNode = model.getNode(parentRef);
const parentIndex = parentRef && model.getListIndex(parentRef);

return this.onDragOver(data, parentNode, parentIndex, originalEvent, false);
}
Expand Down Expand Up @@ -155,7 +157,12 @@ function asListOptions<T, TFilterData, TRef>(modelProvider: () => ITreeModel<T,
enableKeyboardNavigation: options.simpleKeyboardNavigation,
ariaProvider: {
getSetSize(node) {
return node.parent!.visibleChildrenCount;
const model = modelProvider();
const ref = model.getNodeLocation(node);
const parentRef = model.getParentNodeLocation(ref);
const parentNode = model.getNode(parentRef);

return parentNode.visibleChildrenCount;
},
getPosInSet(node) {
return node.visibleChildIndex + 1;
Expand Down Expand Up @@ -233,7 +240,7 @@ class EventCollection<T> implements Collection<T> {
}
}

class TreeRenderer<T, TFilterData, TTemplateData> implements IListRenderer<ITreeNode<T, TFilterData>, ITreeListTemplateData<TTemplateData>> {
class TreeRenderer<T, TFilterData, TRef, TTemplateData> implements IListRenderer<ITreeNode<T, TFilterData>, ITreeListTemplateData<TTemplateData>> {

private static DefaultIndent = 8;

Expand All @@ -251,6 +258,7 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IListRenderer<ITree

constructor(
private renderer: ITreeRenderer<T, TFilterData, TTemplateData>,
private modelProvider: () => ITreeModel<T, TFilterData, TRef>,
onDidChangeCollapseState: Event<ICollapseStateChangeEvent<T, TFilterData>>,
private activeNodes: Collection<ITreeNode<T, TFilterData>>,
options: ITreeRendererOptions = {}
Expand Down Expand Up @@ -381,10 +389,19 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IListRenderer<ITree
}

const disposableStore = new DisposableStore();
const model = this.modelProvider();

let node = target;

while (node.parent && node.parent.parent) {
const parent = node.parent;
while (true) {
const ref = model.getNodeLocation(node);
const parentRef = model.getParentNodeLocation(ref);

if (!parentRef) {
break;
}

const parent = model.getNode(parentRef);
const guide = $<HTMLDivElement>('.indent-guide', { style: `width: ${this.indent}px` });

if (this.activeIndentNodes.has(parent)) {
Expand Down Expand Up @@ -412,12 +429,16 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IListRenderer<ITree
}

const set = new Set<ITreeNode<T, TFilterData>>();
const model = this.modelProvider();

nodes.forEach(node => {
const ref = model.getNodeLocation(node);
const parentRef = model.getParentNodeLocation(ref);

if (node.collapsible && node.children.length > 0 && !node.collapsed) {
set.add(node);
} else if (node.parent) {
set.add(node.parent);
} else if (parentRef) {
set.add(model.getNode(parentRef));
}
});

Expand Down Expand Up @@ -1153,7 +1174,7 @@ class TreeNodeList<T, TFilterData, TRef> extends List<ITreeNode<T, TFilterData>>
export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable {

protected view: TreeNodeList<T, TFilterData, TRef>;
private renderers: TreeRenderer<T, TFilterData, any>[];
private renderers: TreeRenderer<T, TFilterData, TRef, any>[];
protected model: ITreeModel<T, TFilterData, TRef>;
private focus: Trait<T>;
private selection: Trait<T>;
Expand Down Expand Up @@ -1211,7 +1232,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
const activeNodes = new EventCollection(onDidChangeActiveNodes.event);
this.disposables.push(activeNodes);

this.renderers = renderers.map(r => new TreeRenderer<T, TFilterData, any>(r, onDidChangeCollapseStateRelay.event, activeNodes, _options));
this.renderers = renderers.map(r => new TreeRenderer<T, TFilterData, TRef, any>(r, () => this.model, onDidChangeCollapseStateRelay.event, activeNodes, _options));
this.disposables.push(...this.renderers);

let filter: TypeFilter<T> | undefined;
Expand Down Expand Up @@ -1383,7 +1404,9 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
// Tree navigation

getParentElement(location: TRef): T {
return this.model.getParentElement(location);
const parentRef = this.model.getParentNodeLocation(location);
const parentNode = this.model.getNode(parentRef);
return parentNode.element;
}

getFirstElementChild(location: TRef): T | undefined {
Expand Down Expand Up @@ -1539,7 +1562,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
if (!didChange) {
const parentLocation = this.model.getParentNodeLocation(location);

if (parentLocation === null) {
if (!parentLocation) {
return;
}

Expand Down Expand Up @@ -1641,22 +1664,6 @@ class TreeNavigator<T extends NonNullable<any>, TFilterData, TRef> implements IT
return this.current();
}

parent(): T | null {
if (this.index < 0 || this.index >= this.view.length) {
return null;
}

const node = this.view.element(this.index);

if (!node.parent) {
this.index = -1;
return this.current();
}

this.index = this.model.getListIndex(this.model.getNodeLocation(node.parent));
return this.current();
}

first(): T | null {
this.index = 0;
return this.current();
Expand Down
Loading

0 comments on commit 4f39995

Please sign in to comment.