@elicdavis/node-flow 0.2.1 → 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 +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +294 -212
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +294 -212
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/graph.ts +7 -3
- 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/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/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,117 +1872,6 @@ var Port = class {
|
|
|
1869
1872
|
}
|
|
1870
1873
|
};
|
|
1871
1874
|
|
|
1872
|
-
// src/styles/stroke.ts
|
|
1873
|
-
function StrokeStyleWithFallback(input, fallback) {
|
|
1874
|
-
return {
|
|
1875
|
-
color: input?.color === void 0 ? fallback?.color : input?.color,
|
|
1876
|
-
size: input?.size === void 0 ? fallback?.size : input?.size
|
|
1877
|
-
};
|
|
1878
|
-
}
|
|
1879
|
-
var StrokeStyle = class {
|
|
1880
|
-
#size;
|
|
1881
|
-
#color;
|
|
1882
|
-
constructor(config) {
|
|
1883
|
-
this.#size = config?.size === void 0 ? 0.5 : config.size;
|
|
1884
|
-
this.#color = config?.color === void 0 ? "black" : config.color;
|
|
1885
|
-
}
|
|
1886
|
-
setupStyle(ctx, scale) {
|
|
1887
|
-
ctx.strokeStyle = this.#color;
|
|
1888
|
-
ctx.lineWidth = scale * this.#size;
|
|
1889
|
-
}
|
|
1890
|
-
setColor(newColor) {
|
|
1891
|
-
this.#color = newColor;
|
|
1892
|
-
}
|
|
1893
|
-
setSize(newSize) {
|
|
1894
|
-
this.#size = newSize;
|
|
1895
|
-
}
|
|
1896
|
-
size() {
|
|
1897
|
-
return this.#size;
|
|
1898
|
-
}
|
|
1899
|
-
};
|
|
1900
|
-
|
|
1901
|
-
// src/styles/box.ts
|
|
1902
|
-
function BoxStyleWithFallback(input, fallback) {
|
|
1903
|
-
return {
|
|
1904
|
-
radius: input?.radius === void 0 ? fallback?.radius : input?.radius,
|
|
1905
|
-
color: input?.color === void 0 ? fallback?.color : input?.color,
|
|
1906
|
-
border: StrokeStyleWithFallback(input?.border, fallback?.border)
|
|
1907
|
-
};
|
|
1908
|
-
}
|
|
1909
|
-
var BoxStyle = class {
|
|
1910
|
-
#border;
|
|
1911
|
-
#color;
|
|
1912
|
-
#radius;
|
|
1913
|
-
constructor(config) {
|
|
1914
|
-
this.#color = config?.color === void 0 ? "#CCCCCC" : config.color;
|
|
1915
|
-
this.#border = config?.border === void 0 ? null : new StrokeStyle(config.border);
|
|
1916
|
-
this.#radius = config?.radius === void 0 ? 2 : config.radius;
|
|
1917
|
-
}
|
|
1918
|
-
#box(ctx, box, scale, radius) {
|
|
1919
|
-
ctx.fillStyle = this.#color;
|
|
1920
|
-
this.#border?.setupStyle(ctx, scale);
|
|
1921
|
-
ctx.beginPath();
|
|
1922
|
-
ctx.roundRect(
|
|
1923
|
-
box.Position.x,
|
|
1924
|
-
box.Position.y,
|
|
1925
|
-
box.Size.x,
|
|
1926
|
-
box.Size.y,
|
|
1927
|
-
radius
|
|
1928
|
-
);
|
|
1929
|
-
ctx.fill();
|
|
1930
|
-
}
|
|
1931
|
-
#draw(ctx, box, scale, radius) {
|
|
1932
|
-
this.#box(ctx, box, scale, radius);
|
|
1933
|
-
ctx.stroke();
|
|
1934
|
-
}
|
|
1935
|
-
Outline(ctx, box, scale, radius) {
|
|
1936
|
-
this.#border?.setupStyle(ctx, scale);
|
|
1937
|
-
ctx.beginPath();
|
|
1938
|
-
ctx.roundRect(
|
|
1939
|
-
box.Position.x,
|
|
1940
|
-
box.Position.y,
|
|
1941
|
-
box.Size.x,
|
|
1942
|
-
box.Size.y,
|
|
1943
|
-
radius
|
|
1944
|
-
);
|
|
1945
|
-
ctx.stroke();
|
|
1946
|
-
}
|
|
1947
|
-
Draw(ctx, box, scale) {
|
|
1948
|
-
this.#draw(ctx, box, scale, this.#radius * scale);
|
|
1949
|
-
}
|
|
1950
|
-
DrawRoundedTopOnly(ctx, box, scale) {
|
|
1951
|
-
this.#draw(ctx, box, scale, [this.#radius * scale * 2, this.#radius * scale * 2, 0, 0]);
|
|
1952
|
-
}
|
|
1953
|
-
DrawUnderline(ctx, box, scale) {
|
|
1954
|
-
this.#box(ctx, box, scale, [this.#radius * scale * 2, this.#radius * scale * 2, 0, 0]);
|
|
1955
|
-
ctx.beginPath();
|
|
1956
|
-
ctx.moveTo(box.Position.x, box.Position.y + box.Size.y);
|
|
1957
|
-
ctx.lineTo(box.Position.x + box.Size.x, box.Position.y + box.Size.y);
|
|
1958
|
-
ctx.stroke();
|
|
1959
|
-
}
|
|
1960
|
-
borderSize() {
|
|
1961
|
-
if (this.#border === null) {
|
|
1962
|
-
return 0;
|
|
1963
|
-
}
|
|
1964
|
-
return this.#border.size();
|
|
1965
|
-
}
|
|
1966
|
-
radius() {
|
|
1967
|
-
return this.#radius;
|
|
1968
|
-
}
|
|
1969
|
-
setColor(color) {
|
|
1970
|
-
this.#color = color;
|
|
1971
|
-
}
|
|
1972
|
-
setBorderColor(color) {
|
|
1973
|
-
if (this.#border === null) {
|
|
1974
|
-
this.#border = new StrokeStyle({
|
|
1975
|
-
color
|
|
1976
|
-
});
|
|
1977
|
-
} else {
|
|
1978
|
-
this.#border.setColor(color);
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
|
-
};
|
|
1982
|
-
|
|
1983
1875
|
// src/styles/cursor.ts
|
|
1984
1876
|
var CursorStyle = /* @__PURE__ */ ((CursorStyle2) => {
|
|
1985
1877
|
CursorStyle2["Default"] = "default";
|
|
@@ -2001,97 +1893,6 @@ var CursorStyle = /* @__PURE__ */ ((CursorStyle2) => {
|
|
|
2001
1893
|
return CursorStyle2;
|
|
2002
1894
|
})(CursorStyle || {});
|
|
2003
1895
|
|
|
2004
|
-
// src/styles/bevel.ts
|
|
2005
|
-
function drawBevel(ctx, box, scale, colors, sunken) {
|
|
2006
|
-
const width2 = Math.max(1, 2 * scale);
|
|
2007
|
-
const half = width2 / 2;
|
|
2008
|
-
const left = box.Position.x + half;
|
|
2009
|
-
const top = box.Position.y + half;
|
|
2010
|
-
const right = box.Position.x + box.Size.x - half;
|
|
2011
|
-
const bottom = box.Position.y + box.Size.y - half;
|
|
2012
|
-
ctx.save();
|
|
2013
|
-
ctx.lineWidth = width2;
|
|
2014
|
-
ctx.lineCap = "square";
|
|
2015
|
-
ctx.strokeStyle = sunken ? colors.Dark : colors.Light;
|
|
2016
|
-
ctx.beginPath();
|
|
2017
|
-
ctx.moveTo(left, bottom);
|
|
2018
|
-
ctx.lineTo(left, top);
|
|
2019
|
-
ctx.lineTo(right, top);
|
|
2020
|
-
ctx.stroke();
|
|
2021
|
-
ctx.strokeStyle = sunken ? colors.Light : colors.Dark;
|
|
2022
|
-
ctx.beginPath();
|
|
2023
|
-
ctx.moveTo(right, top);
|
|
2024
|
-
ctx.lineTo(right, bottom);
|
|
2025
|
-
ctx.lineTo(left, bottom);
|
|
2026
|
-
ctx.stroke();
|
|
2027
|
-
ctx.restore();
|
|
2028
|
-
}
|
|
2029
|
-
|
|
2030
|
-
// src/widgets/field.ts
|
|
2031
|
-
function widgetFont(scale) {
|
|
2032
|
-
return `${Theme.Widget.FontSize * scale}px ${Theme.FontFamily}`;
|
|
2033
|
-
}
|
|
2034
|
-
function fieldBackground(look) {
|
|
2035
|
-
if (look.background !== void 0) {
|
|
2036
|
-
return look.background;
|
|
2037
|
-
}
|
|
2038
|
-
if (look.input) {
|
|
2039
|
-
return look.hovered ? Theme.Widget.Input.HoverBackgroundColor : Theme.Widget.Input.BackgroundColor;
|
|
2040
|
-
}
|
|
2041
|
-
if (look.pressed) {
|
|
2042
|
-
return Theme.Widget.Button.Click.BackgroundColor;
|
|
2043
|
-
}
|
|
2044
|
-
return look.hovered ? Theme.Widget.Hover.BackgroundColor : Theme.Widget.BackgroundColor;
|
|
2045
|
-
}
|
|
2046
|
-
function drawFieldBox(ctx, box, scale, look) {
|
|
2047
|
-
ctx.fillStyle = fieldBackground(look);
|
|
2048
|
-
ctx.beginPath();
|
|
2049
|
-
ctx.roundRect(box.Position.x, box.Position.y, box.Size.x, box.Size.y, Theme.Widget.Border.Radius * scale);
|
|
2050
|
-
ctx.fill();
|
|
2051
|
-
if (Theme.Widget.Border.Size > 0) {
|
|
2052
|
-
ctx.strokeStyle = look.border ?? Theme.Widget.Border.Color;
|
|
2053
|
-
ctx.lineWidth = Theme.Widget.Border.Size * scale;
|
|
2054
|
-
ctx.stroke();
|
|
2055
|
-
}
|
|
2056
|
-
if (Theme.Widget.Bevel !== null) {
|
|
2057
|
-
drawBevel(ctx, box, scale, Theme.Widget.Bevel, look.input === true || look.pressed === true);
|
|
2058
|
-
}
|
|
2059
|
-
}
|
|
2060
|
-
function drawField(ctx, box, scale, look) {
|
|
2061
|
-
drawFieldBox(ctx, box, scale, look);
|
|
2062
|
-
drawFieldText(ctx, box, scale, look);
|
|
2063
|
-
}
|
|
2064
|
-
function drawFieldText(ctx, box, scale, look) {
|
|
2065
|
-
const padding = Theme.Widget.Padding * scale;
|
|
2066
|
-
const middle = box.Position.y + box.Size.y / 2;
|
|
2067
|
-
const textColor = look.textColor ?? (look.input ? Theme.Widget.Input.FontColor : Theme.Widget.FontColor);
|
|
2068
|
-
ctx.font = widgetFont(scale);
|
|
2069
|
-
ctx.textBaseline = "middle";
|
|
2070
|
-
if (look.label === void 0 || look.label === "") {
|
|
2071
|
-
ctx.textAlign = "center";
|
|
2072
|
-
ctx.fillStyle = textColor;
|
|
2073
|
-
ctx.fillText(
|
|
2074
|
-
fitString(ctx, look.value, box.Size.x - padding * 2),
|
|
2075
|
-
box.Position.x + box.Size.x / 2,
|
|
2076
|
-
middle
|
|
2077
|
-
);
|
|
2078
|
-
return;
|
|
2079
|
-
}
|
|
2080
|
-
const room = box.Size.x - padding * 2;
|
|
2081
|
-
const label = fitString(ctx, look.label, room / 2);
|
|
2082
|
-
const labelWidth = ctx.measureText(label).width;
|
|
2083
|
-
ctx.textAlign = "left";
|
|
2084
|
-
ctx.fillStyle = look.textColor ?? Theme.Widget.LabelColor;
|
|
2085
|
-
ctx.fillText(label, box.Position.x + padding, middle);
|
|
2086
|
-
ctx.textAlign = "right";
|
|
2087
|
-
ctx.fillStyle = textColor;
|
|
2088
|
-
ctx.fillText(
|
|
2089
|
-
fitString(ctx, look.value, room - labelWidth - padding),
|
|
2090
|
-
box.Position.x + box.Size.x - padding,
|
|
2091
|
-
middle
|
|
2092
|
-
);
|
|
2093
|
-
}
|
|
2094
|
-
|
|
2095
1896
|
// src/widgets/inplace.ts
|
|
2096
1897
|
var open = /* @__PURE__ */ new Set();
|
|
2097
1898
|
function placeEditsDuring(canvas, draw) {
|
|
@@ -2312,6 +2113,242 @@ function startingWidgetValue(node, property, configured, fallback) {
|
|
|
2312
2113
|
return fallback;
|
|
2313
2114
|
}
|
|
2314
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
|
+
|
|
2150
|
+
// src/styles/stroke.ts
|
|
2151
|
+
function StrokeStyleWithFallback(input, fallback) {
|
|
2152
|
+
return {
|
|
2153
|
+
color: input?.color === void 0 ? fallback?.color : input?.color,
|
|
2154
|
+
size: input?.size === void 0 ? fallback?.size : input?.size
|
|
2155
|
+
};
|
|
2156
|
+
}
|
|
2157
|
+
var StrokeStyle = class {
|
|
2158
|
+
#size;
|
|
2159
|
+
#color;
|
|
2160
|
+
constructor(config) {
|
|
2161
|
+
this.#size = config?.size === void 0 ? 0.5 : config.size;
|
|
2162
|
+
this.#color = config?.color === void 0 ? "black" : config.color;
|
|
2163
|
+
}
|
|
2164
|
+
setupStyle(ctx, scale) {
|
|
2165
|
+
ctx.strokeStyle = this.#color;
|
|
2166
|
+
ctx.lineWidth = scale * this.#size;
|
|
2167
|
+
}
|
|
2168
|
+
setColor(newColor) {
|
|
2169
|
+
this.#color = newColor;
|
|
2170
|
+
}
|
|
2171
|
+
setSize(newSize) {
|
|
2172
|
+
this.#size = newSize;
|
|
2173
|
+
}
|
|
2174
|
+
size() {
|
|
2175
|
+
return this.#size;
|
|
2176
|
+
}
|
|
2177
|
+
};
|
|
2178
|
+
|
|
2179
|
+
// src/styles/box.ts
|
|
2180
|
+
function BoxStyleWithFallback(input, fallback) {
|
|
2181
|
+
return {
|
|
2182
|
+
radius: input?.radius === void 0 ? fallback?.radius : input?.radius,
|
|
2183
|
+
color: input?.color === void 0 ? fallback?.color : input?.color,
|
|
2184
|
+
border: StrokeStyleWithFallback(input?.border, fallback?.border)
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
2187
|
+
var BoxStyle = class {
|
|
2188
|
+
#border;
|
|
2189
|
+
#color;
|
|
2190
|
+
#radius;
|
|
2191
|
+
constructor(config) {
|
|
2192
|
+
this.#color = config?.color === void 0 ? "#CCCCCC" : config.color;
|
|
2193
|
+
this.#border = config?.border === void 0 ? null : new StrokeStyle(config.border);
|
|
2194
|
+
this.#radius = config?.radius === void 0 ? 2 : config.radius;
|
|
2195
|
+
}
|
|
2196
|
+
#box(ctx, box, scale, radius) {
|
|
2197
|
+
ctx.fillStyle = this.#color;
|
|
2198
|
+
this.#border?.setupStyle(ctx, scale);
|
|
2199
|
+
ctx.beginPath();
|
|
2200
|
+
ctx.roundRect(
|
|
2201
|
+
box.Position.x,
|
|
2202
|
+
box.Position.y,
|
|
2203
|
+
box.Size.x,
|
|
2204
|
+
box.Size.y,
|
|
2205
|
+
radius
|
|
2206
|
+
);
|
|
2207
|
+
ctx.fill();
|
|
2208
|
+
}
|
|
2209
|
+
#draw(ctx, box, scale, radius) {
|
|
2210
|
+
this.#box(ctx, box, scale, radius);
|
|
2211
|
+
ctx.stroke();
|
|
2212
|
+
}
|
|
2213
|
+
Outline(ctx, box, scale, radius) {
|
|
2214
|
+
this.#border?.setupStyle(ctx, scale);
|
|
2215
|
+
ctx.beginPath();
|
|
2216
|
+
ctx.roundRect(
|
|
2217
|
+
box.Position.x,
|
|
2218
|
+
box.Position.y,
|
|
2219
|
+
box.Size.x,
|
|
2220
|
+
box.Size.y,
|
|
2221
|
+
radius
|
|
2222
|
+
);
|
|
2223
|
+
ctx.stroke();
|
|
2224
|
+
}
|
|
2225
|
+
Draw(ctx, box, scale) {
|
|
2226
|
+
this.#draw(ctx, box, scale, this.#radius * scale);
|
|
2227
|
+
}
|
|
2228
|
+
DrawRoundedTopOnly(ctx, box, scale) {
|
|
2229
|
+
this.#draw(ctx, box, scale, [this.#radius * scale * 2, this.#radius * scale * 2, 0, 0]);
|
|
2230
|
+
}
|
|
2231
|
+
DrawUnderline(ctx, box, scale) {
|
|
2232
|
+
this.#box(ctx, box, scale, [this.#radius * scale * 2, this.#radius * scale * 2, 0, 0]);
|
|
2233
|
+
ctx.beginPath();
|
|
2234
|
+
ctx.moveTo(box.Position.x, box.Position.y + box.Size.y);
|
|
2235
|
+
ctx.lineTo(box.Position.x + box.Size.x, box.Position.y + box.Size.y);
|
|
2236
|
+
ctx.stroke();
|
|
2237
|
+
}
|
|
2238
|
+
borderSize() {
|
|
2239
|
+
if (this.#border === null) {
|
|
2240
|
+
return 0;
|
|
2241
|
+
}
|
|
2242
|
+
return this.#border.size();
|
|
2243
|
+
}
|
|
2244
|
+
radius() {
|
|
2245
|
+
return this.#radius;
|
|
2246
|
+
}
|
|
2247
|
+
setColor(color) {
|
|
2248
|
+
this.#color = color;
|
|
2249
|
+
}
|
|
2250
|
+
setBorderColor(color) {
|
|
2251
|
+
if (this.#border === null) {
|
|
2252
|
+
this.#border = new StrokeStyle({
|
|
2253
|
+
color
|
|
2254
|
+
});
|
|
2255
|
+
} else {
|
|
2256
|
+
this.#border.setColor(color);
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
};
|
|
2260
|
+
|
|
2261
|
+
// src/styles/bevel.ts
|
|
2262
|
+
function drawBevel(ctx, box, scale, colors, sunken) {
|
|
2263
|
+
const width2 = Math.max(1, 2 * scale);
|
|
2264
|
+
const half = width2 / 2;
|
|
2265
|
+
const left = box.Position.x + half;
|
|
2266
|
+
const top = box.Position.y + half;
|
|
2267
|
+
const right = box.Position.x + box.Size.x - half;
|
|
2268
|
+
const bottom = box.Position.y + box.Size.y - half;
|
|
2269
|
+
ctx.save();
|
|
2270
|
+
ctx.lineWidth = width2;
|
|
2271
|
+
ctx.lineCap = "square";
|
|
2272
|
+
ctx.strokeStyle = sunken ? colors.Dark : colors.Light;
|
|
2273
|
+
ctx.beginPath();
|
|
2274
|
+
ctx.moveTo(left, bottom);
|
|
2275
|
+
ctx.lineTo(left, top);
|
|
2276
|
+
ctx.lineTo(right, top);
|
|
2277
|
+
ctx.stroke();
|
|
2278
|
+
ctx.strokeStyle = sunken ? colors.Light : colors.Dark;
|
|
2279
|
+
ctx.beginPath();
|
|
2280
|
+
ctx.moveTo(right, top);
|
|
2281
|
+
ctx.lineTo(right, bottom);
|
|
2282
|
+
ctx.lineTo(left, bottom);
|
|
2283
|
+
ctx.stroke();
|
|
2284
|
+
ctx.restore();
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
// src/widgets/field.ts
|
|
2288
|
+
function widgetFont(scale) {
|
|
2289
|
+
return `${Theme.Widget.FontSize * scale}px ${Theme.FontFamily}`;
|
|
2290
|
+
}
|
|
2291
|
+
function fieldBackground(look) {
|
|
2292
|
+
if (look.background !== void 0) {
|
|
2293
|
+
return look.background;
|
|
2294
|
+
}
|
|
2295
|
+
if (look.input) {
|
|
2296
|
+
return look.hovered ? Theme.Widget.Input.HoverBackgroundColor : Theme.Widget.Input.BackgroundColor;
|
|
2297
|
+
}
|
|
2298
|
+
if (look.pressed) {
|
|
2299
|
+
return Theme.Widget.Button.Click.BackgroundColor;
|
|
2300
|
+
}
|
|
2301
|
+
return look.hovered ? Theme.Widget.Hover.BackgroundColor : Theme.Widget.BackgroundColor;
|
|
2302
|
+
}
|
|
2303
|
+
function drawFieldBox(ctx, box, scale, look) {
|
|
2304
|
+
ctx.fillStyle = fieldBackground(look);
|
|
2305
|
+
ctx.beginPath();
|
|
2306
|
+
ctx.roundRect(box.Position.x, box.Position.y, box.Size.x, box.Size.y, Theme.Widget.Border.Radius * scale);
|
|
2307
|
+
ctx.fill();
|
|
2308
|
+
if (Theme.Widget.Border.Size > 0) {
|
|
2309
|
+
ctx.strokeStyle = look.border ?? Theme.Widget.Border.Color;
|
|
2310
|
+
ctx.lineWidth = Theme.Widget.Border.Size * scale;
|
|
2311
|
+
ctx.stroke();
|
|
2312
|
+
}
|
|
2313
|
+
if (Theme.Widget.Bevel !== null) {
|
|
2314
|
+
drawBevel(ctx, box, scale, Theme.Widget.Bevel, look.input === true || look.pressed === true);
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
function drawField(ctx, box, scale, look) {
|
|
2318
|
+
drawFieldBox(ctx, box, scale, look);
|
|
2319
|
+
drawFieldText(ctx, box, scale, look);
|
|
2320
|
+
}
|
|
2321
|
+
function drawFieldText(ctx, box, scale, look) {
|
|
2322
|
+
const padding = Theme.Widget.Padding * scale;
|
|
2323
|
+
const middle = box.Position.y + box.Size.y / 2;
|
|
2324
|
+
const textColor = look.textColor ?? (look.input ? Theme.Widget.Input.FontColor : Theme.Widget.FontColor);
|
|
2325
|
+
ctx.font = widgetFont(scale);
|
|
2326
|
+
ctx.textBaseline = "middle";
|
|
2327
|
+
if (look.label === void 0 || look.label === "") {
|
|
2328
|
+
ctx.textAlign = "center";
|
|
2329
|
+
ctx.fillStyle = textColor;
|
|
2330
|
+
ctx.fillText(
|
|
2331
|
+
fitString(ctx, look.value, box.Size.x - padding * 2),
|
|
2332
|
+
box.Position.x + box.Size.x / 2,
|
|
2333
|
+
middle
|
|
2334
|
+
);
|
|
2335
|
+
return;
|
|
2336
|
+
}
|
|
2337
|
+
const room = box.Size.x - padding * 2;
|
|
2338
|
+
const label = fitString(ctx, look.label, room / 2);
|
|
2339
|
+
const labelWidth = ctx.measureText(label).width;
|
|
2340
|
+
ctx.textAlign = "left";
|
|
2341
|
+
ctx.fillStyle = look.textColor ?? Theme.Widget.LabelColor;
|
|
2342
|
+
ctx.fillText(label, box.Position.x + padding, middle);
|
|
2343
|
+
ctx.textAlign = "right";
|
|
2344
|
+
ctx.fillStyle = textColor;
|
|
2345
|
+
ctx.fillText(
|
|
2346
|
+
fitString(ctx, look.value, room - labelWidth - padding),
|
|
2347
|
+
box.Position.x + box.Size.x - padding,
|
|
2348
|
+
middle
|
|
2349
|
+
);
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2315
2352
|
// src/widgets/value.ts
|
|
2316
2353
|
var ValueWidget = class extends WidgetBase {
|
|
2317
2354
|
#node;
|
|
@@ -5568,7 +5605,8 @@ var FlowNode = class {
|
|
|
5568
5605
|
size.y += this.#portRowHeight(port, tempMeasurement.y) + this.#elementSpacing;
|
|
5569
5606
|
size.x = Math.max(size.x, tempMeasurement.x + doublePadding);
|
|
5570
5607
|
}
|
|
5571
|
-
|
|
5608
|
+
const widgets = this.#hasHiddenPortsToggle() ? [this.#hiddenPortsToggle, ...this.#widgets] : this.#widgets;
|
|
5609
|
+
for (const widget of widgets) {
|
|
5572
5610
|
if (widget.Hidden?.()) {
|
|
5573
5611
|
continue;
|
|
5574
5612
|
}
|
|
@@ -5594,6 +5632,31 @@ var FlowNode = class {
|
|
|
5594
5632
|
this.#output.push(port);
|
|
5595
5633
|
return port;
|
|
5596
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
|
+
}
|
|
5597
5660
|
addWidget(widget) {
|
|
5598
5661
|
this.#widgets.push(widget);
|
|
5599
5662
|
requestRender();
|
|
@@ -5672,6 +5735,11 @@ var FlowNode = class {
|
|
|
5672
5735
|
intersection.Port = this.#output[i];
|
|
5673
5736
|
}
|
|
5674
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
|
+
}
|
|
5675
5743
|
for (let i = 0; i < this.#widgetPositions.Count(); i++) {
|
|
5676
5744
|
const widget = this.#widgets[i];
|
|
5677
5745
|
if (widget !== void 0 && !widget.Hidden?.() && InBox(this.#widgetPositions.At(i), position)) {
|
|
@@ -5941,6 +6009,16 @@ var FlowNode = class {
|
|
|
5941
6009
|
this.#outputPortPositions.Push(port.render(ctx, position, camera, mousePosition, postProcess));
|
|
5942
6010
|
startY += portHeight + scaledElementSpacing;
|
|
5943
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
|
+
}
|
|
5944
6022
|
for (let i = 0; i < this.#widgets.length; i++) {
|
|
5945
6023
|
const widget = this.#widgets[i];
|
|
5946
6024
|
if (widget.Hidden?.()) {
|
|
@@ -5995,6 +6073,7 @@ var FlowNode = class {
|
|
|
5995
6073
|
return false;
|
|
5996
6074
|
}
|
|
5997
6075
|
this.#widgetPositions.Clear();
|
|
6076
|
+
this.#hiddenPortsTogglePosition = null;
|
|
5998
6077
|
return true;
|
|
5999
6078
|
}
|
|
6000
6079
|
placePorts(bounds, zoom) {
|
|
@@ -7655,8 +7734,8 @@ var NodeFlowGraph = class {
|
|
|
7655
7734
|
this.#clickEnd.bind(this),
|
|
7656
7735
|
this.#openContextMenu.bind(this),
|
|
7657
7736
|
this.#fileDrop.bind(this),
|
|
7658
|
-
(
|
|
7659
|
-
this
|
|
7737
|
+
(factor, anchor) => {
|
|
7738
|
+
this.#zoomBy(factor, anchor);
|
|
7660
7739
|
}
|
|
7661
7740
|
);
|
|
7662
7741
|
document.addEventListener(
|
|
@@ -7784,12 +7863,15 @@ var NodeFlowGraph = class {
|
|
|
7784
7863
|
this.#mainNoteSubsystem.addNoteDragStopListener(callback);
|
|
7785
7864
|
}
|
|
7786
7865
|
zoom(amount, anchor) {
|
|
7866
|
+
this.#zoomBy(1 + amount * 0.05, anchor);
|
|
7867
|
+
}
|
|
7868
|
+
#zoomBy(factor, anchor) {
|
|
7787
7869
|
const anchorPos = anchor ?? this.#mousePosition;
|
|
7788
7870
|
let oldPos = void 0;
|
|
7789
7871
|
if (anchorPos !== void 0) {
|
|
7790
7872
|
oldPos = this.#sceenPositionToGraphPosition(anchorPos);
|
|
7791
7873
|
}
|
|
7792
|
-
this.#camera.zoom
|
|
7874
|
+
this.#camera.zoom *= factor;
|
|
7793
7875
|
if (!oldPos || anchorPos === void 0) {
|
|
7794
7876
|
return;
|
|
7795
7877
|
}
|