Update mode for gallery, ranges for properties
This commit is contained in:
Submodule litegraph updated: 6cbae97b3c...cd24bc7356
@@ -50,6 +50,7 @@ export class ImageViewer {
|
||||
showModal(event: Event) {
|
||||
const source = (event.target || event.srcElement) 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;
|
||||
|
||||
@@ -163,6 +163,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
:global(.label-wrap > span:not(.icon)) {
|
||||
color: var(--block-title-text-color);
|
||||
}
|
||||
|
||||
.handle {
|
||||
cursor: grab;
|
||||
z-index: 99999;
|
||||
|
||||
@@ -590,7 +590,7 @@ export default class ComfyApp {
|
||||
for (let i = 0; i < batchCount; i++) {
|
||||
for (const node of this.lGraph._nodes_in_order) {
|
||||
if ("beforeQueued" in node) {
|
||||
(node as ComfyGraphNode).beforeQueued();
|
||||
(node as ComfyGraphNode).beforeQueued(tag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,7 +613,7 @@ export default class ComfyApp {
|
||||
for (const n of p.workflow.nodes) {
|
||||
const node = this.lGraph.getNodeById(n.id);
|
||||
if ("afterQueued" in node) {
|
||||
(node as ComfyGraphNode).afterQueued(p);
|
||||
(node as ComfyGraphNode).afterQueued(p, tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
export let value: number = 0;
|
||||
export let min: number = -1024
|
||||
export let max: number = 1024
|
||||
export let step: number = 1;
|
||||
export let name: string = "";
|
||||
export let disabled: boolean = false;
|
||||
@@ -27,7 +29,7 @@
|
||||
<label class="number-wrapper">
|
||||
<BlockTitle>{name}</BlockTitle>
|
||||
<div class="number">
|
||||
<input type="number" bind:value {step} {disabled}>
|
||||
<input type="number" bind:value {min} {max} {step} {disabled}>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
|
||||
@@ -248,7 +248,9 @@
|
||||
<ComfyNumberProperty
|
||||
name={spec.name}
|
||||
value={getAttribute(target, spec)}
|
||||
step={1}
|
||||
step={spec.step || 1}
|
||||
min={spec.min || -1024}
|
||||
max={spec.max || 1024}
|
||||
disabled={!$uiState.uiUnlocked || !spec.editable}
|
||||
on:change={(e) => updateAttribute(spec, target, e.detail)}
|
||||
/>
|
||||
@@ -285,7 +287,9 @@
|
||||
<ComfyNumberProperty
|
||||
name={spec.name}
|
||||
value={node.properties[spec.name] || spec.defaultValue}
|
||||
step={1}
|
||||
step={spec.step || 1}
|
||||
min={spec.min || -1024}
|
||||
max={spec.max || 1024}
|
||||
disabled={!$uiState.uiUnlocked || !spec.editable}
|
||||
on:change={(e) => updateProperty(spec, e.detail)}
|
||||
/>
|
||||
@@ -321,7 +325,9 @@
|
||||
<ComfyNumberProperty
|
||||
name={spec.name}
|
||||
value={getVar(node, spec)}
|
||||
step={1}
|
||||
step={spec.step || 1}
|
||||
min={spec.min || -1024}
|
||||
max={spec.max || 1024}
|
||||
disabled={!$uiState.uiUnlocked || !spec.editable}
|
||||
on:change={(e) => updateVar(spec, e.detail)}
|
||||
/>
|
||||
@@ -358,7 +364,9 @@
|
||||
<ComfyNumberProperty
|
||||
name={spec.name}
|
||||
value={$layoutState.attrs[spec.name] || spec.defaultValue}
|
||||
step={1}
|
||||
step={spec.step || 1}
|
||||
min={spec.min || -1024}
|
||||
max={spec.max || 1024}
|
||||
disabled={!$uiState.uiUnlocked || !spec.editable}
|
||||
on:change={(e) => updateWorkflowAttribute(spec, e.detail)}
|
||||
/>
|
||||
|
||||
@@ -4,6 +4,8 @@ import { Watch } from "@litegraph-ts/nodes-basic";
|
||||
import type { SerializedPrompt } from "$lib/components/ComfyApp";
|
||||
import { toast } from '@zerodevx/svelte-toast'
|
||||
import type { GalleryOutput } from "./ComfyWidgetNodes";
|
||||
import { get } from "svelte/store";
|
||||
import queueState from "$lib/stores/queueState";
|
||||
|
||||
export interface ComfyQueueEventsProperties extends Record<any, any> {
|
||||
prompt: SerializedPrompt | null
|
||||
@@ -32,14 +34,27 @@ export class ComfyQueueEvents extends ComfyGraphNode {
|
||||
this.setOutputData(2, this.properties.prompt)
|
||||
}
|
||||
|
||||
override beforeQueued() {
|
||||
this.setProperty("value", null)
|
||||
this.triggerSlot(0, "bang")
|
||||
private getActionParams(subgraph: string | null): any {
|
||||
let queue = get(queueState)
|
||||
let remaining = 0;
|
||||
|
||||
if (typeof queue.queueRemaining === "number")
|
||||
remaining = queue.queueRemaining
|
||||
|
||||
return {
|
||||
queueRemaining: remaining,
|
||||
subgraph
|
||||
}
|
||||
}
|
||||
|
||||
override afterQueued(p: SerializedPrompt) {
|
||||
override beforeQueued(subgraph: string | null) {
|
||||
this.setProperty("value", null)
|
||||
this.triggerSlot(0, this.getActionParams(subgraph))
|
||||
}
|
||||
|
||||
override afterQueued(p: SerializedPrompt, subgraph: string | null) {
|
||||
this.setProperty("value", p)
|
||||
this.triggerSlot(1, "bang")
|
||||
this.triggerSlot(1, this.getActionParams(subgraph))
|
||||
}
|
||||
|
||||
override onSerialize(o: SerializedLGraphNode) {
|
||||
|
||||
@@ -20,8 +20,8 @@ export type DefaultWidgetLayout = {
|
||||
export default class ComfyGraphNode extends LGraphNode {
|
||||
isBackendNode?: boolean;
|
||||
|
||||
beforeQueued?(): void;
|
||||
afterQueued?(prompt: SerializedPrompt): void;
|
||||
beforeQueued?(subgraph: string | null): void;
|
||||
afterQueued?(prompt: SerializedPrompt, subgraph: string | null): void;
|
||||
onExecuted?(output: any): void;
|
||||
|
||||
defaultWidgets?: DefaultWidgetLayout
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LiteGraph, type ContextMenuItem, type LGraphNode, type Vector2, LConnectionKind, LLink, LGraphCanvas, type SlotType, TitleMode, type SlotLayout, LGraph, type INodeInputSlot, type ITextWidget, type INodeOutputSlot, type SerializedLGraphNode, BuiltInSlotType } from "@litegraph-ts/core";
|
||||
import { LiteGraph, type ContextMenuItem, type LGraphNode, type Vector2, LConnectionKind, LLink, LGraphCanvas, type SlotType, TitleMode, type SlotLayout, LGraph, type INodeInputSlot, type ITextWidget, type INodeOutputSlot, type SerializedLGraphNode, BuiltInSlotType, type PropertyLayout } from "@litegraph-ts/core";
|
||||
import ComfyGraphNode from "./ComfyGraphNode";
|
||||
import ComboWidget from "$lib/widgets/ComboWidget.svelte";
|
||||
import RangeWidget from "$lib/widgets/RangeWidget.svelte";
|
||||
@@ -397,13 +397,15 @@ export type GalleryOutputEntry = {
|
||||
}
|
||||
|
||||
export interface ComfyGalleryProperties extends ComfyWidgetProperties {
|
||||
index: number
|
||||
index: number,
|
||||
updateMode: "replace" | "append"
|
||||
}
|
||||
|
||||
export class ComfyGalleryNode extends ComfyWidgetNode<GradioFileData[]> {
|
||||
override properties: ComfyGalleryProperties = {
|
||||
defaultValue: [],
|
||||
index: 0
|
||||
index: 0,
|
||||
updateMode: "replace"
|
||||
}
|
||||
|
||||
static slotLayout: SlotLayout = {
|
||||
@@ -417,6 +419,10 @@ export class ComfyGalleryNode extends ComfyWidgetNode<GradioFileData[]> {
|
||||
]
|
||||
}
|
||||
|
||||
static propertyLayout: PropertyLayout = [
|
||||
{ name: "updateMode", defaultValue: "replace", type: "enum", options: { values: ["replace", "append"] } }
|
||||
]
|
||||
|
||||
override svelteComponentType = GalleryWidget
|
||||
override copyFromInputLink = false;
|
||||
override outputIndex = null;
|
||||
@@ -442,10 +448,14 @@ export class ComfyGalleryNode extends ComfyWidgetNode<GradioFileData[]> {
|
||||
|
||||
const galleryItems: GradioFileData[] = this.convertItems(link.data)
|
||||
|
||||
// const currentValue = get(this.value)
|
||||
// this.setValue(currentValue.concat(galleryItems))
|
||||
if (this.properties.updateMode === "append") {
|
||||
const currentValue = get(this.value)
|
||||
this.setValue(currentValue.concat(galleryItems))
|
||||
}
|
||||
else {
|
||||
this.setValue(galleryItems)
|
||||
}
|
||||
}
|
||||
this.setProperty("index", 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,11 +106,6 @@ export type Attributes = {
|
||||
*/
|
||||
title: string,
|
||||
|
||||
/*
|
||||
* If false, hide the title.
|
||||
*/
|
||||
showTitle: boolean,
|
||||
|
||||
/*
|
||||
* List of classes to apply to the component.
|
||||
*/
|
||||
@@ -203,6 +198,21 @@ export type AttributesSpec = {
|
||||
*/
|
||||
values?: string[],
|
||||
|
||||
/*
|
||||
* If `type` is "number", step for the slider
|
||||
*/
|
||||
step?: number,
|
||||
|
||||
/*
|
||||
* If `type` is "number", min for the slider
|
||||
*/
|
||||
min?: number,
|
||||
|
||||
/*
|
||||
* If `type` is "number", max for the slider
|
||||
*/
|
||||
max?: number,
|
||||
|
||||
/*
|
||||
* Valid `LGraphNode.type`s this property applies to if it's located in a node.
|
||||
* These are like "ui/button", "ui/slider".
|
||||
@@ -379,6 +389,8 @@ const ALL_ATTRIBUTES: AttributesSpecList = [
|
||||
location: "nodeProps",
|
||||
editable: true,
|
||||
defaultValue: 0,
|
||||
min: -2 ^ 16,
|
||||
max: 2 ^ 16,
|
||||
validNodeTypes: ["ui/slider"],
|
||||
},
|
||||
{
|
||||
@@ -387,6 +399,8 @@ const ALL_ATTRIBUTES: AttributesSpecList = [
|
||||
location: "nodeProps",
|
||||
editable: true,
|
||||
defaultValue: 10,
|
||||
min: -2 ^ 16,
|
||||
max: 2 ^ 16,
|
||||
validNodeTypes: ["ui/slider"],
|
||||
},
|
||||
{
|
||||
@@ -395,6 +409,8 @@ const ALL_ATTRIBUTES: AttributesSpecList = [
|
||||
location: "nodeProps",
|
||||
editable: true,
|
||||
defaultValue: 1,
|
||||
min: -2 ^ 16,
|
||||
max: 2 ^ 16,
|
||||
validNodeTypes: ["ui/slider"],
|
||||
},
|
||||
|
||||
@@ -408,6 +424,17 @@ const ALL_ATTRIBUTES: AttributesSpecList = [
|
||||
defaultValue: "bang"
|
||||
},
|
||||
|
||||
// gallery
|
||||
{
|
||||
name: "updateMode",
|
||||
type: "enum",
|
||||
location: "nodeProps",
|
||||
editable: true,
|
||||
validNodeTypes: ["ui/gallery"],
|
||||
values: ["replace", "append"],
|
||||
defaultValue: "replace"
|
||||
},
|
||||
|
||||
// Workflow
|
||||
{
|
||||
name: "defaultSubgraph",
|
||||
@@ -544,7 +571,6 @@ function addContainer(parent: ContainerLayout | null, attrs: Partial<Attributes>
|
||||
attrsChanged: writable(false),
|
||||
attrs: {
|
||||
title: "Container",
|
||||
showTitle: true,
|
||||
direction: "vertical",
|
||||
classes: "",
|
||||
containerVariant: "block",
|
||||
@@ -572,7 +598,6 @@ function addWidget(parent: ContainerLayout, node: ComfyWidgetNode, attrs: Partia
|
||||
attrsChanged: writable(false),
|
||||
attrs: {
|
||||
title: widgetName,
|
||||
showTitle: true,
|
||||
direction: "horizontal",
|
||||
classes: "",
|
||||
flexGrow: 100,
|
||||
|
||||
@@ -299,7 +299,10 @@ div.float {
|
||||
padding: var(--ae-accordion-vertical-padding) var(--ae-accordion-horizontal-padding);
|
||||
border-radius: var(--ae-panel-border-radius);
|
||||
line-height: var(--ae-accordion-line-height);
|
||||
color: var(--ae-label-color);
|
||||
|
||||
> span {
|
||||
color: var(--ae-label-color) !important;
|
||||
}
|
||||
/*pointer-events: none !important;*/
|
||||
}
|
||||
.block.gradio-accordion .hide + .open.label-wrap {
|
||||
@@ -588,14 +591,18 @@ button.primary {
|
||||
border-radius: var(--ae-panel-border-radius) !important;
|
||||
background: var(--ae-input-bg-color) !important;
|
||||
color: var(--ae-input-color) !important;
|
||||
}
|
||||
|
||||
button.secondary:hover,
|
||||
button.primary:hover {
|
||||
&:hover {
|
||||
background: var(--ae-primary-color) !important;
|
||||
color: var(--ae-input-bg-color) !important;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: var(--ae-input-bg-color) !important;
|
||||
color: var(--ae-input-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* Sliders Scrollbars */
|
||||
/**********************/
|
||||
|
||||
Reference in New Issue
Block a user