@elicdavis/node-flow 0.2.0 → 0.2.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/index.d.mts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +82 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +82 -42
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/graph.ts +7 -4
- package/src/index.ts +2 -2
- 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/support.ts +15 -2
- package/test/widgets.test.ts +54 -1
package/dist/index.d.mts
CHANGED
|
@@ -289,6 +289,7 @@ declare abstract class WidgetBase implements Widget {
|
|
|
289
289
|
protected box(): Box;
|
|
290
290
|
protected canvas(): HTMLCanvasElement | null;
|
|
291
291
|
protected scale(): number;
|
|
292
|
+
protected editText(value: string, onCommit: (text: string) => void): void;
|
|
292
293
|
protected onPointerDown(pointer: WidgetPointer): void;
|
|
293
294
|
protected onPointerMove(pointer: WidgetPointer): void;
|
|
294
295
|
protected onPointerUp(pointer: WidgetPointer): void;
|
|
@@ -1136,10 +1137,17 @@ interface InPlaceEditConfig {
|
|
|
1136
1137
|
value: string;
|
|
1137
1138
|
onCommit: (text: string) => void;
|
|
1138
1139
|
}
|
|
1140
|
+
interface InPlaceEdit {
|
|
1141
|
+
input: HTMLInputElement;
|
|
1142
|
+
/**
|
|
1143
|
+
* Moves the input over where the widget was just drawn, in canvas pixels.
|
|
1144
|
+
*/
|
|
1145
|
+
place(box: Box, scale: number): void;
|
|
1146
|
+
}
|
|
1139
1147
|
/**
|
|
1140
1148
|
* Lays a text input over a widget. Enter or clicking away keeps what was
|
|
1141
1149
|
* typed; Escape throws it away.
|
|
1142
1150
|
*/
|
|
1143
|
-
declare function editInPlace(config: InPlaceEditConfig):
|
|
1151
|
+
declare function editInPlace(config: InPlaceEditConfig): InPlaceEdit | null;
|
|
1144
1152
|
|
|
1145
|
-
export { type BevelColors, type Box, ButtonWidget, type ButtonWidgetConfig, type CameraOrientation, ColorWidget, type ColorWidgetConfig, Connection, type ConnectionRenderer, type ConnectionRendererParams, type ContextMenuConfig, type ContextMenuItemConfig, ContextMenuItemState, type CopyCallback, CursorStyle, type DanglingConnection, DefaultConnectionRenderer, DefaultTheme, type FieldLook, FlowNode, type FlowNodeConfig, type FlowNodeGraphConfiguration, type FlowNodeStyle, type FlowNodeTitleConfig, FlowNote, type FlowNoteConfig, GlobalWidgetFactory, type GraphRenderer, GraphView, ImageWidget, type ImageWidgetConfig, InBox, type InPlaceEditConfig, type InternalConnection, MessageType, Minimap, type MinimapConfig, type NodeCreatedCallback, NodeFactory, type NodeFactoryConfig, NodeFlowGraph, type NodeIntersection, type NodeMenuFilter, type NodeMessageConfig, NodeState, type NoteAddedCallback, type NoteContentChangeCallback, type NoteDragStartCallback, type NoteDragStopCallback, type NoteRemovedCallback, type NoteSubsystemConfig, type NoteWidthChangeCallback, NumberWidget, type NumberWidgetConfig, type PasteCallback, Port, type PortConfig, type PortStyle, PortType, Publisher, type PublisherConfig, RowWidget, type RowWidgetConfig, type RowWidgetFactoryConfig, SliderWidget, type SliderWidgetConfig, StringWidget, type StringWidgetConfig, TextWidget, type TextWidgetConfig, Theme, type ThemeConfig, type ThemeValues, ToggleWidget, type ToggleWidgetConfig, ValueWidget, type ValueWidgetConfig, type Vector2, type Widget, WidgetBase, type WidgetBuilder, type WidgetConfig, type WidgetConfigs, WidgetFactory, type WidgetPointer, type WidgetTypes, drawField, drawFieldBox, drawFieldText, editInPlace, formatNumber, onThemeChange, portConfigTypes, portsCompatible, renderContinuously, requestRender, setTheme, themeVersion, typeSetsCompatible, widgetFont };
|
|
1153
|
+
export { type BevelColors, type Box, ButtonWidget, type ButtonWidgetConfig, type CameraOrientation, ColorWidget, type ColorWidgetConfig, Connection, type ConnectionRenderer, type ConnectionRendererParams, type ContextMenuConfig, type ContextMenuItemConfig, ContextMenuItemState, type CopyCallback, CursorStyle, type DanglingConnection, DefaultConnectionRenderer, DefaultTheme, type FieldLook, FlowNode, type FlowNodeConfig, type FlowNodeGraphConfiguration, type FlowNodeStyle, type FlowNodeTitleConfig, FlowNote, type FlowNoteConfig, GlobalWidgetFactory, type GraphRenderer, GraphView, ImageWidget, type ImageWidgetConfig, InBox, type InPlaceEdit, type InPlaceEditConfig, type InternalConnection, MessageType, Minimap, type MinimapConfig, type NodeCreatedCallback, NodeFactory, type NodeFactoryConfig, NodeFlowGraph, type NodeIntersection, type NodeMenuFilter, type NodeMessageConfig, NodeState, type NoteAddedCallback, type NoteContentChangeCallback, type NoteDragStartCallback, type NoteDragStopCallback, type NoteRemovedCallback, type NoteSubsystemConfig, type NoteWidthChangeCallback, NumberWidget, type NumberWidgetConfig, type PasteCallback, Port, type PortConfig, type PortStyle, PortType, Publisher, type PublisherConfig, RowWidget, type RowWidgetConfig, type RowWidgetFactoryConfig, SliderWidget, type SliderWidgetConfig, StringWidget, type StringWidgetConfig, TextWidget, type TextWidgetConfig, Theme, type ThemeConfig, type ThemeValues, ToggleWidget, type ToggleWidgetConfig, ValueWidget, type ValueWidgetConfig, type Vector2, type Widget, WidgetBase, type WidgetBuilder, type WidgetConfig, type WidgetConfigs, WidgetFactory, type WidgetPointer, type WidgetTypes, drawField, drawFieldBox, drawFieldText, editInPlace, formatNumber, onThemeChange, portConfigTypes, portsCompatible, renderContinuously, requestRender, setTheme, themeVersion, typeSetsCompatible, widgetFont };
|
package/dist/index.d.ts
CHANGED
|
@@ -289,6 +289,7 @@ declare abstract class WidgetBase implements Widget {
|
|
|
289
289
|
protected box(): Box;
|
|
290
290
|
protected canvas(): HTMLCanvasElement | null;
|
|
291
291
|
protected scale(): number;
|
|
292
|
+
protected editText(value: string, onCommit: (text: string) => void): void;
|
|
292
293
|
protected onPointerDown(pointer: WidgetPointer): void;
|
|
293
294
|
protected onPointerMove(pointer: WidgetPointer): void;
|
|
294
295
|
protected onPointerUp(pointer: WidgetPointer): void;
|
|
@@ -1136,10 +1137,17 @@ interface InPlaceEditConfig {
|
|
|
1136
1137
|
value: string;
|
|
1137
1138
|
onCommit: (text: string) => void;
|
|
1138
1139
|
}
|
|
1140
|
+
interface InPlaceEdit {
|
|
1141
|
+
input: HTMLInputElement;
|
|
1142
|
+
/**
|
|
1143
|
+
* Moves the input over where the widget was just drawn, in canvas pixels.
|
|
1144
|
+
*/
|
|
1145
|
+
place(box: Box, scale: number): void;
|
|
1146
|
+
}
|
|
1139
1147
|
/**
|
|
1140
1148
|
* Lays a text input over a widget. Enter or clicking away keeps what was
|
|
1141
1149
|
* typed; Escape throws it away.
|
|
1142
1150
|
*/
|
|
1143
|
-
declare function editInPlace(config: InPlaceEditConfig):
|
|
1151
|
+
declare function editInPlace(config: InPlaceEditConfig): InPlaceEdit | null;
|
|
1144
1152
|
|
|
1145
|
-
export { type BevelColors, type Box, ButtonWidget, type ButtonWidgetConfig, type CameraOrientation, ColorWidget, type ColorWidgetConfig, Connection, type ConnectionRenderer, type ConnectionRendererParams, type ContextMenuConfig, type ContextMenuItemConfig, ContextMenuItemState, type CopyCallback, CursorStyle, type DanglingConnection, DefaultConnectionRenderer, DefaultTheme, type FieldLook, FlowNode, type FlowNodeConfig, type FlowNodeGraphConfiguration, type FlowNodeStyle, type FlowNodeTitleConfig, FlowNote, type FlowNoteConfig, GlobalWidgetFactory, type GraphRenderer, GraphView, ImageWidget, type ImageWidgetConfig, InBox, type InPlaceEditConfig, type InternalConnection, MessageType, Minimap, type MinimapConfig, type NodeCreatedCallback, NodeFactory, type NodeFactoryConfig, NodeFlowGraph, type NodeIntersection, type NodeMenuFilter, type NodeMessageConfig, NodeState, type NoteAddedCallback, type NoteContentChangeCallback, type NoteDragStartCallback, type NoteDragStopCallback, type NoteRemovedCallback, type NoteSubsystemConfig, type NoteWidthChangeCallback, NumberWidget, type NumberWidgetConfig, type PasteCallback, Port, type PortConfig, type PortStyle, PortType, Publisher, type PublisherConfig, RowWidget, type RowWidgetConfig, type RowWidgetFactoryConfig, SliderWidget, type SliderWidgetConfig, StringWidget, type StringWidgetConfig, TextWidget, type TextWidgetConfig, Theme, type ThemeConfig, type ThemeValues, ToggleWidget, type ToggleWidgetConfig, ValueWidget, type ValueWidgetConfig, type Vector2, type Widget, WidgetBase, type WidgetBuilder, type WidgetConfig, type WidgetConfigs, WidgetFactory, type WidgetPointer, type WidgetTypes, drawField, drawFieldBox, drawFieldText, editInPlace, formatNumber, onThemeChange, portConfigTypes, portsCompatible, renderContinuously, requestRender, setTheme, themeVersion, typeSetsCompatible, widgetFont };
|
|
1153
|
+
export { type BevelColors, type Box, ButtonWidget, type ButtonWidgetConfig, type CameraOrientation, ColorWidget, type ColorWidgetConfig, Connection, type ConnectionRenderer, type ConnectionRendererParams, type ContextMenuConfig, type ContextMenuItemConfig, ContextMenuItemState, type CopyCallback, CursorStyle, type DanglingConnection, DefaultConnectionRenderer, DefaultTheme, type FieldLook, FlowNode, type FlowNodeConfig, type FlowNodeGraphConfiguration, type FlowNodeStyle, type FlowNodeTitleConfig, FlowNote, type FlowNoteConfig, GlobalWidgetFactory, type GraphRenderer, GraphView, ImageWidget, type ImageWidgetConfig, InBox, type InPlaceEdit, type InPlaceEditConfig, type InternalConnection, MessageType, Minimap, type MinimapConfig, type NodeCreatedCallback, NodeFactory, type NodeFactoryConfig, NodeFlowGraph, type NodeIntersection, type NodeMenuFilter, type NodeMessageConfig, NodeState, type NoteAddedCallback, type NoteContentChangeCallback, type NoteDragStartCallback, type NoteDragStopCallback, type NoteRemovedCallback, type NoteSubsystemConfig, type NoteWidthChangeCallback, NumberWidget, type NumberWidgetConfig, type PasteCallback, Port, type PortConfig, type PortStyle, PortType, Publisher, type PublisherConfig, RowWidget, type RowWidgetConfig, type RowWidgetFactoryConfig, SliderWidget, type SliderWidgetConfig, StringWidget, type StringWidgetConfig, TextWidget, type TextWidgetConfig, Theme, type ThemeConfig, type ThemeValues, ToggleWidget, type ToggleWidgetConfig, ValueWidget, type ValueWidgetConfig, type Vector2, type Widget, WidgetBase, type WidgetBuilder, type WidgetConfig, type WidgetConfigs, WidgetFactory, type WidgetPointer, type WidgetTypes, drawField, drawFieldBox, drawFieldText, editInPlace, formatNumber, onThemeChange, portConfigTypes, portsCompatible, renderContinuously, requestRender, setTheme, themeVersion, typeSetsCompatible, widgetFont };
|
package/dist/index.js
CHANGED
|
@@ -2163,40 +2163,72 @@ function drawFieldText(ctx, box, scale, look) {
|
|
|
2163
2163
|
}
|
|
2164
2164
|
|
|
2165
2165
|
// src/widgets/inplace.ts
|
|
2166
|
+
var open = /* @__PURE__ */ new Set();
|
|
2167
|
+
function placeEditsDuring(canvas, draw) {
|
|
2168
|
+
open.forEach((edit) => {
|
|
2169
|
+
if (edit.canvas === canvas) {
|
|
2170
|
+
edit.placed = false;
|
|
2171
|
+
}
|
|
2172
|
+
});
|
|
2173
|
+
draw();
|
|
2174
|
+
open.forEach((edit) => {
|
|
2175
|
+
if (edit.canvas === canvas && !edit.placed) {
|
|
2176
|
+
edit.input.style.opacity = "0";
|
|
2177
|
+
edit.input.style.pointerEvents = "none";
|
|
2178
|
+
}
|
|
2179
|
+
});
|
|
2180
|
+
}
|
|
2166
2181
|
function editInPlace(config) {
|
|
2167
2182
|
const canvas = config.canvas;
|
|
2168
2183
|
if (canvas === null) {
|
|
2169
2184
|
return null;
|
|
2170
2185
|
}
|
|
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
2186
|
const input = document.createElement("input");
|
|
2175
2187
|
input.type = "text";
|
|
2176
2188
|
input.value = config.value;
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2189
|
+
const edit = { canvas, input, placed: true };
|
|
2190
|
+
const place = (box, scale) => {
|
|
2191
|
+
const rect = canvas.getBoundingClientRect();
|
|
2192
|
+
const sx = canvas.width > 0 ? rect.width / canvas.width : 1;
|
|
2193
|
+
const sy = canvas.height > 0 ? rect.height / canvas.height : 1;
|
|
2194
|
+
const left = rect.left + box.Position.x * sx;
|
|
2195
|
+
const top = rect.top + box.Position.y * sy;
|
|
2196
|
+
const width2 = box.Size.x * sx;
|
|
2197
|
+
const height2 = box.Size.y * sy;
|
|
2198
|
+
const clip = [
|
|
2199
|
+
Math.max(0, rect.top - top),
|
|
2200
|
+
Math.max(0, left + width2 - (rect.left + rect.width)),
|
|
2201
|
+
Math.max(0, top + height2 - (rect.top + rect.height)),
|
|
2202
|
+
Math.max(0, rect.left - left)
|
|
2203
|
+
];
|
|
2204
|
+
edit.placed = true;
|
|
2205
|
+
input.style.cssText = [
|
|
2206
|
+
"position: fixed",
|
|
2207
|
+
`left: ${left}px`,
|
|
2208
|
+
`top: ${top}px`,
|
|
2209
|
+
`width: ${width2}px`,
|
|
2210
|
+
`height: ${height2}px`,
|
|
2211
|
+
`clip-path: inset(${clip.map((c) => `${c}px`).join(" ")})`,
|
|
2212
|
+
"box-sizing: border-box",
|
|
2213
|
+
"margin: 0",
|
|
2214
|
+
`padding: 0 ${Theme.Widget.Padding * scale}px`,
|
|
2215
|
+
`font: ${Theme.Widget.FontSize * scale * sy}px ${Theme.FontFamily}`,
|
|
2216
|
+
`color: ${Theme.Widget.FontColor}`,
|
|
2217
|
+
`background: ${Theme.Widget.Hover.BackgroundColor}`,
|
|
2218
|
+
`border: ${Theme.Widget.Border.Size * scale}px solid ${Theme.Widget.Border.Color}`,
|
|
2219
|
+
`border-radius: ${Theme.Widget.Border.Radius * scale}px`,
|
|
2220
|
+
"outline: none",
|
|
2221
|
+
"z-index: 1000"
|
|
2222
|
+
].join(";");
|
|
2223
|
+
};
|
|
2224
|
+
place(config.box, config.scale);
|
|
2194
2225
|
let done = false;
|
|
2195
2226
|
const finish = (keep) => {
|
|
2196
2227
|
if (done) {
|
|
2197
2228
|
return;
|
|
2198
2229
|
}
|
|
2199
2230
|
done = true;
|
|
2231
|
+
open.delete(edit);
|
|
2200
2232
|
input.remove();
|
|
2201
2233
|
if (keep) {
|
|
2202
2234
|
config.onCommit(input.value);
|
|
@@ -2214,10 +2246,11 @@ function editInPlace(config) {
|
|
|
2214
2246
|
}
|
|
2215
2247
|
});
|
|
2216
2248
|
input.addEventListener("blur", () => finish(true));
|
|
2249
|
+
open.add(edit);
|
|
2217
2250
|
document.body.appendChild(input);
|
|
2218
2251
|
input.focus();
|
|
2219
2252
|
input.select();
|
|
2220
|
-
return input;
|
|
2253
|
+
return { input, place };
|
|
2221
2254
|
}
|
|
2222
2255
|
|
|
2223
2256
|
// src/widgets/widget.ts
|
|
@@ -2231,11 +2264,19 @@ var WidgetBase = class {
|
|
|
2231
2264
|
#box = { Position: { x: 0, y: 0 }, Size: { x: 0, y: 0 } };
|
|
2232
2265
|
#canvas = null;
|
|
2233
2266
|
#scale = 1;
|
|
2267
|
+
#editing = null;
|
|
2234
2268
|
Draw(ctx, box, scale, mousePosition) {
|
|
2235
2269
|
this.#box = { Position: { x: box.Position.x, y: box.Position.y }, Size: { x: box.Size.x, y: box.Size.y } };
|
|
2236
2270
|
this.#canvas = ctx.canvas ?? null;
|
|
2237
2271
|
this.#scale = scale;
|
|
2238
2272
|
this.#hovered = !this.#disabled && mousePosition !== void 0 && InBox(box, mousePosition);
|
|
2273
|
+
if (this.#editing !== null) {
|
|
2274
|
+
if (this.#editing.input.isConnected) {
|
|
2275
|
+
this.#editing.place(this.#box, scale);
|
|
2276
|
+
} else {
|
|
2277
|
+
this.#editing = null;
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2239
2280
|
ctx.save();
|
|
2240
2281
|
if (this.#disabled) {
|
|
2241
2282
|
ctx.globalAlpha *= 0.4;
|
|
@@ -2307,6 +2348,15 @@ var WidgetBase = class {
|
|
|
2307
2348
|
scale() {
|
|
2308
2349
|
return this.#scale;
|
|
2309
2350
|
}
|
|
2351
|
+
editText(value, onCommit) {
|
|
2352
|
+
this.#editing = editInPlace({
|
|
2353
|
+
canvas: this.#canvas,
|
|
2354
|
+
box: this.#box,
|
|
2355
|
+
scale: this.#scale,
|
|
2356
|
+
value,
|
|
2357
|
+
onCommit
|
|
2358
|
+
});
|
|
2359
|
+
}
|
|
2310
2360
|
onPointerDown(pointer) {
|
|
2311
2361
|
}
|
|
2312
2362
|
onPointerMove(pointer) {
|
|
@@ -2466,16 +2516,10 @@ var NumberWidget = class extends ValueWidget {
|
|
|
2466
2516
|
return;
|
|
2467
2517
|
}
|
|
2468
2518
|
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
|
-
}
|
|
2519
|
+
this.editText(String(before), (text) => {
|
|
2520
|
+
const parsed = Number.parseFloat(text);
|
|
2521
|
+
if (Number.isFinite(parsed)) {
|
|
2522
|
+
this.commit(this.#clean(parsed), before);
|
|
2479
2523
|
}
|
|
2480
2524
|
});
|
|
2481
2525
|
}
|
|
@@ -2683,13 +2727,7 @@ var StringWidget = class extends ValueWidget {
|
|
|
2683
2727
|
}
|
|
2684
2728
|
onClick() {
|
|
2685
2729
|
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
|
-
});
|
|
2730
|
+
this.editText(before, (text) => this.commit(text, before));
|
|
2693
2731
|
}
|
|
2694
2732
|
};
|
|
2695
2733
|
|
|
@@ -8086,10 +8124,12 @@ var NodeFlowGraph = class {
|
|
|
8086
8124
|
this.#cursor = "default" /* Default */;
|
|
8087
8125
|
TimeExecution("Render_Background", this.#renderBackground.bind(this));
|
|
8088
8126
|
TimeExecution("Render_View_" + this.#currentView, () => {
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8127
|
+
placeEditsDuring(this.#canvas, () => {
|
|
8128
|
+
let results = this.currentView().render(this.#ctx, this.#camera, this.#mousePosition);
|
|
8129
|
+
if (results?.cursorStyle) {
|
|
8130
|
+
this.#cursor = results?.cursorStyle;
|
|
8131
|
+
}
|
|
8132
|
+
});
|
|
8093
8133
|
});
|
|
8094
8134
|
TimeExecution("Render_Minimap", () => {
|
|
8095
8135
|
this.#minimap.render(this.#ctx, this.#canvas, this.#camera, this.#mainNodeSubsystem.getNodes());
|