@selenite/graph-editor
Version:
A graph editor for visual programming, based on rete and svelte.
81 lines (80 loc) • 2.78 kB
JavaScript
import { BaseComponent } from '../components';
import wu from 'wu';
import { Layout, Vector2D } from '@selenite/commons';
export class NodeLayout extends BaseComponent {
async applyOffsets(nodes, offsets) {
if (!this.owner.area) {
console.error("Can't apply offsets, no area.");
return;
}
for (const [node, offset] of wu.zip(nodes, offsets)) {
const view = this.owner.area.nodeViews.get(node.id);
if (!view) {
console.error('Missing view for node.');
continue;
}
const newPos = Vector2D.add(view.position, offset);
await this.owner.area.translate(node.id, newPos);
}
}
getLayoutRectsAndRefPos() {
if (!this.owner.area) {
console.error("Can't get layout rects, no area.");
return { rects: [], refPos: 0 };
}
const selectedNodes = this.owner.selector.nodes;
const pickedNode = this.owner.selector.pickedNode;
const rects = [];
let refPos = 0;
for (const [i, node] of selectedNodes.entries()) {
const view = this.owner.area.nodeViews.get(node.id);
if (!view) {
console.error('Missing view for node.');
continue;
}
const boundingRect = view.element.getBoundingClientRect();
rects.push({
x: view.position.x,
y: view.position.y,
h: node.height,
w: node.width
});
if (node === pickedNode) {
refPos = i;
}
}
return { rects, refPos };
}
getOffsets(offsetFunction) {
const { rects, refPos } = this.getLayoutRectsAndRefPos();
return offsetFunction(rects, { refPos });
}
applyLayout(offsetFunction) {
const offsets = this.getOffsets(offsetFunction);
return this.applyOffsets(this.owner.selector.nodes, offsets);
}
justifyLeft() {
return this.applyLayout(Layout.getJustifyLeftOffsets);
}
justifyRight() {
return this.applyLayout(Layout.getJustifyRightOffsets);
}
justifyCenter() {
return this.applyLayout(Layout.getJustifyCenterOffsets);
}
justifyBetween() {
return this.applyLayout((rects) => Layout.getJustifyBetweenOffsets(rects));
}
alignTop() {
return this.applyLayout(Layout.getAlignTopOffsets);
}
alignMiddle() {
return this.applyLayout(Layout.getAlignMiddleOffsets);
}
alignBottom() {
return this.applyLayout(Layout.getAlignBottomOffsets);
}
spaceVertical() {
return this.applyLayout((rects) => Layout.getAlignBetweenOffsets(rects));
}
}