More bug fixes and node changes
This commit is contained in:
@@ -31,7 +31,7 @@ import nodes
|
||||
######################################## IMPL ########################################
|
||||
######################################################################################
|
||||
|
||||
def highway_impl(_prompt, _id, _workflow, _way_in, kwargs):
|
||||
def highway_impl(_prompt, _id, _workflow, _way_in, flag, kwargs):
|
||||
if isinstance(_prompt, list):
|
||||
_prompt = _prompt[0]
|
||||
if isinstance(_id, list):
|
||||
@@ -57,7 +57,7 @@ def highway_impl(_prompt, _id, _workflow, _way_in, kwargs):
|
||||
for i, curr_input in enumerate(curr_node["inputs"]):
|
||||
if curr_input["name"] in kwargs:
|
||||
name = _workflow["workflow"]["extra"]["0246.__NAME__"][_id]["inputs"][str(i)]["name"][1:]
|
||||
_way_in[("data", name)] = kwargs[curr_input["name"]]
|
||||
_way_in[("data", name)] = lib0246.RevisionBatch(*kwargs[curr_input["name"]]) if flag else kwargs[curr_input["name"]]
|
||||
_way_in[("type", name)] = curr_input["type"]
|
||||
|
||||
res = []
|
||||
@@ -485,7 +485,7 @@ class Highway:
|
||||
|
||||
# Do not remove the "useless" _query parameter, since data need to be consumed for expanding
|
||||
def execute(self, _id = None, _prompt = None, _workflow = None, _way_in = None, _query = None, **kwargs):
|
||||
return highway_impl(_prompt, _id, _workflow, _way_in, kwargs)
|
||||
return highway_impl(_prompt, _id, _workflow, _way_in, False, kwargs)
|
||||
|
||||
@classmethod
|
||||
def IS_CHANGED(self, _query, _id = None, _prompt = None, _workflow = None, _way_in = None, *args, **kwargs):
|
||||
@@ -521,7 +521,7 @@ class HighwayBatch:
|
||||
CATEGORY = "0246"
|
||||
|
||||
def execute(self, _id = None, _prompt = None, _workflow = None, _way_in = None, _query = None, **kwargs):
|
||||
return highway_impl(_prompt, _id, _workflow, gather_highway_impl(_way_in, _id), kwargs)
|
||||
return highway_impl(_prompt, _id, _workflow, gather_highway_impl(_way_in, _id), True, kwargs)
|
||||
|
||||
@classmethod
|
||||
def IS_CHANGED(self, _query, _id = None, _prompt = None, _workflow = None, _way_in = None, *args, **kwargs):
|
||||
@@ -701,9 +701,9 @@ class RandomInt:
|
||||
"optional": {
|
||||
"seed": ("INT", {
|
||||
"default": 0,
|
||||
"min": -9007199254740991,
|
||||
"min": -1125899906842624,
|
||||
# "max": 18446744073709551615
|
||||
"max": 9007199254740991
|
||||
"max": 1125899906842624
|
||||
}),
|
||||
},
|
||||
"hidden": {
|
||||
@@ -720,16 +720,6 @@ class RandomInt:
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
def rand_cond(db, batch_size):
|
||||
return len(db["prev"]) == 0 or db["prev_batch_size"] != batch_size
|
||||
|
||||
def rand_gen(db, min, max, seed, mode, batch_size):
|
||||
if seed != db["seed"] or mode == "force":
|
||||
db["inst"].seed(seed)
|
||||
db["seed"] = seed
|
||||
db["prev"] = [db["inst"].randint(min, max) for _ in range(batch_size)]
|
||||
db["prev_batch_size"] = batch_size
|
||||
|
||||
def execute(self, _id = None, val = None, min = None, max = None, seed = None, batch_size = None, mode = None, **kwargs):
|
||||
if min[0] > max[0]:
|
||||
raise Exception("Min is greater than max.")
|
||||
@@ -749,12 +739,14 @@ class RandomInt:
|
||||
if db["track"] != PROMPT_ID:
|
||||
db["track"] = PROMPT_ID
|
||||
db["flag"] = 0
|
||||
if mode[0] == "keep":
|
||||
if mode[0] == "keep" or db["prev_batch_size"] != batch_size[0]:
|
||||
db["prev"].clear()
|
||||
db["prev_batch_size"] = 0
|
||||
mode[0] = "force"
|
||||
|
||||
raw = val[0].split(",")
|
||||
raw: list = val[0].split(",")
|
||||
if len(raw) > batch_size[0]:
|
||||
raw = raw[:batch_size[0]]
|
||||
|
||||
for i in range(len(raw)):
|
||||
raw[i] = raw[i].strip()
|
||||
@@ -858,6 +850,8 @@ class Hold:
|
||||
result = update_hold_db(_id[0], None if (mode == "ignore" and len(Hold.HOLD_DB[_id[0]]["data"]) > 0) else _data_in)
|
||||
BASE_EXECUTOR.outputs[_id[0]] = Hold.HOLD_DB[_id[0]]["data"]
|
||||
ui_text += f"Size: {len(result)}, "
|
||||
if mode == "clear":
|
||||
Hold.HOLD_DB[_id[0]]["data"] = []
|
||||
else:
|
||||
ui_text += f"None, "
|
||||
result = [None]
|
||||
@@ -999,9 +993,18 @@ class Merge:
|
||||
real_key = key_name[1]
|
||||
while True:
|
||||
if ("data", real_key) not in way:
|
||||
way[("type", real_key)] = type(curr[("data", key_name[1])]).__name__
|
||||
# way[("type", real_key)] = type(curr[("data", key_name[1])]).__name__
|
||||
way[("type", real_key)] = curr[("type", key_name[1])]
|
||||
way[("data", real_key)] = curr[("data", key_name[1])]
|
||||
break
|
||||
elif _mode[0] == "deep" and curr[("type", key_name[1])] == way[("type", real_key)]:
|
||||
if not isinstance(way[("data", real_key)], list):
|
||||
way[("data", real_key)] = lib0246.RevisionBatch(*way[("data", real_key)])
|
||||
if isinstance(curr[("data", key_name[1])], list):
|
||||
way[("data", real_key)].extend(curr[("data", key_name[1])])
|
||||
else:
|
||||
way[("data", real_key)].append(curr[("data", key_name[1])])
|
||||
break
|
||||
real_key += _pad[0]
|
||||
else:
|
||||
batch.append(curr)
|
||||
@@ -1203,7 +1206,7 @@ class BoxRange:
|
||||
|
||||
######################################################################################
|
||||
|
||||
class ScriptImbue:
|
||||
class ScriptNode:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
@@ -1213,7 +1216,7 @@ class ScriptImbue:
|
||||
"default": "",
|
||||
"multiline": False
|
||||
}),
|
||||
"script_pin_mode": (["pin_highway_deep", "pin_highway_flat", "pin_junction"], ),
|
||||
"script_pin_mode": (["pin_highway_deep", "pin_highway_flat", "pin_junction", "pin_direct"], ),
|
||||
"script_res_order": ("STRING", {
|
||||
"default": "",
|
||||
"multiline": False
|
||||
@@ -1230,10 +1233,10 @@ class ScriptImbue:
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = (lib0246.TautologyStr("*"), "SCRIPT_DATA", "SCRIPT_DATA")
|
||||
RETURN_NAMES = ("pipe_out", "script_pin_data", "script_res_data")
|
||||
RETURN_TYPES = (lib0246.TautologyStr("*"), "SCRIPT_DATA", "SCRIPT_DATA", "SCRIPT_DATA")
|
||||
RETURN_NAMES = ("pipe_out", "script_pin_data", "script_exec_data", "script_res_data")
|
||||
INPUT_IS_LIST = False
|
||||
OUTPUT_IS_LIST = (False, False, False)
|
||||
OUTPUT_IS_LIST = lib0246.ContradictAll()
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
@@ -1303,6 +1306,8 @@ class ScriptImbue:
|
||||
return True
|
||||
return False
|
||||
pin_func = temp_func
|
||||
case "pin_direct":
|
||||
raise Exception("pin_direct is not supported yet.")
|
||||
case _:
|
||||
pass
|
||||
|
||||
@@ -1346,28 +1351,36 @@ class ScriptImbue:
|
||||
case _:
|
||||
pass
|
||||
|
||||
return (pipe_in, None if pin_func is None else ScriptData({
|
||||
"id": _id,
|
||||
"func": pin_func,
|
||||
"order": script_pin_order,
|
||||
"kind": "wrap"
|
||||
}), None if res_func is None else ScriptData({
|
||||
"id": _id,
|
||||
"func": res_func,
|
||||
"order": script_res_order,
|
||||
"kind": "wrap"
|
||||
}))
|
||||
return (
|
||||
pipe_in,
|
||||
None if pin_func is None else ScriptData({
|
||||
"id": _id,
|
||||
"func": pin_func,
|
||||
"order": script_pin_order,
|
||||
"kind": "wrap"
|
||||
}), ScriptData({
|
||||
"id": _id,
|
||||
"node_name": script_node,
|
||||
"node_class": class_type,
|
||||
"node_inst": class_type(),
|
||||
"func": plan_exec_node,
|
||||
"kind": "exec"
|
||||
}),
|
||||
None if res_func is None else ScriptData({
|
||||
"id": _id,
|
||||
"func": res_func,
|
||||
"order": script_res_order,
|
||||
"kind": "wrap"
|
||||
})
|
||||
)
|
||||
|
||||
######################################################################################
|
||||
|
||||
class ScriptPlan:
|
||||
class ScriptRule:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"script_node": (list(nodes.NODE_CLASS_MAPPINGS.keys()), ),
|
||||
"script_func": (["_"], ),
|
||||
"script_exec_mode": (["node", "func", "func_list"], ),
|
||||
"script_rule_mode": (["slice", "cycle"], ),
|
||||
},
|
||||
"hidden": {
|
||||
@@ -1375,35 +1388,16 @@ class ScriptPlan:
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("SCRIPT_DATA", "SCRIPT_DATA")
|
||||
RETURN_NAMES = ("script_exec_data", "script_rule_data")
|
||||
RETURN_TYPES = ("SCRIPT_DATA", )
|
||||
RETURN_NAMES = ("script_rule_data", )
|
||||
OUTPUT_IS_LIST = (False, False)
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
def execute(
|
||||
self, _id = None,
|
||||
script_node = None, script_func = None, script_exec_mode = None, script_rule_mode = None,
|
||||
script_chain_type = None
|
||||
self, _id = None, script_rule_mode = None
|
||||
):
|
||||
# chain_type specifies which out pin type to be feed into same node until the batch exhaust
|
||||
|
||||
exec_data = None
|
||||
rule_data = None
|
||||
match script_exec_mode:
|
||||
case "node":
|
||||
exec_data = ScriptData({
|
||||
"id": _id,
|
||||
"node_name": script_node,
|
||||
"node_class": nodes.NODE_CLASS_MAPPINGS[script_node],
|
||||
"node_inst": nodes.NODE_CLASS_MAPPINGS[script_node](),
|
||||
"func": plan_exec_node,
|
||||
"kind": "exec"
|
||||
})
|
||||
case "func":
|
||||
raise Exception(f"Not implemented yet.")
|
||||
case _:
|
||||
raise Exception(f"Invalid exec mode \"{script_exec_mode}\".")
|
||||
|
||||
if script_rule_mode is not None:
|
||||
if script_rule_mode == "_":
|
||||
@@ -1429,7 +1423,7 @@ class ScriptPlan:
|
||||
case _:
|
||||
raise Exception(f"Invalid rule mode \"{script_rule_mode}\".")
|
||||
|
||||
return (exec_data, rule_data)
|
||||
return (rule_data, )
|
||||
|
||||
######################################################################################
|
||||
|
||||
@@ -1659,23 +1653,6 @@ class Hub:
|
||||
"result": [res_data[i] for i in range(len(res_data))]
|
||||
}
|
||||
|
||||
######################################################################################
|
||||
######################################## TODO ########################################
|
||||
######################################################################################
|
||||
|
||||
# class ScriptExpr:
|
||||
# For things that require text-based expression, such as string combine, conditioning combine, etc.
|
||||
# Which allows each operators to associate with a node or func.
|
||||
# => Require 4 widgets: ops, node, add button, and current code.
|
||||
# But how do we specify which parameters for which?
|
||||
# pass
|
||||
|
||||
######################################################################################
|
||||
|
||||
# class Alter:
|
||||
# Use parse_lang to shift around highway and junction data (including script)
|
||||
# pass
|
||||
|
||||
########################################################################################
|
||||
######################################## EXPORT ########################################
|
||||
########################################################################################
|
||||
@@ -1697,8 +1674,8 @@ NODE_CLASS_MAPPINGS = {
|
||||
"0246.Merge": Merge,
|
||||
# "0246.Convert": Convert,
|
||||
"0246.BoxRange": BoxRange,
|
||||
"0246.ScriptImbue": ScriptImbue,
|
||||
"0246.ScriptPlan": ScriptPlan,
|
||||
"0246.ScriptNode": ScriptNode,
|
||||
"0246.ScriptRule": ScriptRule,
|
||||
"0246.Script": Script,
|
||||
"0246.Hub": Hub,
|
||||
# "0246.Pick": Pick,
|
||||
@@ -1718,8 +1695,8 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"0246.Merge": "Merge",
|
||||
# "0246.Convert": "Convert",
|
||||
"0246.BoxRange": "Box Range",
|
||||
"0246.ScriptImbue": "Script Imbue",
|
||||
"0246.ScriptPlan": "Script Plan",
|
||||
"0246.ScriptNode": "Script Node",
|
||||
"0246.ScriptRule": "Script Rule",
|
||||
"0246.Script": "Script",
|
||||
"0246.Hub": "Hub",
|
||||
# "0246.Pick": "Pick",
|
||||
|
||||
@@ -184,6 +184,10 @@ class RevisionDict(dict):
|
||||
|
||||
return self
|
||||
|
||||
class RevisionBatch(list):
|
||||
def __init__(self, *args):
|
||||
self.extend(args)
|
||||
|
||||
class FlatIter:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
+59
-5
@@ -310,11 +310,35 @@ const patch_node_db = [
|
||||
["Stringify", "0246.Stringify"],
|
||||
];
|
||||
|
||||
const patch_node_db_0_0_3 = [
|
||||
["0246.ScriptPlan", "0246.ScriptRule"],
|
||||
["0246.ScriptImbue", "0246.ScriptNode"],
|
||||
];
|
||||
|
||||
let PATCH_SIG = [];
|
||||
|
||||
function patch_script(workflow) {
|
||||
for (let i = 0; i < workflow.nodes.length; ++ i)
|
||||
for (let j = 0; j < patch_node_db_0_0_3.length; ++ j)
|
||||
if (workflow.nodes[i].type === patch_node_db_0_0_3[j][0]) {
|
||||
console.warn(`[ComfyUI-0246] Patching node "${workflow.nodes[i].type}" to "${patch_node_db_0_0_3[j][1]}"`);
|
||||
workflow.nodes[i].type = patch_node_db_0_0_3[j][1];
|
||||
if (workflow.nodes[i].type === "0246.ScriptRule") {
|
||||
workflow.nodes[i].outputs.shift();
|
||||
workflow.nodes[i].widgets_values[0] = workflow.nodes[i].widgets_values[3];
|
||||
} else if (workflow.nodes[i].type === "0246.ScriptNode")
|
||||
workflow.nodes[i].outputs[2].name = "script_exec_data";
|
||||
if (!PATCH_SIG.includes(2))
|
||||
PATCH_SIG.push(2);
|
||||
break;
|
||||
} else if (workflow.nodes[i].type === patch_node_db_0_0_3[j][1])
|
||||
break;
|
||||
}
|
||||
|
||||
lib0246.hijack(app, "loadGraphData", function (workflow) {
|
||||
PATCH_SIG.length = 0;
|
||||
if (workflow) {
|
||||
if (!workflow?.extra?.["0246.VERSION"])
|
||||
if (!workflow?.extra?.["0246.VERSION"]) {
|
||||
for (let i = 0; i < workflow.nodes.length; ++ i) {
|
||||
for (let j = 0; j < patch_node_db.length; ++ j) {
|
||||
if (workflow.nodes[i].type === patch_node_db[j][0]) {
|
||||
@@ -344,6 +368,14 @@ lib0246.hijack(app, "loadGraphData", function (workflow) {
|
||||
}
|
||||
}
|
||||
}
|
||||
patch_script(workflow);
|
||||
}
|
||||
else if (
|
||||
workflow.extra["0246.VERSION"][0] === 0 &&
|
||||
workflow.extra["0246.VERSION"][1] === 0 &&
|
||||
workflow.extra["0246.VERSION"][2] === 3
|
||||
)
|
||||
patch_script(workflow);
|
||||
}
|
||||
}, function (workflow) {
|
||||
if (PATCH_SIG.includes(1))
|
||||
@@ -355,6 +387,24 @@ lib0246.hijack(app, "loadGraphData", function (workflow) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
window.setTimeout(() => {
|
||||
if (PATCH_SIG.includes(2)) {
|
||||
for (let i = 0; i < app.graph._nodes.length; ++ i) {
|
||||
// if (app.graph._nodes[i].type === "0246.ScriptNode")
|
||||
// for (let j = 0; j < app.graph._nodes[i].outputs.length; ++ j)
|
||||
// app.graph._nodes[i].disconnectOutput(j);
|
||||
for (let j = 0; j < patch_node_db_0_0_3.length; ++ j)
|
||||
if (app.graph._nodes[i].type === patch_node_db_0_0_3[j][1])
|
||||
app.graph._nodes[i].setSize([app.graph._nodes[i].size[0], app.graph._nodes[i].computeSize()[1]]);
|
||||
}
|
||||
lib0246.error_popup(lib0246.indent_str `
|
||||
Recent update have 0246.ScriptNode (formerly 0246.ScriptImbue) have it output changed due to bad design.
|
||||
Please reconnect all output to desired node manually.
|
||||
|
||||
Also remember to check for all 0246.ScriptRule if they have intended data.
|
||||
`);
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
@@ -383,6 +433,9 @@ lib0246.hijack(app, "showMissingNodesError", function (nodes) {
|
||||
- Beautify -> 0246.Beautify
|
||||
- Random -> 0246.RandomInt
|
||||
- Stringify -> 0246.Stringify
|
||||
|
||||
- 0246.ScriptPlan -> 0246.ScriptRule
|
||||
- 0246.ScriptImbue -> 0246.ScriptNode
|
||||
`);
|
||||
error_flag = true;
|
||||
break;
|
||||
@@ -393,10 +446,6 @@ lib0246.hijack(app, "showMissingNodesError", function (nodes) {
|
||||
app.registerExtension({
|
||||
name: "0246.Fixes",
|
||||
async setup(app) {
|
||||
window.setTimeout(() => {
|
||||
app.graph.extra["0246.VERSION"] = app.graph.extra["0246.VERSION"] ?? [0, 0, 3]; // Only used when breaking changes happen
|
||||
}, 0);
|
||||
|
||||
if (LiteGraph.Nodes.RerouteNode) {
|
||||
// Hijack Reroute (rgthree) to do onConnectOutput and onConnectInput
|
||||
lib0246.hijack(LiteGraph.Nodes.RerouteNode.prototype, "onConnectionsChange", () => {}, function (type, index, connected, link_info) {
|
||||
@@ -405,5 +454,10 @@ app.registerExtension({
|
||||
|
||||
// Since native "Reroute" already did graph traversal, we don't need to hijack it
|
||||
}
|
||||
|
||||
lib0246.hijack(app.graph, "serialize", function () {
|
||||
// Only used when breaking changes happen
|
||||
app.graph.extra["0246.VERSION"] = [0, 0, 4];
|
||||
}, () => {});
|
||||
}
|
||||
});
|
||||
+87
-44
@@ -2262,7 +2262,7 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
|
||||
ctx.closePath();
|
||||
}
|
||||
|
||||
function draw_number_lock(widget, ctx, x, y, widget_width, widget_height, left_margin, right_margin, text_margin, lock_margin, text, index, text_flag) {
|
||||
function draw_number_lock(widget, ctx, x, y, widget_width, widget_height, left_margin, right_margin, text_margin, lock_margin, text_raw, text_real, lock, text_flag) {
|
||||
ctx.textAlign = "left";
|
||||
ctx.strokeStyle = LiteGraph.WIDGET_OUTLINE_COLOR;
|
||||
ctx.fillStyle = LiteGraph.WIDGET_BGCOLOR;
|
||||
@@ -2291,17 +2291,17 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
|
||||
ctx.fill();
|
||||
}
|
||||
ctx.fillStyle = LiteGraph.WIDGET_SECONDARY_TEXT_COLOR;
|
||||
ctx.fillText(`${widget.label ?? widget.name} (${text}: ${lib0246.snap(widget.value.data[index], widget.options.snap)})`, x + left_margin + text_margin + lock_margin + 5, y + widget_height * 0.7);
|
||||
ctx.fillText(`${widget.label ?? widget.name} (${text_real})`, x + left_margin + text_margin + lock_margin + 5, y + widget_height * 0.7);
|
||||
ctx.fillStyle = LiteGraph.WIDGET_TEXT_COLOR;
|
||||
ctx.textAlign = "right";
|
||||
ctx.fillText(
|
||||
Number(widget.value.data[index]).toFixed(widget.options.precision ?? 3),
|
||||
text_raw,
|
||||
x + widget_width - right_margin - text_margin - 20,
|
||||
y + widget_height * 0.7
|
||||
);
|
||||
}
|
||||
|
||||
draw_lock(ctx, x + left_margin, y, widget_height, widget_height, widget.value.lock[index]);
|
||||
draw_lock(ctx, x + left_margin, y, widget_height, widget_height, lock);
|
||||
}
|
||||
|
||||
function ratio_process_calc(widget, mode, old_value) {
|
||||
@@ -2310,7 +2310,17 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
|
||||
opt = widget.options;
|
||||
switch (Math.abs(mode)) {
|
||||
case 1: {
|
||||
if (lock.height && !lock.ratio) {
|
||||
if (lock.height && lock.width && lock.ratio) {
|
||||
data.height = old_value * data.height / data.width;
|
||||
if (data.height < opt.min) {
|
||||
data.height = opt.min;
|
||||
data.width = data.height * data.ratio;
|
||||
} else if (data.height > opt.max) {
|
||||
data.height = opt.max;
|
||||
data.width = data.height * data.ratio;
|
||||
}
|
||||
data.ratio = data.width / data.height;
|
||||
} else if (lock.height && !lock.ratio) {
|
||||
data.height = data.width / data.ratio;
|
||||
if (data.height < opt.min) {
|
||||
data.height = opt.min;
|
||||
@@ -2335,7 +2345,17 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
|
||||
}
|
||||
} break;
|
||||
case 2: {
|
||||
if (lock.width && !lock.ratio) {
|
||||
if (lock.height && lock.width && lock.ratio) {
|
||||
data.width = old_value * data.width / data.height;
|
||||
if (data.width < opt.min) {
|
||||
data.width = opt.min;
|
||||
data.height = data.width / data.ratio;
|
||||
} else if (data.width > opt.max) {
|
||||
data.width = opt.max;
|
||||
data.height = data.width / data.ratio;
|
||||
}
|
||||
data.ratio = data.width / data.height;
|
||||
} else if (lock.width && !lock.ratio) {
|
||||
data.width = data.height * data.ratio;
|
||||
if (data.width < opt.min) {
|
||||
data.width = opt.min;
|
||||
@@ -2360,7 +2380,12 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
|
||||
}
|
||||
} break;
|
||||
case 3: {
|
||||
if (!lock.height && lock.width) {
|
||||
if (
|
||||
(lock.height && lock.width && lock.ratio) ||
|
||||
(!lock.height && !lock.width && !lock.ratio)
|
||||
) {
|
||||
data.ratio = old_value;
|
||||
} else if (!lock.height && lock.width) {
|
||||
data.width = data.height * data.ratio;
|
||||
if (data.width < opt.min) {
|
||||
data.width = opt.min;
|
||||
@@ -2394,11 +2419,36 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
|
||||
data.ratio = 0;
|
||||
}
|
||||
|
||||
function ratio_notify(node, widget, name, mode, old_value, value, pos, event) {
|
||||
function ratio_notify(node, widget, name, mode, old_value, value, pos, event, w_f, h_f) {
|
||||
if (/^[0-9+\-*/()\s]+|\d+\.\d+$/.test(value))
|
||||
try {
|
||||
widget.value.data[name] = Number(eval(value));
|
||||
ratio_process_calc(widget, mode, old_value);
|
||||
const res = Number(eval(value));
|
||||
if (w_f) {
|
||||
widget.value.data.width = res / widget.value.data.height;
|
||||
if (widget.value.data.width < widget.options.min) {
|
||||
widget.value.data.width = widget.options.min;
|
||||
widget.value.data.height = widget.value.data.width / widget.value.data.ratio;
|
||||
} else if (widget.value.data.width > widget.options.max) {
|
||||
widget.value.data.width = widget.options.max;
|
||||
widget.value.data.height = widget.value.data.width / widget.value.data.ratio;
|
||||
}
|
||||
widget.value.data.ratio = widget.value.data.width / widget.value.data.height;
|
||||
app.canvas.setDirty(true);
|
||||
} else if (h_f) {
|
||||
widget.value.data.height = res / widget.value.data.width;
|
||||
if (widget.value.data.height < widget.options.min) {
|
||||
widget.value.data.height = widget.options.min;
|
||||
widget.value.data.width = widget.value.data.height * widget.value.data.ratio;
|
||||
} else if (widget.value.data.height > widget.options.max) {
|
||||
widget.value.data.height = widget.options.max;
|
||||
widget.value.data.width = widget.value.data.height * widget.value.data.ratio;
|
||||
}
|
||||
widget.value.data.ratio = widget.value.data.width / widget.value.data.height;
|
||||
app.canvas.setDirty(true);
|
||||
} else {
|
||||
widget.value.data[name] = res;
|
||||
ratio_process_calc(widget, mode, old_value);
|
||||
}
|
||||
if (widget.options && widget.options.property && node.properties[widget.options.property] !== undefined)
|
||||
node.setProperty(widget.options.property, value);
|
||||
widget?.callback?.(widget.value, widget, node, pos, event);
|
||||
@@ -2435,9 +2485,24 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
|
||||
this.temp_h = widget_height;
|
||||
this.temp_y = y;
|
||||
|
||||
draw_number_lock(this, ctx, 0, y, calc_width, widget_height, margin, 0, text_margin, lock_margin, "W", "width", show_text);
|
||||
draw_number_lock(this, ctx, calc_width, y, calc_width, widget_height, 0, 0, text_margin, lock_margin, "R", "ratio", show_text);
|
||||
draw_number_lock(this, ctx, calc_width * 2, y, calc_width, widget_height, 0, margin, text_margin, lock_margin, "H", "height", show_text);
|
||||
draw_number_lock(
|
||||
this, ctx, 0, y, calc_width, widget_height, margin, 0, text_margin, lock_margin,
|
||||
lib0246.floor(widget.value.data.width, widget.options.precision ?? 3),
|
||||
`W: ${lib0246.snap(widget.value.data.width, widget.options.snap)}`,
|
||||
widget.value.lock.width, show_text
|
||||
);
|
||||
draw_number_lock(
|
||||
this, ctx, calc_width, y, calc_width, widget_height, 0, 0, text_margin, lock_margin,
|
||||
lib0246.floor(widget.value.data.ratio, widget.options.precision ?? 3),
|
||||
`A: ${lib0246.floor(widget.value.data.width * widget.value.data.height, widget.options.precision ?? 3)}`,
|
||||
widget.value.lock.ratio, show_text
|
||||
);
|
||||
draw_number_lock(
|
||||
this, ctx, calc_width * 2, y, calc_width, widget_height, 0, margin, text_margin, lock_margin,
|
||||
lib0246.floor(widget.value.data.height, widget.options.precision ?? 3),
|
||||
`H: ${lib0246.snap(widget.value.data.height, widget.options.snap)}`,
|
||||
widget.value.lock.height, show_text
|
||||
);
|
||||
|
||||
ctx.restore();
|
||||
},
|
||||
@@ -2542,9 +2607,13 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
|
||||
this.value.data.ratio = Math.max(this.options.min, Math.min(this.options.max, this.value.data.ratio + event.deltaX * 0.001 * this.options.step));
|
||||
this.drag_flag = true;
|
||||
} else if (event.type === "pointerup")
|
||||
if (!this.drag_flag)
|
||||
app.canvas.prompt("Ratio", this.value.data.ratio, (value) => ratio_notify(node, this, "ratio", mode, old_value, value, pos, event), event);
|
||||
else
|
||||
if (!this.drag_flag) {
|
||||
const w_f = this.value.lock.ratio && this.value.lock.width && this.value.lock.height,
|
||||
h_f = !this.value.lock.ratio && !this.value.lock.width && !this.value.lock.height;
|
||||
app.canvas.prompt(w_f ? "Area (width)" : h_f ? "Area (height)" : "Ratio", this.value.data.ratio, (value) => ratio_notify(
|
||||
node, this, "ratio", mode, old_value, value, pos, event, w_f, h_f
|
||||
), event);
|
||||
} else
|
||||
this.drag_flag = false;
|
||||
} else if (lib0246.is_inside_rect(
|
||||
pos[0], pos[1],
|
||||
@@ -3004,11 +3073,11 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
|
||||
node.color = LGraphCanvas.node_colors.green.color;
|
||||
node.bgcolor = LGraphCanvas.node_colors.green.bgcolor;
|
||||
} break;
|
||||
case "0246.ScriptImbue": {
|
||||
case "0246.ScriptNode": {
|
||||
node.color = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.color, "#660029");
|
||||
node.bgcolor = "#4d001f";
|
||||
} break;
|
||||
case "0246.ScriptPlan": {
|
||||
case "0246.ScriptRule": {
|
||||
node.color = "#660029";
|
||||
node.bgcolor = lib0246.mix_color_hue(LGraphCanvas.node_colors.green.bgcolor, "#660029");
|
||||
} break;
|
||||
@@ -3645,34 +3714,8 @@ let defs, node_defs = [], combo_defs = [], type_defs = new Set();
|
||||
case "0246.Script": {
|
||||
junction_impl(nodeType, nodeData, app, null, LiteGraph.GRID_SHAPE, LiteGraph.GRID_SHAPE);
|
||||
} break;
|
||||
case "0246.Pick": {
|
||||
junction_impl(nodeType, nodeData, app, null, LiteGraph.GRID_SHAPE, LiteGraph.GRID_SHAPE);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// var curr_node = LiteGraph.createNode(LiteGraph.getNodeTypesInCategory(LiteGraph.getNodeTypesCategories()[2])[2].type);
|
||||
|
||||
/*
|
||||
[TODO] Make Highway and Junction works with GroupNode; Cast Reroute keep type on configure
|
||||
[TODO] Select, Unselect all for Hub
|
||||
|
||||
[TODO] Cloud node
|
||||
- Output: batch of strings
|
||||
- Flex widget for render multiple text boxes
|
||||
- Two DOM text box:
|
||||
- Show current text content of selected text box
|
||||
- Show entire text content
|
||||
- Must represent:
|
||||
-
|
||||
//*/
|
||||
|
||||
/*
|
||||
[TODO] Fix the bug that when copying Highway, the new node ID when added does not have the old 0246.__NAME__ being cloned over
|
||||
[TODO] Take advantage of an extra state of BoxRange size widget such that: lock (area must be same), unlock (area can be different)
|
||||
- Only affect the current value that are being changed
|
||||
- Why? SDXL requires that any ratio must have same area size as 1024x1024
|
||||
//*/
|
||||
})();
|
||||
Reference in New Issue
Block a user