@ngroznykh/papirus 0.8.4 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/ConnectionManager.d.ts +12 -2
- package/dist/core/ConnectionManager.d.ts.map +1 -1
- package/dist/core/HistoryManager.d.ts +1 -1
- package/dist/core/HistoryManager.d.ts.map +1 -1
- package/dist/core/InteractionManager.d.ts +2 -0
- package/dist/core/InteractionManager.d.ts.map +1 -1
- package/dist/core/history/commands.d.ts +22 -0
- package/dist/core/history/commands.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/papirus.js +292 -29
- package/dist/papirus.js.map +1 -1
- package/dist/utils/outlineConnectHandle.d.ts +18 -0
- package/dist/utils/outlineConnectHandle.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/papirus.js
CHANGED
|
@@ -1731,6 +1731,101 @@ function directionToVector(dir) {
|
|
|
1731
1731
|
};
|
|
1732
1732
|
}
|
|
1733
1733
|
}
|
|
1734
|
+
function clamp$1(value, min, max) {
|
|
1735
|
+
return Math.max(min, Math.min(max, value));
|
|
1736
|
+
}
|
|
1737
|
+
function dist(a, b) {
|
|
1738
|
+
return Math.hypot(a.x - b.x, a.y - b.y);
|
|
1739
|
+
}
|
|
1740
|
+
function closestPointOnRectSide(bounds, side, pointer) {
|
|
1741
|
+
const { x, y, width, height } = bounds;
|
|
1742
|
+
switch (side) {
|
|
1743
|
+
case "top": return {
|
|
1744
|
+
x: clamp$1(pointer.x, x, x + width),
|
|
1745
|
+
y
|
|
1746
|
+
};
|
|
1747
|
+
case "bottom": return {
|
|
1748
|
+
x: clamp$1(pointer.x, x, x + width),
|
|
1749
|
+
y: y + height
|
|
1750
|
+
};
|
|
1751
|
+
case "left": return {
|
|
1752
|
+
x,
|
|
1753
|
+
y: clamp$1(pointer.y, y, y + height)
|
|
1754
|
+
};
|
|
1755
|
+
case "right": return {
|
|
1756
|
+
x: x + width,
|
|
1757
|
+
y: clamp$1(pointer.y, y, y + height)
|
|
1758
|
+
};
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
function closestPointOnRectOutline(bounds, pointer) {
|
|
1762
|
+
const sides = [
|
|
1763
|
+
"top",
|
|
1764
|
+
"right",
|
|
1765
|
+
"bottom",
|
|
1766
|
+
"left"
|
|
1767
|
+
];
|
|
1768
|
+
let side = sides[0];
|
|
1769
|
+
let point = closestPointOnRectSide(bounds, side, pointer);
|
|
1770
|
+
let best = dist(pointer, point);
|
|
1771
|
+
for (let i = 1; i < sides.length; i++) {
|
|
1772
|
+
const nextSide = sides[i];
|
|
1773
|
+
const nextPoint = closestPointOnRectSide(bounds, nextSide, pointer);
|
|
1774
|
+
const nextDist = dist(pointer, nextPoint);
|
|
1775
|
+
if (nextDist < best) {
|
|
1776
|
+
side = nextSide;
|
|
1777
|
+
point = nextPoint;
|
|
1778
|
+
best = nextDist;
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
return {
|
|
1782
|
+
side,
|
|
1783
|
+
point
|
|
1784
|
+
};
|
|
1785
|
+
}
|
|
1786
|
+
function getOutlineConnectHandle(bounds, pointer, offset, prevSide, hysteresis = 8) {
|
|
1787
|
+
const closest = closestPointOnRectOutline(bounds, pointer);
|
|
1788
|
+
let side = closest.side;
|
|
1789
|
+
let attach = closest.point;
|
|
1790
|
+
if (prevSide && prevSide !== closest.side) {
|
|
1791
|
+
const stay = closestPointOnRectSide(bounds, prevSide, pointer);
|
|
1792
|
+
if (dist(pointer, stay) <= dist(pointer, closest.point) + hysteresis) {
|
|
1793
|
+
side = prevSide;
|
|
1794
|
+
attach = stay;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
if (offset === 0) return {
|
|
1798
|
+
side,
|
|
1799
|
+
attach,
|
|
1800
|
+
handle: attach
|
|
1801
|
+
};
|
|
1802
|
+
const delta = {
|
|
1803
|
+
top: {
|
|
1804
|
+
x: 0,
|
|
1805
|
+
y: -offset
|
|
1806
|
+
},
|
|
1807
|
+
right: {
|
|
1808
|
+
x: offset,
|
|
1809
|
+
y: 0
|
|
1810
|
+
},
|
|
1811
|
+
bottom: {
|
|
1812
|
+
x: 0,
|
|
1813
|
+
y: offset
|
|
1814
|
+
},
|
|
1815
|
+
left: {
|
|
1816
|
+
x: -offset,
|
|
1817
|
+
y: 0
|
|
1818
|
+
}
|
|
1819
|
+
}[side];
|
|
1820
|
+
return {
|
|
1821
|
+
side,
|
|
1822
|
+
attach,
|
|
1823
|
+
handle: {
|
|
1824
|
+
x: attach.x + delta.x,
|
|
1825
|
+
y: attach.y + delta.y
|
|
1826
|
+
}
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1734
1829
|
//#endregion
|
|
1735
1830
|
//#region src/core/ConnectionManager.ts
|
|
1736
1831
|
/**
|
|
@@ -1747,6 +1842,9 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
1747
1842
|
this.sourceAnchorId = null;
|
|
1748
1843
|
this.hoverNodeId = null;
|
|
1749
1844
|
this.hoverAnchorId = null;
|
|
1845
|
+
this.hoverPoint = null;
|
|
1846
|
+
this.hoverOutlineHandle = false;
|
|
1847
|
+
this.hoverOutlineSide = null;
|
|
1750
1848
|
this.hoverDisabled = false;
|
|
1751
1849
|
this.reconnectPoint = null;
|
|
1752
1850
|
this.previewTargetAnchorId = null;
|
|
@@ -1808,9 +1906,12 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
1808
1906
|
*/
|
|
1809
1907
|
clearPointerHover() {
|
|
1810
1908
|
if (this.hoverDisabled) return;
|
|
1811
|
-
if (this.hoverNodeId !== null || this.hoverAnchorId !== null) {
|
|
1909
|
+
if (this.hoverNodeId !== null || this.hoverAnchorId !== null || this.hoverOutlineHandle) {
|
|
1812
1910
|
this.hoverNodeId = null;
|
|
1813
1911
|
this.hoverAnchorId = null;
|
|
1912
|
+
this.hoverPoint = null;
|
|
1913
|
+
this.hoverOutlineSide = null;
|
|
1914
|
+
this.clearOutlineHandleCursor();
|
|
1814
1915
|
this.renderer.markDirty();
|
|
1815
1916
|
}
|
|
1816
1917
|
}
|
|
@@ -1837,9 +1938,12 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
1837
1938
|
*/
|
|
1838
1939
|
disableHover() {
|
|
1839
1940
|
this.hoverDisabled = true;
|
|
1840
|
-
if (this.hoverNodeId !== null || this.hoverAnchorId !== null) {
|
|
1941
|
+
if (this.hoverNodeId !== null || this.hoverAnchorId !== null || this.hoverOutlineHandle) {
|
|
1841
1942
|
this.hoverNodeId = null;
|
|
1842
1943
|
this.hoverAnchorId = null;
|
|
1944
|
+
this.hoverPoint = null;
|
|
1945
|
+
this.hoverOutlineSide = null;
|
|
1946
|
+
this.clearOutlineHandleCursor();
|
|
1843
1947
|
this.renderer.markDirty();
|
|
1844
1948
|
}
|
|
1845
1949
|
}
|
|
@@ -1851,7 +1955,7 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
1851
1955
|
}
|
|
1852
1956
|
/**
|
|
1853
1957
|
* Try to start connection from a hovered anchor point.
|
|
1854
|
-
* When attachToOutline
|
|
1958
|
+
* When attachToOutline: drag the outline handle, or Shift+drag from the node body.
|
|
1855
1959
|
* Otherwise: requires clicking on an anchor/port so that node drag still works.
|
|
1856
1960
|
*/
|
|
1857
1961
|
tryStartConnectionAtPoint(event) {
|
|
@@ -1860,18 +1964,18 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
1860
1964
|
x: event.worldX,
|
|
1861
1965
|
y: event.worldY
|
|
1862
1966
|
};
|
|
1967
|
+
if (this.attachToOutline) {
|
|
1968
|
+
const handleHit = this.findOutlineConnectHandleAt(point);
|
|
1969
|
+
if (handleHit) {
|
|
1970
|
+
this.startOutlineConnection(handleHit.node, handleHit.attach);
|
|
1971
|
+
return true;
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1863
1974
|
const node = this.getNodeAtPoint(point, false);
|
|
1864
1975
|
if (!node) return false;
|
|
1865
1976
|
if (this.attachToOutline && event.shiftKey) {
|
|
1866
|
-
const { point: outlinePoint
|
|
1867
|
-
this.
|
|
1868
|
-
this.isConnecting = true;
|
|
1869
|
-
this.sourceAnchorId = null;
|
|
1870
|
-
this.sourcePoint = outlinePoint;
|
|
1871
|
-
this.sourceOutlineParam = param;
|
|
1872
|
-
this.previewEndpoint = point;
|
|
1873
|
-
this.emit("connectionStart", node);
|
|
1874
|
-
this.renderer.markDirty();
|
|
1977
|
+
const { point: outlinePoint } = node.getClosestPointOnOutline(point);
|
|
1978
|
+
this.startOutlineConnection(node, outlinePoint);
|
|
1875
1979
|
return true;
|
|
1876
1980
|
}
|
|
1877
1981
|
const hover = this.getAnchorAtPoint(node, point);
|
|
@@ -2473,7 +2577,10 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2473
2577
|
renderHoverAnchors(ctx) {
|
|
2474
2578
|
if (this.isConnecting || this.isReconnecting) return;
|
|
2475
2579
|
this.renderEditablePolylineControls(ctx);
|
|
2476
|
-
if (this.attachToOutline)
|
|
2580
|
+
if (this.attachToOutline) {
|
|
2581
|
+
this.renderOutlineConnectHandle(ctx);
|
|
2582
|
+
return;
|
|
2583
|
+
}
|
|
2477
2584
|
if (!this.hoverNodeId) return;
|
|
2478
2585
|
const node = this.renderer.getNode(this.hoverNodeId);
|
|
2479
2586
|
if (!node) return;
|
|
@@ -2488,7 +2595,7 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2488
2595
|
ctx.beginPath();
|
|
2489
2596
|
ctx.arc(anchor.point.x, anchor.point.y, radius, 0, Math.PI * 2);
|
|
2490
2597
|
ctx.fill();
|
|
2491
|
-
if (isHovered) this.drawPlus(radius, ctx, anchor);
|
|
2598
|
+
if (isHovered) this.drawPlus(radius, ctx, anchor.point);
|
|
2492
2599
|
}
|
|
2493
2600
|
ctx.restore();
|
|
2494
2601
|
}
|
|
@@ -2507,6 +2614,7 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2507
2614
|
if (edge.state !== "selected" || !edge.isEditablePolyline()) continue;
|
|
2508
2615
|
const controlPoints = edge.getEditableControlPoints();
|
|
2509
2616
|
if (controlPoints.length === 0) continue;
|
|
2617
|
+
const beforePoints = edge.controlPoints?.length ? clonePoints(edge.controlPoints) : clonePoints(controlPoints);
|
|
2510
2618
|
for (let i = 0; i < controlPoints.length; i++) {
|
|
2511
2619
|
const dx = point.x - controlPoints[i].x;
|
|
2512
2620
|
const dy = point.y - controlPoints[i].y;
|
|
@@ -2516,7 +2624,7 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2516
2624
|
edge,
|
|
2517
2625
|
index: i
|
|
2518
2626
|
};
|
|
2519
|
-
this.emit("controlPointDragStart");
|
|
2627
|
+
this.emit("controlPointDragStart", edge, beforePoints);
|
|
2520
2628
|
this.renderer.markDirty();
|
|
2521
2629
|
return true;
|
|
2522
2630
|
}
|
|
@@ -2532,7 +2640,7 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2532
2640
|
edge,
|
|
2533
2641
|
index: insertControl.index
|
|
2534
2642
|
};
|
|
2535
|
-
this.emit("controlPointDragStart");
|
|
2643
|
+
this.emit("controlPointDragStart", edge, beforePoints);
|
|
2536
2644
|
this.renderer.markDirty();
|
|
2537
2645
|
return true;
|
|
2538
2646
|
}
|
|
@@ -2638,15 +2746,15 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2638
2746
|
y
|
|
2639
2747
|
};
|
|
2640
2748
|
}
|
|
2641
|
-
drawPlus(radius, ctx,
|
|
2749
|
+
drawPlus(radius, ctx, point) {
|
|
2642
2750
|
const plusSize = radius * .5;
|
|
2643
2751
|
ctx.strokeStyle = "#ffffff";
|
|
2644
2752
|
ctx.lineWidth = 1.5;
|
|
2645
2753
|
ctx.beginPath();
|
|
2646
|
-
ctx.moveTo(
|
|
2647
|
-
ctx.lineTo(
|
|
2648
|
-
ctx.moveTo(
|
|
2649
|
-
ctx.lineTo(
|
|
2754
|
+
ctx.moveTo(point.x - plusSize, point.y);
|
|
2755
|
+
ctx.lineTo(point.x + plusSize, point.y);
|
|
2756
|
+
ctx.moveTo(point.x, point.y - plusSize);
|
|
2757
|
+
ctx.lineTo(point.x, point.y + plusSize);
|
|
2650
2758
|
ctx.stroke();
|
|
2651
2759
|
}
|
|
2652
2760
|
renderAnchorHighlights(ctx, point, reconnecting) {
|
|
@@ -2667,7 +2775,7 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2667
2775
|
ctx.arc(anchor.point.x, anchor.point.y, radius, 0, Math.PI * 2);
|
|
2668
2776
|
ctx.fill();
|
|
2669
2777
|
if (isNearest) if (forbidden) this.drawCross(radius, ctx, anchor);
|
|
2670
|
-
else this.drawPlus(radius, ctx, anchor);
|
|
2778
|
+
else this.drawPlus(radius, ctx, anchor.point);
|
|
2671
2779
|
}
|
|
2672
2780
|
ctx.restore();
|
|
2673
2781
|
}
|
|
@@ -2692,19 +2800,94 @@ var ConnectionManager = class extends EventEmitter {
|
|
|
2692
2800
|
}
|
|
2693
2801
|
return null;
|
|
2694
2802
|
}
|
|
2803
|
+
startOutlineConnection(node, attach) {
|
|
2804
|
+
const { point: outlinePoint, param } = node.getClosestPointOnOutline(attach);
|
|
2805
|
+
this.sourceNode = node;
|
|
2806
|
+
this.isConnecting = true;
|
|
2807
|
+
this.sourceAnchorId = null;
|
|
2808
|
+
this.sourcePoint = outlinePoint;
|
|
2809
|
+
this.sourceOutlineParam = param;
|
|
2810
|
+
this.previewEndpoint = attach;
|
|
2811
|
+
this.emit("connectionStart", node);
|
|
2812
|
+
this.renderer.markDirty();
|
|
2813
|
+
}
|
|
2814
|
+
outlineHandleHysteresis() {
|
|
2815
|
+
return 8 / Math.max(this.renderer.zoom, 1e-4);
|
|
2816
|
+
}
|
|
2817
|
+
outlineConnectHandleFor(node, pointer) {
|
|
2818
|
+
const prevSide = node.id === this.hoverNodeId ? this.hoverOutlineSide : null;
|
|
2819
|
+
const geom = getOutlineConnectHandle(node.getBounds(), pointer, 0, prevSide, this.outlineHandleHysteresis());
|
|
2820
|
+
const { point: onOutline } = node.getClosestPointOnOutline(geom.attach);
|
|
2821
|
+
return {
|
|
2822
|
+
attach: onOutline,
|
|
2823
|
+
handle: onOutline,
|
|
2824
|
+
side: geom.side
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
outlineHandleHitRadius() {
|
|
2828
|
+
return 10 / Math.max(this.renderer.zoom, 1e-4);
|
|
2829
|
+
}
|
|
2830
|
+
findOutlineConnectHandleAt(point) {
|
|
2831
|
+
if (!this.attachToOutline) return null;
|
|
2832
|
+
const radiusSq = this.outlineHandleHitRadius() ** 2;
|
|
2833
|
+
const nodes = Array.from(this.renderer.nodes.values());
|
|
2834
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
2835
|
+
const node = nodes[i];
|
|
2836
|
+
if (!node.visible || !this.isCompatibleTarget(node)) continue;
|
|
2837
|
+
const { attach, handle } = this.outlineConnectHandleFor(node, point);
|
|
2838
|
+
const dx = point.x - handle.x;
|
|
2839
|
+
const dy = point.y - handle.y;
|
|
2840
|
+
if (dx * dx + dy * dy <= radiusSq) return {
|
|
2841
|
+
node,
|
|
2842
|
+
attach,
|
|
2843
|
+
handle
|
|
2844
|
+
};
|
|
2845
|
+
}
|
|
2846
|
+
return null;
|
|
2847
|
+
}
|
|
2848
|
+
renderOutlineConnectHandle(ctx) {
|
|
2849
|
+
if (!this.hoverNodeId || !this.hoverPoint) return;
|
|
2850
|
+
const node = this.renderer.getNode(this.hoverNodeId);
|
|
2851
|
+
if (!node) return;
|
|
2852
|
+
const { handle } = this.outlineConnectHandleFor(node, this.hoverPoint);
|
|
2853
|
+
const radius = this.hoverOutlineHandle ? 6 : 4;
|
|
2854
|
+
ctx.save();
|
|
2855
|
+
ctx.setLineDash([]);
|
|
2856
|
+
ctx.fillStyle = "#3b82f6";
|
|
2857
|
+
ctx.beginPath();
|
|
2858
|
+
ctx.arc(handle.x, handle.y, radius, 0, Math.PI * 2);
|
|
2859
|
+
ctx.fill();
|
|
2860
|
+
this.drawPlus(radius, ctx, handle);
|
|
2861
|
+
ctx.restore();
|
|
2862
|
+
}
|
|
2863
|
+
clearOutlineHandleCursor() {
|
|
2864
|
+
if (this.hoverOutlineHandle) {
|
|
2865
|
+
this.hoverOutlineHandle = false;
|
|
2866
|
+
this.setCursor("");
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2695
2869
|
updateHover(point) {
|
|
2696
2870
|
if (this.hoverDisabled) return;
|
|
2697
|
-
const
|
|
2871
|
+
const handleHit = this.findOutlineConnectHandleAt(point);
|
|
2872
|
+
const node = handleHit?.node ?? this.getNodeAtPoint(point, false);
|
|
2698
2873
|
const prevNodeId = this.hoverNodeId;
|
|
2699
2874
|
const prevAnchorId = this.hoverAnchorId;
|
|
2875
|
+
const prevOutlineHandle = this.hoverOutlineHandle;
|
|
2876
|
+
this.hoverPoint = node ? point : null;
|
|
2700
2877
|
if (!node) {
|
|
2701
2878
|
this.hoverNodeId = null;
|
|
2702
2879
|
this.hoverAnchorId = null;
|
|
2880
|
+
this.hoverOutlineSide = null;
|
|
2881
|
+
this.clearOutlineHandleCursor();
|
|
2703
2882
|
} else {
|
|
2704
2883
|
this.hoverNodeId = node.id;
|
|
2705
|
-
this.hoverAnchorId = this.getAnchorAtPoint(node, point)?.id ?? null;
|
|
2884
|
+
this.hoverAnchorId = handleHit ? null : this.getAnchorAtPoint(node, point)?.id ?? null;
|
|
2885
|
+
this.hoverOutlineHandle = handleHit !== null;
|
|
2886
|
+
if (this.attachToOutline) this.hoverOutlineSide = this.outlineConnectHandleFor(node, point).side;
|
|
2887
|
+
if (this.hoverOutlineHandle) this.setCursor("crosshair");
|
|
2888
|
+
else if (prevOutlineHandle) this.setCursor("");
|
|
2706
2889
|
}
|
|
2707
|
-
if (prevNodeId !== this.hoverNodeId || prevAnchorId !== this.hoverAnchorId) this.renderer.markDirty();
|
|
2890
|
+
if (prevNodeId !== this.hoverNodeId || prevAnchorId !== this.hoverAnchorId || prevOutlineHandle !== this.hoverOutlineHandle || this.attachToOutline && node !== null) this.renderer.markDirty();
|
|
2708
2891
|
}
|
|
2709
2892
|
getAnchorAtPoint(node, point) {
|
|
2710
2893
|
const anchorIds = !this.attachToOutline && node.ports.length > 0 ? node.getPortAnchorIds() : null;
|
|
@@ -3195,6 +3378,32 @@ var MoveNodesCommand = class {
|
|
|
3195
3378
|
}
|
|
3196
3379
|
}
|
|
3197
3380
|
};
|
|
3381
|
+
var ResizeNodesCommand = class {
|
|
3382
|
+
constructor(getNode, changes) {
|
|
3383
|
+
this.getNode = getNode;
|
|
3384
|
+
this.changes = new Map(Array.from(changes.entries()).map(([id, v]) => [id, {
|
|
3385
|
+
before: { ...v.before },
|
|
3386
|
+
after: { ...v.after }
|
|
3387
|
+
}]));
|
|
3388
|
+
}
|
|
3389
|
+
execute() {
|
|
3390
|
+
this.apply("after");
|
|
3391
|
+
}
|
|
3392
|
+
undo() {
|
|
3393
|
+
this.apply("before");
|
|
3394
|
+
}
|
|
3395
|
+
apply(which) {
|
|
3396
|
+
for (const [id, bounds] of this.changes) {
|
|
3397
|
+
const node = this.getNode(id);
|
|
3398
|
+
if (node === void 0) continue;
|
|
3399
|
+
const next = bounds[which];
|
|
3400
|
+
node.x = next.x;
|
|
3401
|
+
node.y = next.y;
|
|
3402
|
+
node.width = next.width;
|
|
3403
|
+
node.height = next.height;
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
};
|
|
3198
3407
|
/**
|
|
3199
3408
|
* Restores editable-polyline control points on undo (used with node drag composite).
|
|
3200
3409
|
*/
|
|
@@ -3209,13 +3418,13 @@ var ChangeEditablePolylineControlPointsCommand = class {
|
|
|
3209
3418
|
execute() {
|
|
3210
3419
|
for (const [id, { after }] of this.changes) {
|
|
3211
3420
|
const edge = this.getEdge(id);
|
|
3212
|
-
if (edge?.isEditablePolyline()) edge.controlPoints = clonePoints(after);
|
|
3421
|
+
if (edge?.isEditablePolyline()) edge.controlPoints = after.length > 0 ? clonePoints(after) : void 0;
|
|
3213
3422
|
}
|
|
3214
3423
|
}
|
|
3215
3424
|
undo() {
|
|
3216
3425
|
for (const [id, { before }] of this.changes) {
|
|
3217
3426
|
const edge = this.getEdge(id);
|
|
3218
|
-
if (edge?.isEditablePolyline()) edge.controlPoints = clonePoints(before);
|
|
3427
|
+
if (edge?.isEditablePolyline()) edge.controlPoints = before.length > 0 ? clonePoints(before) : void 0;
|
|
3219
3428
|
}
|
|
3220
3429
|
}
|
|
3221
3430
|
};
|
|
@@ -7210,6 +7419,8 @@ var InteractionManager = class {
|
|
|
7210
7419
|
this.overlayCleanup = null;
|
|
7211
7420
|
this.dragStartPositions = /* @__PURE__ */ new Map();
|
|
7212
7421
|
this.dragStartEditablePolylinePoints = /* @__PURE__ */ new Map();
|
|
7422
|
+
this.controlPointGestureBefore = /* @__PURE__ */ new Map();
|
|
7423
|
+
this.resizeStartBounds = null;
|
|
7213
7424
|
this.reconnectOrigins = /* @__PURE__ */ new Map();
|
|
7214
7425
|
this.labelEditor = new LabelEditor();
|
|
7215
7426
|
this.scrollbarDragState = null;
|
|
@@ -7495,6 +7706,42 @@ var InteractionManager = class {
|
|
|
7495
7706
|
});
|
|
7496
7707
|
this.reconnectOrigins.delete(edge.id);
|
|
7497
7708
|
});
|
|
7709
|
+
this.resizeManager.on("resizeStart", (_nodeId, _handle, startBounds) => {
|
|
7710
|
+
this.resizeStartBounds = { ...startBounds };
|
|
7711
|
+
});
|
|
7712
|
+
this.resizeManager.on("resizeEnd", (nodeId, bounds) => {
|
|
7713
|
+
const before = this.resizeStartBounds;
|
|
7714
|
+
this.resizeStartBounds = null;
|
|
7715
|
+
if (!before) return;
|
|
7716
|
+
if (before.x === bounds.x && before.y === bounds.y && before.width === bounds.width && before.height === bounds.height) return;
|
|
7717
|
+
this.historyManager.execute(new ResizeNodesCommand((id) => this.renderer.getNode(id), new Map([[nodeId, {
|
|
7718
|
+
before: { ...before },
|
|
7719
|
+
after: {
|
|
7720
|
+
x: bounds.x,
|
|
7721
|
+
y: bounds.y,
|
|
7722
|
+
width: bounds.width,
|
|
7723
|
+
height: bounds.height
|
|
7724
|
+
}
|
|
7725
|
+
}]])));
|
|
7726
|
+
});
|
|
7727
|
+
this.connectionManager.on("controlPointDragStart", (edge, before) => {
|
|
7728
|
+
this.controlPointGestureBefore.set(edge.id, clonePoints(before));
|
|
7729
|
+
});
|
|
7730
|
+
this.connectionManager.on("controlPointDragEnd", () => {
|
|
7731
|
+
const changes = /* @__PURE__ */ new Map();
|
|
7732
|
+
for (const [id, before] of this.controlPointGestureBefore) {
|
|
7733
|
+
const edge = this.renderer.getEdge(id);
|
|
7734
|
+
if (!edge?.isEditablePolyline()) continue;
|
|
7735
|
+
const after = clonePoints(edge.controlPoints ?? []);
|
|
7736
|
+
if (!this.editablePolylinePointsEqual(before, after)) changes.set(id, {
|
|
7737
|
+
before: clonePoints(before),
|
|
7738
|
+
after
|
|
7739
|
+
});
|
|
7740
|
+
}
|
|
7741
|
+
this.controlPointGestureBefore.clear();
|
|
7742
|
+
if (changes.size === 0) return;
|
|
7743
|
+
this.historyManager.execute(new ChangeEditablePolylineControlPointsCommand((id) => this.renderer.getEdge(id), changes));
|
|
7744
|
+
});
|
|
7498
7745
|
}
|
|
7499
7746
|
this.historyManager.on("change", () => {
|
|
7500
7747
|
this.renderer.markDirty();
|
|
@@ -7653,7 +7900,23 @@ var InteractionManager = class {
|
|
|
7653
7900
|
if (this.renderer.blocksDiagramPointerAtScreen(event.screenX, event.screenY)) return;
|
|
7654
7901
|
if (this.dragManager.handledMouseDown || this.resizeManager.handledMouseDown || this.connectionManager.connecting) return;
|
|
7655
7902
|
if (this.navigationOnly) return;
|
|
7656
|
-
|
|
7903
|
+
const polylineBeforeByEdge = /* @__PURE__ */ new Map();
|
|
7904
|
+
for (const edge of this.renderer.edges.values()) {
|
|
7905
|
+
if (edge.state !== "selected" || !edge.isEditablePolyline()) continue;
|
|
7906
|
+
polylineBeforeByEdge.set(edge.id, clonePoints(edge.controlPoints?.length ? edge.controlPoints : edge.getEditableControlPoints()));
|
|
7907
|
+
}
|
|
7908
|
+
if (this.connectionManager.handleDoubleClick(event)) {
|
|
7909
|
+
const changes = /* @__PURE__ */ new Map();
|
|
7910
|
+
for (const [id, before] of polylineBeforeByEdge) {
|
|
7911
|
+
const after = clonePoints(this.renderer.getEdge(id)?.controlPoints ?? []);
|
|
7912
|
+
if (!this.editablePolylinePointsEqual(before, after)) changes.set(id, {
|
|
7913
|
+
before: clonePoints(before),
|
|
7914
|
+
after
|
|
7915
|
+
});
|
|
7916
|
+
}
|
|
7917
|
+
if (changes.size > 0) this.historyManager.execute(new ChangeEditablePolylineControlPointsCommand((id) => this.renderer.getEdge(id), changes));
|
|
7918
|
+
return;
|
|
7919
|
+
}
|
|
7657
7920
|
const point = {
|
|
7658
7921
|
x: event.worldX,
|
|
7659
7922
|
y: event.worldY
|
|
@@ -15281,6 +15544,6 @@ function applyEdgeStyle(ctx, style) {
|
|
|
15281
15544
|
return baseOpacity * strokeOpacity;
|
|
15282
15545
|
}
|
|
15283
15546
|
//#endregion
|
|
15284
|
-
export { AddNodeCommand, AnimationManager, AutoLayout, AutoRouting, BezierPathStrategy, CContainer, CDivider, CIcon, CShape, CText, ChangeEdgePropertiesCommand, ChangeEditablePolylineControlPointsCommand, ChangeGroupPropertiesCommand, ChangeNodePropertiesCommand, CircleNode, ClipboardManager, CompositeCommand, CompositeNode, ConnectionManager, ContextMenuManager, CustomShapeNode, DARK_THEME, DEFAULT_THEME, DiagramRenderer, DiamondNode, DragManager, Edge, Element, EventEmitter, GridOverlay, Group, GuidesOverlay, HistoryManager, ImageExporter, InputHandler, InteractionManager, MiniMap, MoveNodesCommand, NavigationManager, Node, NodeImage, PolylinePathStrategy, Port, PropertyChangeBatcher, RectangleNode, RemoveNodeCommand, ResizeManager, RulersOverlay, SearchManager, SelectionManager, Serializer, ShapeFactories, StraightPathStrategy, StyleManager, SvgExporter, TextLabel, alignNodes, angle, applyEdgeStyle, applyNodeStyle, bezierPoint, boundsCenter, calculateBezierControlPoints, clamp, clonePoints, container, deserializeCComponent, directionFromAngle, distance, distanceToSegment, distributeNodes, divider, drawRoundedRectPath, expandBounds, flexLayout, generateId, getClosestPointOnPath, getPathPointAt, icon, isCornerPlacement, isEdgeEdgeEndpoint, isNodeEdgeEndpoint, lerp, mergeBounds, normalizeSides, pointInEllipse, pointInRect, rectIntersection, rectUnion, rectsIntersect, renderFillAndStroke, resetIdCounter, resetPortIdCounter, resolveContentInset, rotatePoint, segmentRectIntersections, shape, snapPointToGrid, snapToGrid, text };
|
|
15547
|
+
export { AddNodeCommand, AnimationManager, AutoLayout, AutoRouting, BezierPathStrategy, CContainer, CDivider, CIcon, CShape, CText, ChangeEdgePropertiesCommand, ChangeEditablePolylineControlPointsCommand, ChangeGroupPropertiesCommand, ChangeNodePropertiesCommand, CircleNode, ClipboardManager, CompositeCommand, CompositeNode, ConnectionManager, ContextMenuManager, CustomShapeNode, DARK_THEME, DEFAULT_THEME, DiagramRenderer, DiamondNode, DragManager, Edge, Element, EventEmitter, GridOverlay, Group, GuidesOverlay, HistoryManager, ImageExporter, InputHandler, InteractionManager, MiniMap, MoveNodesCommand, NavigationManager, Node, NodeImage, PolylinePathStrategy, Port, PropertyChangeBatcher, RectangleNode, RemoveNodeCommand, ResizeManager, ResizeNodesCommand, RulersOverlay, SearchManager, SelectionManager, Serializer, ShapeFactories, StraightPathStrategy, StyleManager, SvgExporter, TextLabel, alignNodes, angle, applyEdgeStyle, applyNodeStyle, bezierPoint, boundsCenter, calculateBezierControlPoints, clamp, clonePoints, container, deserializeCComponent, directionFromAngle, distance, distanceToSegment, distributeNodes, divider, drawRoundedRectPath, expandBounds, flexLayout, generateId, getClosestPointOnPath, getPathPointAt, icon, isCornerPlacement, isEdgeEdgeEndpoint, isNodeEdgeEndpoint, lerp, mergeBounds, normalizeSides, pointInEllipse, pointInRect, rectIntersection, rectUnion, rectsIntersect, renderFillAndStroke, resetIdCounter, resetPortIdCounter, resolveContentInset, rotatePoint, segmentRectIntersections, shape, snapPointToGrid, snapToGrid, text };
|
|
15285
15548
|
|
|
15286
15549
|
//# sourceMappingURL=papirus.js.map
|