mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-02-14 07:22:36 +08:00
copy/paste bug fixes for batch images
enhance selector preview on clipspace menu add img_paste_mode option into clipspace menu
This commit is contained in:
parent
8aac84a2e4
commit
286b731de3
@ -4,13 +4,14 @@ import { ComfyApp } from "/scripts/app.js";
|
|||||||
|
|
||||||
export class ClipspaceDialog extends ComfyDialog {
|
export class ClipspaceDialog extends ComfyDialog {
|
||||||
static items = [];
|
static items = [];
|
||||||
static is_opened = false; // prevent redundant popup
|
static instance = null;
|
||||||
|
|
||||||
static registerButton(name, callback) {
|
static registerButton(name, contextPredicate, callback) {
|
||||||
const item =
|
const item =
|
||||||
$el("button", {
|
$el("button", {
|
||||||
type: "button",
|
type: "button",
|
||||||
textContent: name,
|
textContent: name,
|
||||||
|
contextPredicate: contextPredicate,
|
||||||
onclick: callback
|
onclick: callback
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -18,59 +19,109 @@ export class ClipspaceDialog extends ComfyDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static invalidatePreview() {
|
static invalidatePreview() {
|
||||||
const img_preview = document.getElementById("clipspace_preview");
|
if(ComfyApp.clipspace && ComfyApp.clipspace.imgs && ComfyApp.clipspace.imgs.length > 0) {
|
||||||
img_preview.src = ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src;
|
const img_preview = document.getElementById("clipspace_preview");
|
||||||
img_preview.style.height = "100px";
|
if(img_preview) {
|
||||||
|
img_preview.src = ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src;
|
||||||
|
img_preview.style.maxHeight = "100%";
|
||||||
|
img_preview.style.maxWidth = "100%";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static invalidate() {
|
||||||
|
if(ClipspaceDialog.instance) {
|
||||||
|
const self = ClipspaceDialog.instance;
|
||||||
|
// allow reconstruct controls when copying from non-image to image content.
|
||||||
|
const children = $el("div.comfy-modal-content",[
|
||||||
|
self.createImgSettings(),
|
||||||
|
// self.createImgPreview(),
|
||||||
|
...self.createButtons()
|
||||||
|
]);
|
||||||
|
|
||||||
|
if(self.element) {
|
||||||
|
// update
|
||||||
|
self.element.removeChild(self.element.firstChild);
|
||||||
|
self.element.appendChild(children);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// new
|
||||||
|
self.element = $el("div.comfy-modal", { parent: document.body }, [children,]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipspaceDialog.invalidatePreview();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.element =
|
|
||||||
$el("div.comfy-modal", { parent: document.body },
|
|
||||||
[$el("div.comfy-modal-content",[
|
|
||||||
this.createImgSelector(),
|
|
||||||
this.createImgPreview(),
|
|
||||||
...this.createButtons()]),]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createButtons() {
|
createButtons(self) {
|
||||||
const buttons = [];
|
const buttons = [];
|
||||||
|
|
||||||
for(let idx in ClipspaceDialog.items) {
|
for(let idx in ClipspaceDialog.items) {
|
||||||
const item = ClipspaceDialog.items[idx];
|
const item = ClipspaceDialog.items[idx];
|
||||||
buttons.push(ClipspaceDialog.items[idx]);
|
if(!item.contextPredicate || item.contextPredicate())
|
||||||
|
buttons.push(ClipspaceDialog.items[idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
buttons.push(
|
buttons.push(
|
||||||
$el("button", {
|
$el("button", {
|
||||||
type: "button",
|
type: "button",
|
||||||
textContent: "Close",
|
textContent: "Close",
|
||||||
onclick: () => {
|
onclick: () => { this.close(); }
|
||||||
ClipspaceDialog.is_opened = false;
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
createImgSelector() {
|
createImgSettings() {
|
||||||
if(ComfyApp.clipspace.imgs != undefined) {
|
if(ComfyApp.clipspace.imgs) {
|
||||||
const combo_items = [];
|
const combo_items = [];
|
||||||
const imgs = ComfyApp.clipspace.imgs;
|
const imgs = ComfyApp.clipspace.imgs;
|
||||||
|
|
||||||
for(let i=0; i < imgs.length; i++) {
|
for(let i=0; i < imgs.length; i++) {
|
||||||
combo_items.push($el("option", {value:i}, [`${i}`]));
|
combo_items.push($el("option", {value:i}, [`${i}`]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const combo = $el("select",
|
const combo1 = $el("select",
|
||||||
{id:"clipspace_img_selector", onchange:(event) => {
|
{id:"clipspace_img_selector", onchange:(event) => {
|
||||||
ComfyApp.clipspace['selectedIndex'] = event.target.selectedIndex;
|
ComfyApp.clipspace['selectedIndex'] = event.target.selectedIndex;
|
||||||
ClipspaceDialog.invalidatePreview();
|
ClipspaceDialog.invalidatePreview();
|
||||||
} }, combo_items);
|
} }, combo_items);
|
||||||
return combo;
|
|
||||||
|
const row1 =
|
||||||
|
$el("tr", {},[
|
||||||
|
$el("td", {}, [$el("font", {color:"white"}, ["Select Image"])]),
|
||||||
|
$el("td", {}, [combo1])
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
const combo2 = $el("select",
|
||||||
|
{id:"clipspace_img_paste_mode", onchange:(event) => {
|
||||||
|
ComfyApp.clipspace['img_paste_mode'] = event.target.value;
|
||||||
|
} },
|
||||||
|
[
|
||||||
|
$el("option", {value:'all'}, 'all'),
|
||||||
|
$el("option", {value:'selected'}, 'selected')
|
||||||
|
]);
|
||||||
|
|
||||||
|
const row2 =
|
||||||
|
$el("tr", {},[
|
||||||
|
$el("td", {}, [$el("font", {color:"white"}, ["Paste Mode"])]),
|
||||||
|
$el("td", {}, [combo2])
|
||||||
|
]);
|
||||||
|
|
||||||
|
const td = $el("td", {align:'center', width:'100px', height:'100px', colSpan:'2'},
|
||||||
|
[ $el("img",{id:"clipspace_preview"},[]) ]
|
||||||
|
);
|
||||||
|
|
||||||
|
const row3 =
|
||||||
|
$el("tr", {}, [td]);
|
||||||
|
|
||||||
|
return $el("table", {}, [row1, row2, row3]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return [];
|
return [];
|
||||||
@ -78,7 +129,7 @@ export class ClipspaceDialog extends ComfyDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createImgPreview() {
|
createImgPreview() {
|
||||||
if(ComfyApp.clipspace.imgs != undefined) {
|
if(ComfyApp.clipspace.imgs) {
|
||||||
return $el("img",{id:"clipspace_preview"});
|
return $el("img",{id:"clipspace_preview"});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -86,10 +137,8 @@ export class ClipspaceDialog extends ComfyDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
ClipspaceDialog.is_opened = true;
|
|
||||||
const img_preview = document.getElementById("clipspace_preview");
|
const img_preview = document.getElementById("clipspace_preview");
|
||||||
img_preview.src = ComfyApp.clipspace.imgs[0].src;
|
ClipspaceDialog.invalidate();
|
||||||
img_preview.style.height = "100px";
|
|
||||||
|
|
||||||
this.element.style.display = "block";
|
this.element.style.display = "block";
|
||||||
}
|
}
|
||||||
@ -100,13 +149,16 @@ app.registerExtension({
|
|||||||
init(app) {
|
init(app) {
|
||||||
app.openClipspace =
|
app.openClipspace =
|
||||||
function () {
|
function () {
|
||||||
if(!ClipspaceDialog.is_opened) {
|
if(!ClipspaceDialog.instance) {
|
||||||
let dlg = new ClipspaceDialog(app);
|
ClipspaceDialog.instance = new ClipspaceDialog(app);
|
||||||
if(ComfyApp.clipspace)
|
ComfyApp.clipspace_invalidate_handler = ClipspaceDialog.invalidate;
|
||||||
dlg.show();
|
}
|
||||||
else
|
|
||||||
app.ui.dialog.show("Clipspace is Empty!");
|
if(ComfyApp.clipspace) {
|
||||||
}
|
ClipspaceDialog.instance.show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
app.ui.dialog.show("Clipspace is Empty!");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -42,7 +42,7 @@ async function uploadMask(filepath, formData) {
|
|||||||
|
|
||||||
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']] = new Image();
|
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']] = new Image();
|
||||||
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src = `view?filename=${filepath.filename}&type=${filepath.type}`;
|
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src = `view?filename=${filepath.filename}&type=${filepath.type}`;
|
||||||
ComfyApp.clipspace.images = [filepath];
|
ComfyApp.clipspace.images[ComfyApp.clipspace['selectedIndex']] = filepath;
|
||||||
|
|
||||||
ClipspaceDialog.invalidatePreview();
|
ClipspaceDialog.invalidatePreview();
|
||||||
}
|
}
|
||||||
@ -562,6 +562,7 @@ app.registerExtension({
|
|||||||
dlg.show();
|
dlg.show();
|
||||||
};
|
};
|
||||||
|
|
||||||
ClipspaceDialog.registerButton("MaskEditor", callback);
|
const context_predicate = () => ComfyApp.clipspace && ComfyApp.clipspace.imgs && ComfyApp.clipspace.imgs.length > 0
|
||||||
|
ClipspaceDialog.registerButton("MaskEditor", context_predicate, callback);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -25,6 +25,7 @@ export class ComfyApp {
|
|||||||
* @type {serialized node object}
|
* @type {serialized node object}
|
||||||
*/
|
*/
|
||||||
static clipspace = null;
|
static clipspace = null;
|
||||||
|
static clipspace_invalidate_handler = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.ui = new ComfyUI(this);
|
this.ui = new ComfyUI(this);
|
||||||
@ -164,8 +165,13 @@ export class ComfyApp {
|
|||||||
'imgs': imgs,
|
'imgs': imgs,
|
||||||
'original_imgs': orig_imgs,
|
'original_imgs': orig_imgs,
|
||||||
'images': this.images,
|
'images': this.images,
|
||||||
'selectedIndex': 0
|
'selectedIndex': 0,
|
||||||
|
'img_paste_mode': 'all'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if(ComfyApp.clipspace_invalidate_handler) {
|
||||||
|
ComfyApp.clipspace_invalidate_handler();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -174,31 +180,52 @@ export class ComfyApp {
|
|||||||
{
|
{
|
||||||
content: "Paste (Clipspace)",
|
content: "Paste (Clipspace)",
|
||||||
callback: () => {
|
callback: () => {
|
||||||
if(ComfyApp.clipspace != null) {
|
if(ComfyApp.clipspace) {
|
||||||
// image paste
|
// image paste
|
||||||
if(ComfyApp.clipspace.imgs != undefined && this.imgs != undefined && this.widgets != null) {
|
if(ComfyApp.clipspace.imgs && this.imgs) {
|
||||||
var filename = "";
|
var filename = "";
|
||||||
if(this.images && ComfyApp.clipspace.images) {
|
if(this.images && ComfyApp.clipspace.images) {
|
||||||
this.images = ComfyApp.clipspace.images;
|
if(ComfyApp.clipspace['img_paste_mode'] == 'selected') {
|
||||||
|
app.nodeOutputs[this.id + ""].images = this.images = [ComfyApp.clipspace.images[ComfyApp.clipspace['selectedIndex']]];
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
app.nodeOutputs[this.id + ""].images = this.images = ComfyApp.clipspace.images;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ComfyApp.clipspace.images != undefined) {
|
if(ComfyApp.clipspace.imgs) {
|
||||||
const clip_image = ComfyApp.clipspace.images[0];
|
// deep-copy to cut link with clipspace
|
||||||
|
if(ComfyApp.clipspace['img_paste_mode'] == 'selected') {
|
||||||
|
const img = new Image();
|
||||||
|
img.src = ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src;
|
||||||
|
this.imgs = [img];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const imgs = [];
|
||||||
|
for(let i=0; i<ComfyApp.clipspace.imgs.length; i++) {
|
||||||
|
imgs[i] = new Image();
|
||||||
|
imgs[i].src = ComfyApp.clipspace.imgs[i].src;
|
||||||
|
this.imgs = imgs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ComfyApp.clipspace.images) {
|
||||||
|
const clip_image = ComfyApp.clipspace.images[ComfyApp.clipspace['selectedIndex']];
|
||||||
if(clip_image.subfolder != '')
|
if(clip_image.subfolder != '')
|
||||||
filename = `${clip_image.subfolder}/`;
|
filename = `${clip_image.subfolder}/`;
|
||||||
filename += `${clip_image.filename} [${clip_image.type}]`;
|
filename += `${clip_image.filename} [${clip_image.type}]`;
|
||||||
}
|
}
|
||||||
else if(ComfyApp.clipspace.widgets != undefined) {
|
else if(ComfyApp.clipspace.widgets) {
|
||||||
const index_in_clip = ComfyApp.clipspace.widgets.findIndex(obj => obj.name === 'image');
|
const index_in_clip = ComfyApp.clipspace.widgets.findIndex(obj => obj.name === 'image');
|
||||||
if(index_in_clip >= 0) {
|
if(index_in_clip >= 0) {
|
||||||
filename = `${ComfyApp.clipspace.widgets[index_in_clip].value}`;
|
filename = `${ComfyApp.clipspace.widgets[index_in_clip].value}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const index = this.widgets.findIndex(obj => obj.name === 'image');
|
// for Load Image node.
|
||||||
if(index >= 0 && filename != "" && ComfyApp.clipspace.imgs != undefined) {
|
const index = this.widgets.findIndex(obj => obj.name === 'image');
|
||||||
this.imgs = ComfyApp.clipspace.imgs;
|
if(index >= 0 && filename != "") {
|
||||||
|
|
||||||
this.widgets[index].value = filename;
|
this.widgets[index].value = filename;
|
||||||
if(this.widgets_values != undefined) {
|
if(this.widgets_values != undefined) {
|
||||||
this.widgets_values[index] = filename;
|
this.widgets_values[index] = filename;
|
||||||
@ -207,7 +234,7 @@ export class ComfyApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ensure render after update widget_value
|
// ensure render after update widget_value
|
||||||
if(ComfyApp.clipspace.widgets != null && this.widgets != null) {
|
if(ComfyApp.clipspace.widgets && this.widgets) {
|
||||||
ComfyApp.clipspace.widgets.forEach(({ type, name, value }) => {
|
ComfyApp.clipspace.widgets.forEach(({ type, name, value }) => {
|
||||||
const prop = Object.values(this.widgets).find(obj => obj.type === type && obj.name === name);
|
const prop = Object.values(this.widgets).find(obj => obj.type === type && obj.name === name);
|
||||||
if (prop && prop.type != 'button') {
|
if (prop && prop.type != 'button') {
|
||||||
@ -216,6 +243,8 @@ export class ComfyApp {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.graph.setDirtyCanvas(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user