add:easy imageSplitGrid
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
|
||||
**v1.1.7**
|
||||
|
||||
- Added `easy imageSplitGrid`
|
||||
- `easy kSamplerInpainting` added options such as different diffusion and brushnet in **additional** widget
|
||||
- Support for brushnet model loading - [ComfyUI-BrushNet](https://github.com/nullquant/ComfyUI-BrushNet)
|
||||
- Added `easy applyFooocusInpaint` - Replace FooocusInpaintLoader
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
**v1.1.7**
|
||||
|
||||
- 增加 `easy imageSplitGrid` - 图像网格拆分
|
||||
- `easy kSamplerInpainting` 的 **additional** 属性增加差异扩散和brushnet等相关选项
|
||||
- 增加 brushnet模型加载的支持 - [ComfyUI-BrushNet](https://github.com/nullquant/ComfyUI-BrushNet)
|
||||
- 增加 `easy applyFooocusInpaint` - Fooocus内补节点 替代原有的 FooocusInpaintLoader
|
||||
|
||||
@@ -153,6 +153,20 @@ LAYER_DIFFUSION = {
|
||||
},
|
||||
}
|
||||
|
||||
# IC Light
|
||||
IC_LIGHT_DIR = os.path.join(folder_paths.models_dir, "ic_light")
|
||||
IC_LIGHT_MODELS = {
|
||||
"iclight_fc": {
|
||||
"sd1": {
|
||||
"model_url": "https://huggingface.co/lllyasviel/ic-light/resolve/main/iclight_sd15_fc.safetensors"
|
||||
},
|
||||
"sdxl": {
|
||||
"model_url": None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# REMBG
|
||||
REMBG_DIR = os.path.join(folder_paths.models_dir, "rembg")
|
||||
REMBG_MODELS = {
|
||||
|
||||
+35
-32
@@ -1,4 +1,4 @@
|
||||
import sys, os, re, json, time, math, copy
|
||||
import sys, os, re, json, time
|
||||
import torch
|
||||
import folder_paths
|
||||
import comfy.utils, comfy.sample, comfy.samplers, comfy.controlnet, comfy.model_base, comfy.model_management
|
||||
@@ -16,7 +16,7 @@ from PIL import Image
|
||||
|
||||
from server import PromptServer
|
||||
from nodes import MAX_RESOLUTION, LatentFromBatch, RepeatLatentBatch, NODE_CLASS_MAPPINGS as ALL_NODE_CLASS_MAPPINGS, ConditioningSetMask, ConditioningConcat, CLIPTextEncode, VAEEncodeForInpaint, InpaintModelConditioning
|
||||
from .config import MAX_SEED_NUM, BASE_RESOLUTIONS, RESOURCES_DIR, INPAINT_DIR, FOOOCUS_STYLES_DIR, FOOOCUS_INPAINT_HEAD, FOOOCUS_INPAINT_PATCH, BRUSHNET_MODELS, IPADAPTER_DIR, IPADAPTER_MODELS, DYNAMICRAFTER_DIR, DYNAMICRAFTER_MODELS
|
||||
from .config import MAX_SEED_NUM, BASE_RESOLUTIONS, RESOURCES_DIR, INPAINT_DIR, FOOOCUS_STYLES_DIR, FOOOCUS_INPAINT_HEAD, FOOOCUS_INPAINT_PATCH, BRUSHNET_MODELS, IPADAPTER_DIR, IPADAPTER_MODELS, DYNAMICRAFTER_DIR, DYNAMICRAFTER_MODELS, IC_LIGHT_DIR, IC_LIGHT_MODELS
|
||||
from .log import log_node_info, log_node_error, log_node_warn
|
||||
from .wildcards import process_with_loras, get_wildcard_list, process
|
||||
from .adv_encode import advanced_encode
|
||||
@@ -52,6 +52,7 @@ add_folder_path_and_extensions("ipadapter", [os.path.join(model_path, "ipadapter
|
||||
add_folder_path_and_extensions("dynamicrafter_models", [os.path.join(model_path, "dynamicrafter_models")], folder_paths.supported_pt_extensions)
|
||||
add_folder_path_and_extensions("mediapipe", [os.path.join(model_path, "mediapipe")], set(['.tflite','.pth']))
|
||||
add_folder_path_and_extensions("t5", [os.path.join(model_path, "t5")], set(['.safetensors','.bin','.json']))
|
||||
add_folder_path_and_extensions("ic_light", [os.path.join(model_path, "ic_light")], set(['.safetensors','.bin','.json']))
|
||||
|
||||
add_folder_path_and_extensions("checkpoints_thumb", [os.path.join(model_path, "checkpoints")], image_suffixs)
|
||||
add_folder_path_and_extensions("loras_thumb", [os.path.join(model_path, "loras")], image_suffixs)
|
||||
@@ -2087,34 +2088,6 @@ class LLLiteLoader:
|
||||
# FooocusInpaint
|
||||
from .fooocus import InpaintHead, InpaintWorker
|
||||
inpaint_head_model = None
|
||||
# class fooocusInpaintLoader:
|
||||
# @classmethod
|
||||
# def INPUT_TYPES(s):
|
||||
# return {
|
||||
# "required": {
|
||||
# "head": (list(FOOOCUS_INPAINT_HEAD.keys()),),
|
||||
# "patch": (list(FOOOCUS_INPAINT_PATCH.keys()),),
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# RETURN_TYPES = ("INPAINT_PATCH",)
|
||||
# RETURN_NAMES = ("patch",)
|
||||
# CATEGORY = "EasyUse/Inpaint"
|
||||
# FUNCTION = "apply"
|
||||
#
|
||||
# def apply(self, head, patch):
|
||||
# global inpaint_head_model
|
||||
#
|
||||
# head_file = get_local_filepath(FOOOCUS_INPAINT_HEAD[head]["model_url"], INPAINT_DIR)
|
||||
# if inpaint_head_model is None:
|
||||
# inpaint_head_model = InpaintHead()
|
||||
# sd = torch.load(head_file, map_location='cpu')
|
||||
# inpaint_head_model.load_state_dict(sd)
|
||||
#
|
||||
# patch_file = get_local_filepath(FOOOCUS_INPAINT_PATCH[patch]["model_url"], INPAINT_DIR)
|
||||
# inpaint_lora = comfy.utils.load_torch_file(patch_file, safe_load=True)
|
||||
#
|
||||
# return ((inpaint_head_model, inpaint_lora),)
|
||||
|
||||
class applyFooocusInpaint:
|
||||
@classmethod
|
||||
@@ -2155,6 +2128,8 @@ class applyFooocusInpaint:
|
||||
|
||||
|
||||
#---------------------------------------------------------------适配器 开始----------------------------------------------------------------------#
|
||||
|
||||
# 风格对齐
|
||||
from .libs.styleAlign import styleAlignBatch, SHARE_NORM_OPTIONS, SHARE_ATTN_OPTIONS
|
||||
class styleAlignedBatchAlign:
|
||||
|
||||
@@ -2176,6 +2151,33 @@ class styleAlignedBatchAlign:
|
||||
def align(self, model, share_norm, share_attn, scale):
|
||||
return (styleAlignBatch(model, share_norm, share_attn, scale),)
|
||||
|
||||
# 光照对齐
|
||||
from .ic_light.func import ICLight
|
||||
class icLightApply:
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"mode": (list(IC_LIGHT_MODELS.keys()),),
|
||||
"model": ("MODEL",),
|
||||
"latent": ("LATENT",),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("MODEL",)
|
||||
FUNCTION = "apply"
|
||||
CATEGORY = "EasyUse/Adapter"
|
||||
|
||||
def apply(self, mode, model, latent):
|
||||
model_type = get_sd_version(model)
|
||||
if model_type == 'sdxl':
|
||||
raise Exception("IC Light model is not supported for SDXL")
|
||||
model_path = get_local_filepath(IC_LIGHT_MODELS[mode]['sd1']["model_url"], IC_LIGHT_DIR)
|
||||
m = ICLight().apply(model_path, model, latent)
|
||||
return (m,)
|
||||
|
||||
|
||||
def insightface_loader(provider):
|
||||
try:
|
||||
from insightface.app import FaceAnalysis
|
||||
@@ -5687,8 +5689,7 @@ class detailerFix:
|
||||
del pipe
|
||||
|
||||
if image_output in ("Hide", "Hide&Save"):
|
||||
return {"ui": {},
|
||||
"result": (new_pipe, result_img, result_cropped_enhanced, result_cropped_enhanced_alpha, result_mask, result_cnet_images )}
|
||||
return (new_pipe, result_img, result_cropped_enhanced, result_cropped_enhanced_alpha, result_mask, result_cnet_images)
|
||||
|
||||
if image_output in ("Sender", "Sender&Save"):
|
||||
PromptServer.instance.send_sync("img-send", {"link_id": link_id, "images": results})
|
||||
@@ -7154,6 +7155,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"easy instantIDApply": instantIDApply,
|
||||
"easy instantIDApplyADV": instantIDApplyAdvanced,
|
||||
"easy styleAlignedBatchAlign": styleAlignedBatchAlign,
|
||||
"easy icLightApply": icLightApply,
|
||||
# Inpaint 内补
|
||||
# "easy fooocusInpaintLoader": fooocusInpaintLoader,
|
||||
"easy applyFooocusInpaint": applyFooocusInpaint,
|
||||
@@ -7261,6 +7263,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"easy instantIDApply": "Easy Apply InstantID",
|
||||
"easy instantIDApplyADV": "Easy Apply InstantID (Advanced)",
|
||||
"easy styleAlignedBatchAlign": "Easy Apply StyleAlign",
|
||||
"easy icLightApply": "Easy Apply ICLight",
|
||||
# Inpaint 内补
|
||||
# "easy fooocusInpaintLoader": "Load Fooocus Inpaint(Removed)",
|
||||
"easy applyFooocusInpaint": "Apply Fooocus Inpaint",
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import os
|
||||
import torch
|
||||
import safetensors.torch
|
||||
from typing import Tuple, TypedDict, Callable, NamedTuple
|
||||
|
||||
import folder_paths
|
||||
import comfy.model_management
|
||||
from comfy.diffusers_convert import convert_unet_state_dict
|
||||
from comfy.model_patcher import ModelPatcher
|
||||
from comfy.ldm.modules.diffusionmodules.openaimodel import UNetModel
|
||||
from comfy.model_base import BaseModel
|
||||
from comfy.conds import CONDRegular
|
||||
|
||||
class UnetParams(TypedDict):
|
||||
input: torch.Tensor
|
||||
timestep: torch.Tensor
|
||||
c: dict
|
||||
cond_or_uncond: torch.Tensor
|
||||
|
||||
class ICLight:
|
||||
|
||||
@staticmethod
|
||||
def apply_c_concat(cond, uncond, c_concat: torch.Tensor):
|
||||
def write_c_concat(cond):
|
||||
new_cond = []
|
||||
for t in cond:
|
||||
n = [t[0], t[1].copy()]
|
||||
if "model_conds" not in n[1]:
|
||||
n[1]["model_conds"] = {}
|
||||
n[1]["model_conds"]["c_concat"] = CONDRegular(c_concat)
|
||||
new_cond.append(n)
|
||||
return new_cond
|
||||
|
||||
return (write_c_concat(cond), write_c_concat(uncond))
|
||||
|
||||
@staticmethod
|
||||
def create_custom_conv(
|
||||
original_conv: torch.nn.Module,
|
||||
dtype: torch.dtype,
|
||||
device=torch.device,
|
||||
) -> torch.nn.Module:
|
||||
with torch.no_grad():
|
||||
new_conv_in = torch.nn.Conv2d(
|
||||
8,
|
||||
original_conv.out_channels,
|
||||
original_conv.kernel_size,
|
||||
original_conv.stride,
|
||||
original_conv.padding,
|
||||
)
|
||||
new_conv_in.weight.zero_()
|
||||
new_conv_in.weight[:, :4, :, :].copy_(original_conv.weight)
|
||||
new_conv_in.bias = original_conv.bias
|
||||
return new_conv_in.to(dtype=dtype, device=device)
|
||||
|
||||
|
||||
def apply(self, model_path, model: ModelPatcher, c_concat: dict,) -> Tuple[ModelPatcher]:
|
||||
|
||||
device = comfy.model_management.get_torch_device()
|
||||
dtype = comfy.model_management.unet_dtype()
|
||||
work_model = model.clone()
|
||||
c_concat_samples: torch.Tensor = c_concat["samples"]
|
||||
|
||||
def wrapped_unet(unet_apply: Callable, params: UnetParams):
|
||||
# Apply concat.
|
||||
sample = params["input"]
|
||||
params["c"]["c_concat"] = torch.cat(
|
||||
(
|
||||
[c_concat_samples.to(sample.device)]
|
||||
* (sample.shape[0] // c_concat_samples.shape[0])
|
||||
)
|
||||
+ params["c"].get("c_concat", []),
|
||||
dim=0,
|
||||
)
|
||||
return unet_apply(x=sample, t=params["timestep"], **params["c"])
|
||||
|
||||
work_model.add_object_patch(
|
||||
"diffusion_model.input_blocks.0.0",
|
||||
self.create_custom_conv(
|
||||
original_conv=work_model.get_model_object("diffusion_model.input_blocks.0.0"),
|
||||
dtype=dtype,
|
||||
device=device,
|
||||
),
|
||||
)
|
||||
work_model.set_model_unet_function_wrapper(wrapped_unet)
|
||||
sd_offset = convert_unet_state_dict(safetensors.torch.load_file(model_path))
|
||||
|
||||
work_model.add_patches(
|
||||
patches={
|
||||
("diffusion_model." + key): (
|
||||
sd_offset[key].to(dtype=dtype, device=device),
|
||||
)
|
||||
for key in sd_offset.keys()
|
||||
}
|
||||
)
|
||||
|
||||
return work_model
|
||||
+81
-5
@@ -540,6 +540,41 @@ class imageSplitList:
|
||||
new_images[1].append(img)
|
||||
return new_images
|
||||
|
||||
class imageSplitGrid:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"images": ("IMAGE",),
|
||||
"row": ("INT", {"default": 1,"min": 1,"max": 10,"step": 1,}),
|
||||
"column": ("INT", {"default": 1,"min": 1,"max": 10,"step": 1,}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("images",)
|
||||
FUNCTION = "doit"
|
||||
CATEGORY = "EasyUse/Image"
|
||||
|
||||
def crop(self, image, width, height, x, y):
|
||||
x = min(x, image.shape[2] - 1)
|
||||
y = min(y, image.shape[1] - 1)
|
||||
to_x = width + x
|
||||
to_y = height + y
|
||||
img = image[:, y:to_y, x:to_x, :]
|
||||
return img
|
||||
|
||||
def doit(self, images, row, column):
|
||||
_, height, width, _ = images.shape
|
||||
sub_width = width // column
|
||||
sub_height = height // row
|
||||
new_images = []
|
||||
for i in range(row):
|
||||
for j in range(column):
|
||||
new_images.append(self.crop(images, sub_width, sub_height, j * sub_width, i * sub_height))
|
||||
|
||||
return (torch.cat(new_images, dim=0),)
|
||||
|
||||
class imagesSplitImage:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
@@ -558,6 +593,34 @@ class imagesSplitImage:
|
||||
new_images = torch.chunk(images, len(images), dim=0)
|
||||
return new_images
|
||||
|
||||
|
||||
class imageConcat:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {
|
||||
"image1": ("IMAGE",),
|
||||
"image2": ("IMAGE",),
|
||||
"direction": (['right','down','left','up',],{"default": 'right'}),
|
||||
"match_image_size": ("BOOLEAN", {"default": False}),
|
||||
}}
|
||||
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
FUNCTION = "concat"
|
||||
CATEGORY = "EasyUse/image"
|
||||
|
||||
def concat(self, image1, image2, direction, match_image_size):
|
||||
if match_image_size:
|
||||
image2 = torch.nn.functional.interpolate(image2, size=(image1.shape[2], image1.shape[3]), mode="bilinear")
|
||||
if direction == 'right':
|
||||
row = torch.cat((image1, image2), dim=2)
|
||||
elif direction == 'down':
|
||||
row = torch.cat((image1, image2), dim=1)
|
||||
elif direction == 'left':
|
||||
row = torch.cat((image2, image1), dim=2)
|
||||
elif direction == 'up':
|
||||
row = torch.cat((image2, image1), dim=1)
|
||||
return (row,)
|
||||
|
||||
# 图片背景移除
|
||||
from .briaai.rembg import BriaRMBG, preprocess_image, postprocess_image
|
||||
from .libs.utils import get_local_filepath, easySave, install_package
|
||||
@@ -633,12 +696,12 @@ class imageChooser(PreviewImage):
|
||||
def INPUT_TYPES(self):
|
||||
return {
|
||||
"required":{
|
||||
|
||||
"mode": (['Always Pause', 'Keep Last Selection'], {"default": "Always Pause"}),
|
||||
},
|
||||
"optional": {
|
||||
"images": ("IMAGE",),
|
||||
},
|
||||
"hidden": {"prompt": "PROMPT", "my_unique_id": "UNIQUE_ID"},
|
||||
"hidden": {"prompt": "PROMPT", "my_unique_id": "UNIQUE_ID", "extra_pnginfo": "EXTRA_PNGINFO"},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
@@ -661,8 +724,7 @@ class imageChooser(PreviewImage):
|
||||
else:
|
||||
return None
|
||||
|
||||
def chooser(self, prompt=None, my_unique_id=None, **kwargs):
|
||||
|
||||
def chooser(self, prompt=None, my_unique_id=None, extra_pnginfo=None, **kwargs):
|
||||
id = my_unique_id[0]
|
||||
if id not in ChooserMessage.stash:
|
||||
ChooserMessage.stash[id] = {}
|
||||
@@ -685,9 +747,19 @@ class imageChooser(PreviewImage):
|
||||
images = result['ui']['images']
|
||||
PromptServer.instance.send_sync("easyuse-image-choose", {"id": id, "urls": images})
|
||||
|
||||
# 获取上次选择
|
||||
mode = kwargs.pop('mode', 'Always Pause')
|
||||
last_choosen = None
|
||||
if mode == 'Keep Last Selection':
|
||||
if id and extra_pnginfo[0] and "workflow" in extra_pnginfo[0]:
|
||||
workflow = extra_pnginfo[0]["workflow"]
|
||||
node = next((x for x in workflow["nodes"] if str(x["id"]) == id), None)
|
||||
if node:
|
||||
last_choosen = node['properties']['values']
|
||||
|
||||
# wait for selection
|
||||
try:
|
||||
selections = ChooserMessage.waitForMessage(id, asList=True)
|
||||
selections = ChooserMessage.waitForMessage(id, asList=True) if last_choosen is None or len(last_choosen)<1 else last_choosen
|
||||
choosen = [x for x in selections if x >= 0] if len(selections)>1 else [0]
|
||||
except ChooserCancelled:
|
||||
raise comfy.model_management.InterruptProcessingException()
|
||||
@@ -1332,7 +1404,9 @@ NODE_CLASS_MAPPINGS = {
|
||||
"easy imageScaleDownToSize": imageScaleDownToSize,
|
||||
"easy imageRatio": imageRatio,
|
||||
"easy imageToMask": imageToMask,
|
||||
"easy imageConcat": imageConcat,
|
||||
"easy imageSplitList": imageSplitList,
|
||||
"easy imageSplitGrid": imageSplitGrid,
|
||||
"easy imagesSplitImage": imagesSplitImage,
|
||||
"easy imageCropFromMask": imageCropFromMask,
|
||||
"easy imageUncropFromBBOX": imageUncropFromBBOX,
|
||||
@@ -1362,7 +1436,9 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"easy imageRatio": "ImageRatio",
|
||||
"easy imageToMask": "ImageToMask",
|
||||
"easy imageHSVMask": "ImageHSVMask",
|
||||
"easy imageConcat": "imageConcat",
|
||||
"easy imageSplitList": "imageSplitList",
|
||||
"easy imageSplitGrid": "imageSplitGrid",
|
||||
"easy imagesSplitImage": "imagesSplitImage",
|
||||
"easy imageCropFromMask": "imageCropFromMask",
|
||||
"easy imageUncropFromBBOX": "imageUncropFromBBOX",
|
||||
|
||||
@@ -27,4 +27,9 @@
|
||||
}
|
||||
.easyuse-chooser-dialog-images img.selected{
|
||||
border: 4px solid var(--success-color);
|
||||
}
|
||||
|
||||
.easyuse-chooser-hidden{
|
||||
display: none;
|
||||
height:0;
|
||||
}
|
||||
+3
-6
@@ -139,7 +139,7 @@
|
||||
}
|
||||
.easyuse-guide-dialog p{
|
||||
margin:4px 0;
|
||||
font-size: 10px;
|
||||
font-size: 12px;
|
||||
font-weight: 300;
|
||||
}
|
||||
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 {
|
||||
@@ -161,7 +161,7 @@
|
||||
font-size: 14px;
|
||||
}
|
||||
.markdown-body h4{
|
||||
font-size: 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.markdown-body table {
|
||||
display: block;
|
||||
@@ -183,7 +183,7 @@
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
.markdown-body table td {
|
||||
font-size: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.markdown-body table th:last-child, .markdown-body table td:last-child{
|
||||
border-right: none;
|
||||
@@ -199,9 +199,6 @@
|
||||
.markdown-body table th:last-child{
|
||||
width:100%;
|
||||
}
|
||||
.markdown-body a{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.markdown-body .warning{
|
||||
color:var(--warning-color)
|
||||
}
|
||||
|
||||
+8
-5
@@ -29,12 +29,15 @@ api.addEventListener("easyuse-toast",event=>{
|
||||
let draggerEl = null
|
||||
let isGroupMapcanMove = true
|
||||
function createGroupMap(){
|
||||
let div = document.querySelector('#easyuse_groups_map')
|
||||
if(div){
|
||||
div.style.display = div.style.display == 'none' ? 'flex' : 'none'
|
||||
return
|
||||
}
|
||||
let groups = app.canvas.graph._groups
|
||||
let nodes = app.canvas.graph._nodes
|
||||
let old_nodes = groups.length
|
||||
let div =
|
||||
document.querySelector('#easyuse_groups_map') ||
|
||||
document.createElement('div')
|
||||
div = document.createElement('div')
|
||||
div.id = 'easyuse_groups_map'
|
||||
div.innerHTML = ''
|
||||
let btn = document.createElement('div')
|
||||
@@ -381,10 +384,11 @@ class GuideDialog {
|
||||
}
|
||||
}
|
||||
|
||||
const getEnableToolBar = _ => app.ui.settings.getSettingValue(toolBarId, true)
|
||||
|
||||
const toolBarId = "Comfy.EasyUse.toolBar"
|
||||
|
||||
let enableToolBar = true
|
||||
let enableToolBar = getEnableToolBar()
|
||||
let disableRenderInfo = localStorage['Comfy.Settings.Comfy.EasyUse.disableRenderInfo'] ? true : false
|
||||
export function addToolBar(app) {
|
||||
app.ui.settings.addSetting({
|
||||
@@ -400,7 +404,6 @@ export function addToolBar(app) {
|
||||
},
|
||||
});
|
||||
}
|
||||
const getEnableToolBar = _ => app.ui.settings.getSettingValue(toolBarId, true)
|
||||
|
||||
let note = null
|
||||
let toolbar = null
|
||||
|
||||
@@ -72,6 +72,10 @@ class chooserImageDialog extends ComfyDialog {
|
||||
function progressButtonPressed() {
|
||||
const node = app.graph._nodes_by_id[this.node_id];
|
||||
if (node) {
|
||||
const selected = [...node.selected]
|
||||
if(selected?.length>0){
|
||||
node.setProperty('values',selected)
|
||||
}
|
||||
if (FlowState.paused()) {
|
||||
send_message(node.id, [...node.selected, -1, ...node.anti_selected]);
|
||||
}
|
||||
@@ -79,10 +83,26 @@ function progressButtonPressed() {
|
||||
skip_next_restart_message();
|
||||
restart_from_here(node.id).then(() => { send_message(node.id, [...node.selected, -1, ...node.anti_selected]); });
|
||||
}
|
||||
const maxlength = node.imgs.length;
|
||||
if (FlowState.paused_here(node.id) && selected>0) {
|
||||
node.send_button_widget.name = (selected>1) ? "Progress selected (" + selected + '/' + maxlength +")" : "Progress selected image";
|
||||
} else if (FlowState.idle() && selected>0) {
|
||||
node.send_button_widget.name = (selected>1) ? "Progress selected (" + selected + '/' + maxlength +")" : "Progress selected image as restart";
|
||||
}
|
||||
else {
|
||||
node.send_button_widget.name = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cancelButtonPressed() { if (FlowState.running()) { send_cancel(); } }
|
||||
function cancelButtonPressed() {
|
||||
if (FlowState.running()) { send_cancel();}
|
||||
const node = app.graph._nodes_by_id[this.node_id];
|
||||
if (node) {
|
||||
node.send_button_widget.name = "";
|
||||
node.cancel_button_widget.name = "";
|
||||
}
|
||||
}
|
||||
|
||||
app.registerExtension({
|
||||
name:'comfy.easyuse.imageChooser',
|
||||
@@ -126,9 +146,12 @@ app.registerExtension({
|
||||
},
|
||||
|
||||
async nodeCreated(node, app) {
|
||||
|
||||
if(node.comfyClass == 'easy imageChooser'){
|
||||
node.send_button_widget = node.addWidget("button", "", "", progressButtonPressed, {serialize: false});
|
||||
node.cancel_button_widget = node.addWidget("button", "", "", cancelButtonPressed, {serialize: false});
|
||||
node.setProperty('values',[])
|
||||
|
||||
/* Capture clicks */
|
||||
const org_onMouseDown = node.onMouseDown;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user