@elicdavis/node-flow 0.2.0 → 0.2.2
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/index.d.mts +17 -4
- package/dist/index.d.ts +17 -4
- package/dist/index.js +344 -222
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +344 -222
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/graph.ts +14 -7
- package/src/index.ts +2 -2
- package/src/input.ts +6 -8
- package/src/node.ts +53 -1
- package/src/port.ts +6 -1
- package/src/theme.ts +179 -179
- package/src/widgets/hidden_ports.ts +49 -0
- package/src/widgets/inplace.ts +75 -23
- package/src/widgets/number.ts +5 -12
- package/src/widgets/string.ts +1 -8
- package/src/widgets/widget.ts +201 -180
- package/test/hidden_port.test.ts +6 -5
- package/test/hidden_ports_toggle.test.ts +102 -0
- package/test/pinch_zoom.test.ts +78 -0
- package/test/support.ts +15 -2
- package/test/widgets.test.ts +54 -1
package/dist/index.mjs
CHANGED
|
@@ -735,7 +735,7 @@ var ContextMenu = class _ContextMenu {
|
|
|
735
735
|
// src/input.ts
|
|
736
736
|
var LONG_PRESS_MS = 500;
|
|
737
737
|
var LONG_PRESS_SLOP = 12;
|
|
738
|
-
var
|
|
738
|
+
var WHEEL_ZOOM_PER_PIXEL = 5e-4;
|
|
739
739
|
var SUPPRESS_MOUSE_MS = 600;
|
|
740
740
|
var MouseObserver = class {
|
|
741
741
|
#clicked;
|
|
@@ -833,13 +833,12 @@ var MouseObserver = class {
|
|
|
833
833
|
} else if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
|
|
834
834
|
dy *= this.#ele.clientHeight;
|
|
835
835
|
}
|
|
836
|
-
|
|
837
|
-
if (amount === 0) {
|
|
836
|
+
if (dy === 0) {
|
|
838
837
|
return;
|
|
839
838
|
}
|
|
840
839
|
const anchor = this.#mousePos(event);
|
|
841
840
|
this.#moveCallback(anchor);
|
|
842
|
-
this.#zoomCallback(
|
|
841
|
+
this.#zoomCallback(Math.exp(-dy * WHEEL_ZOOM_PER_PIXEL), anchor);
|
|
843
842
|
}
|
|
844
843
|
#move(event) {
|
|
845
844
|
if (this.#fromTouch()) {
|
|
@@ -915,7 +914,7 @@ var MouseObserver = class {
|
|
|
915
914
|
const anchor = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
916
915
|
if (this.#pinchDist > 0) {
|
|
917
916
|
this.#moveCallback(anchor);
|
|
918
|
-
this.#zoomCallback(
|
|
917
|
+
this.#zoomCallback(dist / this.#pinchDist, anchor);
|
|
919
918
|
}
|
|
920
919
|
this.#pinchDist = dist;
|
|
921
920
|
return;
|
|
@@ -1765,9 +1764,13 @@ var Port = class {
|
|
|
1765
1764
|
}
|
|
1766
1765
|
}
|
|
1767
1766
|
/**
|
|
1768
|
-
* A port asked to hide still shows while anything is connected to it
|
|
1767
|
+
* A port asked to hide still shows while anything is connected to it,
|
|
1768
|
+
* and while its node is showing its hidden ports.
|
|
1769
1769
|
*/
|
|
1770
1770
|
hidden() {
|
|
1771
|
+
return this.tucked() && !(this.#node?.hiddenPortsShown() ?? false);
|
|
1772
|
+
}
|
|
1773
|
+
tucked() {
|
|
1771
1774
|
return this.#hidden && this.#connections.length === 0;
|
|
1772
1775
|
}
|
|
1773
1776
|
addConnectionRemovedListener(callback) {
|
|
@@ -1869,6 +1872,281 @@ var Port = class {
|
|
|
1869
1872
|
}
|
|
1870
1873
|
};
|
|
1871
1874
|
|
|
1875
|
+
// src/styles/cursor.ts
|
|
1876
|
+
var CursorStyle = /* @__PURE__ */ ((CursorStyle2) => {
|
|
1877
|
+
CursorStyle2["Default"] = "default";
|
|
1878
|
+
CursorStyle2["Pointer"] = "pointer";
|
|
1879
|
+
CursorStyle2["Grab"] = "grab";
|
|
1880
|
+
CursorStyle2["Grabbing"] = "grabbing";
|
|
1881
|
+
CursorStyle2["Wait"] = "wait";
|
|
1882
|
+
CursorStyle2["Help"] = "help";
|
|
1883
|
+
CursorStyle2["Crosshair"] = "crosshair";
|
|
1884
|
+
CursorStyle2["Cell"] = "cell";
|
|
1885
|
+
CursorStyle2["Text"] = "text";
|
|
1886
|
+
CursorStyle2["Move"] = "move";
|
|
1887
|
+
CursorStyle2["NotAllowed"] = "not-allowed";
|
|
1888
|
+
CursorStyle2["ZoomIn"] = "zoom-in";
|
|
1889
|
+
CursorStyle2["ZoomOut"] = "zoom-out";
|
|
1890
|
+
CursorStyle2["None"] = "none";
|
|
1891
|
+
CursorStyle2["ContextMenu"] = "context-menu";
|
|
1892
|
+
CursorStyle2["EWResize"] = "ew-resize";
|
|
1893
|
+
return CursorStyle2;
|
|
1894
|
+
})(CursorStyle || {});
|
|
1895
|
+
|
|
1896
|
+
// src/widgets/inplace.ts
|
|
1897
|
+
var open = /* @__PURE__ */ new Set();
|
|
1898
|
+
function placeEditsDuring(canvas, draw) {
|
|
1899
|
+
open.forEach((edit) => {
|
|
1900
|
+
if (edit.canvas === canvas) {
|
|
1901
|
+
edit.placed = false;
|
|
1902
|
+
}
|
|
1903
|
+
});
|
|
1904
|
+
draw();
|
|
1905
|
+
open.forEach((edit) => {
|
|
1906
|
+
if (edit.canvas === canvas && !edit.placed) {
|
|
1907
|
+
edit.input.style.opacity = "0";
|
|
1908
|
+
edit.input.style.pointerEvents = "none";
|
|
1909
|
+
}
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1912
|
+
function editInPlace(config) {
|
|
1913
|
+
const canvas = config.canvas;
|
|
1914
|
+
if (canvas === null) {
|
|
1915
|
+
return null;
|
|
1916
|
+
}
|
|
1917
|
+
const input = document.createElement("input");
|
|
1918
|
+
input.type = "text";
|
|
1919
|
+
input.value = config.value;
|
|
1920
|
+
const edit = { canvas, input, placed: true };
|
|
1921
|
+
const place = (box, scale) => {
|
|
1922
|
+
const rect = canvas.getBoundingClientRect();
|
|
1923
|
+
const sx = canvas.width > 0 ? rect.width / canvas.width : 1;
|
|
1924
|
+
const sy = canvas.height > 0 ? rect.height / canvas.height : 1;
|
|
1925
|
+
const left = rect.left + box.Position.x * sx;
|
|
1926
|
+
const top = rect.top + box.Position.y * sy;
|
|
1927
|
+
const width2 = box.Size.x * sx;
|
|
1928
|
+
const height2 = box.Size.y * sy;
|
|
1929
|
+
const clip = [
|
|
1930
|
+
Math.max(0, rect.top - top),
|
|
1931
|
+
Math.max(0, left + width2 - (rect.left + rect.width)),
|
|
1932
|
+
Math.max(0, top + height2 - (rect.top + rect.height)),
|
|
1933
|
+
Math.max(0, rect.left - left)
|
|
1934
|
+
];
|
|
1935
|
+
edit.placed = true;
|
|
1936
|
+
input.style.cssText = [
|
|
1937
|
+
"position: fixed",
|
|
1938
|
+
`left: ${left}px`,
|
|
1939
|
+
`top: ${top}px`,
|
|
1940
|
+
`width: ${width2}px`,
|
|
1941
|
+
`height: ${height2}px`,
|
|
1942
|
+
`clip-path: inset(${clip.map((c) => `${c}px`).join(" ")})`,
|
|
1943
|
+
"box-sizing: border-box",
|
|
1944
|
+
"margin: 0",
|
|
1945
|
+
`padding: 0 ${Theme.Widget.Padding * scale}px`,
|
|
1946
|
+
`font: ${Theme.Widget.FontSize * scale * sy}px ${Theme.FontFamily}`,
|
|
1947
|
+
`color: ${Theme.Widget.FontColor}`,
|
|
1948
|
+
`background: ${Theme.Widget.Hover.BackgroundColor}`,
|
|
1949
|
+
`border: ${Theme.Widget.Border.Size * scale}px solid ${Theme.Widget.Border.Color}`,
|
|
1950
|
+
`border-radius: ${Theme.Widget.Border.Radius * scale}px`,
|
|
1951
|
+
"outline: none",
|
|
1952
|
+
"z-index: 1000"
|
|
1953
|
+
].join(";");
|
|
1954
|
+
};
|
|
1955
|
+
place(config.box, config.scale);
|
|
1956
|
+
let done = false;
|
|
1957
|
+
const finish = (keep) => {
|
|
1958
|
+
if (done) {
|
|
1959
|
+
return;
|
|
1960
|
+
}
|
|
1961
|
+
done = true;
|
|
1962
|
+
open.delete(edit);
|
|
1963
|
+
input.remove();
|
|
1964
|
+
if (keep) {
|
|
1965
|
+
config.onCommit(input.value);
|
|
1966
|
+
}
|
|
1967
|
+
requestRender();
|
|
1968
|
+
};
|
|
1969
|
+
input.addEventListener("keydown", (event) => {
|
|
1970
|
+
event.stopPropagation();
|
|
1971
|
+
if (event.key === "Enter") {
|
|
1972
|
+
event.preventDefault();
|
|
1973
|
+
finish(true);
|
|
1974
|
+
} else if (event.key === "Escape") {
|
|
1975
|
+
event.preventDefault();
|
|
1976
|
+
finish(false);
|
|
1977
|
+
}
|
|
1978
|
+
});
|
|
1979
|
+
input.addEventListener("blur", () => finish(true));
|
|
1980
|
+
open.add(edit);
|
|
1981
|
+
document.body.appendChild(input);
|
|
1982
|
+
input.focus();
|
|
1983
|
+
input.select();
|
|
1984
|
+
return { input, place };
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
// src/widgets/widget.ts
|
|
1988
|
+
var width = 150;
|
|
1989
|
+
var height = 25;
|
|
1990
|
+
var WidgetBase = class {
|
|
1991
|
+
#hidden = false;
|
|
1992
|
+
#disabled = false;
|
|
1993
|
+
#hovered = false;
|
|
1994
|
+
#pressed = false;
|
|
1995
|
+
#box = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };
|
|
1996
|
+
#canvas = null;
|
|
1997
|
+
#scale = 1;
|
|
1998
|
+
#editing = null;
|
|
1999
|
+
Draw(ctx, box, scale, mousePosition) {
|
|
2000
|
+
this.#box = { Position: { x: box.Position.x, y: box.Position.y }, Size: { x: box.Size.x, y: box.Size.y } };
|
|
2001
|
+
this.#canvas = ctx.canvas ?? null;
|
|
2002
|
+
this.#scale = scale;
|
|
2003
|
+
this.#hovered = !this.#disabled && mousePosition !== void 0 && InBox(box, mousePosition);
|
|
2004
|
+
if (this.#editing !== null) {
|
|
2005
|
+
if (this.#editing.input.isConnected) {
|
|
2006
|
+
this.#editing.place(this.#box, scale);
|
|
2007
|
+
} else {
|
|
2008
|
+
this.#editing = null;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
ctx.save();
|
|
2012
|
+
if (this.#disabled) {
|
|
2013
|
+
ctx.globalAlpha *= 0.4;
|
|
2014
|
+
}
|
|
2015
|
+
this.render(ctx, box, scale);
|
|
2016
|
+
ctx.restore();
|
|
2017
|
+
}
|
|
2018
|
+
PointerDown(pointer) {
|
|
2019
|
+
if (this.#disabled) {
|
|
2020
|
+
return;
|
|
2021
|
+
}
|
|
2022
|
+
this.#pressed = true;
|
|
2023
|
+
this.onPointerDown(pointer);
|
|
2024
|
+
requestRender();
|
|
2025
|
+
}
|
|
2026
|
+
PointerMove(pointer) {
|
|
2027
|
+
if (!this.#pressed) {
|
|
2028
|
+
return;
|
|
2029
|
+
}
|
|
2030
|
+
this.onPointerMove(pointer);
|
|
2031
|
+
requestRender();
|
|
2032
|
+
}
|
|
2033
|
+
PointerUp(pointer) {
|
|
2034
|
+
if (!this.#pressed) {
|
|
2035
|
+
return;
|
|
2036
|
+
}
|
|
2037
|
+
this.#pressed = false;
|
|
2038
|
+
this.onPointerUp(pointer);
|
|
2039
|
+
if (pointer.inside) {
|
|
2040
|
+
this.onClick(pointer);
|
|
2041
|
+
}
|
|
2042
|
+
requestRender();
|
|
2043
|
+
}
|
|
2044
|
+
Cursor() {
|
|
2045
|
+
return "pointer" /* Pointer */;
|
|
2046
|
+
}
|
|
2047
|
+
Hidden() {
|
|
2048
|
+
return this.#hidden;
|
|
2049
|
+
}
|
|
2050
|
+
setHidden(hidden) {
|
|
2051
|
+
this.#hidden = hidden;
|
|
2052
|
+
requestRender();
|
|
2053
|
+
}
|
|
2054
|
+
Disabled() {
|
|
2055
|
+
return this.#disabled;
|
|
2056
|
+
}
|
|
2057
|
+
setDisabled(disabled) {
|
|
2058
|
+
this.#disabled = disabled;
|
|
2059
|
+
if (disabled) {
|
|
2060
|
+
this.#pressed = false;
|
|
2061
|
+
}
|
|
2062
|
+
requestRender();
|
|
2063
|
+
}
|
|
2064
|
+
hovered() {
|
|
2065
|
+
return this.#hovered;
|
|
2066
|
+
}
|
|
2067
|
+
pressed() {
|
|
2068
|
+
return this.#pressed;
|
|
2069
|
+
}
|
|
2070
|
+
/**
|
|
2071
|
+
* Where the widget was last drawn, in canvas pixels.
|
|
2072
|
+
*/
|
|
2073
|
+
box() {
|
|
2074
|
+
return this.#box;
|
|
2075
|
+
}
|
|
2076
|
+
canvas() {
|
|
2077
|
+
return this.#canvas;
|
|
2078
|
+
}
|
|
2079
|
+
scale() {
|
|
2080
|
+
return this.#scale;
|
|
2081
|
+
}
|
|
2082
|
+
editText(value, onCommit) {
|
|
2083
|
+
this.#editing = editInPlace({
|
|
2084
|
+
canvas: this.#canvas,
|
|
2085
|
+
box: this.#box,
|
|
2086
|
+
scale: this.#scale,
|
|
2087
|
+
value,
|
|
2088
|
+
onCommit
|
|
2089
|
+
});
|
|
2090
|
+
}
|
|
2091
|
+
onPointerDown(pointer) {
|
|
2092
|
+
}
|
|
2093
|
+
onPointerMove(pointer) {
|
|
2094
|
+
}
|
|
2095
|
+
onPointerUp(pointer) {
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2098
|
+
* A press and release that both landed on the widget.
|
|
2099
|
+
*/
|
|
2100
|
+
onClick(pointer) {
|
|
2101
|
+
}
|
|
2102
|
+
};
|
|
2103
|
+
function startingWidgetValue(node, property, configured, fallback) {
|
|
2104
|
+
if (configured !== void 0) {
|
|
2105
|
+
return configured;
|
|
2106
|
+
}
|
|
2107
|
+
if (property !== void 0 && property !== null) {
|
|
2108
|
+
const existing = node.getProperty(property);
|
|
2109
|
+
if (existing !== void 0 && existing !== null) {
|
|
2110
|
+
return existing;
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
return fallback;
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
// src/widgets/hidden_ports.ts
|
|
2117
|
+
var HiddenPortsToggle = class extends WidgetBase {
|
|
2118
|
+
constructor(owner) {
|
|
2119
|
+
super();
|
|
2120
|
+
this.owner = owner;
|
|
2121
|
+
}
|
|
2122
|
+
Size() {
|
|
2123
|
+
return { x: 150, y: 16 };
|
|
2124
|
+
}
|
|
2125
|
+
render(ctx, box, scale) {
|
|
2126
|
+
const label = this.owner.hiddenPortsShown() ? "\u25B4 less" : `\u25BE ${this.owner.hiddenPortCount()} more`;
|
|
2127
|
+
const midY = box.Position.y + box.Size.y / 2;
|
|
2128
|
+
const centerX = box.Position.x + box.Size.x / 2;
|
|
2129
|
+
ctx.font = `${11 * scale}px ${Theme.FontFamily}`;
|
|
2130
|
+
const half = ctx.measureText(label).width / 2 + 6 * scale;
|
|
2131
|
+
ctx.globalAlpha = this.hovered() ? 1 : 0.5;
|
|
2132
|
+
ctx.strokeStyle = Theme.Widget.FontColor;
|
|
2133
|
+
ctx.fillStyle = Theme.Widget.FontColor;
|
|
2134
|
+
ctx.lineWidth = Math.max(1, scale);
|
|
2135
|
+
ctx.beginPath();
|
|
2136
|
+
ctx.moveTo(box.Position.x, midY);
|
|
2137
|
+
ctx.lineTo(centerX - half, midY);
|
|
2138
|
+
ctx.moveTo(centerX + half, midY);
|
|
2139
|
+
ctx.lineTo(box.Position.x + box.Size.x, midY);
|
|
2140
|
+
ctx.stroke();
|
|
2141
|
+
ctx.textAlign = "center";
|
|
2142
|
+
ctx.textBaseline = "middle";
|
|
2143
|
+
ctx.fillText(label, centerX, midY);
|
|
2144
|
+
}
|
|
2145
|
+
onClick() {
|
|
2146
|
+
this.owner.setHiddenPortsShown(!this.owner.hiddenPortsShown());
|
|
2147
|
+
}
|
|
2148
|
+
};
|
|
2149
|
+
|
|
1872
2150
|
// src/styles/stroke.ts
|
|
1873
2151
|
function StrokeStyleWithFallback(input, fallback) {
|
|
1874
2152
|
return {
|
|
@@ -1980,27 +2258,6 @@ var BoxStyle = class {
|
|
|
1980
2258
|
}
|
|
1981
2259
|
};
|
|
1982
2260
|
|
|
1983
|
-
// src/styles/cursor.ts
|
|
1984
|
-
var CursorStyle = /* @__PURE__ */ ((CursorStyle2) => {
|
|
1985
|
-
CursorStyle2["Default"] = "default";
|
|
1986
|
-
CursorStyle2["Pointer"] = "pointer";
|
|
1987
|
-
CursorStyle2["Grab"] = "grab";
|
|
1988
|
-
CursorStyle2["Grabbing"] = "grabbing";
|
|
1989
|
-
CursorStyle2["Wait"] = "wait";
|
|
1990
|
-
CursorStyle2["Help"] = "help";
|
|
1991
|
-
CursorStyle2["Crosshair"] = "crosshair";
|
|
1992
|
-
CursorStyle2["Cell"] = "cell";
|
|
1993
|
-
CursorStyle2["Text"] = "text";
|
|
1994
|
-
CursorStyle2["Move"] = "move";
|
|
1995
|
-
CursorStyle2["NotAllowed"] = "not-allowed";
|
|
1996
|
-
CursorStyle2["ZoomIn"] = "zoom-in";
|
|
1997
|
-
CursorStyle2["ZoomOut"] = "zoom-out";
|
|
1998
|
-
CursorStyle2["None"] = "none";
|
|
1999
|
-
CursorStyle2["ContextMenu"] = "context-menu";
|
|
2000
|
-
CursorStyle2["EWResize"] = "ew-resize";
|
|
2001
|
-
return CursorStyle2;
|
|
2002
|
-
})(CursorStyle || {});
|
|
2003
|
-
|
|
2004
2261
|
// src/styles/bevel.ts
|
|
2005
2262
|
function drawBevel(ctx, box, scale, colors, sunken) {
|
|
2006
2263
|
const width2 = Math.max(1, 2 * scale);
|
|
@@ -2092,176 +2349,6 @@ function drawFieldText(ctx, box, scale, look) {
|
|
|
2092
2349
|
);
|
|
2093
2350
|
}
|
|
2094
2351
|
|
|
2095
|
-
// src/widgets/inplace.ts
|
|
2096
|
-
function editInPlace(config) {
|
|
2097
|
-
const canvas = config.canvas;
|
|
2098
|
-
if (canvas === null) {
|
|
2099
|
-
return null;
|
|
2100
|
-
}
|
|
2101
|
-
const rect = canvas.getBoundingClientRect();
|
|
2102
|
-
const sx = canvas.width > 0 ? rect.width / canvas.width : 1;
|
|
2103
|
-
const sy = canvas.height > 0 ? rect.height / canvas.height : 1;
|
|
2104
|
-
const input = document.createElement("input");
|
|
2105
|
-
input.type = "text";
|
|
2106
|
-
input.value = config.value;
|
|
2107
|
-
input.style.cssText = [
|
|
2108
|
-
"position: fixed",
|
|
2109
|
-
`left: ${rect.left + config.box.Position.x * sx}px`,
|
|
2110
|
-
`top: ${rect.top + config.box.Position.y * sy}px`,
|
|
2111
|
-
`width: ${config.box.Size.x * sx}px`,
|
|
2112
|
-
`height: ${config.box.Size.y * sy}px`,
|
|
2113
|
-
"box-sizing: border-box",
|
|
2114
|
-
"margin: 0",
|
|
2115
|
-
`padding: 0 ${Theme.Widget.Padding * config.scale}px`,
|
|
2116
|
-
`font: ${Theme.Widget.FontSize * config.scale * sy}px ${Theme.FontFamily}`,
|
|
2117
|
-
`color: ${Theme.Widget.FontColor}`,
|
|
2118
|
-
`background: ${Theme.Widget.Hover.BackgroundColor}`,
|
|
2119
|
-
`border: ${Theme.Widget.Border.Size * config.scale}px solid ${Theme.Widget.Border.Color}`,
|
|
2120
|
-
`border-radius: ${Theme.Widget.Border.Radius * config.scale}px`,
|
|
2121
|
-
"outline: none",
|
|
2122
|
-
"z-index: 1000"
|
|
2123
|
-
].join(";");
|
|
2124
|
-
let done = false;
|
|
2125
|
-
const finish = (keep) => {
|
|
2126
|
-
if (done) {
|
|
2127
|
-
return;
|
|
2128
|
-
}
|
|
2129
|
-
done = true;
|
|
2130
|
-
input.remove();
|
|
2131
|
-
if (keep) {
|
|
2132
|
-
config.onCommit(input.value);
|
|
2133
|
-
}
|
|
2134
|
-
requestRender();
|
|
2135
|
-
};
|
|
2136
|
-
input.addEventListener("keydown", (event) => {
|
|
2137
|
-
event.stopPropagation();
|
|
2138
|
-
if (event.key === "Enter") {
|
|
2139
|
-
event.preventDefault();
|
|
2140
|
-
finish(true);
|
|
2141
|
-
} else if (event.key === "Escape") {
|
|
2142
|
-
event.preventDefault();
|
|
2143
|
-
finish(false);
|
|
2144
|
-
}
|
|
2145
|
-
});
|
|
2146
|
-
input.addEventListener("blur", () => finish(true));
|
|
2147
|
-
document.body.appendChild(input);
|
|
2148
|
-
input.focus();
|
|
2149
|
-
input.select();
|
|
2150
|
-
return input;
|
|
2151
|
-
}
|
|
2152
|
-
|
|
2153
|
-
// src/widgets/widget.ts
|
|
2154
|
-
var width = 150;
|
|
2155
|
-
var height = 25;
|
|
2156
|
-
var WidgetBase = class {
|
|
2157
|
-
#hidden = false;
|
|
2158
|
-
#disabled = false;
|
|
2159
|
-
#hovered = false;
|
|
2160
|
-
#pressed = false;
|
|
2161
|
-
#box = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };
|
|
2162
|
-
#canvas = null;
|
|
2163
|
-
#scale = 1;
|
|
2164
|
-
Draw(ctx, box, scale, mousePosition) {
|
|
2165
|
-
this.#box = { Position: { x: box.Position.x, y: box.Position.y }, Size: { x: box.Size.x, y: box.Size.y } };
|
|
2166
|
-
this.#canvas = ctx.canvas ?? null;
|
|
2167
|
-
this.#scale = scale;
|
|
2168
|
-
this.#hovered = !this.#disabled && mousePosition !== void 0 && InBox(box, mousePosition);
|
|
2169
|
-
ctx.save();
|
|
2170
|
-
if (this.#disabled) {
|
|
2171
|
-
ctx.globalAlpha *= 0.4;
|
|
2172
|
-
}
|
|
2173
|
-
this.render(ctx, box, scale);
|
|
2174
|
-
ctx.restore();
|
|
2175
|
-
}
|
|
2176
|
-
PointerDown(pointer) {
|
|
2177
|
-
if (this.#disabled) {
|
|
2178
|
-
return;
|
|
2179
|
-
}
|
|
2180
|
-
this.#pressed = true;
|
|
2181
|
-
this.onPointerDown(pointer);
|
|
2182
|
-
requestRender();
|
|
2183
|
-
}
|
|
2184
|
-
PointerMove(pointer) {
|
|
2185
|
-
if (!this.#pressed) {
|
|
2186
|
-
return;
|
|
2187
|
-
}
|
|
2188
|
-
this.onPointerMove(pointer);
|
|
2189
|
-
requestRender();
|
|
2190
|
-
}
|
|
2191
|
-
PointerUp(pointer) {
|
|
2192
|
-
if (!this.#pressed) {
|
|
2193
|
-
return;
|
|
2194
|
-
}
|
|
2195
|
-
this.#pressed = false;
|
|
2196
|
-
this.onPointerUp(pointer);
|
|
2197
|
-
if (pointer.inside) {
|
|
2198
|
-
this.onClick(pointer);
|
|
2199
|
-
}
|
|
2200
|
-
requestRender();
|
|
2201
|
-
}
|
|
2202
|
-
Cursor() {
|
|
2203
|
-
return "pointer" /* Pointer */;
|
|
2204
|
-
}
|
|
2205
|
-
Hidden() {
|
|
2206
|
-
return this.#hidden;
|
|
2207
|
-
}
|
|
2208
|
-
setHidden(hidden) {
|
|
2209
|
-
this.#hidden = hidden;
|
|
2210
|
-
requestRender();
|
|
2211
|
-
}
|
|
2212
|
-
Disabled() {
|
|
2213
|
-
return this.#disabled;
|
|
2214
|
-
}
|
|
2215
|
-
setDisabled(disabled) {
|
|
2216
|
-
this.#disabled = disabled;
|
|
2217
|
-
if (disabled) {
|
|
2218
|
-
this.#pressed = false;
|
|
2219
|
-
}
|
|
2220
|
-
requestRender();
|
|
2221
|
-
}
|
|
2222
|
-
hovered() {
|
|
2223
|
-
return this.#hovered;
|
|
2224
|
-
}
|
|
2225
|
-
pressed() {
|
|
2226
|
-
return this.#pressed;
|
|
2227
|
-
}
|
|
2228
|
-
/**
|
|
2229
|
-
* Where the widget was last drawn, in canvas pixels.
|
|
2230
|
-
*/
|
|
2231
|
-
box() {
|
|
2232
|
-
return this.#box;
|
|
2233
|
-
}
|
|
2234
|
-
canvas() {
|
|
2235
|
-
return this.#canvas;
|
|
2236
|
-
}
|
|
2237
|
-
scale() {
|
|
2238
|
-
return this.#scale;
|
|
2239
|
-
}
|
|
2240
|
-
onPointerDown(pointer) {
|
|
2241
|
-
}
|
|
2242
|
-
onPointerMove(pointer) {
|
|
2243
|
-
}
|
|
2244
|
-
onPointerUp(pointer) {
|
|
2245
|
-
}
|
|
2246
|
-
/**
|
|
2247
|
-
* A press and release that both landed on the widget.
|
|
2248
|
-
*/
|
|
2249
|
-
onClick(pointer) {
|
|
2250
|
-
}
|
|
2251
|
-
};
|
|
2252
|
-
function startingWidgetValue(node, property, configured, fallback) {
|
|
2253
|
-
if (configured !== void 0) {
|
|
2254
|
-
return configured;
|
|
2255
|
-
}
|
|
2256
|
-
if (property !== void 0 && property !== null) {
|
|
2257
|
-
const existing = node.getProperty(property);
|
|
2258
|
-
if (existing !== void 0 && existing !== null) {
|
|
2259
|
-
return existing;
|
|
2260
|
-
}
|
|
2261
|
-
}
|
|
2262
|
-
return fallback;
|
|
2263
|
-
}
|
|
2264
|
-
|
|
2265
2352
|
// src/widgets/value.ts
|
|
2266
2353
|
var ValueWidget = class extends WidgetBase {
|
|
2267
2354
|
#node;
|
|
@@ -2396,16 +2483,10 @@ var NumberWidget = class extends ValueWidget {
|
|
|
2396
2483
|
return;
|
|
2397
2484
|
}
|
|
2398
2485
|
const before = this.value();
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
value: String(before),
|
|
2404
|
-
onCommit: (text) => {
|
|
2405
|
-
const parsed = Number.parseFloat(text);
|
|
2406
|
-
if (Number.isFinite(parsed)) {
|
|
2407
|
-
this.commit(this.#clean(parsed), before);
|
|
2408
|
-
}
|
|
2486
|
+
this.editText(String(before), (text) => {
|
|
2487
|
+
const parsed = Number.parseFloat(text);
|
|
2488
|
+
if (Number.isFinite(parsed)) {
|
|
2489
|
+
this.commit(this.#clean(parsed), before);
|
|
2409
2490
|
}
|
|
2410
2491
|
});
|
|
2411
2492
|
}
|
|
@@ -2613,13 +2694,7 @@ var StringWidget = class extends ValueWidget {
|
|
|
2613
2694
|
}
|
|
2614
2695
|
onClick() {
|
|
2615
2696
|
const before = this.value();
|
|
2616
|
-
|
|
2617
|
-
canvas: this.canvas(),
|
|
2618
|
-
box: this.box(),
|
|
2619
|
-
scale: this.scale(),
|
|
2620
|
-
value: before,
|
|
2621
|
-
onCommit: (text) => this.commit(text, before)
|
|
2622
|
-
});
|
|
2697
|
+
this.editText(before, (text) => this.commit(text, before));
|
|
2623
2698
|
}
|
|
2624
2699
|
};
|
|
2625
2700
|
|
|
@@ -5530,7 +5605,8 @@ var FlowNode = class {
|
|
|
5530
5605
|
size.y += this.#portRowHeight(port, tempMeasurement.y) + this.#elementSpacing;
|
|
5531
5606
|
size.x = Math.max(size.x, tempMeasurement.x + doublePadding);
|
|
5532
5607
|
}
|
|
5533
|
-
|
|
5608
|
+
const widgets = this.#hasHiddenPortsToggle() ? [this.#hiddenPortsToggle, ...this.#widgets] : this.#widgets;
|
|
5609
|
+
for (const widget of widgets) {
|
|
5534
5610
|
if (widget.Hidden?.()) {
|
|
5535
5611
|
continue;
|
|
5536
5612
|
}
|
|
@@ -5556,6 +5632,31 @@ var FlowNode = class {
|
|
|
5556
5632
|
this.#output.push(port);
|
|
5557
5633
|
return port;
|
|
5558
5634
|
}
|
|
5635
|
+
#hiddenPortsShown = false;
|
|
5636
|
+
#hiddenPortsToggle = new HiddenPortsToggle(this);
|
|
5637
|
+
#hiddenPortsTogglePosition = null;
|
|
5638
|
+
hiddenPortsShown() {
|
|
5639
|
+
return this.#hiddenPortsShown;
|
|
5640
|
+
}
|
|
5641
|
+
setHiddenPortsShown(shown) {
|
|
5642
|
+
if (shown === this.#hiddenPortsShown) {
|
|
5643
|
+
return;
|
|
5644
|
+
}
|
|
5645
|
+
this.#hiddenPortsShown = shown;
|
|
5646
|
+
this.invalidateLayout();
|
|
5647
|
+
}
|
|
5648
|
+
hiddenPortCount() {
|
|
5649
|
+
let count = 0;
|
|
5650
|
+
for (const port of [...this.#input, ...this.#output]) {
|
|
5651
|
+
if (port.tucked()) {
|
|
5652
|
+
count++;
|
|
5653
|
+
}
|
|
5654
|
+
}
|
|
5655
|
+
return count;
|
|
5656
|
+
}
|
|
5657
|
+
#hasHiddenPortsToggle() {
|
|
5658
|
+
return this.hiddenPortCount() > 0;
|
|
5659
|
+
}
|
|
5559
5660
|
addWidget(widget) {
|
|
5560
5661
|
this.#widgets.push(widget);
|
|
5561
5662
|
requestRender();
|
|
@@ -5634,6 +5735,11 @@ var FlowNode = class {
|
|
|
5634
5735
|
intersection.Port = this.#output[i];
|
|
5635
5736
|
}
|
|
5636
5737
|
}
|
|
5738
|
+
if (this.#hiddenPortsTogglePosition !== null && InBox(this.#hiddenPortsTogglePosition, position)) {
|
|
5739
|
+
intersection.Node = this;
|
|
5740
|
+
intersection.Widget = this.#hiddenPortsToggle;
|
|
5741
|
+
intersection.WidgetBox = this.#hiddenPortsTogglePosition;
|
|
5742
|
+
}
|
|
5637
5743
|
for (let i = 0; i < this.#widgetPositions.Count(); i++) {
|
|
5638
5744
|
const widget = this.#widgets[i];
|
|
5639
5745
|
if (widget !== void 0 && !widget.Hidden?.() && InBox(this.#widgetPositions.At(i), position)) {
|
|
@@ -5903,6 +6009,16 @@ var FlowNode = class {
|
|
|
5903
6009
|
this.#outputPortPositions.Push(port.render(ctx, position, camera, mousePosition, postProcess));
|
|
5904
6010
|
startY += portHeight + scaledElementSpacing;
|
|
5905
6011
|
}
|
|
6012
|
+
this.#hiddenPortsTogglePosition = null;
|
|
6013
|
+
if (this.#hasHiddenPortsToggle()) {
|
|
6014
|
+
const box = {
|
|
6015
|
+
Position: { x: nodeBounds.Position.x + scaledPadding, y: startY },
|
|
6016
|
+
Size: { x: nodeBounds.Size.x - scaledPadding * 2, y: this.#hiddenPortsToggle.Size().y * camera.zoom }
|
|
6017
|
+
};
|
|
6018
|
+
this.#hiddenPortsToggle.Draw(ctx, box, camera.zoom, mousePosition);
|
|
6019
|
+
this.#hiddenPortsTogglePosition = box;
|
|
6020
|
+
startY += box.Size.y + scaledElementSpacing;
|
|
6021
|
+
}
|
|
5906
6022
|
for (let i = 0; i < this.#widgets.length; i++) {
|
|
5907
6023
|
const widget = this.#widgets[i];
|
|
5908
6024
|
if (widget.Hidden?.()) {
|
|
@@ -5957,6 +6073,7 @@ var FlowNode = class {
|
|
|
5957
6073
|
return false;
|
|
5958
6074
|
}
|
|
5959
6075
|
this.#widgetPositions.Clear();
|
|
6076
|
+
this.#hiddenPortsTogglePosition = null;
|
|
5960
6077
|
return true;
|
|
5961
6078
|
}
|
|
5962
6079
|
placePorts(bounds, zoom) {
|
|
@@ -7617,8 +7734,8 @@ var NodeFlowGraph = class {
|
|
|
7617
7734
|
this.#clickEnd.bind(this),
|
|
7618
7735
|
this.#openContextMenu.bind(this),
|
|
7619
7736
|
this.#fileDrop.bind(this),
|
|
7620
|
-
(
|
|
7621
|
-
this
|
|
7737
|
+
(factor, anchor) => {
|
|
7738
|
+
this.#zoomBy(factor, anchor);
|
|
7622
7739
|
}
|
|
7623
7740
|
);
|
|
7624
7741
|
document.addEventListener(
|
|
@@ -7746,12 +7863,15 @@ var NodeFlowGraph = class {
|
|
|
7746
7863
|
this.#mainNoteSubsystem.addNoteDragStopListener(callback);
|
|
7747
7864
|
}
|
|
7748
7865
|
zoom(amount, anchor) {
|
|
7866
|
+
this.#zoomBy(1 + amount * 0.05, anchor);
|
|
7867
|
+
}
|
|
7868
|
+
#zoomBy(factor, anchor) {
|
|
7749
7869
|
const anchorPos = anchor ?? this.#mousePosition;
|
|
7750
7870
|
let oldPos = void 0;
|
|
7751
7871
|
if (anchorPos !== void 0) {
|
|
7752
7872
|
oldPos = this.#sceenPositionToGraphPosition(anchorPos);
|
|
7753
7873
|
}
|
|
7754
|
-
this.#camera.zoom
|
|
7874
|
+
this.#camera.zoom *= factor;
|
|
7755
7875
|
if (!oldPos || anchorPos === void 0) {
|
|
7756
7876
|
return;
|
|
7757
7877
|
}
|
|
@@ -8016,10 +8136,12 @@ var NodeFlowGraph = class {
|
|
|
8016
8136
|
this.#cursor = "default" /* Default */;
|
|
8017
8137
|
TimeExecution("Render_Background", this.#renderBackground.bind(this));
|
|
8018
8138
|
TimeExecution("Render_View_" + this.#currentView, () => {
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8139
|
+
placeEditsDuring(this.#canvas, () => {
|
|
8140
|
+
let results = this.currentView().render(this.#ctx, this.#camera, this.#mousePosition);
|
|
8141
|
+
if (results?.cursorStyle) {
|
|
8142
|
+
this.#cursor = results?.cursorStyle;
|
|
8143
|
+
}
|
|
8144
|
+
});
|
|
8023
8145
|
});
|
|
8024
8146
|
TimeExecution("Render_Minimap", () => {
|
|
8025
8147
|
this.#minimap.render(this.#ctx, this.#canvas, this.#camera, this.#mainNodeSubsystem.getNodes());
|