Copy action and button
This commit is contained in:
44
src/lib/widgets/ButtonWidget.svelte
Normal file
44
src/lib/widgets/ButtonWidget.svelte
Normal file
@@ -0,0 +1,44 @@
|
||||
<script lang="ts">
|
||||
import type { ComfyButtonNode } from "$lib/nodes/ComfyWidgetNodes";
|
||||
import type { ComfySliderNode } from "$lib/nodes/index";
|
||||
import { type WidgetLayout } from "$lib/stores/layoutState";
|
||||
import { Button } from "@gradio/button";
|
||||
import { get, type Writable } from "svelte/store";
|
||||
export let widget: WidgetLayout | null = null;
|
||||
let node: ComfyButtonNode | null = null;
|
||||
let nodeValue: Writable<boolean> | null = null;
|
||||
let propsChanged: Writable<boolean> | null = null;
|
||||
|
||||
$: widget && setNodeValue(widget);
|
||||
|
||||
function setNodeValue(widget: WidgetLayout) {
|
||||
if (widget) {
|
||||
node = widget.node as ComfyButtonNode
|
||||
nodeValue = node.value;
|
||||
propsChanged = node.propsChanged;
|
||||
}
|
||||
};
|
||||
|
||||
function onClick(e: MouseEvent) {
|
||||
node.onClick();
|
||||
}
|
||||
|
||||
const style = {
|
||||
full_width: "100%"
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="wrapper gr-button">
|
||||
{#if node !== null}
|
||||
<Button on:click={onClick} variant="primary" {style}>
|
||||
{widget.attrs.title}
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
padding: 2px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -1,56 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { ImageViewer } from "$lib/ImageViewer";
|
||||
import { Block } from "@gradio/atoms";
|
||||
import { Gallery } from "@gradio/gallery";
|
||||
import type { Styles } from "@gradio/utils";
|
||||
|
||||
export let item: WidgetUIState | null = null;
|
||||
let itemValue: WidgetUIStateStore | null = null; // stores must be declared at top level
|
||||
|
||||
$: if(item) {
|
||||
itemValue = item.value;
|
||||
}
|
||||
|
||||
let style: Styles = {
|
||||
// grid_cols: [2],
|
||||
grid: [3],
|
||||
// object_fit: "cover",
|
||||
}
|
||||
let element: HTMLDivElement;
|
||||
|
||||
function updateForLightbox() {
|
||||
// Wait for gradio gallery to show the large preview image, if no timeout then
|
||||
// the event might fire too early
|
||||
setTimeout(() => {
|
||||
const images = element.querySelectorAll<HTMLImageElement>('div.block div > img')
|
||||
if (images != null) {
|
||||
images.forEach(ImageViewer.instance.setupImageForLightbox.bind(ImageViewer.instance));
|
||||
}
|
||||
ImageViewer.instance.updateOnBackgroundChange();
|
||||
}, 200)
|
||||
}
|
||||
|
||||
</script>
|
||||
<div class="wrapper comfy-gallery-widget gr-gallery" bind:this={element}>
|
||||
{#if item && itemValue}
|
||||
<Block variant="solid" padding={false}>
|
||||
<Gallery
|
||||
bind:value={$itemValue}
|
||||
label={item.widget.name}
|
||||
show_label={true}
|
||||
{style}
|
||||
root={""}
|
||||
root_url={""}
|
||||
on:select={updateForLightbox}
|
||||
/>
|
||||
</Block>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
padding: 2px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { get } from "svelte/store";
|
||||
import type { WidgetPanelOptions } from "@litegraph-ts/core";
|
||||
import ComfyWidget from "./ComfyWidget";
|
||||
import type { ComfyImageResult } from "$lib/nodes/ComfySaveImageNode";
|
||||
import queueState from "$lib/stores/queueState";
|
||||
|
||||
export type ComfyGalleryEntry = [string, string | null]; // <img> src and alt/title, gradio format
|
||||
|
||||
export interface ComfyGalleryWidgetOptions extends WidgetPanelOptions {
|
||||
}
|
||||
|
||||
export default class ComfyGalleryWidget extends ComfyWidget<ComfyGalleryWidgetOptions, ComfyGalleryEntry[]> {
|
||||
override type = "comfy/gallery";
|
||||
override isVirtual = true;
|
||||
|
||||
addImages(images: ComfyImageResult[]) {
|
||||
this.setValue(this.value.concat(images));
|
||||
}
|
||||
|
||||
override afterQueued() {
|
||||
let queue = get(queueState)
|
||||
if (!(typeof queue.queueRemaining === "number" && queue.queueRemaining > 1)) {
|
||||
this.setValue([])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
import type { IEnumWidget, IEnumWidgetOptions, INumberWidget, LGraphNode, WidgetPanelOptions } from "@litegraph-ts/core";
|
||||
import ComfyWidget from "./ComfyWidget";
|
||||
import type { ComfyImageResult } from "$lib/nodes/ComfySaveImageNode";
|
||||
import type ComfyGraphNode from "$lib/nodes/ComfyGraphNode";
|
||||
|
||||
export interface ComfyValueControlWidgetOptions extends IEnumWidgetOptions {
|
||||
}
|
||||
|
||||
export default class ComfyValueControlWidget extends ComfyWidget<ComfyValueControlWidgetOptions, string> {
|
||||
override type = "combo";
|
||||
targetWidget: INumberWidget;
|
||||
|
||||
constructor(name: string, value: string, node: ComfyGraphNode, targetWidget: INumberWidget) {
|
||||
super(name, value, node)
|
||||
this.targetWidget = targetWidget;
|
||||
this.options = { values: ["fixed", "increment", "decrement", "randomize"], serialize: false };
|
||||
}
|
||||
|
||||
override afterQueued() {
|
||||
var v = this.value;
|
||||
|
||||
let min = this.targetWidget.options.min;
|
||||
let max = this.targetWidget.options.max;
|
||||
// limit to something that javascript can handle
|
||||
max = Math.min(1125899906842624, max);
|
||||
min = Math.max(-1125899906842624, min);
|
||||
let range = (max - min) / (this.targetWidget.options.step);
|
||||
|
||||
//adjust values based on valueControl Behaviour
|
||||
switch (v) {
|
||||
case "fixed":
|
||||
break;
|
||||
case "increment":
|
||||
this.targetWidget.value += this.targetWidget.options.step;
|
||||
break;
|
||||
case "decrement":
|
||||
this.targetWidget.value -= this.targetWidget.options.step;
|
||||
break;
|
||||
case "randomize":
|
||||
this.targetWidget.value = Math.floor(Math.random() * range) * (this.targetWidget.options.step) + min;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*check if values are over or under their respective
|
||||
* ranges and set them to min or max.*/
|
||||
if (this.targetWidget.value < min)
|
||||
this.targetWidget.value = min;
|
||||
|
||||
if (this.targetWidget.value > max)
|
||||
this.targetWidget.value = max;
|
||||
|
||||
// nodeState.widgetStateChanged(this.node.id, this.targetWidget);
|
||||
}
|
||||
}
|
||||
78
src/lib/widgets/GalleryWidget.svelte
Normal file
78
src/lib/widgets/GalleryWidget.svelte
Normal file
@@ -0,0 +1,78 @@
|
||||
<script lang="ts">
|
||||
import { ImageViewer } from "$lib/ImageViewer";
|
||||
import { Block } from "@gradio/atoms";
|
||||
import { Gallery } from "@gradio/gallery";
|
||||
import type { Styles } from "@gradio/utils";
|
||||
import type { WidgetLayout } from "$lib/stores/layoutState";
|
||||
import type { Writable } from "svelte/store";
|
||||
import type { ComfyGalleryNode } from "$lib/nodes/ComfyWidgetNodes";
|
||||
import type { FileData as GradioFileData } from "@gradio/upload";
|
||||
|
||||
export let widget: WidgetLayout | null = null;
|
||||
let node: ComfyGalleryNode | null = null;
|
||||
let nodeValue: Writable<GradioFileData[]> | null = null;
|
||||
let propsChanged: Writable<boolean> | null = null;
|
||||
let option: number | null = null;
|
||||
|
||||
$: widget && setNodeValue(widget);
|
||||
|
||||
function setNodeValue(widget: WidgetLayout) {
|
||||
if (widget) {
|
||||
node = widget.node as ComfyGalleryNode
|
||||
nodeValue = node.value;
|
||||
propsChanged = node.propsChanged;
|
||||
}
|
||||
};
|
||||
|
||||
let style: Styles = {
|
||||
// grid_cols: [2],
|
||||
grid: [3],
|
||||
// object_fit: "cover",
|
||||
}
|
||||
let element: HTMLDivElement;
|
||||
|
||||
function updateForLightbox() {
|
||||
// Wait for gradio gallery to show the large preview image, if no timeout then
|
||||
// the event might fire too early
|
||||
setTimeout(() => {
|
||||
const images = element.querySelectorAll<HTMLImageElement>('div.block div > img')
|
||||
if (images != null) {
|
||||
images.forEach(ImageViewer.instance.setupImageForLightbox.bind(ImageViewer.instance));
|
||||
}
|
||||
ImageViewer.instance.updateOnBackgroundChange();
|
||||
}, 200)
|
||||
}
|
||||
|
||||
</script>
|
||||
<div class="wrapper comfy-gallery-widget gr-gallery" bind:this={element}>
|
||||
{#if widget && node && nodeValue}
|
||||
<Block variant="solid" padding={false}>
|
||||
<div class="padding">
|
||||
<Gallery
|
||||
bind:value={$nodeValue}
|
||||
label={widget.attrs.title}
|
||||
show_label={true}
|
||||
{style}
|
||||
root={""}
|
||||
root_url={""}
|
||||
on:select={updateForLightbox}
|
||||
/>
|
||||
</div>
|
||||
</Block>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
padding: 2px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.padding {
|
||||
height: 30rem;
|
||||
}
|
||||
|
||||
.wrapper :global(button.thumbnail-lg) {
|
||||
width: var(--size-32);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user