Initial MultiText & Multi int click and drag

This commit is contained in:
Blueprint Coding
2025-02-16 12:07:45 -07:00
parent 88bd6837c4
commit 758636e033
5 changed files with 2410 additions and 4 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ class MultiInt:
RETURN_TYPES = ("INT",) * 20
RETURN_NAMES = tuple(f"i{i+1}" for i in range(20))
FUNCTION = "process"
CATEGORY = "AIDocsClinicalTools"
CATEGORY = "AIDoc"
UI = "MultiIntNode" # Must match the JS filename "MultiIntNode.js"
def process(self, **kwargs):
+64
View File
@@ -0,0 +1,64 @@
# MultiText.py
class MultiText:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"separator": ("STRING", {
"default": " ",
"multiline": False,
"hidden": True,
"forceInput": True
}),
"active": ("BOOLEAN", {"default": True, "hidden": True}),
},
"hidden": {
**{f"enabled{i}": ("BOOLEAN", {"default": True}) for i in range(1, 21)},
**{f"text{i}": ("STRING", {"multiline": True}) for i in range(1, 21)},
**{f"weight{i}": ("FLOAT", {
"default": 1.0,
"min": 0.0,
"max": 2.0,
"step": 0.1
}) for i in range(1, 21)}
}
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("*",)
FUNCTION = "combine_text"
CATEGORY = "AIDoc"
def combine_text(self, separator=" ", active=True, **kwargs):
if not active:
return ("",)
texts = []
for i in range(1, 21):
# read enabled{i}
enabled = kwargs.get(f"enabled{i}", True)
if not enabled:
continue # skip if disabled
text = kwargs.get(f"text{i}", "").strip()
weight = 1.0
if weight is None:
weight = 1.0
if text:
if weight == 1.0:
texts.append(text)
else:
texts.append(text)
return (separator.join(texts),)
# Mappings for MultiText
NODE_CLASS_MAPPINGS = {
"MultiText": MultiText # Class mapping for the MultiText node
}
NODE_DISPLAY_NAME_MAPPINGS = {
"MultiText": "Multi Text" # Display name for the MultiText node
}
+10 -2
View File
@@ -1,3 +1,5 @@
# __init__.py
WEB_DIRECTORY = "./js"
CSS_DIRECTORY = "./css"
@@ -13,5 +15,11 @@ from .MultiIntNode import (
NODE_DISPLAY_NAME_MAPPINGS as MULTIINT_DISPLAY_NAME_MAPPINGS,
)
NODE_CLASS_MAPPINGS = {**MULTIINT_NODE_CLASS_MAPPINGS}
NODE_DISPLAY_NAME_MAPPINGS = {**MULTIINT_DISPLAY_NAME_MAPPINGS}
from .MultiText import (
NODE_CLASS_MAPPINGS as MULTITEXT_NODE_CLASS_MAPPINGS, # Import the class mappings for MultiText
NODE_DISPLAY_NAME_MAPPINGS as MULTITEXT_DISPLAY_NAME_MAPPINGS, # Import the display name mappings
)
# Combine the mappings from both MultiInt and MultiText nodes
NODE_CLASS_MAPPINGS = {**MULTIINT_NODE_CLASS_MAPPINGS, **MULTITEXT_NODE_CLASS_MAPPINGS}
NODE_DISPLAY_NAME_MAPPINGS = {**MULTIINT_DISPLAY_NAME_MAPPINGS, **MULTITEXT_DISPLAY_NAME_MAPPINGS}
+88 -1
View File
@@ -268,7 +268,82 @@ class MultiIntNode {
};
}
startValueDragToggle(index, initialEvent) {
// If already dragging, then stop dragging (commit the value)
if (this.dragActive) {
this.stopValueDrag();
return;
}
// Start drag mode for this value.
this.dragActive = true;
this.dragIndex = index;
this.dragInitialX = initialEvent.clientX;
this.dragInitialValue = this.node.properties.values[index];
const step = this.node.properties.intStep || 1;
const sensitivity = 10; // pixels per step change
// Get the canvas element.
const canvasEl = document.getElementById("graph-canvas");
if (!canvasEl) return;
// Define a pointermove handler to update the value as the pointer moves.
this._onValuePointerMove = (e) => {
const dx = e.clientX - this.dragInitialX;
const steps = Math.floor(dx / sensitivity);
const newValue = this.dragInitialValue + steps * step;
if (newValue !== this.node.properties.values[this.dragIndex]) {
this.node.properties.values[this.dragIndex] = newValue;
if (this.node.widgets[this.dragIndex]) {
this.node.widgets[this.dragIndex].value = newValue;
}
this.node.setDirtyCanvas(true, true);
}
};
// Attach the pointermove handler to the canvas.
canvasEl.addEventListener("pointermove", this._onValuePointerMove);
// Define a global click handler to stop the drag.
this._onGlobalClickToStop = (e) => {
// Prevent this click from re-triggering startValueDragToggle immediately.
console.log("Global click detected—stopping drag");
this.stopValueDrag();
};
// Attach the global click handler with capture so it fires before other click handlers.
document.addEventListener("click", this._onGlobalClickToStop, { capture: true });
// Also attach a keydown handler on the document so that Enter or Esc stop drag mode.
this._onKeyDownToStop = (e) => {
if (e.key === "Enter" || e.key === "Escape") {
console.log("Keydown (" + e.key + ") detected—stopping drag");
this.stopValueDrag();
}
};
document.addEventListener("keydown", this._onKeyDownToStop);
}
stopValueDrag() {
const canvasEl = document.getElementById("graph-canvas");
if (!canvasEl) return;
if (this._onValuePointerMove) {
canvasEl.removeEventListener("pointermove", this._onValuePointerMove);
this._onValuePointerMove = null;
}
if (this._onGlobalClickToStop) {
document.removeEventListener("click", this._onGlobalClickToStop, { capture: true });
this._onGlobalClickToStop = null;
}
if (this._onKeyDownToStop) {
document.removeEventListener("keydown", this._onKeyDownToStop);
this._onKeyDownToStop = null;
}
this.dragActive = false;
this.dragIndex = null;
this.node.setDirtyCanvas(true, true);
}
onMouseDown(e, pos) {
// Check pencil icons
@@ -322,6 +397,18 @@ class MultiIntNode {
}
}
// Check if the click is in a value rectangle and start drag-to-change behavior
// Then, check if the click is in a value rectangle:
for (let i = 0; i < this.valueRects.length; i++) {
const r = this.valueRects[i];
if (r && pos[0] >= r.x && pos[0] <= r.x + r.w &&
pos[1] >= r.y && pos[1] <= r.y + r.h) {
// Toggle drag mode on the value at index i.
this.startValueDragToggle(i, e);
return true;
}
}
// Check gear icon
if (this.gearRect) {
const r = this.gearRect;
+2247
View File
File diff suppressed because it is too large Load Diff