mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-04-20 03:13:30 +00:00
Refactor frontend widget instantiation
This commit is contained in:
parent
f542f248f1
commit
7e5645e956
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ output/
|
|||||||
models/checkpoints
|
models/checkpoints
|
||||||
models/vae
|
models/vae
|
||||||
models/embeddings
|
models/embeddings
|
||||||
|
models/loras
|
||||||
|
34
nodes.py
34
nodes.py
@ -127,8 +127,8 @@ class CheckpointLoader:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required": { "config_name": (filter_files_extensions(recursive_search(s.config_dir), '.yaml'), ),
|
return {"required": { "config_name": ("COMBO", { "choices": filter_files_extensions(recursive_search(s.config_dir), '.yaml') }),
|
||||||
"ckpt_name": (filter_files_extensions(recursive_search(s.ckpt_dir), supported_ckpt_extensions), )}}
|
"ckpt_name": ("COMBO", { "choices": filter_files_extensions(recursive_search(s.ckpt_dir), supported_ckpt_extensions) })}}
|
||||||
RETURN_TYPES = ("MODEL", "CLIP", "VAE")
|
RETURN_TYPES = ("MODEL", "CLIP", "VAE")
|
||||||
FUNCTION = "load_checkpoint"
|
FUNCTION = "load_checkpoint"
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ class LoraLoader:
|
|||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required": { "model": ("MODEL",),
|
return {"required": { "model": ("MODEL",),
|
||||||
"clip": ("CLIP", ),
|
"clip": ("CLIP", ),
|
||||||
"lora_name": (filter_files_extensions(recursive_search(s.lora_dir), supported_pt_extensions), ),
|
"lora_name": ("COMBO", { "choices": filter_files_extensions(recursive_search(s.lora_dir), supported_pt_extensions) }),
|
||||||
"strength_model": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
"strength_model": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
||||||
"strength_clip": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
"strength_clip": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
||||||
}}
|
}}
|
||||||
@ -165,7 +165,7 @@ class VAELoader:
|
|||||||
vae_dir = os.path.join(models_dir, "vae")
|
vae_dir = os.path.join(models_dir, "vae")
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required": { "vae_name": (filter_files_extensions(recursive_search(s.vae_dir), supported_pt_extensions), )}}
|
return {"required": { "vae_name": ("COMBO", { "choices": filter_files_extensions(recursive_search(s.vae_dir), supported_pt_extensions) })}}
|
||||||
RETURN_TYPES = ("VAE",)
|
RETURN_TYPES = ("VAE",)
|
||||||
FUNCTION = "load_vae"
|
FUNCTION = "load_vae"
|
||||||
|
|
||||||
@ -182,7 +182,7 @@ class CLIPLoader:
|
|||||||
clip_dir = os.path.join(models_dir, "clip")
|
clip_dir = os.path.join(models_dir, "clip")
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required": { "clip_name": (filter_files_extensions(recursive_search(s.clip_dir), supported_pt_extensions), ),
|
return {"required": { "clip_name": ("COMBO", { "choices": filter_files_extensions(recursive_search(s.clip_dir), supported_pt_extensions) }),
|
||||||
"stop_at_clip_layer": ("INT", {"default": -1, "min": -24, "max": -1, "step": 1}),
|
"stop_at_clip_layer": ("INT", {"default": -1, "min": -24, "max": -1, "step": 1}),
|
||||||
}}
|
}}
|
||||||
RETURN_TYPES = ("CLIP",)
|
RETURN_TYPES = ("CLIP",)
|
||||||
@ -237,10 +237,10 @@ class LatentUpscale:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required": { "samples": ("LATENT",), "upscale_method": (s.upscale_methods,),
|
return {"required": { "samples": ("LATENT",), "upscale_method": ("COMBO", { "choices" : s.upscale_methods }),
|
||||||
"width": ("INT", {"default": 512, "min": 64, "max": 4096, "step": 64}),
|
"width": ("INT", {"default": 512, "min": 64, "max": 4096, "step": 64}),
|
||||||
"height": ("INT", {"default": 512, "min": 64, "max": 4096, "step": 64}),
|
"height": ("INT", {"default": 512, "min": 64, "max": 4096, "step": 64}),
|
||||||
"crop": (s.crop_methods,)}}
|
"crop": ("COMBO", { "choices": s.crop_methods })}}
|
||||||
RETURN_TYPES = ("LATENT",)
|
RETURN_TYPES = ("LATENT",)
|
||||||
FUNCTION = "upscale"
|
FUNCTION = "upscale"
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ class LatentFlip:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required": { "samples": ("LATENT",),
|
return {"required": { "samples": ("LATENT",),
|
||||||
"flip_method": (["x-axis: vertically", "y-axis: horizontally"],),
|
"flip_method": ("COMBO", { "choices": ["x-axis: vertically", "y-axis: horizontally"] }),
|
||||||
}}
|
}}
|
||||||
RETURN_TYPES = ("LATENT",)
|
RETURN_TYPES = ("LATENT",)
|
||||||
FUNCTION = "flip"
|
FUNCTION = "flip"
|
||||||
@ -409,8 +409,8 @@ class KSampler:
|
|||||||
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
||||||
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
|
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
|
||||||
"cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
|
"cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
|
||||||
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
|
"sampler_name": ("COMBO", { "choices": comfy.samplers.KSampler.SAMPLERS }),
|
||||||
"scheduler": (comfy.samplers.KSampler.SCHEDULERS, ),
|
"scheduler": ("COMBO", { "choices": comfy.samplers.KSampler.SCHEDULERS }),
|
||||||
"positive": ("CONDITIONING", ),
|
"positive": ("CONDITIONING", ),
|
||||||
"negative": ("CONDITIONING", ),
|
"negative": ("CONDITIONING", ),
|
||||||
"latent_image": ("LATENT", ),
|
"latent_image": ("LATENT", ),
|
||||||
@ -433,18 +433,18 @@ class KSamplerAdvanced:
|
|||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required":
|
return {"required":
|
||||||
{"model": ("MODEL",),
|
{"model": ("MODEL",),
|
||||||
"add_noise": (["enable", "disable"], ),
|
"add_noise": ("COMBO", { "choices": ["enable", "disable"] }),
|
||||||
"noise_seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
"noise_seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
||||||
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
|
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
|
||||||
"cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
|
"cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
|
||||||
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
|
"sampler_name": ("COMBO", {"choices": comfy.samplers.KSampler.SAMPLERS}),
|
||||||
"scheduler": (comfy.samplers.KSampler.SCHEDULERS, ),
|
"scheduler": ("COMBO", {"choices": comfy.samplers.KSampler.SCHEDULERS}),
|
||||||
"positive": ("CONDITIONING", ),
|
"positive": ("CONDITIONING", ),
|
||||||
"negative": ("CONDITIONING", ),
|
"negative": ("CONDITIONING", ),
|
||||||
"latent_image": ("LATENT", ),
|
"latent_image": ("LATENT", ),
|
||||||
"start_at_step": ("INT", {"default": 0, "min": 0, "max": 10000}),
|
"start_at_step": ("INT", {"default": 0, "min": 0, "max": 10000}),
|
||||||
"end_at_step": ("INT", {"default": 10000, "min": 0, "max": 10000}),
|
"end_at_step": ("INT", {"default": 10000, "min": 0, "max": 10000}),
|
||||||
"return_with_leftover_noise": (["disable", "enable"], ),
|
"return_with_leftover_noise": ("COMBO", { "choices": ["disable", "enable"] }),
|
||||||
}}
|
}}
|
||||||
|
|
||||||
RETURN_TYPES = ("LATENT",)
|
RETURN_TYPES = ("LATENT",)
|
||||||
@ -513,7 +513,7 @@ class LoadImage:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required":
|
return {"required":
|
||||||
{"image": (os.listdir(s.input_dir), )},
|
{"image": ("COMBO", { "choices": os.listdir(s.input_dir) })},
|
||||||
}
|
}
|
||||||
|
|
||||||
CATEGORY = "image"
|
CATEGORY = "image"
|
||||||
@ -541,10 +541,10 @@ class ImageScale:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {"required": { "image": ("IMAGE",), "upscale_method": (s.upscale_methods,),
|
return {"required": { "image": ("IMAGE",), "upscale_method": ("COMBO", { "choices": s.upscale_methods}),
|
||||||
"width": ("INT", {"default": 512, "min": 1, "max": 4096, "step": 1}),
|
"width": ("INT", {"default": 512, "min": 1, "max": 4096, "step": 1}),
|
||||||
"height": ("INT", {"default": 512, "min": 1, "max": 4096, "step": 1}),
|
"height": ("INT", {"default": 512, "min": 1, "max": 4096, "step": 1}),
|
||||||
"crop": (s.crop_methods,)}}
|
"crop": ("COMBO", {"choices": s.crop_methods})}}
|
||||||
RETURN_TYPES = ("IMAGE",)
|
RETURN_TYPES = ("IMAGE",)
|
||||||
FUNCTION = "upscale"
|
FUNCTION = "upscale"
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<canvas id='mycanvas' width='1000' height='1000' style='width: 100%; height: 100%;'></canvas>
|
<canvas id='mycanvas' width='1000' height='1000' style='width: 100%; height: 100%;'></canvas>
|
||||||
|
<script type="text/javascript" src="widgets.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var graph = new LGraph();
|
var graph = new LGraph();
|
||||||
|
|
||||||
@ -105,9 +106,9 @@ function afterLoadGraph()
|
|||||||
}
|
}
|
||||||
|
|
||||||
setInterval(saveGraph, 1000);
|
setInterval(saveGraph, 1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onObjectInfo(json) {
|
function onObjectInfo(json) {
|
||||||
for (let key in json) {
|
for (let key in json) {
|
||||||
function MyNode()
|
function MyNode()
|
||||||
@ -120,126 +121,18 @@ function onObjectInfo(json) {
|
|||||||
min_width = 1;
|
min_width = 1;
|
||||||
for (let x in inp) {
|
for (let x in inp) {
|
||||||
let default_val = min_val = max_val = step_val = multiline = undefined;
|
let default_val = min_val = max_val = step_val = multiline = undefined;
|
||||||
|
let opts = {};
|
||||||
if (inp[x].length > 1) {
|
if (inp[x].length > 1) {
|
||||||
default_val = inp[x][1]['default'];
|
opts = inp[x][1];
|
||||||
min_val = inp[x][1]['min'];
|
|
||||||
max_val = inp[x][1]['max'];
|
|
||||||
step_val = inp[x][1]['step'];
|
|
||||||
multiline = inp[x][1]['multiline'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let type = inp[x][0];
|
let type = inp[x][0];
|
||||||
|
let widgetClass = COMFY_WIDGETS[type];
|
||||||
if (Array.isArray(type)) {
|
if (Array.isArray(type)) {
|
||||||
w = this.addWidget("combo", x, type[0], function(v){}, { values: type } );
|
w = this.addWidget("combo", x, type[0], function(v){}, { values: type } );
|
||||||
this._widgets += [w]
|
this._widgets += [w]
|
||||||
} else if (type == "INT") {
|
} else if (widgetClass) {
|
||||||
if (default_val == undefined) default_val = 0;
|
new widgetClass(opts).addWidget(this, x);
|
||||||
if (min_val == undefined) min_val = 0;
|
|
||||||
if (max_val == undefined) max_val = 2048;
|
|
||||||
if (step_val == undefined) step_val = 1;
|
|
||||||
w = this.addWidget("number", x, default_val, function(v){let s = this.options.step / 10;this.value = Math.round( v / s ) * s;}, { min: min_val, max: max_val, step: 10.0 * step_val} );
|
|
||||||
this._widgets += [w]
|
|
||||||
if (x == "seed" || x == "noise_seed") {
|
|
||||||
w1 = this.addWidget("toggle", "Random seed after every gen", true, function(v){}, { on: "enabled", off:"disabled"} );
|
|
||||||
w1.to_randomize = w;
|
|
||||||
this._widgets += [w1]
|
|
||||||
}
|
|
||||||
} else if (type == "FLOAT") {
|
|
||||||
if (default_val == undefined) default_val = 0;
|
|
||||||
if (min_val == undefined) min_val = 0;
|
|
||||||
if (max_val == undefined) max_val = 2048;
|
|
||||||
if (step_val == undefined) step_val = 0.5;
|
|
||||||
|
|
||||||
// if (min_val == 0.0 && max_val == 1.0) {
|
|
||||||
// w = this.slider = this.addWidget("slider", x, default_val, function(v){}, { min: min_val, max: max_val} );
|
|
||||||
// } else {
|
|
||||||
w = this.addWidget("number", x, default_val, function(v){}, { min: min_val, max: max_val, step: 10.0 * step_val} );
|
|
||||||
// }
|
|
||||||
this._widgets += [w]
|
|
||||||
} else if (type == "STRING") {
|
|
||||||
if (default_val == undefined) default_val = "";
|
|
||||||
if (multiline == undefined) multiline = false;
|
|
||||||
|
|
||||||
if (multiline) {
|
|
||||||
var w = {
|
|
||||||
type: "customtext",
|
|
||||||
name: x,
|
|
||||||
get value() { return this.input_div.innerText;},
|
|
||||||
set value(x) { this.input_div.innerText = x;},
|
|
||||||
callback: function(v){console.log(v);},
|
|
||||||
options: {},
|
|
||||||
draw: function(ctx, node, widget_width, y, H){
|
|
||||||
var show_text = canvas.ds.scale > 0.5;
|
|
||||||
// this.input_div.style.top = `${y}px`;
|
|
||||||
let t = ctx.getTransform();
|
|
||||||
let margin = 10;
|
|
||||||
let x_div = t.a * margin * 2 + t.e;
|
|
||||||
let y_div = t.d * (y + H) + t.f;
|
|
||||||
let width_div = (widget_width - margin * 2 - 3) * t.a;
|
|
||||||
let height_div = (this.parent.size[1] - (y + H) - 3)* t.d;
|
|
||||||
this.input_div.style.left = `${x_div}px`;
|
|
||||||
this.input_div.style.top = `${y_div}px`;
|
|
||||||
this.input_div.style.width = width_div;
|
|
||||||
this.input_div.style.height = height_div;
|
|
||||||
this.input_div.style.position = 'absolute';
|
|
||||||
this.input_div.style.zIndex = 1;
|
|
||||||
this.input_div.style.fontSize = t.d * 10.0;
|
|
||||||
|
|
||||||
if (show_text) {
|
|
||||||
this.input_div.hidden = false;
|
|
||||||
} else {
|
|
||||||
this.input_div.hidden = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
// ctx.fillText(String(this.value).substr(0,30), 0, y + H * 0.7);
|
|
||||||
ctx.restore();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
w.input_div = document.createElement('div');
|
|
||||||
w.input_div.contentEditable = true;
|
|
||||||
w.input_div.style.backgroundColor = "#FFFFFF";
|
|
||||||
w.input_div.style.overflow = 'hidden';
|
|
||||||
w.input_div.style.overflowY = 'auto';
|
|
||||||
w.input_div.style.padding = 2;
|
|
||||||
w.input_div.innerText = default_val;
|
|
||||||
document.addEventListener('click', function(event) {
|
|
||||||
if (!w.input_div.contains(event.target)) {
|
|
||||||
w.input_div.blur();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
w.parent = this;
|
|
||||||
min_height = Math.max(min_height, 200);
|
|
||||||
min_width = Math.max(min_width, 400);
|
|
||||||
ccc.parentNode.appendChild(w.input_div);
|
|
||||||
|
|
||||||
w = this.addCustomWidget(w);
|
|
||||||
canvas.onDrawBackground = function() {
|
|
||||||
for (let n in graph._nodes) {
|
|
||||||
n = graph._nodes[n];
|
|
||||||
for (let w in n.widgets) {
|
|
||||||
let wid = n.widgets[w];
|
|
||||||
if (Object.hasOwn(wid, 'input_div')) {
|
|
||||||
wid.input_div.style.left = -8000;
|
|
||||||
wid.input_div.style.position = 'absolute';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// w = this.addWidget("text", x, "", function(v){}, { multiline:true } );
|
|
||||||
console.log(w, this);
|
|
||||||
this._widgets += [w]
|
|
||||||
this.onRemoved = function() {
|
|
||||||
for (let y in this.widgets) {
|
|
||||||
if (this.widgets[y].input_div) {
|
|
||||||
this.widgets[y].input_div.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
w = this.addWidget("text", x, default_val, function(v){}, { multiline:false } );
|
|
||||||
this._widgets += [w];
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.addInput(x, type);
|
this.addInput(x, type);
|
||||||
}
|
}
|
||||||
|
162
webshit/widgets.js
Normal file
162
webshit/widgets.js
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
var COMFY_WIDGETS = [];
|
||||||
|
|
||||||
|
|
||||||
|
class BaseWidget {
|
||||||
|
addWidget(node) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class IntWidget extends BaseWidget {
|
||||||
|
constructor(opts) {
|
||||||
|
super();
|
||||||
|
this.default_val = opts['default'] || 0;
|
||||||
|
this.min_val = opts['min'] || 0;
|
||||||
|
this.max_val = opts['max'] || 2048;
|
||||||
|
this.step_val = opts['step'] || 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
addWidget(node, x) {
|
||||||
|
let onSet = function(v) {
|
||||||
|
let s = this.options.step / 10;
|
||||||
|
this.value = Math.round( v / s ) * s;
|
||||||
|
};
|
||||||
|
let w = node.addWidget("number", x, this.default_val, onSet, { min: this.min_val, max: this.max_val, step: 10.0 * this.step_val});
|
||||||
|
node._widgets += [w]
|
||||||
|
if (x == "seed" || x == "noise_seed") {
|
||||||
|
let w1 = node.addWidget("toggle", "Random seed after every gen", true, function(v){}, { on: "enabled", off: "disabled" } );
|
||||||
|
w1.to_randomize = w;
|
||||||
|
node._widgets += [w1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
COMFY_WIDGETS["INT"] = IntWidget;
|
||||||
|
|
||||||
|
|
||||||
|
class FloatWidget extends BaseWidget {
|
||||||
|
constructor(opts) {
|
||||||
|
super();
|
||||||
|
this.default_val = opts['default'] || 0;
|
||||||
|
this.min_val = opts['min'] || 0;
|
||||||
|
this.max_val = opts['max'] || 2048;
|
||||||
|
this.step_val = opts['step'] || 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
addWidget(node, x) {
|
||||||
|
// if (min_val == 0.0 && max_val == 1.0) {
|
||||||
|
// w = this.slider = this.addWidget("slider", x, default_val, function(v){}, { min: min_val, max: max_val} );
|
||||||
|
// } else {
|
||||||
|
let w = node.addWidget("number", x, this.default_val, function(v){}, { min: this.min_val, max: this.max_val, step: 10.0 * this.step_val} );
|
||||||
|
// }
|
||||||
|
node._widgets += [w];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
COMFY_WIDGETS["FLOAT"] = FloatWidget;
|
||||||
|
|
||||||
|
|
||||||
|
class StringWidget extends BaseWidget {
|
||||||
|
constructor(opts) {
|
||||||
|
super();
|
||||||
|
this.default_val = opts['default'] || "";
|
||||||
|
this.multiline = opts['multiline'] || false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addWidget(node, x) {
|
||||||
|
if (this.multiline) {
|
||||||
|
var w = {
|
||||||
|
type: "customtext",
|
||||||
|
name: x,
|
||||||
|
get value() { return this.input_div.innerText;},
|
||||||
|
set value(x) { this.input_div.innerText = x;},
|
||||||
|
callback: function(v){console.log(v);},
|
||||||
|
options: {},
|
||||||
|
draw: function(ctx, node, widget_width, y, H){
|
||||||
|
var show_text = canvas.ds.scale > 0.5;
|
||||||
|
// this.input_div.style.top = `${y}px`;
|
||||||
|
let t = ctx.getTransform();
|
||||||
|
let margin = 10;
|
||||||
|
let x_div = t.a * margin * 2 + t.e;
|
||||||
|
let y_div = t.d * (y + H) + t.f;
|
||||||
|
let width_div = (widget_width - margin * 2 - 3) * t.a;
|
||||||
|
let height_div = (this.parent.size[1] - (y + H) - 3)* t.d;
|
||||||
|
this.input_div.style.left = `${x_div}px`;
|
||||||
|
this.input_div.style.top = `${y_div}px`;
|
||||||
|
this.input_div.style.width = width_div;
|
||||||
|
this.input_div.style.height = height_div;
|
||||||
|
this.input_div.style.position = 'absolute';
|
||||||
|
this.input_div.style.zIndex = 1;
|
||||||
|
this.input_div.style.fontSize = t.d * 10.0;
|
||||||
|
|
||||||
|
if (show_text) {
|
||||||
|
this.input_div.hidden = false;
|
||||||
|
} else {
|
||||||
|
this.input_div.hidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
// ctx.fillText(String(this.value).substr(0,30), 0, y + H * 0.7);
|
||||||
|
ctx.restore();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
w.input_div = document.createElement('div');
|
||||||
|
w.input_div.contentEditable = true;
|
||||||
|
w.input_div.style.backgroundColor = "#FFFFFF";
|
||||||
|
w.input_div.style.overflow = 'hidden';
|
||||||
|
w.input_div.style.overflowY = 'auto';
|
||||||
|
w.input_div.style.padding = 2;
|
||||||
|
w.input_div.innerText = this.default_val;
|
||||||
|
document.addEventListener('click', function(event) {
|
||||||
|
if (!w.input_div.contains(event.target)) {
|
||||||
|
w.input_div.blur();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
w.parent = node;
|
||||||
|
min_height = Math.max(min_height, 200);
|
||||||
|
min_width = Math.max(min_width, 400);
|
||||||
|
ccc.parentNode.appendChild(w.input_div);
|
||||||
|
|
||||||
|
w = node.addCustomWidget(w);
|
||||||
|
canvas.onDrawBackground = function() {
|
||||||
|
for (let n in graph._nodes) {
|
||||||
|
n = graph._nodes[n];
|
||||||
|
for (let w in n.widgets) {
|
||||||
|
let wid = n.widgets[w];
|
||||||
|
if (Object.hasOwn(wid, 'input_div')) {
|
||||||
|
wid.input_div.style.left = -8000;
|
||||||
|
wid.input_div.style.position = 'absolute';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// w = node.addWidget("text", x, "", function(v){}, { multiline:true } );
|
||||||
|
console.log(w, node);
|
||||||
|
node._widgets += [w]
|
||||||
|
node.onRemoved = function() {
|
||||||
|
for (let y in node.widgets) {
|
||||||
|
if (node.widgets[y].input_div) {
|
||||||
|
node.widgets[y].input_div.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
w = node.addWidget("text", x, this.default_val, function(v){}, { multiline:false } );
|
||||||
|
node._widgets += [w];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
COMFY_WIDGETS["STRING"] = StringWidget;
|
||||||
|
|
||||||
|
|
||||||
|
class ComboWidget extends BaseWidget {
|
||||||
|
constructor(opts) {
|
||||||
|
super();
|
||||||
|
this.choices = opts['choices'] || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
addWidget(node, x) {
|
||||||
|
let w = node.addWidget("combo", x, this.choices[0], function(v){}, { values: this.choices } );
|
||||||
|
node._widgets += [w]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
COMFY_WIDGETS["COMBO"] = ComboWidget;
|
Loading…
Reference in New Issue
Block a user