@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 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): HTMLInputElement | null;
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): HTMLInputElement | null;
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
- 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(";");
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
- editInPlace({
2470
- canvas: this.canvas(),
2471
- box: this.box(),
2472
- scale: this.scale(),
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
- editInPlace({
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
- let results = this.currentView().render(this.#ctx, this.#camera, this.#mousePosition);
8090
- if (results?.cursorStyle) {
8091
- this.#cursor = results?.cursorStyle;
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());