Compare commits

...
20 Commits
Author SHA1 Message Date
yolain eff718c13f Upgrade v1.2.9 to ComfyRegistry 2025-04-15 14:20:58 +08:00
yolain 615a2abcfe Fix ImageChooser causes workflow processing to cancel #732 2025-04-15 13:28:53 +08:00
yolain 2b4b38ce03 Fix brushnet tensor(640) error 2025-04-13 02:11:55 +08:00
yolain dbbd2ffef3 Fix missing output optional_clip when Apply Lora Stack is disabled #729 2025-04-13 01:50:34 +08:00
yolain b1a875b151 Fix last commit bug 2025-04-08 00:59:38 +08:00
yolain 6a39ea1188 Fix widgets not hidden in v1.6.0 frontend 2025-04-08 00:49:37 +08:00
yolain 69aac075e8 Compatible drawNodeShape with stable front-end version 2025-04-06 15:53:48 +08:00
yolain e1dc9250b9 Fix missing strokeStyle on nodes during restart resulting in misconnections. 2025-04-06 15:46:59 +08:00
yolain 8b9c577f55 Fix outer border color should be red when node doesn't exist 2025-04-06 13:31:48 +08:00
yolain 6d8c266b04 Fix missing progressBar in latest frontend version 2025-04-06 12:48:41 +08:00
yolain 9292f22862 Removed global changes to the control widget, ComfyUI frontend was fixed this issue #714 2025-03-30 12:59:50 +08:00
yolain 10e9629ca3 Fix the context menu to miss Add Reroute #713 2025-03-29 07:23:35 +08:00
yolain 4f694195a2 Fix samplers can't display output image 2025-03-27 15:22:02 +08:00
yolain ff6c0f0e39 Fix image chooser can not select images #706 2025-03-26 11:37:42 +08:00
yolain a6e8783605 Fix save image simple doesn't show preview #708 2025-03-26 10:39:26 +08:00
yolain 3e84b8cd77 Fix contextMenu monkey patching to affect custom scripts (pysssss) nodes 2025-03-17 09:36:49 +08:00
yolain 9e70cc0090 Merge pull request #697 from Naix2012/main
Update prompt.py
2025-03-16 12:02:43 +08:00
Naix2012 7dddd2d6e5 Update prompt.py 2025-03-16 01:16:43 +08:00
yolain 63a1ca5ec6 Merge pull request #693 from ComfyNodePRs/update-publish-yaml
Update Github Action for Publishing to Comfy Registry
2025-03-14 15:06:39 +08:00
snomiao 17e022a7aa chore(publish): update GitHub Actions workflow for node publishing
- Add permissions for issue writing
- Update action version to v1 for publish-node-action
- Add condition to run job only for 'yolain' repository owner
2025-01-20 21:28:03 +00:00
13 changed files with 197 additions and 140 deletions
+6 -2
View File
@@ -7,15 +7,19 @@ on:
paths:
- "pyproject.toml"
permissions:
issues: write
jobs:
publish-node:
name: Publish Custom Node to registry
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'yolain' }}
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Publish Custom Node
uses: Comfy-Org/publish-node-action@main
uses: Comfy-Org/publish-node-action@v1
with:
## Add your own personal access token to your Github Repository secrets and reference it here.
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
+8
View File
@@ -52,6 +52,14 @@ git clone https://github.com/yolain/ComfyUI-Easy-Use
## 📜 更新日志
**v1.2.9**
- 修复 Imagechooser 会导致工作流处理取消
- 修复 brushnet tensor(640) 错误
- 修复v1.6.0前端之后无法隐藏小部件的bug
- 修复图像选择器无法选择图像
- 修复ContextMenu Monkey修补以影响自定义脚本(PYSSSS)节点
**v1.2.8**
- 修复了一些BUG (😹)
+8
View File
@@ -47,6 +47,14 @@ Double-click install.bat to install the required dependencies
## 📜 Changelog
**v1.2.9**
- Fix ImageChooser causes workflow processing to cancel
- Fix brushnet tensor(640) error
- Fix widgets not hidden after v1.6.0 frontend
- Fix image chooser can not select images
- Fix contextMenu monkey patching to affect custom scripts (pysssss) nodes
**v1.2.8**
- Added the multi-language catalog
+1 -1
View File
@@ -1,4 +1,4 @@
__version__ = "1.2.8"
__version__ = "1.2.9"
import yaml
import json
+20 -12
View File
@@ -272,11 +272,11 @@ class BrushNet:
# unload vae
del vae
for loaded_model in comfy.model_management.current_loaded_models:
if type(loaded_model.model.model) in ModelsToUnload:
comfy.model_management.current_loaded_models.remove(loaded_model)
loaded_model.model_unload()
del loaded_model
# for loaded_model in comfy.model_management.current_loaded_models:
# if type(loaded_model.model.model) in ModelsToUnload:
# comfy.model_management.current_loaded_models.remove(loaded_model)
# loaded_model.model_unload()
# del loaded_model
# prepare embeddings
prompt_embeds = positive[0][0].to(dtype=torch_dtype).to(brushnet['brushnet'].device)
@@ -449,11 +449,11 @@ class BrushNet:
# unload vae and CLIPs
del vae
del clip
for loaded_model in comfy.model_management.current_loaded_models:
if type(loaded_model.model.model) in ModelsToUnload:
comfy.model_management.current_loaded_models.remove(loaded_model)
loaded_model.model_unload()
del loaded_model
# for loaded_model in comfy.model_management.current_loaded_models:
# if type(loaded_model.model.model) in ModelsToUnload:
# comfy.model_management.current_loaded_models.remove(loaded_model)
# loaded_model.model_unload()
# del loaded_model
# apply patch to model
@@ -663,8 +663,16 @@ def add_brushnet_patch(model, brushnet, torch_dtype, conditioning_latents,
is_SDXL = isinstance(model.model.model_config, comfy.supported_models.SDXL)
if model.model.model_config.custom_operations is None:
fp8 = model.model.model_config.optimizations.get("fp8", model.model.model_config.scaled_fp8 is not None)
operations = comfy.ops.pick_operations(model.model.model_config.unet_config.get("dtype", None), model.model.manual_cast_dtype,
fp8_optimizations=fp8, scaled_fp8=model.model.model_config.scaled_fp8)
else:
# such as gguf
operations = model.model.model_config.custom_operations
if is_SDXL:
input_blocks = [[0, comfy.ops.manual_cast.Conv2d],
input_blocks = [[0, operations.Conv2d],
[1, comfy.ldm.modules.diffusionmodules.openaimodel.ResBlock],
[2, comfy.ldm.modules.diffusionmodules.openaimodel.ResBlock],
[3, comfy.ldm.modules.diffusionmodules.openaimodel.Downsample],
@@ -686,7 +694,7 @@ def add_brushnet_patch(model, brushnet, torch_dtype, conditioning_latents,
[7, comfy.ldm.modules.diffusionmodules.openaimodel.ResBlock],
[8, comfy.ldm.modules.diffusionmodules.openaimodel.ResBlock]]
else:
input_blocks = [[0, comfy.ops.manual_cast.Conv2d],
input_blocks = [[0, operations.Conv2d],
[1, comfy.ldm.modules.attention.SpatialTransformer],
[2, comfy.ldm.modules.attention.SpatialTransformer],
[3, comfy.ldm.modules.diffusionmodules.openaimodel.Downsample],
+1 -1
View File
@@ -40,7 +40,7 @@ class applyLoraStack:
lora = {"lora_name": lora[0], "model": model, "clip": optional_clip, "model_strength": lora[1],
"clip_strength": lora[2]}
model, clip = easyCache.load_lora(lora, model, optional_clip, use_cache=False)
return (model, clip)
return (model, optional_clip if clip is None else clip)
class applyControlnetStack:
@classmethod
+1 -2
View File
@@ -485,8 +485,7 @@ class imageSaveSimple:
def save(self, images, filename_prefix="ComfyUI", only_preview=False, prompt=None, extra_pnginfo=None):
if only_preview:
PreviewImage().save_images(images, filename_prefix, prompt, extra_pnginfo)
return ()
return PreviewImage().save_images(images, filename_prefix, prompt, extra_pnginfo)
else:
return SaveImage().save_images(images, filename_prefix, prompt, extra_pnginfo)
+1 -1
View File
@@ -165,7 +165,7 @@ class stylesPromptSelector:
negative_prompt += ', ' + all_styles[val]['negative_prompt'] if negative_prompt else all_styles[val]['negative_prompt']
if has_prompt == False and positive:
positive_prompt = positive + ', '
positive_prompt = positive + positive_prompt + ', '
return (positive_prompt, negative_prompt)
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui-easy-use"
description = "To enhance the usability of ComfyUI, optimizations and integrations have been implemented for several commonly used nodes."
version = "1.2.8"
version = "1.2.9"
license = { file = "LICENSE" }
dependencies = ["diffusers", "accelerate", "clip_interrogator>=0.6.0", "sentencepiece", "lark", "onnxruntime", "spandrel", "opencv-python", "matplotlib", "peft"]
+147 -117
View File
@@ -12,22 +12,22 @@ const ipadapterNodes = ["easy ipadapterApply", "easy ipadapterApplyADV" ,"easy i
const pipeNodes = ['easy pipeIn','easy pipeOut', 'easy pipeEdit']
const xyNodes = ['easy XYPlot', 'easy XYPlotAdvanced']
const extraNodes = ['easy setNode']
const modelNormalNodes = [...["Reroute"],...['RescaleCFG','LoraLoaderModelOnly','LoraLoader','FreeU','FreeU_v2'],...ipadapterNodes,...extraNodes]
const modelNormalNodes = [...['RescaleCFG','LoraLoaderModelOnly','LoraLoader','FreeU','FreeU_v2'],...ipadapterNodes,...extraNodes]
const suggestions = {
// prompt
"easy seed":{
"from":{
"INT": [...["Reroute"],...preSamplingNodes,...['easy fullkSampler']]
"INT": [...preSamplingNodes,...['easy fullkSampler']]
}
},
"easy positive":{
"from":{
"STRING": [...["Reroute"],...propmts]
"STRING": [...propmts]
}
},
"easy negative":{
"from":{
"STRING": [...["Reroute"],...propmts]
"STRING": [...propmts]
}
},
"easy wildcards":{
@@ -53,214 +53,225 @@ const suggestions = {
// sd相关
"easy fullLoader": {
"from":{
"PIPE_LINE": [...["Reroute"],...preSamplingNodes,...['easy fullkSampler'],...pipeNodes,...extraNodes],
"PIPE_LINE": [...preSamplingNodes,...['easy fullkSampler'],...pipeNodes,...extraNodes],
"MODEL":modelNormalNodes
},
"to":{
"STRING": [...["Reroute"],...propmts]
"STRING": [...propmts]
}
},
"easy a1111Loader": {
"from": {
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes],
"PIPE_LINE": [ ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes],
"MODEL": modelNormalNodes
},
"to":{
"STRING": [...["Reroute"],...propmts]
"STRING": [...propmts]
}
},
"easy comfyLoader": {
"from": {
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes],
"PIPE_LINE": [ ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes],
"MODEL": modelNormalNodes
},
"to":{
"STRING": [...["Reroute"],...propmts]
"STRING": [...propmts]
}
},
"easy svdLoader":{
"from": {
"PIPE_LINE": [...["Reroute"], ...["easy preSampling", "easy preSamplingAdvanced", "easy preSamplingDynamicCFG"], ...pipeNodes, ...extraNodes],
"PIPE_LINE": [ ...["easy preSampling", "easy preSamplingAdvanced", "easy preSamplingDynamicCFG"], ...pipeNodes, ...extraNodes],
"MODEL": modelNormalNodes
},
"to":{
"STRING": [...["Reroute"],...propmts]
"STRING": [...propmts]
}
},
"easy zero123Loader":{
"from": {
"PIPE_LINE": [...["Reroute"], ...["easy preSampling", "easy preSamplingAdvanced", "easy preSamplingDynamicCFG"], ...pipeNodes, ...extraNodes],
"PIPE_LINE": [ ...["easy preSampling", "easy preSamplingAdvanced", "easy preSamplingDynamicCFG"], ...pipeNodes, ...extraNodes],
"MODEL": modelNormalNodes
},
"to":{
"STRING": [...["Reroute"],...propmts]
"STRING": [...propmts]
}
},
"easy sv3dLoader":{
"from": {
"PIPE_LINE": [...["Reroute"], ...["easy preSampling", "easy preSamplingAdvanced", "easy preSamplingDynamicCFG"], ...pipeNodes, ...extraNodes],
"PIPE_LINE": [ ...["easy preSampling", "easy preSamplingAdvanced", "easy preSamplingDynamicCFG"], ...pipeNodes, ...extraNodes],
"MODEL": modelNormalNodes
},
"to":{
"STRING": [...["Reroute"],...propmts]
"STRING": [...propmts]
}
},
"easy preSampling": {
"from": {
"PIPE_LINE": [...["Reroute"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
"PIPE_LINE": [ ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
},
},
"easy preSamplingAdvanced": {
"from": {
"PIPE_LINE": [...["Reroute"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
"PIPE_LINE": [ ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
}
},
"easy preSamplingDynamicCFG": {
"from": {
"PIPE_LINE": [...["Reroute"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
"PIPE_LINE": [ ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
}
},
"easy preSamplingCustom": {
"from": {
"PIPE_LINE": [...["Reroute"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
"PIPE_LINE": [ ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
}
},
"easy preSamplingLayerDiffusion": {
"from": {
"PIPE_LINE": [...["Reroute", "easy kSamplerLayerDiffusion"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
"PIPE_LINE": [...["easy kSamplerLayerDiffusion"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
}
},
"easy preSamplingNoiseIn": {
"from": {
"PIPE_LINE": [...["Reroute"], ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
"PIPE_LINE": [ ...kSampler, ...pipeNodes, ...controlNetNodes, ...xyNodes, ...extraNodes]
}
},
// ksampler
"easy fullkSampler": {
"from": {
"PIPE_LINE": [...["Reroute"], ...pipeNodes.reverse(), ...['easy preDetailerFix', 'easy preMaskDetailerFix'], ...preSamplingNodes, ...extraNodes]
"PIPE_LINE": [ ...pipeNodes.reverse(), ...['easy preDetailerFix', 'easy preMaskDetailerFix'], ...preSamplingNodes, ...extraNodes]
}
},
"easy kSampler": {
"from": {
"PIPE_LINE": [...["Reroute"], ...pipeNodes.reverse(), ...['easy preDetailerFix', 'easy preMaskDetailerFix', 'easy hiresFix'], ...preSamplingNodes, ...extraNodes],
"PIPE_LINE": [ ...pipeNodes.reverse(), ...['easy preDetailerFix', 'easy preMaskDetailerFix', 'easy hiresFix'], ...preSamplingNodes, ...extraNodes],
}
},
// cn
"easy controlnetLoader": {
"from": {
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes]
"PIPE_LINE": [ ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes]
}
},
"easy controlnetLoaderADV":{
"from": {
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes]
"PIPE_LINE": [ ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes]
}
},
// instant
"easy instantIDApply": {
"from": {
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes],
"PIPE_LINE": [ ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes],
"MODEL": modelNormalNodes
},
"to":{
"COMBO": [...["Reroute", "easy promptLine"]]
"COMBO": [...["easy promptLine"]]
}
},
"easy instantIDApplyADV":{
"from": {
"PIPE_LINE": [...["Reroute"], ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes],
"PIPE_LINE": [ ...preSamplingNodes, ...controlNetNodes, ...instantIDNodes, ...pipeNodes, ...extraNodes],
"MODEL": modelNormalNodes
},
"to":{
"COMBO": [...["Reroute", "easy promptLine"]]
"COMBO": [...["easy promptLine"]]
}
},
"easy ipadapterApply":{
"to":{
"COMBO": [...["Reroute", "easy promptLine"]]
"COMBO": [...["easy promptLine"]]
}
},
"easy ipadapterApplyADV":{
"to":{
"STRING": [...["Reroute", "easy sliderControl"], ...propmts],
"COMBO": [...["Reroute", "easy promptLine"]]
"STRING": [...["easy sliderControl"], ...propmts],
"COMBO": [...["easy promptLine"]]
}
},
"easy ipadapterStyleComposition":{
"to":{
"COMBO": [...["Reroute", "easy promptLine"]]
"COMBO": [...["easy promptLine"]]
}
},
// fix
"easy preDetailerFix":{
"from": {
"PIPE_LINE": [...["Reroute", "easy detailerFix"], ...pipeNodes, ...extraNodes]
"PIPE_LINE": [...["easy detailerFix"], ...pipeNodes, ...extraNodes]
},
"to":{
"PIPE_LINE": [...["Reroute", "easy ultralyticsDetectorPipe", "easy samLoaderPipe", "easy kSampler", "easy fullkSampler"]]
"PIPE_LINE": [...["easy ultralyticsDetectorPipe", "easy samLoaderPipe", "easy kSampler", "easy fullkSampler"]]
}
},
"easy preMaskDetailerFix":{
"from": {
"PIPE_LINE": [...["Reroute", "easy detailerFix"], ...pipeNodes, ...extraNodes]
"PIPE_LINE": [...["easy detailerFix"], ...pipeNodes, ...extraNodes]
}
},
"easy samLoaderPipe": {
"from":{
"PIPE_LINE": [...["Reroute", "easy preDetailerFix"], ...pipeNodes, ...extraNodes]
"PIPE_LINE": [...["easy preDetailerFix"], ...pipeNodes, ...extraNodes]
}
},
"easy ultralyticsDetectorPipe": {
"from":{
"PIPE_LINE": [...["Reroute", "easy preDetailerFix"], ...pipeNodes, ...extraNodes]
"PIPE_LINE": [...["easy preDetailerFix"], ...pipeNodes, ...extraNodes]
}
},
// cascade相关
"easy cascadeLoader":{
"from": {
"PIPE_LINE": [...["Reroute"], ...["easy fullCascadeKSampler", 'easy preSamplingCascade'], ...controlNetNodes, ...pipeNodes, ...extraNodes],
"PIPE_LINE": [ ...["easy fullCascadeKSampler", 'easy preSamplingCascade'], ...controlNetNodes, ...pipeNodes, ...extraNodes],
"MODEL": modelNormalNodes.filter(cate => !ipadapterNodes.includes(cate))
}
},
"easy fullCascadeKSampler":{
"from": {
"PIPE_LINE": [...["Reroute"], ...["easy preSampling", "easy preSamplingAdvanced"], ...pipeNodes, ...extraNodes]
"PIPE_LINE": [ ...["easy preSampling", "easy preSamplingAdvanced"], ...pipeNodes, ...extraNodes]
}
},
"easy preSamplingCascade":{
"from": {
"PIPE_LINE": [...["Reroute"], ...["easy cascadeKSampler",], ...pipeNodes, ...extraNodes]
"PIPE_LINE": [ ...["easy cascadeKSampler",], ...pipeNodes, ...extraNodes]
}
},
"easy cascadeKSampler": {
"from": {
"PIPE_LINE": [...["Reroute"], ...["easy preSampling", "easy preSamplingAdvanced"], ...pipeNodes, ...extraNodes]
"PIPE_LINE": [ ...["easy preSampling", "easy preSamplingAdvanced"], ...pipeNodes, ...extraNodes]
}
},
}
class NullGraphError extends Error {
constructor(message="Attempted to access LGraph reference that was null or undefined.", cause) {
super(message, {cause})
this.name = "NullGraphError"
}
}
app.registerExtension({
name: "comfy.easyuse.suggestions",
async setup(app) {
async setup() {
const createDefaultNodeForSlot = LGraphCanvas.prototype.createDefaultNodeForSlot;
LGraphCanvas.prototype.createDefaultNodeForSlot = function(optPass) { // addNodeMenu for connection
var optPass = optPass || {};
var opts = Object.assign({ nodeFrom: null // input
,slotFrom: null // input
,nodeTo: null // output
,slotTo: null // output
,position: [] // pass the event coords
,nodeType: null // choose a nodetype to add, AUTO to set at first good
,posAdd:[0,0] // adjust x,y
,posSizeFix:[0,0] // alpha, adjust the position x,y based on the new node size w,h
}
,optPass
);
var that = this;
const opts = Object.assign({ nodeFrom: null // input
,slotFrom: null // input
,nodeTo: null // output
,slotTo: null // output
,position: [] // pass the event coords
,nodeType: null // choose a nodetype to add, AUTO to set at first good
,posAdd:[0,0] // adjust x,y
,posSizeFix:[0,0] // alpha, adjust the position x,y based on the new node size w,h
}
, optPass || {}
);
const { afterRerouteId } = opts
const that = this;
var isFrom = opts.nodeFrom && opts.slotFrom!==null;
var isTo = !isFrom && opts.nodeTo && opts.slotTo!==null;
const isFrom = opts.nodeFrom && opts.slotFrom!==null;
const isTo = !isFrom && opts.nodeTo && opts.slotTo!==null;
const node = isFrom ? opts.nodeFrom : opts.nodeTo
// Not an Easy Use node, skip showConnectionMenu hijack
if(!node || !Object.keys(suggestions).includes(node.type)){
return createDefaultNodeForSlot.call(this, optPass)
}
if (!isFrom && !isTo){
console.warn("No data passed to createDefaultNodeForSlot "+opts.nodeFrom+" "+opts.slotFrom+" "+opts.nodeTo+" "+opts.slotTo);
@@ -271,24 +282,24 @@ app.registerExtension({
return false;
}
var nodeX = isFrom ? opts.nodeFrom : opts.nodeTo;
var slotX = isFrom ? opts.slotFrom : opts.slotTo;
var nodeType = nodeX.type
const nodeX = isFrom ? opts.nodeFrom : opts.nodeTo;
const nodeType = nodeX.type
let slotX = isFrom ? opts.slotFrom : opts.slotTo;
var iSlotConn = false;
let iSlotConn = false;
switch (typeof slotX){
case "string":
iSlotConn = isFrom ? nodeX.findOutputSlot(slotX,false) : nodeX.findInputSlot(slotX,false);
slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX];
break;
break;
case "object":
// ok slotX
iSlotConn = isFrom ? nodeX.findOutputSlot(slotX.name) : nodeX.findInputSlot(slotX.name);
break;
break;
case "number":
iSlotConn = slotX;
slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX];
break;
break;
case "undefined":
default:
// bad ?
@@ -324,8 +335,7 @@ app.registerExtension({
for(var typeX in slotTypesDefault[fromSlotType]){
if (opts.nodeType == slotTypesDefault[fromSlotType][typeX] || opts.nodeType == "AUTO"){
nodeNewType = slotTypesDefault[fromSlotType][typeX];
// console.log("opts.nodeType == slotTypesDefault[fromSlotType][typeX] :: "+opts.nodeType);
break; // --------
break;
}
}
}else{
@@ -379,9 +389,7 @@ app.registerExtension({
// add the node
that.graph.add(newNode);
newNode.pos = [ opts.position[0]+opts.posAdd[0]+(opts.posSizeFix[0]?opts.posSizeFix[0]*newNode.size[0]:0)
,opts.position[1]+opts.posAdd[1]+(opts.posSizeFix[1]?opts.posSizeFix[1]*newNode.size[1]:0)]; //that.last_click_position; //[e.canvasX+30, e.canvasX+5];*/
//that.graph.afterChange();
,opts.position[1]+opts.posAdd[1]+(opts.posSizeFix[1]?opts.posSizeFix[1]*newNode.size[1]:0)]; //that.last_click_position; //[e.canvasX+30, e.canvasX+5];*/
// connect the two!
if (isFrom){
@@ -390,11 +398,6 @@ app.registerExtension({
opts.nodeTo.connectByTypeOutput( iSlotConn, newNode, fromSlotType );
}
// if connecting in between
if (isFrom && isTo){
// TODO
}
return true;
}else{
@@ -405,43 +408,54 @@ app.registerExtension({
return false;
}
let showConnectionMenu = LGraphCanvas.prototype.showConnectionMenu
LGraphCanvas.prototype.showConnectionMenu = function(optPass) { // addNodeMenu for connection
var optPass = optPass || {};
var opts = Object.assign({ nodeFrom: null // input
,slotFrom: null // input
,nodeTo: null // output
,slotTo: null // output
,e: null
}
,optPass
);
var that = this;
const opts = Object.assign({
nodeFrom: null, // input
slotFrom: null, // input
nodeTo: null, // output
slotTo: null, // output
e: undefined,
allow_searchbox: this.allow_searchbox,
showSearchBox: this.showSearchBox,
}
,optPass || {}
);
const that = this;
const { graph } = this
const { afterRerouteId } = opts
const isFrom = opts.nodeFrom && opts.slotFrom;
const isTo = !isFrom && opts.nodeTo && opts.slotTo;
const node = isFrom ? opts.nodeFrom : opts.nodeTo
var isFrom = opts.nodeFrom && opts.slotFrom;
var isTo = !isFrom && opts.nodeTo && opts.slotTo;
// Not an Easy Use node, skip showConnectionMenu hijack
if(!node || !Object.keys(suggestions).includes(node.type)){
return showConnectionMenu.call(this, optPass)
}
if (!isFrom && !isTo){
console.warn("No data passed to showConnectionMenu");
return false;
}
var nodeX = isFrom ? opts.nodeFrom : opts.nodeTo;
var slotX = isFrom ? opts.slotFrom : opts.slotTo;
const nodeX = isFrom ? opts.nodeFrom : opts.nodeTo;
if (!nodeX) throw new TypeError("nodeX was null when creating default node for slot.")
let slotX = isFrom ? opts.slotFrom : opts.slotTo;
var iSlotConn = false;
let iSlotConn = false;
switch (typeof slotX){
case "string":
iSlotConn = isFrom ? nodeX.findOutputSlot(slotX,false) : nodeX.findInputSlot(slotX,false);
slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX];
break;
break;
case "object":
// ok slotX
iSlotConn = isFrom ? nodeX.findOutputSlot(slotX.name) : nodeX.findInputSlot(slotX.name);
break;
break;
case "number":
iSlotConn = slotX;
slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX];
break;
break;
default:
// bad ?
//iSlotConn = 0;
@@ -449,9 +463,8 @@ app.registerExtension({
return false;
}
var options = ["Add Node",null];
if (that.allow_searchbox){
const options = ["Add Node", "Add Reroute", null]
if (opts.allow_searchbox){
options.push("Search");
options.push(null);
}
@@ -479,8 +492,12 @@ app.registerExtension({
// build menu
var menu = new LiteGraph.ContextMenu(options, {
event: opts.e,
title: (slotX && slotX.name!="" ? (slotX.name + (fromSlotType?" | ":"")) : "")+(slotX && fromSlotType ? fromSlotType : ""),
callback: inner_clicked
extra: slotX,
title:
(slotX && slotX.name != ""
? slotX.name + (fromSlotType ? " | " : "")
: "") + (slotX && fromSlotType ? fromSlotType : ""),
callback: inner_clicked,
});
// callback
@@ -488,32 +505,45 @@ app.registerExtension({
//console.log("Process showConnectionMenu selection");
switch (v) {
case "Add Node":
LGraphCanvas.onMenuAdd(null, null, e, menu, function(node){
if (isFrom){
opts.nodeFrom.connectByType( iSlotConn, node, fromSlotType );
}else{
opts.nodeTo.connectByTypeOutput( iSlotConn, node, fromSlotType );
LGraphCanvas.onMenuAdd(null, null, e, menu, function (node) {
if (!node) return
if (isFrom) {
opts.nodeFrom?.connectByType(iSlotConn, node, fromSlotType, { afterRerouteId })
} else {
opts.nodeTo?.connectByTypeOutput(iSlotConn, node, fromSlotType, { afterRerouteId })
}
});
})
break;
case "Add Reroute":
const node = isFrom ? opts.nodeFrom : opts.nodeTo
const slot = options.extra
if (!graph) throw new NullGraphError()
if (!node) throw new TypeError("Cannot add reroute: node was null")
if (!slot) throw new TypeError("Cannot add reroute: slot was null")
if (!opts.e) throw new TypeError("Cannot add reroute: CanvasPointerEvent was null")
const reroute = node.connectFloatingReroute([opts.e.canvasX, opts.e.canvasY], slot, afterRerouteId)
if (!reroute) throw new Error("Failed to create reroute")
that.dirty_canvas = true
that.dirty_bgcanvas = true
break
case "Search":
if(isFrom){
that.showSearchBox(e,{node_from: opts.nodeFrom, slot_from: slotX, type_filter_in: fromSlotType});
opts.showSearchBox(e,{node_from: opts.nodeFrom, slot_from: slotX, type_filter_in: fromSlotType});
}else{
that.showSearchBox(e,{node_to: opts.nodeTo, slot_from: slotX, type_filter_out: fromSlotType});
opts.showSearchBox(e,{node_to: opts.nodeTo, slot_from: slotX, type_filter_out: fromSlotType});
}
break;
default:
// check for defaults nodes for this slottype
var nodeCreated = that.createDefaultNodeForSlot(Object.assign(opts,{ position: [opts.e.canvasX, opts.e.canvasY]
,nodeType: v
}));
if (nodeCreated){
// new node created
//console.log("node "+v+" created")
}else{
// failed or v is not in defaults
const customProps = {
position: [opts.e?.canvasX ?? 0, opts.e?.canvasY ?? 0],
nodeType: v,
afterRerouteId,
}
// check for defaults nodes for this slottype
that.createDefaultNodeForSlot(Object.assign(opts, customProps))
break;
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long