Fixes for UI

This commit is contained in:
space-nuko
2023-05-18 01:23:10 -05:00
parent 2071e51827
commit 6e3748c114
8 changed files with 73 additions and 435 deletions

View File

@@ -82,6 +82,7 @@ export default class ComfyGraphCanvas extends LGraphCanvas {
let state = get(queueState);
let ss = get(selectionState);
const isRunningNode = node.id === state.runningNodeID
let color = null;
let thickness = 1;
@@ -92,16 +93,22 @@ export default class ComfyGraphCanvas extends LGraphCanvas {
if (ss.currentHoveredNodes.has(node.id)) {
color = "lightblue";
}
else if (node.id === +state.runningNodeID) {
else if (isRunningNode) {
color = "#0f0";
}
if (color) {
this.drawNodeOutline(node, ctx, state.progress, size, fgColor, bgColor, color, thickness)
this.drawNodeOutline(node, ctx, size, fgColor, bgColor, color, thickness)
}
if (isRunningNode && state.progress) {
ctx.fillStyle = "green";
ctx.fillRect(0, 0, size[0] * (state.progress.value / state.progress.max), 6);
ctx.fillStyle = bgColor;
}
}
private drawNodeOutline(node: LGraphNode, ctx: CanvasRenderingContext2D, progress?: Progress, size: Vector2, fgColor: string, bgColor: string, outlineColor: string, outlineThickness: number) {
private drawNodeOutline(node: LGraphNode, ctx: CanvasRenderingContext2D, size: Vector2, fgColor: string, bgColor: string, outlineColor: string, outlineThickness: number) {
const shape = node.shape || BuiltInSlotShape.ROUND_SHAPE;
ctx.lineWidth = outlineThickness;
ctx.globalAlpha = 0.8;
@@ -131,12 +138,6 @@ export default class ComfyGraphCanvas extends LGraphCanvas {
ctx.stroke();
ctx.strokeStyle = fgColor;
ctx.globalAlpha = 1;
if (progress) {
ctx.fillStyle = "green";
ctx.fillRect(0, 0, size[0] * (progress.value / progress.max), 6);
ctx.fillStyle = bgColor;
}
}
private alignToGrid(node: LGraphNode, ctx: CanvasRenderingContext2D) {

View File

@@ -137,45 +137,22 @@ export class ImageViewer {
}
}
setupGalleryImageForLightbox(e: HTMLImageElement) {
if (e.dataset.modded === "true")
showLightbox(source: HTMLImageElement) {
const initiallyZoomed = true
this.modalZoomSet(this.modalImage, initiallyZoomed)
const galleryElem = source.closest<HTMLDivElement>("div.block")
console.debug("[ImageViewer] showModal", event, source, galleryElem);
if (!galleryElem || ImageViewer.all_gallery_buttons(galleryElem).length === 0) {
console.error("No buttons found on gallery element!", galleryElem)
return;
}
e.dataset.modded = "true";
e.style.cursor = 'pointer'
e.style.userSelect = 'none'
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
// For Firefox, listening on click first switched to next image then shows the lightbox.
// If you know how to fix this without switching to mousedown event, please.
// For other browsers the event is click to make it possiblr to drag picture.
var event = isFirefox ? 'mousedown' : 'click'
e.addEventListener(event, (evt) => {
// if (!opts.js_modal_lightbox || evt.button != 0) return;
const initiallyZoomed = true
this.modalZoomSet(this.modalImage, initiallyZoomed)
evt.preventDefault()
const source = evt.target as HTMLImageElement;
const galleryElem = source.closest<HTMLDivElement>("div.block")
console.debug("[ImageViewer] showModal", event, source, galleryElem);
if (!galleryElem || ImageViewer.all_gallery_buttons(galleryElem).length === 0) {
console.error("No buttons found on gallery element!", galleryElem)
return;
}
let urls = ImageViewer.get_gallery_urls(galleryElem)
const [_currentButton, index] = ImageViewer.selected_gallery_button(galleryElem)
console.warn("Gallery!", index, urls, galleryElem)
this.showModal(urls, index, galleryElem)
evt.stopPropagation();
}, true);
let urls = ImageViewer.get_gallery_urls(galleryElem)
const [_currentButton, index] = ImageViewer.selected_gallery_button(galleryElem)
console.warn("Gallery!", index, urls, galleryElem)
this.showModal(urls, index, galleryElem)
}
modalZoomSet(modalImage: HTMLImageElement, enable: boolean) {

View File

@@ -65,9 +65,11 @@
dateStr = formatDate(date);
}
const subgraphs: string[] | null = entry.extraData?.extra_pnginfo?.comfyBoxSubgraphs;
let message = "Prompt";
if (entry.extraData.subgraphs)
message = `Prompt: ${entry.extraData.subgraphs.join(', ')}`
if (subgraphs?.length > 0)
message = `Prompt: ${subgraphs.join(', ')}`
let submessage = `Nodes: ${Object.keys(entry.prompt).length}`
if (Object.keys(entry.outputs).length > 0) {
@@ -156,12 +158,14 @@
}
let showModal = false;
let expandAll = false;
let selectedPrompt = null;
let selectedImages = [];
function showPrompt(entry: QueueUIEntry, e: MouseEvent) {
selectedPrompt = entry.entry.prompt;
selectedImages = entry.images;
showModal = true;
expandAll = false
}
$: if(!showModal)
@@ -180,8 +184,16 @@
<h1 style="padding-bottom: 1rem;">Prompt Details</h1>
</div>
{#if selectedPrompt}
<PromptDisplay prompt={selectedPrompt} images={selectedImages} />
<PromptDisplay prompt={selectedPrompt} images={selectedImages} {expandAll} />
{/if}
<div slot="buttons" let:closeDialog>
<Button variant="secondary" on:click={closeDialog}>
Close
</Button>
<Button variant="secondary" on:click={() => (expandAll = !expandAll)}>
Expand All
</Button>
</div>
</Modal>
<div class="queue">

View File

@@ -25,6 +25,7 @@
}
function doClose() {
showModal = false;
dialog.close();
dispatch("close")
}
@@ -41,7 +42,7 @@
<slot name="header" />
<slot />
<div class="button-row">
<slot name="buttons">
<slot name="buttons" {closeDialog}>
<!-- svelte-ignore a11y-autofocus -->
<Button variant="secondary" on:click={doClose}>Close</Button>
</slot>

View File

@@ -6,16 +6,20 @@
import { JSON as JSONIcon, Copy, Check } from "@gradio/icons";
import Accordion from "$lib/components/gradio/app/Accordion.svelte";
import Gallery from "$lib/components/gradio/gallery/Gallery.svelte";
import type { Styles } from "@gradio/utils";
import { ImageViewer } from "$lib/ImageViewer";
import type { Styles } from "@gradio/utils";
const splitLength = 50;
export let prompt: SerializedPromptInputsAll;
export let images: string[] = [];
export let isMobile: boolean = false;
export let expandAll: boolean = false;
let galleryStyle: Styles = {
grid_cols: [2],
object_fit: "cover",
height: "var(--size-96)"
}
function isInputLink(input: SerializedPromptInput): boolean {
@@ -59,6 +63,11 @@
copyFeedback(nodeID, inputName);
}
}
function onGalleryImageClicked(e: CustomEvent<HTMLImageElement>) {
// TODO dialog renders over it
// ImageViewer.instance.showLightbox(e.detail)
}
</script>
<div class="prompt-display">
@@ -70,7 +79,7 @@
{#if filtered.length > 0}
<div class="accordion">
<Block padding={true}>
<Accordion label="Node {i+1}: {classType}" open={false}>
<Accordion label="Node {i+1}: {classType}" open={expandAll}>
{#each filtered as [inputName, input]}
<Block>
<button class="copy-button" on:click={() => handleCopy(nodeID, inputName, input)}>
@@ -121,6 +130,7 @@
style={galleryStyle}
root={""}
root_url={""}
on:clicked={onGalleryImageClicked}
/>
</Block>
</div>

View File

@@ -26,6 +26,7 @@
const dispatch = createEventDispatcher<{
select: SelectData;
clicked: HTMLImageElement
}>();
// tracks whether the value of the gallery was reset
@@ -142,6 +143,14 @@
let height = 0;
let window_height = 0;
let imgElem = null;
function onClick() {
// selected_image = next
if (imgElem)
dispatch("clicked", imgElem)
}
</script>
<svelte:window bind:innerHeight={window_height} />
@@ -166,7 +175,8 @@
<ModifyUpload on:clear={() => (selected_image = null)} />
<img
on:click={() => (selected_image = next)}
on:click={onClick}
bind:this={imgElem}
src={_value[selected_image][0].data}
alt={_value[selected_image][1] || ""}
title={_value[selected_image][1] || null}

View File

@@ -49,7 +49,7 @@
let mobileLightbox = null;
function showMobileLightbox(event: Event) {
function showMobileLightbox(source: HTMLImageElement) {
if (!f7)
return
@@ -58,16 +58,14 @@
mobileLightbox = null;
}
const source = (event.target || event.srcElement) as HTMLImageElement;
const galleryElem = source.closest<HTMLDivElement>("div.block")
console.debug("[ImageViewer] showModal", event, source, galleryElem);
console.debug("[ImageViewer] showModal", source, galleryElem);
if (!galleryElem || ImageViewer.all_gallery_buttons(galleryElem).length === 0) {
console.error("No buttons found on gallery element!", galleryElem)
return;
}
const allGalleryButtons = ImageViewer.all_gallery_buttons(galleryElem);
const selectedSource = source.src
const images = allGalleryButtons.map(button => {
return {
@@ -84,47 +82,18 @@
type: 'popup',
});
mobileLightbox.open(selected_image)
event.stopPropagation()
}
function setupImageForMobileLightbox(e: HTMLImageElement) {
if (e.dataset.modded === "true")
return;
e.dataset.modded = "true";
e.style.cursor = "pointer";
e.style.userSelect = "none";
var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
// For Firefox, listening on click first switched to next image then shows the lightbox.
// If you know how to fix this without switching to mousedown event, please.
// For other browsers the event is click to make it possiblr to drag picture.
var event = isFirefox ? 'mousedown' : 'click'
e.addEventListener(event, (evt) => {
evt.preventDefault()
showMobileLightbox(evt)
}, true);
function onClicked(e: CustomEvent<HTMLImageElement>) {
if (isMobile) {
showMobileLightbox(e.detail)
}
else {
ImageViewer.instance.showLightbox(e.detail)
}
}
function onSelect(e: CustomEvent<GradioSelectData>) {
// Setup lightbox
// Wait for gradio gallery to show the large preview image, if no timeout then
// the event might fire too early
const callback = isMobile ? setupImageForMobileLightbox
: ImageViewer.instance.setupGalleryImageForLightbox.bind(ImageViewer.instance)
setTimeout(() => {
const images = element.querySelectorAll<HTMLImageElement>('div.block div > img')
if (images != null) {
images.forEach(callback);
}
ImageViewer.instance.refreshImages();
}, 200)
// Update index
node.setProperty("index", e.detail.index as number)
}
@@ -176,6 +145,7 @@
root={""}
root_url={""}
on:select={onSelect}
on:clicked={onClicked}
bind:imageWidth={$imageWidth}
bind:imageHeight={$imageHeight}
bind:selected_image