@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.js
CHANGED
|
@@ -805,7 +805,7 @@ var ContextMenu = class _ContextMenu {
|
|
|
805
805
|
// src/input.ts
|
|
806
806
|
var LONG_PRESS_MS = 500;
|
|
807
807
|
var LONG_PRESS_SLOP = 12;
|
|
808
|
-
var
|
|
808
|
+
var WHEEL_ZOOM_PER_PIXEL = 5e-4;
|
|
809
809
|
var SUPPRESS_MOUSE_MS = 600;
|
|
810
810
|
var MouseObserver = class {
|
|
811
811
|
#clicked;
|
|
@@ -903,13 +903,12 @@ var MouseObserver = class {
|
|
|
903
903
|
} else if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
|
|
904
904
|
dy *= this.#ele.clientHeight;
|
|
905
905
|
}
|
|
906
|
-
|
|
907
|
-
if (amount === 0) {
|
|
906
|
+
if (dy === 0) {
|
|
908
907
|
return;
|
|
909
908
|
}
|
|
910
909
|
const anchor = this.#mousePos(event);
|
|
911
910
|
this.#moveCallback(anchor);
|
|
912
|
-
this.#zoomCallback(
|
|
911
|
+
this.#zoomCallback(Math.exp(-dy * WHEEL_ZOOM_PER_PIXEL), anchor);
|
|
913
912
|
}
|
|
914
913
|
#move(event) {
|
|
915
914
|
if (this.#fromTouch()) {
|
|
@@ -985,7 +984,7 @@ var MouseObserver = class {
|
|
|
985
984
|
const anchor = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };
|
|
986
985
|
if (this.#pinchDist > 0) {
|
|
987
986
|
this.#moveCallback(anchor);
|
|
988
|
-
this.#zoomCallback(
|
|
987
|
+
this.#zoomCallback(dist / this.#pinchDist, anchor);
|
|
989
988
|
}
|
|
990
989
|
this.#pinchDist = dist;
|
|
991
990
|
return;
|
|
@@ -1835,9 +1834,13 @@ var Port = class {
|
|
|
1835
1834
|
}
|
|
1836
1835
|
}
|
|
1837
1836
|
/**
|
|
1838
|
-
* A port asked to hide still shows while anything is connected to it
|
|
1837
|
+
* A port asked to hide still shows while anything is connected to it,
|
|
1838
|
+
* and while its node is showing its hidden ports.
|
|
1839
1839
|
*/
|
|
1840
1840
|
hidden() {
|
|
1841
|
+
return this.tucked() && !(this.#node?.hiddenPortsShown() ?? false);
|
|
1842
|
+
}
|
|
1843
|
+
tucked() {
|
|
1841
1844
|
return this.#hidden && this.#connections.length === 0;
|
|
1842
1845
|
}
|
|
1843
1846
|
addConnectionRemovedListener(callback) {
|
|
@@ -1939,6 +1942,281 @@ var Port = class {
|
|
|
1939
1942
|
}
|
|
1940
1943
|
};
|
|
1941
1944
|
|
|
1945
|
+
// src/styles/cursor.ts
|
|
1946
|
+
var CursorStyle = /* @__PURE__ */ ((CursorStyle2) => {
|
|
1947
|
+
CursorStyle2["Default"] = "default";
|
|
1948
|
+
CursorStyle2["Pointer"] = "pointer";
|
|
1949
|
+
CursorStyle2["Grab"] = "grab";
|
|
1950
|
+
CursorStyle2["Grabbing"] = "grabbing";
|
|
1951
|
+
CursorStyle2["Wait"] = "wait";
|
|
1952
|
+
CursorStyle2["Help"] = "help";
|
|
1953
|
+
CursorStyle2["Crosshair"] = "crosshair";
|
|
1954
|
+
CursorStyle2["Cell"] = "cell";
|
|
1955
|
+
CursorStyle2["Text"] = "text";
|
|
1956
|
+
CursorStyle2["Move"] = "move";
|
|
1957
|
+
CursorStyle2["NotAllowed"] = "not-allowed";
|
|
1958
|
+
CursorStyle2["ZoomIn"] = "zoom-in";
|
|
1959
|
+
CursorStyle2["ZoomOut"] = "zoom-out";
|
|
1960
|
+
CursorStyle2["None"] = "none";
|
|
1961
|
+
CursorStyle2["ContextMenu"] = "context-menu";
|
|
1962
|
+
CursorStyle2["EWResize"] = "ew-resize";
|
|
1963
|
+
return CursorStyle2;
|
|
1964
|
+
})(CursorStyle || {});
|
|
1965
|
+
|
|
1966
|
+
// src/widgets/inplace.ts
|
|
1967
|
+
var open = /* @__PURE__ */ new Set();
|
|
1968
|
+
function placeEditsDuring(canvas, draw) {
|
|
1969
|
+
open.forEach((edit) => {
|
|
1970
|
+
if (edit.canvas === canvas) {
|
|
1971
|
+
edit.placed = false;
|
|
1972
|
+
}
|
|
1973
|
+
});
|
|
1974
|
+
draw();
|
|
1975
|
+
open.forEach((edit) => {
|
|
1976
|
+
if (edit.canvas === canvas && !edit.placed) {
|
|
1977
|
+
edit.input.style.opacity = "0";
|
|
1978
|
+
edit.input.style.pointerEvents = "none";
|
|
1979
|
+
}
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1982
|
+
function editInPlace(config) {
|
|
1983
|
+
const canvas = config.canvas;
|
|
1984
|
+
if (canvas === null) {
|
|
1985
|
+
return null;
|
|
1986
|
+
}
|
|
1987
|
+
const input = document.createElement("input");
|
|
1988
|
+
input.type = "text";
|
|
1989
|
+
input.value = config.value;
|
|
1990
|
+
const edit = { canvas, input, placed: true };
|
|
1991
|
+
const place = (box, scale) => {
|
|
1992
|
+
const rect = canvas.getBoundingClientRect();
|
|
1993
|
+
const sx = canvas.width > 0 ? rect.width / canvas.width : 1;
|
|
1994
|
+
const sy = canvas.height > 0 ? rect.height / canvas.height : 1;
|
|
1995
|
+
const left = rect.left + box.Position.x * sx;
|
|
1996
|
+
const top = rect.top + box.Position.y * sy;
|
|
1997
|
+
const width2 = box.Size.x * sx;
|
|
1998
|
+
const height2 = box.Size.y * sy;
|
|
1999
|
+
const clip = [
|
|
2000
|
+
Math.max(0, rect.top - top),
|
|
2001
|
+
Math.max(0, left + width2 - (rect.left + rect.width)),
|
|
2002
|
+
Math.max(0, top + height2 - (rect.top + rect.height)),
|
|
2003
|
+
Math.max(0, rect.left - left)
|
|
2004
|
+
];
|
|
2005
|
+
edit.placed = true;
|
|
2006
|
+
input.style.cssText = [
|
|
2007
|
+
"position: fixed",
|
|
2008
|
+
`left: ${left}px`,
|
|
2009
|
+
`top: ${top}px`,
|
|
2010
|
+
`width: ${width2}px`,
|
|
2011
|
+
`height: ${height2}px`,
|
|
2012
|
+
`clip-path: inset(${clip.map((c) => `${c}px`).join(" ")})`,
|
|
2013
|
+
"box-sizing: border-box",
|
|
2014
|
+
"margin: 0",
|
|
2015
|
+
`padding: 0 ${Theme.Widget.Padding * scale}px`,
|
|
2016
|
+
`font: ${Theme.Widget.FontSize * scale * sy}px ${Theme.FontFamily}`,
|
|
2017
|
+
`color: ${Theme.Widget.FontColor}`,
|
|
2018
|
+
`background: ${Theme.Widget.Hover.BackgroundColor}`,
|
|
2019
|
+
`border: ${Theme.Widget.Border.Size * scale}px solid ${Theme.Widget.Border.Color}`,
|
|
2020
|
+
`border-radius: ${Theme.Widget.Border.Radius * scale}px`,
|
|
2021
|
+
"outline: none",
|
|
2022
|
+
"z-index: 1000"
|
|
2023
|
+
].join(";");
|
|
2024
|
+
};
|
|
2025
|
+
place(config.box, config.scale);
|
|
2026
|
+
let done = false;
|
|
2027
|
+
const finish = (keep) => {
|
|
2028
|
+
if (done) {
|
|
2029
|
+
return;
|
|
2030
|
+
}
|
|
2031
|
+
done = true;
|
|
2032
|
+
open.delete(edit);
|
|
2033
|
+
input.remove();
|
|
2034
|
+
if (keep) {
|
|
2035
|
+
config.onCommit(input.value);
|
|
2036
|
+
}
|
|
2037
|
+
requestRender();
|
|
2038
|
+
};
|
|
2039
|
+
input.addEventListener("keydown", (event) => {
|
|
2040
|
+
event.stopPropagation();
|
|
2041
|
+
if (event.key === "Enter") {
|
|
2042
|
+
event.preventDefault();
|
|
2043
|
+
finish(true);
|
|
2044
|
+
} else if (event.key === "Escape") {
|
|
2045
|
+
event.preventDefault();
|
|
2046
|
+
finish(false);
|
|
2047
|
+
}
|
|
2048
|
+
});
|
|
2049
|
+
input.addEventListener("blur", () => finish(true));
|
|
2050
|
+
open.add(edit);
|
|
2051
|
+
document.body.appendChild(input);
|
|
2052
|
+
input.focus();
|
|
2053
|
+
input.select();
|
|
2054
|
+
return { input, place };
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
// src/widgets/widget.ts
|
|
2058
|
+
var width = 150;
|
|
2059
|
+
var height = 25;
|
|
2060
|
+
var WidgetBase = class {
|
|
2061
|
+
#hidden = false;
|
|
2062
|
+
#disabled = false;
|
|
2063
|
+
#hovered = false;
|
|
2064
|
+
#pressed = false;
|
|
2065
|
+
#box = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };
|
|
2066
|
+
#canvas = null;
|
|
2067
|
+
#scale = 1;
|
|
2068
|
+
#editing = null;
|
|
2069
|
+
Draw(ctx, box, scale, mousePosition) {
|
|
2070
|
+
this.#box = { Position: { x: box.Position.x, y: box.Position.y }, Size: { x: box.Size.x, y: box.Size.y } };
|
|
2071
|
+
this.#canvas = ctx.canvas ?? null;
|
|
2072
|
+
this.#scale = scale;
|
|
2073
|
+
this.#hovered = !this.#disabled && mousePosition !== void 0 && InBox(box, mousePosition);
|
|
2074
|
+
if (this.#editing !== null) {
|
|
2075
|
+
if (this.#editing.input.isConnected) {
|
|
2076
|
+
this.#editing.place(this.#box, scale);
|
|
2077
|
+
} else {
|
|
2078
|
+
this.#editing = null;
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
ctx.save();
|
|
2082
|
+
if (this.#disabled) {
|
|
2083
|
+
ctx.globalAlpha *= 0.4;
|
|
2084
|
+
}
|
|
2085
|
+
this.render(ctx, box, scale);
|
|
2086
|
+
ctx.restore();
|
|
2087
|
+
}
|
|
2088
|
+
PointerDown(pointer) {
|
|
2089
|
+
if (this.#disabled) {
|
|
2090
|
+
return;
|
|
2091
|
+
}
|
|
2092
|
+
this.#pressed = true;
|
|
2093
|
+
this.onPointerDown(pointer);
|
|
2094
|
+
requestRender();
|
|
2095
|
+
}
|
|
2096
|
+
PointerMove(pointer) {
|
|
2097
|
+
if (!this.#pressed) {
|
|
2098
|
+
return;
|
|
2099
|
+
}
|
|
2100
|
+
this.onPointerMove(pointer);
|
|
2101
|
+
requestRender();
|
|
2102
|
+
}
|
|
2103
|
+
PointerUp(pointer) {
|
|
2104
|
+
if (!this.#pressed) {
|
|
2105
|
+
return;
|
|
2106
|
+
}
|
|
2107
|
+
this.#pressed = false;
|
|
2108
|
+
this.onPointerUp(pointer);
|
|
2109
|
+
if (pointer.inside) {
|
|
2110
|
+
this.onClick(pointer);
|
|
2111
|
+
}
|
|
2112
|
+
requestRender();
|
|
2113
|
+
}
|
|
2114
|
+
Cursor() {
|
|
2115
|
+
return "pointer" /* Pointer */;
|
|
2116
|
+
}
|
|
2117
|
+
Hidden() {
|
|
2118
|
+
return this.#hidden;
|
|
2119
|
+
}
|
|
2120
|
+
setHidden(hidden) {
|
|
2121
|
+
this.#hidden = hidden;
|
|
2122
|
+
requestRender();
|
|
2123
|
+
}
|
|
2124
|
+
Disabled() {
|
|
2125
|
+
return this.#disabled;
|
|
2126
|
+
}
|
|
2127
|
+
setDisabled(disabled) {
|
|
2128
|
+
this.#disabled = disabled;
|
|
2129
|
+
if (disabled) {
|
|
2130
|
+
this.#pressed = false;
|
|
2131
|
+
}
|
|
2132
|
+
requestRender();
|
|
2133
|
+
}
|
|
2134
|
+
hovered() {
|
|
2135
|
+
return this.#hovered;
|
|
2136
|
+
}
|
|
2137
|
+
pressed() {
|
|
2138
|
+
return this.#pressed;
|
|
2139
|
+
}
|
|
2140
|
+
/**
|
|
2141
|
+
* Where the widget was last drawn, in canvas pixels.
|
|
2142
|
+
*/
|
|
2143
|
+
box() {
|
|
2144
|
+
return this.#box;
|
|
2145
|
+
}
|
|
2146
|
+
canvas() {
|
|
2147
|
+
return this.#canvas;
|
|
2148
|
+
}
|
|
2149
|
+
scale() {
|
|
2150
|
+
return this.#scale;
|
|
2151
|
+
}
|
|
2152
|
+
editText(value, onCommit) {
|
|
2153
|
+
this.#editing = editInPlace({
|
|
2154
|
+
canvas: this.#canvas,
|
|
2155
|
+
box: this.#box,
|
|
2156
|
+
scale: this.#scale,
|
|
2157
|
+
value,
|
|
2158
|
+
onCommit
|
|
2159
|
+
});
|
|
2160
|
+
}
|
|
2161
|
+
onPointerDown(pointer) {
|
|
2162
|
+
}
|
|
2163
|
+
onPointerMove(pointer) {
|
|
2164
|
+
}
|
|
2165
|
+
onPointerUp(pointer) {
|
|
2166
|
+
}
|
|
2167
|
+
/**
|
|
2168
|
+
* A press and release that both landed on the widget.
|
|
2169
|
+
*/
|
|
2170
|
+
onClick(pointer) {
|
|
2171
|
+
}
|
|
2172
|
+
};
|
|
2173
|
+
function startingWidgetValue(node, property, configured, fallback) {
|
|
2174
|
+
if (configured !== void 0) {
|
|
2175
|
+
return configured;
|
|
2176
|
+
}
|
|
2177
|
+
if (property !== void 0 && property !== null) {
|
|
2178
|
+
const existing = node.getProperty(property);
|
|
2179
|
+
if (existing !== void 0 && existing !== null) {
|
|
2180
|
+
return existing;
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
return fallback;
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
// src/widgets/hidden_ports.ts
|
|
2187
|
+
var HiddenPortsToggle = class extends WidgetBase {
|
|
2188
|
+
constructor(owner) {
|
|
2189
|
+
super();
|
|
2190
|
+
this.owner = owner;
|
|
2191
|
+
}
|
|
2192
|
+
Size() {
|
|
2193
|
+
return { x: 150, y: 16 };
|
|
2194
|
+
}
|
|
2195
|
+
render(ctx, box, scale) {
|
|
2196
|
+
const label = this.owner.hiddenPortsShown() ? "\u25B4 less" : `\u25BE ${this.owner.hiddenPortCount()} more`;
|
|
2197
|
+
const midY = box.Position.y + box.Size.y / 2;
|
|
2198
|
+
const centerX = box.Position.x + box.Size.x / 2;
|
|
2199
|
+
ctx.font = `${11 * scale}px ${Theme.FontFamily}`;
|
|
2200
|
+
const half = ctx.measureText(label).width / 2 + 6 * scale;
|
|
2201
|
+
ctx.globalAlpha = this.hovered() ? 1 : 0.5;
|
|
2202
|
+
ctx.strokeStyle = Theme.Widget.FontColor;
|
|
2203
|
+
ctx.fillStyle = Theme.Widget.FontColor;
|
|
2204
|
+
ctx.lineWidth = Math.max(1, scale);
|
|
2205
|
+
ctx.beginPath();
|
|
2206
|
+
ctx.moveTo(box.Position.x, midY);
|
|
2207
|
+
ctx.lineTo(centerX - half, midY);
|
|
2208
|
+
ctx.moveTo(centerX + half, midY);
|
|
2209
|
+
ctx.lineTo(box.Position.x + box.Size.x, midY);
|
|
2210
|
+
ctx.stroke();
|
|
2211
|
+
ctx.textAlign = "center";
|
|
2212
|
+
ctx.textBaseline = "middle";
|
|
2213
|
+
ctx.fillText(label, centerX, midY);
|
|
2214
|
+
}
|
|
2215
|
+
onClick() {
|
|
2216
|
+
this.owner.setHiddenPortsShown(!this.owner.hiddenPortsShown());
|
|
2217
|
+
}
|
|
2218
|
+
};
|
|
2219
|
+
|
|
1942
2220
|
// src/styles/stroke.ts
|
|
1943
2221
|
function StrokeStyleWithFallback(input, fallback) {
|
|
1944
2222
|
return {
|
|
@@ -2050,27 +2328,6 @@ var BoxStyle = class {
|
|
|
2050
2328
|
}
|
|
2051
2329
|
};
|
|
2052
2330
|
|
|
2053
|
-
// src/styles/cursor.ts
|
|
2054
|
-
var CursorStyle = /* @__PURE__ */ ((CursorStyle2) => {
|
|
2055
|
-
CursorStyle2["Default"] = "default";
|
|
2056
|
-
CursorStyle2["Pointer"] = "pointer";
|
|
2057
|
-
CursorStyle2["Grab"] = "grab";
|
|
2058
|
-
CursorStyle2["Grabbing"] = "grabbing";
|
|
2059
|
-
CursorStyle2["Wait"] = "wait";
|
|
2060
|
-
CursorStyle2["Help"] = "help";
|
|
2061
|
-
CursorStyle2["Crosshair"] = "crosshair";
|
|
2062
|
-
CursorStyle2["Cell"] = "cell";
|
|
2063
|
-
CursorStyle2["Text"] = "text";
|
|
2064
|
-
CursorStyle2["Move"] = "move";
|
|
2065
|
-
CursorStyle2["NotAllowed"] = "not-allowed";
|
|
2066
|
-
CursorStyle2["ZoomIn"] = "zoom-in";
|
|
2067
|
-
CursorStyle2["ZoomOut"] = "zoom-out";
|
|
2068
|
-
CursorStyle2["None"] = "none";
|
|
2069
|
-
CursorStyle2["ContextMenu"] = "context-menu";
|
|
2070
|
-
CursorStyle2["EWResize"] = "ew-resize";
|
|
2071
|
-
return CursorStyle2;
|
|
2072
|
-
})(CursorStyle || {});
|
|
2073
|
-
|
|
2074
2331
|
// src/styles/bevel.ts
|
|
2075
2332
|
function drawBevel(ctx, box, scale, colors, sunken) {
|
|
2076
2333
|
const width2 = Math.max(1, 2 * scale);
|
|
@@ -2162,176 +2419,6 @@ function drawFieldText(ctx, box, scale, look) {
|
|
|
2162
2419
|
);
|
|
2163
2420
|
}
|
|
2164
2421
|
|
|
2165
|
-
// src/widgets/inplace.ts
|
|
2166
|
-
function editInPlace(config) {
|
|
2167
|
-
const canvas = config.canvas;
|
|
2168
|
-
if (canvas === null) {
|
|
2169
|
-
return null;
|
|
2170
|
-
}
|
|
2171
|
-
const rect = canvas.getBoundingClientRect();
|
|
2172
|
-
const sx = canvas.width > 0 ? rect.width / canvas.width : 1;
|
|
2173
|
-
const sy = canvas.height > 0 ? rect.height / canvas.height : 1;
|
|
2174
|
-
const input = document.createElement("input");
|
|
2175
|
-
input.type = "text";
|
|
2176
|
-
input.value = config.value;
|
|
2177
|
-
input.style.cssText = [
|
|
2178
|
-
"position: fixed",
|
|
2179
|
-
`left: ${rect.left + config.box.Position.x * sx}px`,
|
|
2180
|
-
`top: ${rect.top + config.box.Position.y * sy}px`,
|
|
2181
|
-
`width: ${config.box.Size.x * sx}px`,
|
|
2182
|
-
`height: ${config.box.Size.y * sy}px`,
|
|
2183
|
-
"box-sizing: border-box",
|
|
2184
|
-
"margin: 0",
|
|
2185
|
-
`padding: 0 ${Theme.Widget.Padding * config.scale}px`,
|
|
2186
|
-
`font: ${Theme.Widget.FontSize * config.scale * sy}px ${Theme.FontFamily}`,
|
|
2187
|
-
`color: ${Theme.Widget.FontColor}`,
|
|
2188
|
-
`background: ${Theme.Widget.Hover.BackgroundColor}`,
|
|
2189
|
-
`border: ${Theme.Widget.Border.Size * config.scale}px solid ${Theme.Widget.Border.Color}`,
|
|
2190
|
-
`border-radius: ${Theme.Widget.Border.Radius * config.scale}px`,
|
|
2191
|
-
"outline: none",
|
|
2192
|
-
"z-index: 1000"
|
|
2193
|
-
].join(";");
|
|
2194
|
-
let done = false;
|
|
2195
|
-
const finish = (keep) => {
|
|
2196
|
-
if (done) {
|
|
2197
|
-
return;
|
|
2198
|
-
}
|
|
2199
|
-
done = true;
|
|
2200
|
-
input.remove();
|
|
2201
|
-
if (keep) {
|
|
2202
|
-
config.onCommit(input.value);
|
|
2203
|
-
}
|
|
2204
|
-
requestRender();
|
|
2205
|
-
};
|
|
2206
|
-
input.addEventListener("keydown", (event) => {
|
|
2207
|
-
event.stopPropagation();
|
|
2208
|
-
if (event.key === "Enter") {
|
|
2209
|
-
event.preventDefault();
|
|
2210
|
-
finish(true);
|
|
2211
|
-
} else if (event.key === "Escape") {
|
|
2212
|
-
event.preventDefault();
|
|
2213
|
-
finish(false);
|
|
2214
|
-
}
|
|
2215
|
-
});
|
|
2216
|
-
input.addEventListener("blur", () => finish(true));
|
|
2217
|
-
document.body.appendChild(input);
|
|
2218
|
-
input.focus();
|
|
2219
|
-
input.select();
|
|
2220
|
-
return input;
|
|
2221
|
-
}
|
|
2222
|
-
|
|
2223
|
-
// src/widgets/widget.ts
|
|
2224
|
-
var width = 150;
|
|
2225
|
-
var height = 25;
|
|
2226
|
-
var WidgetBase = class {
|
|
2227
|
-
#hidden = false;
|
|
2228
|
-
#disabled = false;
|
|
2229
|
-
#hovered = false;
|
|
2230
|
-
#pressed = false;
|
|
2231
|
-
#box = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };
|
|
2232
|
-
#canvas = null;
|
|
2233
|
-
#scale = 1;
|
|
2234
|
-
Draw(ctx, box, scale, mousePosition) {
|
|
2235
|
-
this.#box = { Position: { x: box.Position.x, y: box.Position.y }, Size: { x: box.Size.x, y: box.Size.y } };
|
|
2236
|
-
this.#canvas = ctx.canvas ?? null;
|
|
2237
|
-
this.#scale = scale;
|
|
2238
|
-
this.#hovered = !this.#disabled && mousePosition !== void 0 && InBox(box, mousePosition);
|
|
2239
|
-
ctx.save();
|
|
2240
|
-
if (this.#disabled) {
|
|
2241
|
-
ctx.globalAlpha *= 0.4;
|
|
2242
|
-
}
|
|
2243
|
-
this.render(ctx, box, scale);
|
|
2244
|
-
ctx.restore();
|
|
2245
|
-
}
|
|
2246
|
-
PointerDown(pointer) {
|
|
2247
|
-
if (this.#disabled) {
|
|
2248
|
-
return;
|
|
2249
|
-
}
|
|
2250
|
-
this.#pressed = true;
|
|
2251
|
-
this.onPointerDown(pointer);
|
|
2252
|
-
requestRender();
|
|
2253
|
-
}
|
|
2254
|
-
PointerMove(pointer) {
|
|
2255
|
-
if (!this.#pressed) {
|
|
2256
|
-
return;
|
|
2257
|
-
}
|
|
2258
|
-
this.onPointerMove(pointer);
|
|
2259
|
-
requestRender();
|
|
2260
|
-
}
|
|
2261
|
-
PointerUp(pointer) {
|
|
2262
|
-
if (!this.#pressed) {
|
|
2263
|
-
return;
|
|
2264
|
-
}
|
|
2265
|
-
this.#pressed = false;
|
|
2266
|
-
this.onPointerUp(pointer);
|
|
2267
|
-
if (pointer.inside) {
|
|
2268
|
-
this.onClick(pointer);
|
|
2269
|
-
}
|
|
2270
|
-
requestRender();
|
|
2271
|
-
}
|
|
2272
|
-
Cursor() {
|
|
2273
|
-
return "pointer" /* Pointer */;
|
|
2274
|
-
}
|
|
2275
|
-
Hidden() {
|
|
2276
|
-
return this.#hidden;
|
|
2277
|
-
}
|
|
2278
|
-
setHidden(hidden) {
|
|
2279
|
-
this.#hidden = hidden;
|
|
2280
|
-
requestRender();
|
|
2281
|
-
}
|
|
2282
|
-
Disabled() {
|
|
2283
|
-
return this.#disabled;
|
|
2284
|
-
}
|
|
2285
|
-
setDisabled(disabled) {
|
|
2286
|
-
this.#disabled = disabled;
|
|
2287
|
-
if (disabled) {
|
|
2288
|
-
this.#pressed = false;
|
|
2289
|
-
}
|
|
2290
|
-
requestRender();
|
|
2291
|
-
}
|
|
2292
|
-
hovered() {
|
|
2293
|
-
return this.#hovered;
|
|
2294
|
-
}
|
|
2295
|
-
pressed() {
|
|
2296
|
-
return this.#pressed;
|
|
2297
|
-
}
|
|
2298
|
-
/**
|
|
2299
|
-
* Where the widget was last drawn, in canvas pixels.
|
|
2300
|
-
*/
|
|
2301
|
-
box() {
|
|
2302
|
-
return this.#box;
|
|
2303
|
-
}
|
|
2304
|
-
canvas() {
|
|
2305
|
-
return this.#canvas;
|
|
2306
|
-
}
|
|
2307
|
-
scale() {
|
|
2308
|
-
return this.#scale;
|
|
2309
|
-
}
|
|
2310
|
-
onPointerDown(pointer) {
|
|
2311
|
-
}
|
|
2312
|
-
onPointerMove(pointer) {
|
|
2313
|
-
}
|
|
2314
|
-
onPointerUp(pointer) {
|
|
2315
|
-
}
|
|
2316
|
-
/**
|
|
2317
|
-
* A press and release that both landed on the widget.
|
|
2318
|
-
*/
|
|
2319
|
-
onClick(pointer) {
|
|
2320
|
-
}
|
|
2321
|
-
};
|
|
2322
|
-
function startingWidgetValue(node, property, configured, fallback) {
|
|
2323
|
-
if (configured !== void 0) {
|
|
2324
|
-
return configured;
|
|
2325
|
-
}
|
|
2326
|
-
if (property !== void 0 && property !== null) {
|
|
2327
|
-
const existing = node.getProperty(property);
|
|
2328
|
-
if (existing !== void 0 && existing !== null) {
|
|
2329
|
-
return existing;
|
|
2330
|
-
}
|
|
2331
|
-
}
|
|
2332
|
-
return fallback;
|
|
2333
|
-
}
|
|
2334
|
-
|
|
2335
2422
|
// src/widgets/value.ts
|
|
2336
2423
|
var ValueWidget = class extends WidgetBase {
|
|
2337
2424
|
#node;
|
|
@@ -2466,16 +2553,10 @@ var NumberWidget = class extends ValueWidget {
|
|
|
2466
2553
|
return;
|
|
2467
2554
|
}
|
|
2468
2555
|
const before = this.value();
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
value: String(before),
|
|
2474
|
-
onCommit: (text) => {
|
|
2475
|
-
const parsed = Number.parseFloat(text);
|
|
2476
|
-
if (Number.isFinite(parsed)) {
|
|
2477
|
-
this.commit(this.#clean(parsed), before);
|
|
2478
|
-
}
|
|
2556
|
+
this.editText(String(before), (text) => {
|
|
2557
|
+
const parsed = Number.parseFloat(text);
|
|
2558
|
+
if (Number.isFinite(parsed)) {
|
|
2559
|
+
this.commit(this.#clean(parsed), before);
|
|
2479
2560
|
}
|
|
2480
2561
|
});
|
|
2481
2562
|
}
|
|
@@ -2683,13 +2764,7 @@ var StringWidget = class extends ValueWidget {
|
|
|
2683
2764
|
}
|
|
2684
2765
|
onClick() {
|
|
2685
2766
|
const before = this.value();
|
|
2686
|
-
|
|
2687
|
-
canvas: this.canvas(),
|
|
2688
|
-
box: this.box(),
|
|
2689
|
-
scale: this.scale(),
|
|
2690
|
-
value: before,
|
|
2691
|
-
onCommit: (text) => this.commit(text, before)
|
|
2692
|
-
});
|
|
2767
|
+
this.editText(before, (text) => this.commit(text, before));
|
|
2693
2768
|
}
|
|
2694
2769
|
};
|
|
2695
2770
|
|
|
@@ -5600,7 +5675,8 @@ var FlowNode = class {
|
|
|
5600
5675
|
size.y += this.#portRowHeight(port, tempMeasurement.y) + this.#elementSpacing;
|
|
5601
5676
|
size.x = Math.max(size.x, tempMeasurement.x + doublePadding);
|
|
5602
5677
|
}
|
|
5603
|
-
|
|
5678
|
+
const widgets = this.#hasHiddenPortsToggle() ? [this.#hiddenPortsToggle, ...this.#widgets] : this.#widgets;
|
|
5679
|
+
for (const widget of widgets) {
|
|
5604
5680
|
if (widget.Hidden?.()) {
|
|
5605
5681
|
continue;
|
|
5606
5682
|
}
|
|
@@ -5626,6 +5702,31 @@ var FlowNode = class {
|
|
|
5626
5702
|
this.#output.push(port);
|
|
5627
5703
|
return port;
|
|
5628
5704
|
}
|
|
5705
|
+
#hiddenPortsShown = false;
|
|
5706
|
+
#hiddenPortsToggle = new HiddenPortsToggle(this);
|
|
5707
|
+
#hiddenPortsTogglePosition = null;
|
|
5708
|
+
hiddenPortsShown() {
|
|
5709
|
+
return this.#hiddenPortsShown;
|
|
5710
|
+
}
|
|
5711
|
+
setHiddenPortsShown(shown) {
|
|
5712
|
+
if (shown === this.#hiddenPortsShown) {
|
|
5713
|
+
return;
|
|
5714
|
+
}
|
|
5715
|
+
this.#hiddenPortsShown = shown;
|
|
5716
|
+
this.invalidateLayout();
|
|
5717
|
+
}
|
|
5718
|
+
hiddenPortCount() {
|
|
5719
|
+
let count = 0;
|
|
5720
|
+
for (const port of [...this.#input, ...this.#output]) {
|
|
5721
|
+
if (port.tucked()) {
|
|
5722
|
+
count++;
|
|
5723
|
+
}
|
|
5724
|
+
}
|
|
5725
|
+
return count;
|
|
5726
|
+
}
|
|
5727
|
+
#hasHiddenPortsToggle() {
|
|
5728
|
+
return this.hiddenPortCount() > 0;
|
|
5729
|
+
}
|
|
5629
5730
|
addWidget(widget) {
|
|
5630
5731
|
this.#widgets.push(widget);
|
|
5631
5732
|
requestRender();
|
|
@@ -5704,6 +5805,11 @@ var FlowNode = class {
|
|
|
5704
5805
|
intersection.Port = this.#output[i];
|
|
5705
5806
|
}
|
|
5706
5807
|
}
|
|
5808
|
+
if (this.#hiddenPortsTogglePosition !== null && InBox(this.#hiddenPortsTogglePosition, position)) {
|
|
5809
|
+
intersection.Node = this;
|
|
5810
|
+
intersection.Widget = this.#hiddenPortsToggle;
|
|
5811
|
+
intersection.WidgetBox = this.#hiddenPortsTogglePosition;
|
|
5812
|
+
}
|
|
5707
5813
|
for (let i = 0; i < this.#widgetPositions.Count(); i++) {
|
|
5708
5814
|
const widget = this.#widgets[i];
|
|
5709
5815
|
if (widget !== void 0 && !widget.Hidden?.() && InBox(this.#widgetPositions.At(i), position)) {
|
|
@@ -5973,6 +6079,16 @@ var FlowNode = class {
|
|
|
5973
6079
|
this.#outputPortPositions.Push(port.render(ctx, position, camera, mousePosition, postProcess));
|
|
5974
6080
|
startY += portHeight + scaledElementSpacing;
|
|
5975
6081
|
}
|
|
6082
|
+
this.#hiddenPortsTogglePosition = null;
|
|
6083
|
+
if (this.#hasHiddenPortsToggle()) {
|
|
6084
|
+
const box = {
|
|
6085
|
+
Position: { x: nodeBounds.Position.x + scaledPadding, y: startY },
|
|
6086
|
+
Size: { x: nodeBounds.Size.x - scaledPadding * 2, y: this.#hiddenPortsToggle.Size().y * camera.zoom }
|
|
6087
|
+
};
|
|
6088
|
+
this.#hiddenPortsToggle.Draw(ctx, box, camera.zoom, mousePosition);
|
|
6089
|
+
this.#hiddenPortsTogglePosition = box;
|
|
6090
|
+
startY += box.Size.y + scaledElementSpacing;
|
|
6091
|
+
}
|
|
5976
6092
|
for (let i = 0; i < this.#widgets.length; i++) {
|
|
5977
6093
|
const widget = this.#widgets[i];
|
|
5978
6094
|
if (widget.Hidden?.()) {
|
|
@@ -6027,6 +6143,7 @@ var FlowNode = class {
|
|
|
6027
6143
|
return false;
|
|
6028
6144
|
}
|
|
6029
6145
|
this.#widgetPositions.Clear();
|
|
6146
|
+
this.#hiddenPortsTogglePosition = null;
|
|
6030
6147
|
return true;
|
|
6031
6148
|
}
|
|
6032
6149
|
placePorts(bounds, zoom) {
|
|
@@ -7687,8 +7804,8 @@ var NodeFlowGraph = class {
|
|
|
7687
7804
|
this.#clickEnd.bind(this),
|
|
7688
7805
|
this.#openContextMenu.bind(this),
|
|
7689
7806
|
this.#fileDrop.bind(this),
|
|
7690
|
-
(
|
|
7691
|
-
this
|
|
7807
|
+
(factor, anchor) => {
|
|
7808
|
+
this.#zoomBy(factor, anchor);
|
|
7692
7809
|
}
|
|
7693
7810
|
);
|
|
7694
7811
|
document.addEventListener(
|
|
@@ -7816,12 +7933,15 @@ var NodeFlowGraph = class {
|
|
|
7816
7933
|
this.#mainNoteSubsystem.addNoteDragStopListener(callback);
|
|
7817
7934
|
}
|
|
7818
7935
|
zoom(amount, anchor) {
|
|
7936
|
+
this.#zoomBy(1 + amount * 0.05, anchor);
|
|
7937
|
+
}
|
|
7938
|
+
#zoomBy(factor, anchor) {
|
|
7819
7939
|
const anchorPos = anchor ?? this.#mousePosition;
|
|
7820
7940
|
let oldPos = void 0;
|
|
7821
7941
|
if (anchorPos !== void 0) {
|
|
7822
7942
|
oldPos = this.#sceenPositionToGraphPosition(anchorPos);
|
|
7823
7943
|
}
|
|
7824
|
-
this.#camera.zoom
|
|
7944
|
+
this.#camera.zoom *= factor;
|
|
7825
7945
|
if (!oldPos || anchorPos === void 0) {
|
|
7826
7946
|
return;
|
|
7827
7947
|
}
|
|
@@ -8086,10 +8206,12 @@ var NodeFlowGraph = class {
|
|
|
8086
8206
|
this.#cursor = "default" /* Default */;
|
|
8087
8207
|
TimeExecution("Render_Background", this.#renderBackground.bind(this));
|
|
8088
8208
|
TimeExecution("Render_View_" + this.#currentView, () => {
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8209
|
+
placeEditsDuring(this.#canvas, () => {
|
|
8210
|
+
let results = this.currentView().render(this.#ctx, this.#camera, this.#mousePosition);
|
|
8211
|
+
if (results?.cursorStyle) {
|
|
8212
|
+
this.#cursor = results?.cursorStyle;
|
|
8213
|
+
}
|
|
8214
|
+
});
|
|
8093
8215
|
});
|
|
8094
8216
|
TimeExecution("Render_Minimap", () => {
|
|
8095
8217
|
this.#minimap.render(this.#ctx, this.#canvas, this.#camera, this.#mainNodeSubsystem.getNodes());
|