* widget_vector tweaked to disallow non-numerics

* widgetHookControl streamlined
This commit is contained in:
Alexander G. Morano
2025-05-13 17:06:09 -04:00
parent 635e6da827
commit 4caec76623
7 changed files with 73 additions and 139 deletions
+1 -1
View File
@@ -539,7 +539,7 @@ Perform single function operations like absolute value, mean, median, mode, magn
"default": (0,0,0,0),
"label": ["X", "Y", "Z", "W"]}),
Lexicon.FILL: (EnumFillOperation._member_names_, {
"default": EnumFillOperation.DEFAULT.name}),
"default": EnumFillOperation.DEFAULT.name})
}
})
return Lexicon._parse(d)
+3 -3
View File
@@ -15,9 +15,9 @@ app.registerExtension({
const onNodeCreated = nodeType.prototype.onNodeCreated
nodeType.prototype.onNodeCreated = async function () {
const me = await onNodeCreated?.apply(this);
widgetHookControl(this, 'type', 'alpha', true);
widgetHookControl(this, 'type', 'aa');
widgetHookControl(this, 'type', 'bb');
await widgetHookControl(this, 'type', 'alpha', true);
await widgetHookControl(this, 'type', 'aa');
await widgetHookControl(this, 'type', 'bb');
return me;
}
return nodeType;
+2 -2
View File
@@ -16,8 +16,8 @@ app.registerExtension({
nodeType.prototype.onNodeCreated = async function () {
const me = await onNodeCreated?.apply(this);
console.info(this);
widgetHookControl(this, 'type', 'aa');
widgetHookControl(this, 'type', 'bb');
await widgetHookControl(this, 'type', 'aa');
await widgetHookControl(this, 'type', 'bb');
return me;
}
+3 -34
View File
@@ -16,40 +16,9 @@ app.registerExtension({
const onNodeCreated = nodeType.prototype.onNodeCreated
nodeType.prototype.onNodeCreated = async function () {
const me = await onNodeCreated?.apply(this);
widgetHookControl(this, 'type', 'aa');
await widgetHookControl(this, 'type', 'aa');
return me;
}
/*
const onConnectionsChange = nodeType.prototype.onConnectionsChange
nodeType.prototype.onConnectionsChange = function (slotType, slot_idx, event, link_info, node_slot) {
const me = onConnectionsChange?.apply(this, arguments);
let connected = false;
const output = this.outputs[0];
if (slotType == TypeSlot.Input && link_info && event == TypeSlotEvent.Connect) {
const fromNode = this.graph._nodes.find(
(otherNode) => otherNode.id == link_info.origin_id
)
if (fromNode) {
const parent_link = fromNode.outputs[link_info.origin_slot];
if (parent_link) {
output.type = parent_link.type;
//output.name = parent_link.name;
//output.localized_name = parent_link.localized_name;
connected = true;
}
}
}
if (connected == false) {
output.type = "*";
//output.name = "❔";
//output.localized_name = "❔";
}
nodeFitHeight(this);
return me;
}
*/
return nodeType;
return nodeType;
}
})
})
+2 -2
View File
@@ -21,8 +21,8 @@ app.registerExtension({
this.outputs[3].type = "*";
this.outputs[4].type = "*";
const ab_data = widgetHookControl(this, 'type', 'aa');
widgetHookControl(this, 'type', 'bb');
const ab_data = await widgetHookControl(this, 'type', 'aa');
await widgetHookControl(this, 'type', 'bb');
const oldCallback = ab_data.callback;
ab_data.callback = () => {
+49 -80
View File
@@ -38,111 +38,80 @@ export async function apiJovimetrix(id, cmd, data=null, route="message", ) {
}
}
function widgetShowVector(widget, values={}, type) {
if (["FLOAT"].includes(type)) {
type = "VEC1";
} else if (["INT"].includes(type)) {
type = "VEC1INT";
} else if (type == "BOOLEAN") {
type = "toggle";
}
if (type !== undefined) {
widget.type = type;
}
if (widget.value === undefined) {
widget.value = widget.options?.default || {};
}
// convert widget.value to pure dict/object
if (Array.isArray(widget.value)) {
let new_val = {};
for (let i = 0; i < widget.value.length; i++) {
new_val[i] = widget.value[i];
}
widget.value = new_val;
}
widget.options.step = 1;
widget.options.round = 1;
widget.options.precision = 0;
if (widget.type != 'toggle') {
let size = 1;
const match = /\d/.exec(widget.type);
if (match) {
size = match[0];
}
if (!widget.type.endsWith('INT') && widget.type != 'BOOLEAN') {
widget.options.step = 0.01;
widget.options.round = 0.001;
widget.options.precision = 3;
}
widget.value = {};
for (let i = 0; i < size; i++) {
widget.value[i] = (widget.options.precision == 0) ? Number(values[i]) : parseFloat(values[i]).toFixed(widget.options.precision);
}
} else {
widget.value = values[0] ? true : false;
}
}
/*
* matchFloatSize forces the target to be float[n] based on its type size
*/
export function widgetHookControl(node, control_key, child_key, matchFloatSize=false) {
export async function widgetHookControl(node, control_key, child_key) {
const control = node.widgets.find(w => w.name == control_key);
const target = node.widgets.find(w => w.name == child_key);
const combo = node.widgets.find(w => w.name == control_key);
if (!target || !combo) {
const target_input = node.inputs.find(w => w.name == child_key);
if (!control || !target || !target_input) {
throw new Error("Required widgets not found");
}
const initializeTrack = (widget) => {
const track = {};
for (let i = 0; i < 4; i++) {
track[i] = widget.options?.default[i];
}
Object.assign(track, widget.value);
return track;
const track_xyzw = {
0: target.options?.default?.[0] || 0,
1: target.options?.default?.[1] || 0,
2: target.options?.default?.[2] || 0,
3: target.options?.default?.[3] || 0,
};
const { widgets } = node;
const controlCallback = control.callback;
control.callback = async () => {
const me = await controlCallback?.apply(this, arguments);
if (["VEC2", "VEC3", "VEC4", "FLOAT", "INT", "BOOLEAN"].includes(control.value)) {
target_input.type = control.value;
//target.options.step = 0.01;
//target.options.round = 0.001;
//target.options.precision = 3;
const data = {
track_xyzw: initializeTrack(target),
target,
combo
};
if (["INT", "FLOAT", "BOOLEAN"].includes(control.value)) {
target.type = "VEC1";
} else {
target.type = control.value;
}
const oldCallback = combo.callback;
combo.callback = () => {
const me = oldCallback?.apply(this, arguments);
if (["VEC2", "VEC3", "VEC4", "BOOLEAN", "INT", "FLOAT"].includes(combo.value)) {
let type = combo.value;
if (matchFloatSize) {
if (["BOOLEAN", "INT"].includes(combo.value)) {
type = "FLOAT";
let size = 1;
if (control.value == "INT") {
target.options.int = true;
} else if (["VEC2", "VEC3", "VEC4"].includes(control.value)) {
const match = /\d/.exec(control.value);
size = match[0];
}
target.value = {};
if (["VEC2", "VEC3", "VEC4", "FLOAT"].includes(control.value)) {
for (let i = 0; i < size; i++) {
target.value[i] = parseFloat(track_xyzw[i]).toFixed(target.options.precision);
}
} else if (control.value == "INT") {
target.value[0] = Number(track_xyzw[0]);
} else if (control.value == "BOOLEAN") {
target.value[0] = track_xyzw[0] != 0 ? true : false;
}
widgetShowVector(target, data.track_xyzw, type);
}
nodeFitHeight(node);
return me;
}
target.callback = () => {
const targetCallback = target.callback;
target.callback = async () => {
const me = await targetCallback?.apply(this, arguments);
if (target.type == "toggle") {
data.track_xyzw[0] = target.value ? 1 : 0;
track_xyzw[0] = target.value != 0 ? 1 : 0;
} else if (["INT", "FLOAT"].includes(target.type)) {
track_xyzw[0] = target.value;
} else {
Object.keys(target.value).forEach((key) => {
data.track_xyzw[key] = target.value[key];
track_xyzw[key] = target.value[key];
});
}
return me;
};
return data;
await control.callback();
return control;
}
export function nodeFitHeight(node) {
+13 -17
View File
@@ -184,30 +184,24 @@ const VectorWidget = (app, inputName, options, initial) => {
try {
v = eval(v);
} catch {
// Suppressed exception
v = old_value[index];
}
} else {
v = old_value[index];
}
if (this.value[index] != v) {
setTimeout(
function () {
clamp(this, v, index);
domInnerValueChange(node, pos, this, this.value, eUp);
}.bind(this), 20)
}.bind(this), 5)
}
}.bind(this), eUp);
if (old_value != this.value) {
setTimeout(
function () {
domInnerValueChange(node, pos, this, this.value, eUp);
}.bind(this), 20);
}
return
return;
}
if (!this.options?.rgb) return;
//const rgba = widget.value;
const rgba = Object.values(this?.value || []);
const color = colorRGB2Hex(rgba.slice(0, 3));
@@ -260,23 +254,25 @@ const VectorWidget = (app, inputName, options, initial) => {
pointer.onDrag = (eMove) => {
if (!eMove.deltaX || !(index > -1)) return;
let v = parseFloat(this.value[index]);
v += this.options.step * Math.sign(eMove.deltaX);
clamp(this, v, index);
if (widget.callback) {
widget.callback(widget.value, app.canvas, node)
}
}
}
widget.serializeValue = async () => {
const value = widget.value;
if (value === null) {
if (widget.value === null) {
return null;
}
if (Array.isArray(value)) {
return value.reduce((acc, tuple, index) => ({ ...acc, [index]: tuple }), {});
if (Array.isArray(widget.value)) {
return widget.value.reduce((acc, tuple, index) => ({ ...acc, [index]: tuple }), {});
}
return value;
return widget.value;
}
return widget;