Files

1042 lines
37 KiB
JavaScript

import { app } from "../../../scripts/app.js";
import { GroupNodeHandler } from "../../../extensions/core/groupNode.js";
import * as lib0246 from "./utils.js";
import * as wg0246 from "./widgets.js";
const hub_list = [];
app.registerExtension({
name: "0246.Node",
registerCustomNodes(app) {
const reroute_class = lib0246.clone_class(LiteGraph.registered_node_types.Reroute);
reroute_class.prototype.onNodeCreated = function() {
const DATA_TEMP = [];
lib0246.hijack(this, "onConnectionsChange", function () {
if (arguments[2])
if (!this.mark) {
DATA_TEMP[0] = this.self.inputs[0].type;
DATA_TEMP[1] = this.self.outputs[0].type;
DATA_TEMP[2] = this.self.size[0];
DATA_TEMP[3] = app.graph.getNodeById(arguments[3]?.target_id)?.inputs?.[arguments[3]?.target_slot];
if (DATA_TEMP[3]?.type === "*") {
DATA_TEMP[4] = DATA_TEMP[3].type;
DATA_TEMP[3].type = this.self.widgets[0].value;
}
this.self.inputs[0].type = this.self.outputs[0].type = this.self.widgets[0].value;
} else {
this.self.inputs[0].type = DATA_TEMP[0];
this.self.outputs[0].type = DATA_TEMP[1];
this.self.size[0] = DATA_TEMP[2];
if (DATA_TEMP[3])
DATA_TEMP[3].type = DATA_TEMP[4];
}
});
const type_widget = this.addWidget("combo", "", "*", function(value, widget, node) {
let curr_input_node = node.getInputNode(0),
curr_output_node = node.getOutputNodes(0),
prev_input_slot = app.graph.links?.[node.inputs[0].link]?.origin_slot,
prev_output_slot = [];
if (node.outputs[0].links)
for (let i = 0; i < node.outputs[0].links.length; ++ i)
prev_output_slot.push(app.graph.links[node.outputs[0].links[i]].target_slot);
node.disconnectInput(0);
node.disconnectOutput(0);
wg0246.process_reroute(node);
if (curr_output_node && curr_output_node.length > 0) {
node.inputs[0].widget = curr_output_node[0].inputs[prev_output_slot[0]].widget;
for (let i = 0; i < curr_output_node.length; ++ i)
node.connect(0, curr_output_node[i], prev_output_slot[i]);
} else
node.inputs[0].widget = {};
if (curr_input_node)
curr_input_node.connect(prev_input_slot, node, 0);
}, {
values: wg0246.type_defs
});
type_widget.y = 3;
let prev_size = this.computeSize();
prev_size[0] = 100;
this.serialize_widgets = true;
this.setSize(prev_size);
};
lib0246.hijack(reroute_class.prototype, "onDrawForeground", function () {
if (!this.mark)
wg0246.process_reroute(this.self);
});
// [TODO] CastReroute being late registered.
LiteGraph.registerNodeType(
"0246.CastReroute",
Object.assign(reroute_class, {
title_mode: LiteGraph.NO_TITLE,
title: "Cast Reroute",
collapsable: false,
})
);
reroute_class.category = "0246";
},
nodeCreated(node) {
switch (node.comfyClass) {
case "0246.Highway": {
node.color = LGraphCanvas.node_colors.brown.color;
node.bgcolor = LGraphCanvas.node_colors.brown.bgcolor;
} break;
case "0246.HighwayBatch": {
node.color = lib0246.mix_color_hue(LGraphCanvas.node_colors.brown.color, "#660029");
node.bgcolor = LGraphCanvas.node_colors.brown.bgcolor;
} break;
case "0246.Junction": {
node.color = LGraphCanvas.node_colors.blue.color;
node.bgcolor = LGraphCanvas.node_colors.blue.bgcolor;
} break;
case "0246.JunctionBatch": {
node.color = lib0246.mix_color_hue(LGraphCanvas.node_colors.blue.color, "#660029");
node.bgcolor = LGraphCanvas.node_colors.blue.bgcolor;
} break;
case "0246.Loop": {
node.color = LGraphCanvas.node_colors.yellow.color;
node.bgcolor = LGraphCanvas.node_colors.yellow.bgcolor;
} break;
case "0246.Count": {
node.color = LGraphCanvas.node_colors.green.color;
node.bgcolor = LGraphCanvas.node_colors.yellow.bgcolor;
} break;
case "0246.Hold": {
node.color = "#666600";
node.bgcolor = LGraphCanvas.node_colors.yellow.bgcolor;
} break;
case "0246.Beautify": {
// Pink UwU
node.color = "#652069";
node.bgcolor = "#764378";
} break;
case "0246.RandomInt": {
node.color = LGraphCanvas.node_colors.red.color;
node.bgcolor = LGraphCanvas.node_colors.green.bgcolor;
} break;
case "0246.Stringify": {
node.color = LGraphCanvas.node_colors.red.color;
node.bgcolor = LGraphCanvas.node_colors.green.bgcolor;
} break;
case "0246.Merge": {
node.color = "#660029";
node.bgcolor = "#4d001f";
} break;
case "0246.BoxRange": {
node.color = LGraphCanvas.node_colors.green.color;
node.bgcolor = LGraphCanvas.node_colors.green.bgcolor;
} break;
case "0246.ScriptNode": {
node.color = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.color, "#660029");
node.bgcolor = "#4d001f";
} break;
case "0246.ScriptRule": {
node.color = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.color, "#660029");
node.bgcolor = LGraphCanvas.node_colors.green.bgcolor;
} break;
case "0246.ScriptPile": {
node.color = "#660029";
node.bgcolor = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.bgcolor, "#660029");
} break;
case "0246.Script": {
node.color = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.color, "#660029");
node.bgcolor = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.bgcolor, "#660029");
} break;
case "0246.Hub": {
node.color = "#1a1a1a";
node.bgcolor = "#111";
} break;
case "0246.Cloud": {
node.color = "#595959";
node.bgcolor = "#676767";
} break;
case "0246.Switch": {
// node.color = LGraphCanvas.node_colors.yellow.color;
// node.bgcolor = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.bgcolor, "#660029");
node.color = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.color, "#660029");
node.bgcolor = LGraphCanvas.node_colors.yellow.bgcolor;
} break;
case "0246.Meta": {
node.color = "#652069";
node.bgcolor = LGraphCanvas.node_colors.green.bgcolor;
} break;
case "0246.Tag": {
node.color = "#652069";
node.bgcolor = LGraphCanvas.node_colors.yellow.bgcolor;
} break;
}
// use_everywhere.js messing with colors :(
node._color = node.color;
node._bgcolor = node.bgcolor;
},
async setup(app) {
lib0246.hijack(app, "graphToPrompt", async function () {
if (!this.mark)
for (let i = 0; i < this.self.graph._nodes.length; ++ i) {
const node = this.self.graph._nodes[i];
if (node.comfyClass === "0246.Hub")
wg0246.setup_hijack_widget(node, ["0246.Hub"], wg0246.hijack_widget_name);
}
else
for (let i = 0; i < this.self.graph._nodes.length; ++ i) {
const node = this.self.graph._nodes[i];
if (node.comfyClass === "0246.Hub")
wg0246.reset_hijack_widget(node);
}
});
lib0246.hijack(app.canvas, "drawNodeWidgets", function () {
if (!this.mark) {
const node = arguments[0];
if (node.comfyClass === "0246.Hub")
node.hubSize();
}
});
lib0246.hijack(app.graph, "remove", function (node) {
if (!this.mark && node.type === "0246.Junction") {
for (let i = node.inputs.length - 1; i >= 0; -- i)
node.removeInput(i);
for (let i = node.outputs.length - 1; i >= 0; -- i)
node.removeOutput(i);
}
});
},
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (typeof nodeData.category === "string" && nodeData.category.startsWith("0246")) {
switch (nodeData.name) {
case "0246.BoxRange": {
lib0246.hijack(nodeType.prototype, "onNodeCreated", function () {
if (this.mark) {
const node = this.self;
const ratio_widget = node.widgets.find(w => w.name === "box_range_ratio"),
box_widget = node.widgets.find(w => w.name === "box_range");
lib0246.hijack(node, "getExtraMenuOptions", function (canvas, options) {
if (!this.mark)
wg0246.help_option(nodeType, wg0246.HELP["box_range"], options);
});
ratio_widget.callback = function (value, widget, node, pos, event) {
if (widget.name === "box_range_ratio") {
box_widget.flex.ratio = widget.value.data.ratio;
app.canvas.setDirty(true);
}
};
lib0246.hijack(node, "onWidgetChanged", function (name, value, old_value, widget) {
if (!this.mark && name === "box_range_ratio")
box_widget.flex.ratio = value.data.ratio;
});
box_widget.flex.ratio = ratio_widget.value.data.ratio;
const regex_widget = node.widgets.find(w => w.name === "script_box_regex");
regex_widget.options = regex_widget.options ?? {};
regex_widget.options.multiline = true;
node.serialize_widgets = true;
node.setSize([node.size[0], Math.max(node.computeSize()[1], node.size[1])]);
}
}, function (mode) {
if (mode === 0b100000) {
this.self.size[0] = Math.max(this.self.size[0], 350);
this.self.size[1] = Math.max(this.self.size[1], 350);
}
});
lib0246.hijack(nodeType.prototype, "onAdded", function () {
if (this.mark) {
const ratio_widget = this.self.widgets.find(w => w.name === "box_range_ratio"),
box_widget = this.self.widgets.find(w => w.name === "box_range");
box_widget.flex.ratio = ratio_widget.value.data.ratio;
app.canvas.setDirty(true);
}
});
wg0246.single_impl_output(nodeType, nodeData, app, LiteGraph.CIRCLE_SHAPE);
} break;
case "0246.Highway": {
wg0246.highway_impl(nodeType, nodeData, app, LiteGraph.CIRCLE_SHAPE, LiteGraph.CIRCLE_SHAPE);
} break;
case "0246.HighwayBatch": {
wg0246.highway_impl(nodeType, nodeData, app, LiteGraph.GRID_SHAPE, LiteGraph.GRID_SHAPE);
} break;
case "0246.Junction": {
wg0246.junction_impl(nodeType, nodeData, app, "_offset", LiteGraph.CIRCLE_SHAPE, LiteGraph.CIRCLE_SHAPE);
} break;
case "0246.JunctionBatch": {
// [TODO] Dynamically change shape when _mode is changed
wg0246.junction_impl(nodeType, nodeData, app, "_offset", LiteGraph.GRID_SHAPE, LiteGraph.GRID_SHAPE);
} break;
case "0246.Loop": {
wg0246.single_impl_input(nodeType, nodeData, app, LiteGraph.CIRCLE_SHAPE);
} break;
case "0246.Count": {
wg0246.setup_log(nodeType.prototype);
} break;
case "0246.Hold": {
wg0246.single_impl_pin(nodeType, [
"_data_in", LiteGraph.INPUT, LiteGraph.CIRCLE_SHAPE,
"_data_out", LiteGraph.OUTPUT, LiteGraph.GRID_SHAPE,
"_data_out_all", LiteGraph.OUTPUT, LiteGraph.GRID_SHAPE
]);
wg0246.setup_log(nodeType.prototype);
} break;
case "0246.RandomInt": {
lib0246.hijack(nodeType.prototype, "onNodeCreated", function () {
if (this.mark) {
const self = this.self;
self.outputs[0].shape = LiteGraph.GRID_SHAPE;
const val_widget = self.widgets.find(w => w.name === "val");
val_widget.options = val_widget.options ?? {};
val_widget.options.multiline = true;
this.self.addWidget("button", "Random Seed", null, () => {
const seed_widget = self.widgets.find(w => w.name === "seed");
seed_widget.value = Math.floor(Math.random() * (seed_widget.options.max - seed_widget.options.min + 1)) + seed_widget.options.min;
}, {
serialize: false
});
this.self.addWidget("button", "Random Value", null, () => {
const val_widget = self.widgets.find(w => w.name === "val"),
min_widget = self.widgets.find(w => w.name === "min"),
max_widget = self.widgets.find(w => w.name === "max"),
batch_widget = self.widgets.find(w => w.name === "batch_size");
let res = val_widget.value.split(",");
if (res.length > batch_widget.value)
res.length = batch_widget.value;
else if (res.length < batch_widget.value)
for (let i = res.length; i < batch_widget.value; ++ i)
res.push("0");
for (let i = 0; i < batch_widget.value; ++ i) {
if (res[i])
res[i] = res[i].trim();
if (res[i] !== "rand" && res[i] !== "add" && res[i] !== "sub")
res[i] = String(Math.floor(Math.random() * (max_widget.value - min_widget.value + 1)) + min_widget.value);
}
val_widget.value = res.join(", ");
}, {
serialize: false
});
this.self.addWidget("button", "Change Mode", null, () => {
const val_widget = self.widgets.find(w => w.name === "val"),
batch_widget = self.widgets.find(w => w.name === "batch_size");
let res = val_widget.value.split(",");
if (res.length > batch_widget.value)
res.length = batch_widget.value;
else if (res.length < batch_widget.value)
for (let i = res.length; i < batch_widget.value; ++ i)
res.push("sub");
for (let i = 0; i < batch_widget.value; ++ i)
if (res[i]) {
res[i] = res[i].trim();
if (isNaN(res[i])) {
if (res[i] !== "rand" && res[i] !== "add")
res[i] = "rand";
else if (res[i] === "rand")
res[i] = "add";
else
res[i] = "sub";
}
}
val_widget.value = res.join(", ");
}, {
serialize: false
});
}
});
wg0246.setup_log(nodeType.prototype, true);
} break;
case "0246.Beautify": {
wg0246.setup_log(nodeType.prototype);
lib0246.hijack(nodeType.prototype, "onNodeCreated", () => {}, function (mode) {
if (mode === 0b100000)
this.self.size[1] = Math.max(this.self.size[1], 100);
});
wg0246.single_impl_pin(nodeType, [
"data", LiteGraph.INPUT, LiteGraph.GRID_SHAPE,
]);
} break;
case "0246.Stringify": {
wg0246.single_impl_input(nodeType, nodeData, app, LiteGraph.CIRCLE_SHAPE);
} break;
case "0246.Merge": {
wg0246.single_impl_input(nodeType, nodeData, app, LiteGraph.CIRCLE_SHAPE);
} break;
case "0246.Hub": {
const Hub = nodeType;
// [TODO] Force tracked node render by hijack app.canvas.computeVisibleNodes and
// change getBounding of each nodes to be within app.canvas.visible_area
lib0246.hijack(Hub.prototype, "onNodeCreated", function () {
if (this.mark) {
const node = this.self;
const prim_widget = node.addWidget("combo", "base:prim", "INT", () => {}, {
serialize: false,
values: [
"INT", "FLOAT", "STRING", "BOOLEAN",
"__BATCH_PRIM__", "__BATCH_COMBO__", "__PIPE__"
// "__SCRIPT_DATA_WRAP__", "__SCRIPT_DATA_EXEC__"
]
});
node.addWidget("button", "Add Sole Primitive Widget", null, () => {
node.hubPushWidgetPrim(prim_widget.value);
}, {
serialize: false
});
const combo_widget = node.addWidget("combo", "base:combo", ["KSampler", "required", "sampler_name"], () => {}, {
serialize: false,
values: wg0246.combo_defs
});
node.addWidget("button", "Add Sole Combo Widget", null, () => {
node.hubPushWidgetCombo(...combo_widget.value);
}, {
serialize: false
});
const node_widget = node.addWidget("combo", "base:node", "KSampler", () => {}, {
serialize: false,
values: wg0246.node_defs
});
node.addWidget("button", "Add Sole Primitive Widgets from Node", null, () => {
node.hubPushWidgetNode(node_widget.value);
}, {
serialize: false
});
const del_widget = node.addWidget("combo", "base:del", "", () => {}, {
serialize: false,
values: function (widget) {
let res = [];
for (let i = 0; i < node.hub.sole_widget.length; ++ i)
res.push(node.hub.sole_widget[i].name);
return res;
}
});
node.addWidget("button", "Delete Sole Widget", null, () => {
node.hubPullWidget(node.hub.sole_widget.find(w => w.name === del_widget.value));
}, {
serialize: false
});
lib0246.hijack(node, "connect", function (slot, target_node, target_slot) {
if (!this.mark) {
const output_data = this.self.hub.data.sole_type[this.self.outputs[slot].name];
if (output_data[2] === "combo") {
Hub.nodeData = Hub.nodeData ?? {};
Hub.nodeData.output = Hub.nodeData.output ?? {};
const curr_type = app.graph.extra["0246.HUB_DATA"][this.self.id].sole_type[this.self.outputs[slot].name];
if (curr_type.length === 7)
Hub.nodeData.output[slot] = wg0246.defs[output_data[3]].input[output_data[4]][output_data[5]][0];
else if (curr_type[3] === "__BATCH_COMBO__") {
const curr_value = this.self.widgets.find(_ => _.name === this.self.outputs[slot].name).value;
Hub.nodeData.output[slot] = wg0246.defs[curr_value[0]].input[curr_value[1]][curr_value[2]][0];
}
}
} else {
const output_data = this.self.hub.data.sole_type[this.self.outputs[slot].name];
if (output_data[2] === "combo")
delete Hub.nodeData.output[slot];
}
});
lib0246.hijack(node, "clone", function () {
if (this.mark) {
this.res.widgets = this.res.widgets ?? [];
for (let i = 0; i < node.widgets.length; ++ i) {
this.res.widgets[i] = this.res.widgets[i] ?? {};
this.res.widgets[i].value = structuredClone(node.widgets[i].value);
}
lib0246.hijack(this.res, "serialize", function () {
if (this.mark) {
this.res.__id__ = node.id;
// Technically we don't need to call serialize, but only need to update widget values
node.widgets_values = node.serialize().widgets_values;
}
});
}
});
}
}, function (mode) {
if (mode === 0b100000)
this.self.size[0] = Math.max(this.self.size[0], 350);
});
const HUB_PASS_DATA = Symbol("pass_data"), HUB_PASS_CALL = Symbol("pass_call");
lib0246.hijack(Hub.prototype, "onAdded", function () {
if (this.mark) {
const node = this.self;
node.hub = node.hub ?? {};
app.graph.extra["0246.HUB_DATA"] = app.graph.extra["0246.HUB_DATA"] ?? {};
app.graph.extra["0246.HUB_DATA"][node.id] = app.graph.extra["0246.HUB_DATA"][node.id] ?? {};
node.hub.data = app.graph.extra["0246.HUB_DATA"][node.id];
node.hub.data.node_list = node.hub.data.node_list ?? [];
node.hub.data.node_img = node.hub.data.node_img ?? [];
node.hub.data.sole_name = node.hub.data.sole_name ?? {};
node.hub.data.sole_type = node.hub.data.sole_type ?? {};
// Temp data
node.hub.node_area = {};
node.hub.node_widget = {};
node.hub.space_widget = {};
node.hub.node_func = {};
node.hub.sole_widget = [];
node.hub.sole_space = null;
if (node[HUB_PASS_DATA]) {
window.setTimeout(() => {
Object.assign(node.hub.data, structuredClone(app.graph.extra["0246.HUB_DATA"][node[HUB_PASS_DATA].__id__]));
node[HUB_PASS_DATA].widgets_values = structuredClone(app.graph.getNodeById(node[HUB_PASS_DATA].__id__).widgets_values);
wg0246.hub_setup_widget(node, node[HUB_PASS_DATA], node[HUB_PASS_DATA].__id__);
delete node[HUB_PASS_DATA];
}, 0);
}
}
});
lib0246.hijack(Hub.prototype, "onConfigure", function (data) {
if (this.mark) {
const node = this.self;
if (node.id > -1)
hub_list.push(node, structuredClone(data));
else
node[HUB_PASS_DATA] = data;
}
});
lib0246.hijack(Hub.prototype, "onRemoved", function () {
if (!this.mark) {
const node = this.self;
if (node.hub.data)
while (node.hub.data.node_list.length > 0)
node.hubPullNode(node.hub.data.node_list[0]);
delete app.graph.extra["0246.HUB_DATA"][node.id];
}
});
lib0246.hijack(Hub.prototype, "getExtraMenuOptions", function (canvas, options) {
if (!this.mark) {
const node = this.self;
options.push(
{
content: "[0246.Hub] Add widgets from \"graph selected nodes\"",
callback: function() {
for (let key in app.canvas.selected_nodes) {
const curr_node = app.canvas.selected_nodes[key];
if (curr_node === node || node.isVirtualNode || curr_node.type === "0246.Hub")
continue;
node.hubPushNode(curr_node);
}
app.canvas.setDirty(true);
}
}, {
content: "[0246.Hub] Add sole widgets from \"graph selected nodes\"",
callback: function() {
for (let key in app.canvas.selected_nodes) {
const curr_node = app.canvas.selected_nodes[key];
if (curr_node === node || node.isVirtualNode || curr_node.type === "0246.Hub")
continue;
node.hubPushNode(curr_node.type);
}
app.canvas.setDirty(true);
}
}, {
content: "[0246.Hub] Remove widgets from \"hub selected nodes\"",
callback: function() {
for (let node_id in node.hub.space_widget) {
if (node.hub.space_widget[node_id].select)
node.hubPullNode(node.hub.space_widget[node_id].value);
}
app.canvas.setDirty(true);
}
}, {
content: "[0246.Hub] Select All",
callback: function() {
for (let node_id in node.hub.space_widget)
node.hub.space_widget[node_id].select = true;
app.canvas.setDirty(true);
}
}, {
content: "[0246.Hub] Deselect All",
callback: function() {
for (let node_id in node.hub.space_widget)
node.hub.space_widget[node_id].select = false;
app.canvas.setDirty(true);
}
}
);
wg0246.help_option(Hub, wg0246.HELP["hub"], options);
options.push(null);
}
});
lib0246.hijack(Hub.prototype, "computeSize", function () {
if (this.mark)
this.res[1] -= this.self.outputs.length > 0 ? 0 : LiteGraph.NODE_SLOT_HEIGHT;
});
Hub.prototype.hubSize = function (extra = 0) {
const curr_size = this.computeSize();
curr_size[0] = Math.max(curr_size[0], LiteGraph.NODE_WIDTH, this.size[0]);
this.setSize(curr_size);
};
Hub.prototype.hubPushWidgetPrim = function (type, ...args) {
const node = this;
switch (type) {
case "INT": {
return node.hubPushWidget({
type: "number",
value: 0,
options: {
min: Number.MIN_SAFE_INTEGER,
max: Number.MAX_SAFE_INTEGER,
step: 10, // litegraph.js internally multiply by 0.1
precision: 0
},
}, "int", "INT", ...args);
} break;
case "FLOAT": {
return node.hubPushWidget({
type: "number",
value: 0,
options: {
min: -Infinity,
max: Infinity,
step: 1,
precision: 5
},
}, "float", "FLOAT", ...args);
} break;
case "STRING": {
return node.hubPushWidget({
type: "string",
value: "",
options: {
multiline: true
}
}, "string", "STRING", ...args);
} break;
case "BOOLEAN": {
return node.hubPushWidget({
type: "toggle",
value: false,
options: {}
}, "boolean", "BOOLEAN", ...args);
} break;
case "__BATCH_PRIM__": {
return this.hubPushWidgetComboRaw(wg0246.type_defs, type, wg0246.hub_combo_pin_type_func, ...args);
} break;
case "__BATCH_COMBO__": {
return this.hubPushWidgetComboRaw(wg0246.combo_defs, type, wg0246.hub_combo_pin_type_func, args[0], args[1], wg0246.hub_serialize_batch_combo);
} break;
case "__PIPE__": {
return this.hubPushWidgetComboRaw(wg0246.PIPE_COMBO, type, wg0246.hub_combo_pin_type_func, ...args);
} break;
}
};
Hub.prototype.hubPushWidgetCombo = function (node_name, part_name, pin_name, full_name) {
return this.hubPushWidgetComboRaw(wg0246.defs[node_name].input[part_name][pin_name][0], "COMBO", () => {}, [node_name, part_name, pin_name], full_name);
};
Hub.prototype.hubPushWidgetComboRaw = function (combo_data, combo_type, func, extra_name, full_name, serialize_func) {
const widget = this.hubPushWidget({
type: "combo",
value: combo_data[0],
callback: func ?? (() => {}),
options: {
values: combo_data
},
}, "combo", combo_type, extra_name, full_name);
if (serialize_func && serialize_func.constructor.name === "AsyncFunction")
widget.serializeValue = serialize_func;
window.setTimeout(() => {
widget.callback(widget.value, app.canvas, this, null, null);
}, 0);
return widget;
};
Hub.prototype.hubPushWidgetNode = function (node_name, full_name) {
for (let part_name in wg0246.defs[node_name].input)
for (let pin_name in wg0246.defs[node_name].input[part_name]) {
const curr_type = wg0246.defs[node_name].input[part_name][pin_name][0];
if (Array.isArray(curr_type))
this.hubPushWidgetCombo(node_name, part_name, pin_name, full_name);
else
this.hubPushWidgetPrim(curr_type, [node_name, part_name, pin_name], full_name);
}
};
Hub.prototype.hubPushWidget = function (widget, id_type, pin_type, extra_name = [], full_name = "") {
if (!this.hub.sole_space) {
this.hub.sole_space = wg0246.SPACE_TITLE_WIDGET();
lib0246.get_array(this, "widgets").splice(wg0246.HUB_SOLE + 1, 0, this.hub.sole_space);
}
lib0246.get_array(this, "widgets").splice(wg0246.HUB_SOLE + 2 + this.hub.sole_widget.length, 0, widget);
this.hub.sole_widget.push(widget);
if (full_name.length > 0) {
widget.name = full_name;
for (let i = 0; i < this.outputs.length; ++ i)
if (this.outputs[i].name === full_name) {
widget[wg0246.HUB_WIDGET_PIN] = this.outputs[i];
break;
}
} else {
this.hub.data.sole_name[id_type] = this.hub.data.sole_name[id_type] ?? 0;
let list_name = [
"sole", String(this.hub.data.sole_name[id_type] ++),
id_type, ...extra_name, pin_type
];
full_name = list_name.reduce((a, b) =>
typeof a !== "string" ? (b ?? "") :
typeof b !== "string" ? (a ?? "") :
a + ":" + b
);
const old_w = this.size[0];
widget[wg0246.HUB_WIDGET_PIN] = this.addOutput(widget.name = full_name, pin_type === "__BATCH_COMBO__" ? "COMBO" : pin_type);
this.size[0] = old_w;
this.hub.data.sole_type[full_name] = list_name;
}
this.hubSize();
return widget;
};
Hub.prototype.hubPullWidget = function (widget) {
const widget_index = lib0246.get_array(this, "widgets").indexOf(widget);
if (widget_index === -1)
return;
lib0246.get_array(this, "widgets").splice(widget_index, 1);
delete this.hub.data.sole_type[widget.name];
const output_index = this.outputs.indexOf(this.outputs.find(o => o.name === widget.name));
if (output_index > -1) {
delete Hub.nodeData.output[output_index];
this.removeOutput(output_index);
}
const sole_widget_index = this.hub.sole_widget.indexOf(widget);
if (sole_widget_index > -1)
this.hub.sole_widget.splice(sole_widget_index, 1);
if (this.hub.sole_widget.length === 0) {
lib0246.get_array(this, "widgets").splice(wg0246.HUB_SOLE + 1, 1);
this.hub.sole_space = null;
}
this.hubSize();
};
const HUB_PARENT = Symbol("hub_parent");
Hub.prototype.hubPushNode = function (curr_node, flag = false) {
const node = this;
if (curr_node[HUB_PARENT] === node || !curr_node.widgets || curr_node.widgets.length === 0)
return;
curr_node[HUB_PARENT] = node;
if (!flag || (flag && node.hub.data.node_list.indexOf(curr_node.id) === -1))
node.hub.data.node_list.push(curr_node.id);
node.hub.node_func[curr_node.id] = {};
node.hub.node_func[curr_node.id].bound = lib0246.hijack(curr_node, "onBounding", function (area) {
if (this.mark)
node.hub.node_area[curr_node.id] = area;
});
node.hub.node_func[curr_node.id].remove = lib0246.hijack(curr_node, "onRemoved", function () {
if (!this.mark)
node.hubPullNode(curr_node.id);
});
node.hub.node_widget[curr_node.id] = curr_node.widgets;
node.hub.space_widget[curr_node.id] = node.addCustomWidget(wg0246.SPACE_TITLE_WIDGET());
node.hub.space_widget[curr_node.id].value = curr_node.id;
node.hub.node_func[curr_node.id].draw_bg = lib0246.hijack(curr_node, "onDrawBackground", function (ctx, visible_area) {
if (this.mark) {
const curr_widget = node.hub.space_widget[curr_node.id];
if (node.hub.space_widget[curr_node.id].select) {
ctx.beginPath();
ctx.strokeStyle = curr_widget.select_color;
ctx.lineWidth = 2;
ctx.setLineDash([]);
ctx.roundRect(
-12, -12 - LiteGraph.NODE_TITLE_HEIGHT,
this.self.size[0] + 24, this.self.size[1] + 24 + LiteGraph.NODE_TITLE_HEIGHT,
5, 5
);
ctx.stroke();
ctx.closePath();
}
}
});
for (let i = 0; i < curr_node.widgets.length; ++ i) {
const widget = curr_node.widgets[i];
node.addCustomWidget(widget);
widget[wg0246.NODE_PARENT] = curr_node;
}
if (curr_node.imgs && curr_node.imgs.length > 0)
node.hub.data.node_img.push(curr_node.id);
node.hubSize();
};
Hub.prototype.hubPullNode = function (curr_id) {
const node_index = this.hub.data.node_list.indexOf(curr_id);
if (node_index === -1)
return;
this.hub.data.node_list.splice(node_index, 1);
const node_img_index = this.hub.data.node_img.indexOf(curr_id);
if (node_img_index > -1)
this.hub.data.node_img.splice(node_img_index, 1);
delete this.hub.node_area[curr_id];
if (this.hub.node_widget[curr_id]) {
for (let widget of this.hub.node_widget[curr_id]) {
let widget_index = lib0246.get_array(this, "widgets").indexOf(widget);
if (widget_index > -1)
lib0246.get_array(this, "widgets").splice(widget_index, 1);
}
delete this.hub.node_widget[curr_id];
}
// [TODO] For some reason there's trailing space_widget
const space_widget_index = lib0246.get_array(this, "widgets").indexOf(this.hub.space_widget[curr_id]);
if (space_widget_index > -1)
lib0246.get_array(this, "widgets").splice(space_widget_index, 1);
delete this.hub.space_widget[curr_id];
const curr_node = app.graph.getNodeById(curr_id);
if (curr_node && this.hub.node_func[curr_id]) {
delete curr_node[HUB_PARENT];
curr_node.onBounding = this.hub.node_func[curr_id].bound;
curr_node.onRemoved = this.hub.node_func[curr_id].remove;
curr_node.onDrawBackground = this.hub.node_func[curr_id].draw_bg;
}
delete this.hub.node_func[curr_id];
this.hubSize();
};
let temp_parent = [];
lib0246.hijack(GroupNodeHandler, "fromNodes", function (nodes) {
if (!this.mark) {
for (let i = 0; i < nodes.length; ++ i) {
if (nodes[i][HUB_PARENT] && temp_parent.indexOf(nodes[i].id) === -1) {
temp_parent.push(nodes[i][HUB_PARENT].id);
nodes[i][HUB_PARENT].hubPullNode(nodes[i].id);
}
nodes[i][wg0246.SOFT_REMOVE] = true;
}
} else {
if (this.res) {
const node_list = this.res.getInnerNodes();
let count = 0;
while (temp_parent.length > 0) {
const curr_parent = app.graph.getNodeById(temp_parent.pop());
curr_parent.hubPushNode(this.res);
const curr_count = count ++;
node_list[curr_count][HUB_PARENT] = curr_parent;
node_list[curr_count][wg0246.SOFT_REMOVE] = false;
}
lib0246.hijack(this.res, "convertToNodes", function () {
if (!this.mark) {
for (let i = 0; i < node_list.length; ++ i)
if (node_list[i][HUB_PARENT]) {
node_list[i][HUB_PARENT].hubPullNode(node_list[i].id);
temp_parent.push(node_list[i][HUB_PARENT].id, node_list[i].id);
}
} else while (temp_parent.length > 0) {
const curr_node = app.graph.getNodeById(temp_parent.pop()),
curr_parent = app.graph.getNodeById(temp_parent.pop());
for (let i = 0; i < this.res.length; ++ i)
if (this.res[i].id === curr_node.id) {
curr_parent.hubPushNode(this.res[i]);
break;
}
}
});
}
}
});
wg0246.rgthree_exec("addConnectionLayoutSupport", Hub, app);
} break;
case "0246.Script": {
wg0246.junction_impl(nodeType, nodeData, app, null, LiteGraph.GRID_SHAPE, LiteGraph.GRID_SHAPE);
} break;
case "0246.ScriptPile": {
lib0246.hijack(nodeType.prototype, "onNodeCreated", function () {
if (this.mark) {
const regex_widget = this.self.widgets.find(w => w.name === "script_rule_regex");
regex_widget.options = regex_widget.options ?? {};
regex_widget.options.multiline = true;
}
});
} break;
case "0246.ScriptNode": {
lib0246.hijack(nodeType.prototype, "onNodeCreated", function () {
if (this.mark) {
const regex_widget = this.self.widgets.find(w => w.name === "script_ignore_regex");
regex_widget.options = regex_widget.options ?? {};
regex_widget.options.multiline = true;
}
});
} break;
case "0246.Cloud": {
const Cloud = nodeType;
lib0246.hijack(nodeType.prototype, "getExtraMenuOptions", function (canvas, options) {
if (!this.mark) {
this.self.constructor.nodeData[wg0246.CLOUD_MARK].self = this.self;
wg0246.cloud_menu("cloud", options);
} else
this.self.constructor.nodeData[wg0246.CLOUD_MARK].self = null;
});
wg0246.single_impl_input(Cloud, nodeData, app, LiteGraph.CIRCLE_SHAPE);
lib0246.hijack(Cloud.prototype, "onConnectExpand", wg0246.cloud_expand_func);
} break;
case "0246.Switch": {
wg0246.junction_impl(nodeType, nodeData, app, null, LiteGraph.GRID_SHAPE, LiteGraph.GRID_SHAPE);
lib0246.hijack(
nodeType.prototype, "onConnectionsChange",
function (type, index, connected, link_info) {
const node = this.self;
if (this.mark && !connected) {
if (type === LiteGraph.OUTPUT && node.outputs[link_info.origin_slot].name !== "..." && node.widgets && node.outputs[link_info.origin_slot].links.length === 0) {
node.widgets.splice(node.widgets.length - 1, 1);
for (let i = 0; i < node.inputs.length; ++ i)
if (node.inputs[i].name.startsWith("switch:") && i >= node.widgets.length) {
node.inputs.splice(i --, 1);
break;
}
}
// [TODO] Maybe avoid setTimeout
window.setTimeout(() => {
node.widgets = node.widgets ?? [];
for (let i = 0; i < node.widgets.length; ++ i)
if (node.inputs.findIndex(_ => (_.label ?? _.name) === node.widgets[i].value) === -1)
node.widgets[i].value = "_";
}, 0);
}
},
);
nodeType.prototype.onNameExpand = function (type, kind, ...args) {
const index = type ? args[1] : args[0];
if (kind === LiteGraph.OUTPUT)
return `${this.inputs?.find?.(_ => (_.label ?? _.name) === lib0246.get_array(this, "widgets")?.[index]?.value)?.type ?? "_"}:${index}`;
};
lib0246.hijack(nodeType.prototype, "onConfigure", function (data) {
if (this.mark) {
const node = this.self;
for (let i = 0; i < node.inputs.length; ++ i)
lib0246.hijack_value(node.inputs[i], "label", wg0246.switch_input_label_change.bind(null, app, node, i));
for (let i = 0; i < node.outputs.length; ++ i)
if (node.outputs[i].name !== "...")
wg0246.switch_widget(node, i, data.widgets_values[i]);
}
});
lib0246.hijack(nodeType.prototype, "onConnectOutput", function (
this_slot_index,
other_slot_type,
other_slot_obj,
other_node,
other_slot_index
) {
const node = this.self;
if (!this.mark && node.outputs[this_slot_index].name === "..." && !other_node.inputs[other_slot_index].link)
wg0246.switch_widget(node, this_slot_index, "_");
});
lib0246.hijack(nodeType.prototype, "onConnectInput", function (
this_slot_index,
other_slot_type,
other_slot_obj,
other_node,
other_slot_index
) {
const node = this.self;
if (this.mark)
window.setTimeout(lib0246.hijack_value.bind(
null, node.inputs[this_slot_index], "label",
wg0246.switch_input_label_change.bind(null, app, node, this_slot_index)
), 0);
});
lib0246.hijack(nodeType.prototype, "onConnectExpand", function (mode, name) {
if (this.mark && this.res !== true)
this.res = name.startsWith("switch:");
});
} break;
case "0246.Meta": {
wg0246.single_impl_pin(nodeType, [
"data", LiteGraph.INPUT, LiteGraph.GRID_SHAPE,
]);
} break;
}
}
},
async afterConfigureGraph() {
// "setup" only called once so we have to move this here
window.setTimeout(() => {
for (let i = 0; i < hub_list.length; i += 2)
wg0246.hub_setup_widget(hub_list[i], hub_list[i + 1], hub_list[i].id);
hub_list.length = 0;
}, 0);
},
});
// [TODO] New node that integrate with rgthree to immediate execute a sole node