Canvas: Tree View Navigation (#51855)

* tree navigation using rc-tree library
This commit is contained in:
Adela Almasan
2022-07-12 08:31:02 -05:00
committed by GitHub
parent db9c9b5354
commit c73d78eaac
13 changed files with 621 additions and 23 deletions
+14 -1
View File
@@ -74,6 +74,19 @@ export class FrameState extends ElementState {
this.reinitializeMoveable();
}
// used for tree view
reorderTree(src: ElementState, dest: ElementState, firstPosition = false) {
const result = Array.from(this.elements);
const srcIndex = this.elements.indexOf(src);
const destIndex = firstPosition ? this.elements.length - 1 : this.elements.indexOf(dest);
const [removed] = result.splice(srcIndex, 1);
result.splice(destIndex, 0, removed);
this.elements = result;
this.reinitializeMoveable();
}
doMove(child: ElementState, action: LayerActionID) {
const vals = this.elements.filter((v) => v !== child);
if (action === LayerActionID.MoveBottom) {
@@ -176,7 +189,7 @@ export class FrameState extends ElementState {
render() {
return (
<div key={this.UID} ref={this.initElement} style={{ overflow: 'hidden' }}>
<div key={this.UID} ref={this.initElement}>
{this.elements.map((v) => v.render())}
</div>
);
@@ -417,6 +417,65 @@ export class Scene {
});
};
reorderElements = (src: ElementState, dest: ElementState, dragToGap: boolean, destPosition: number) => {
switch (dragToGap) {
case true:
switch (destPosition) {
case -1:
// top of the tree
if (src.parent instanceof FrameState) {
// move outside the frame
if (dest.parent) {
this.updateElements(src, dest.parent, dest.parent.elements.length);
src.updateData(dest.parent.scene.context);
}
} else {
dest.parent?.reorderTree(src, dest, true);
}
break;
default:
if (dest.parent) {
this.updateElements(src, dest.parent, dest.parent.elements.indexOf(dest));
src.updateData(dest.parent.scene.context);
}
break;
}
break;
case false:
if (dest instanceof FrameState) {
if (src.parent === dest) {
// same frame parent
src.parent?.reorderTree(src, dest, true);
} else {
this.updateElements(src, dest);
src.updateData(dest.scene.context);
}
} else if (src.parent === dest.parent) {
src.parent?.reorderTree(src, dest);
} else {
if (dest.parent) {
this.updateElements(src, dest.parent);
src.updateData(dest.parent.scene.context);
}
}
break;
}
};
private updateElements = (src: ElementState, dest: FrameState | RootElement, idx: number | null = null) => {
src.parent?.doAction(LayerActionID.Delete, src);
src.parent = dest;
const elementContainer = src.div?.getBoundingClientRect();
src.setPlacementFromConstraint(elementContainer, dest.div?.getBoundingClientRect());
const destIndex = idx ?? dest.elements.length - 1;
dest.elements.splice(destIndex, 0, src);
dest.scene.save();
dest.reinitializeMoveable();
};
render() {
const canShowContextMenu = this.isPanelEditing || (!this.isPanelEditing && this.isEditingEnabled);