Add clipboard source toggle for paste operations

Introduces a clipboardPreference setting to choose between system clipboard and ComfyUI Clipspace as the source for paste operations in CanvasLayers. Adds a UI button in CanvasView to toggle the clipboard source, improving user control over paste behavior.
This commit is contained in:
Dariusz L
2025-06-30 01:14:13 +02:00
parent 6718198a27
commit 2624cf02a2
2 changed files with 80 additions and 36 deletions

View File

@@ -27,6 +27,7 @@ export class CanvasLayers {
this.blendOpacity = 100;
this.isAdjustingOpacity = false;
this.internalClipboard = [];
this.clipboardPreference = 'system'; // 'system', 'clipspace'
}
async copySelectedLayers() {
@@ -86,46 +87,66 @@ export class CanvasLayers {
async handlePaste(addMode = 'mouse') {
try {
// 1. FIRST: Check Internal Clipboard
log.info(`Paste operation started with preference: ${this.clipboardPreference}`);
// ALWAYS FIRST: Check Internal Clipboard
if (this.internalClipboard.length > 0) {
log.info("Pasting from internal clipboard");
this.pasteLayers();
return;
}
// 2. SECOND: Try ComfyUI Clipspace
try {
log.info("Attempting to paste from ComfyUI Clipspace");
const clipspaceResult = ComfyApp.pasteFromClipspace(this.canvas.node);
// Check if clipspace operation was successful and node has images
if (this.canvas.node.imgs && this.canvas.node.imgs.length > 0) {
const clipspaceImage = this.canvas.node.imgs[0];
if (clipspaceImage && clipspaceImage.src) {
log.info("Successfully got image from ComfyUI Clipspace");
const img = new Image();
img.onload = async () => {
await this.addLayerWithImage(img, {}, addMode);
};
img.src = clipspaceImage.src;
return;
}
// SECOND: Use preference setting
if (this.clipboardPreference === 'clipspace') {
log.info("Attempting paste from ComfyUI Clipspace");
if (!await this.tryClipspacePaste(addMode)) {
log.info("No image found in ComfyUI Clipspace");
}
log.info("No image found in ComfyUI Clipspace, trying system clipboard");
} catch (clipspaceError) {
log.warn("ComfyUI Clipspace paste failed:", clipspaceError);
} else if (this.clipboardPreference === 'system') {
log.info("Attempting paste from system clipboard");
await this.trySystemClipboardPaste(addMode);
}
// 3. THIRD: Try System Clipboard
if (!navigator.clipboard?.read) {
log.info("Browser does not support clipboard read API. No more options available.");
return;
}
} catch (err) {
log.error("Paste operation failed:", err);
}
}
async tryClipspacePaste(addMode) {
try {
log.info("Attempting to paste from ComfyUI Clipspace");
const clipspaceResult = ComfyApp.pasteFromClipspace(this.canvas.node);
// Check if clipspace operation was successful and node has images
if (this.canvas.node.imgs && this.canvas.node.imgs.length > 0) {
const clipspaceImage = this.canvas.node.imgs[0];
if (clipspaceImage && clipspaceImage.src) {
log.info("Successfully got image from ComfyUI Clipspace");
const img = new Image();
img.onload = async () => {
await this.addLayerWithImage(img, {}, addMode);
};
img.src = clipspaceImage.src;
return true;
}
}
return false;
} catch (clipspaceError) {
log.warn("ComfyUI Clipspace paste failed:", clipspaceError);
return false;
}
}
async trySystemClipboardPaste(addMode) {
if (!navigator.clipboard?.read) {
log.info("Browser does not support clipboard read API");
return false;
}
try {
log.info("Attempting to paste from system clipboard");
const clipboardItems = await navigator.clipboard.read();
let imagePasted = false;
for (const item of clipboardItems) {
const imageType = item.types.find(type => type.startsWith('image/'));
@@ -140,18 +161,16 @@ export class CanvasLayers {
img.src = event.target.result;
};
reader.readAsDataURL(blob);
imagePasted = true;
log.info("Successfully pasted image from system clipboard");
break;
return true;
}
}
if (!imagePasted) {
log.info("No image found in system clipboard. Paste operation completed with no result.");
}
} catch (err) {
log.error("Paste operation failed:", err);
log.info("No image found in system clipboard");
return false;
} catch (error) {
log.warn("System clipboard paste failed:", error);
return false;
}
}

View File

@@ -563,6 +563,31 @@ async function createCanvasWidget(node, widget, app) {
canvas.canvasLayers.handlePaste(addMode);
}
}),
$el("button.painter-button", {
id: `clipboard-toggle-${node.id}`,
textContent: "📋 System",
title: "Toggle clipboard source: System Clipboard",
style: {
minWidth: "100px",
fontSize: "11px",
backgroundColor: "#4a4a4a"
},
onclick: (e) => {
const button = e.target;
if (canvas.canvasLayers.clipboardPreference === 'system') {
canvas.canvasLayers.clipboardPreference = 'clipspace';
button.textContent = "📋 Clipspace";
button.title = "Toggle clipboard source: ComfyUI Clipspace";
button.style.backgroundColor = "#4a6cd4";
} else {
canvas.canvasLayers.clipboardPreference = 'system';
button.textContent = "📋 System";
button.title = "Toggle clipboard source: System Clipboard";
button.style.backgroundColor = "#4a4a4a";
}
log.info(`Clipboard preference toggled to: ${canvas.canvasLayers.clipboardPreference}`);
}
}),
]),
$el("div.painter-separator"),