Image dimensions output for image upload widget
This commit is contained in:
@@ -306,7 +306,6 @@ export class ComfySetNodeModeAction extends ComfyGraphNode {
|
|||||||
} else {
|
} else {
|
||||||
newMode = NodeMode.NEVER;
|
newMode = NodeMode.NEVER;
|
||||||
}
|
}
|
||||||
console.warn("CHANGEMODE", newMode == NodeMode.ALWAYS ? "ALWAYS" : "NEVER", tags, node)
|
|
||||||
node.changeMode(newMode);
|
node.changeMode(newMode);
|
||||||
if ("notifyPropsChanged" in node)
|
if ("notifyPropsChanged" in node)
|
||||||
(node as ComfyWidgetNode).notifyPropsChanged();
|
(node as ComfyWidgetNode).notifyPropsChanged();
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { BuiltInSlotType, LiteGraph, NodeMode, type INodeInputSlot, type SlotLayout, type INodeOutputSlot, LLink, LConnectionKind, type ITextWidget } from "@litegraph-ts/core";
|
import { BuiltInSlotType, LiteGraph, NodeMode, type INodeInputSlot, type SlotLayout, type INodeOutputSlot, LLink, LConnectionKind, type ITextWidget, type SerializedLGraphNode, type IComboWidget } from "@litegraph-ts/core";
|
||||||
import ComfyGraphNode, { type ComfyGraphNodeProperties } from "./ComfyGraphNode";
|
import ComfyGraphNode, { type ComfyGraphNodeProperties } from "./ComfyGraphNode";
|
||||||
import { Watch } from "@litegraph-ts/nodes-basic";
|
import { Watch } from "@litegraph-ts/nodes-basic";
|
||||||
|
|
||||||
|
export type PickFirstMode = "anyActiveLink" | "truthy" | "dataNonNull"
|
||||||
|
|
||||||
export interface ComfyPickFirstNodeProperties extends ComfyGraphNodeProperties {
|
export interface ComfyPickFirstNodeProperties extends ComfyGraphNodeProperties {
|
||||||
acceptNullLinkData: boolean
|
mode: PickFirstMode
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextLetter(s: string): string {
|
function nextLetter(s: string): string {
|
||||||
@@ -20,7 +22,7 @@ function nextLetter(s: string): string {
|
|||||||
export default class ComfyPickFirstNode extends ComfyGraphNode {
|
export default class ComfyPickFirstNode extends ComfyGraphNode {
|
||||||
override properties: ComfyPickFirstNodeProperties = {
|
override properties: ComfyPickFirstNodeProperties = {
|
||||||
tags: [],
|
tags: [],
|
||||||
acceptNullLinkData: false
|
mode: "dataNonNull"
|
||||||
}
|
}
|
||||||
|
|
||||||
static slotLayout: SlotLayout = {
|
static slotLayout: SlotLayout = {
|
||||||
@@ -38,11 +40,13 @@ export default class ComfyPickFirstNode extends ComfyGraphNode {
|
|||||||
private selected: number = -1;
|
private selected: number = -1;
|
||||||
|
|
||||||
displayWidget: ITextWidget;
|
displayWidget: ITextWidget;
|
||||||
|
modeWidget: IComboWidget;
|
||||||
|
|
||||||
constructor(title?: string) {
|
constructor(title?: string) {
|
||||||
super(title);
|
super(title);
|
||||||
this.displayWidget = this.addWidget("text", "Value", "")
|
this.displayWidget = this.addWidget("text", "Value", "")
|
||||||
this.displayWidget.disabled = true;
|
this.displayWidget.disabled = true;
|
||||||
|
this.modeWidget = this.addWidget("combo", "Mode", this.properties.mode, null, { property: "mode", values: ["anyActiveLink", "truthy", "dataNonNull"] })
|
||||||
}
|
}
|
||||||
|
|
||||||
override onDrawBackground(ctx: CanvasRenderingContext2D) {
|
override onDrawBackground(ctx: CanvasRenderingContext2D) {
|
||||||
@@ -117,7 +121,12 @@ export default class ComfyPickFirstNode extends ComfyGraphNode {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return link.data != null || this.properties.acceptNullLinkData;
|
if (this.properties.mode === "dataNonNull")
|
||||||
|
return link.data != null;
|
||||||
|
else if (this.properties.mode === "truthy")
|
||||||
|
return Boolean(link.data)
|
||||||
|
else // anyActiveLink
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -594,6 +594,7 @@ export class ComfyGalleryNode extends ComfyWidgetNode<GradioFileData[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override setValue(value: any) {
|
override setValue(value: any) {
|
||||||
|
console.warn("SETVALUE", value)
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
super.setValue(value)
|
super.setValue(value)
|
||||||
}
|
}
|
||||||
@@ -669,6 +670,10 @@ export class ComfyCheckboxNode extends ComfyWidgetNode<boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static slotLayout: SlotLayout = {
|
static slotLayout: SlotLayout = {
|
||||||
|
inputs: [
|
||||||
|
{ name: "value", type: "boolean" },
|
||||||
|
{ name: "store", type: BuiltInSlotType.ACTION }
|
||||||
|
],
|
||||||
outputs: [
|
outputs: [
|
||||||
{ name: "value", type: "boolean" },
|
{ name: "value", type: "boolean" },
|
||||||
{ name: "changed", type: BuiltInSlotType.EVENT },
|
{ name: "changed", type: BuiltInSlotType.EVENT },
|
||||||
@@ -678,6 +683,10 @@ export class ComfyCheckboxNode extends ComfyWidgetNode<boolean> {
|
|||||||
override svelteComponentType = CheckboxWidget;
|
override svelteComponentType = CheckboxWidget;
|
||||||
override defaultValue = false;
|
override defaultValue = false;
|
||||||
|
|
||||||
|
constructor(name?: string) {
|
||||||
|
super(name, false)
|
||||||
|
}
|
||||||
|
|
||||||
override setValue(value: any) {
|
override setValue(value: any) {
|
||||||
value = Boolean(value)
|
value = Boolean(value)
|
||||||
const changed = value != get(this.value);
|
const changed = value != get(this.value);
|
||||||
@@ -686,8 +695,9 @@ export class ComfyCheckboxNode extends ComfyWidgetNode<boolean> {
|
|||||||
this.triggerSlot(1, value)
|
this.triggerSlot(1, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(name?: string) {
|
override onAction(action: any, param: any) {
|
||||||
super(name, false)
|
if (action === "store")
|
||||||
|
this.setValue(Boolean(param))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -770,6 +780,8 @@ export class ComfyImageUploadNode extends ComfyWidgetNode<Array<GradioFileData>>
|
|||||||
static slotLayout: SlotLayout = {
|
static slotLayout: SlotLayout = {
|
||||||
outputs: [
|
outputs: [
|
||||||
{ name: "filename", type: "string" }, // TODO support batches
|
{ name: "filename", type: "string" }, // TODO support batches
|
||||||
|
{ name: "width", type: "number" },
|
||||||
|
{ name: "height", type: "number" },
|
||||||
{ name: "changed", type: BuiltInSlotType.EVENT },
|
{ name: "changed", type: BuiltInSlotType.EVENT },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -777,7 +789,9 @@ export class ComfyImageUploadNode extends ComfyWidgetNode<Array<GradioFileData>>
|
|||||||
override svelteComponentType = ImageUploadWidget;
|
override svelteComponentType = ImageUploadWidget;
|
||||||
override defaultValue = null;
|
override defaultValue = null;
|
||||||
override outputIndex = null;
|
override outputIndex = null;
|
||||||
override changedIndex = 1;
|
override changedIndex = 3;
|
||||||
|
|
||||||
|
imageSize: Vector2 = [1, 1];
|
||||||
|
|
||||||
constructor(name?: string) {
|
constructor(name?: string) {
|
||||||
super(name, [])
|
super(name, [])
|
||||||
@@ -787,10 +801,16 @@ export class ComfyImageUploadNode extends ComfyWidgetNode<Array<GradioFileData>>
|
|||||||
super.onExecute(param, options);
|
super.onExecute(param, options);
|
||||||
|
|
||||||
const value = get(this.value)
|
const value = get(this.value)
|
||||||
if (value.length > 0 && value[0].name)
|
if (value.length > 0 && value[0].name) {
|
||||||
this.setOutputData(0, value[0].name) // TODO when ComfyUI LoadImage supports loading an image batch
|
this.setOutputData(0, value[0].name) // TODO when ComfyUI LoadImage supports loading an image batch
|
||||||
else
|
this.setOutputData(1, this.imageSize[0])
|
||||||
|
this.setOutputData(2, this.imageSize[1])
|
||||||
|
}
|
||||||
|
else {
|
||||||
this.setOutputData(0, "")
|
this.setOutputData(0, "")
|
||||||
|
this.setOutputData(1, 1)
|
||||||
|
this.setOutputData(2, 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override formatValue(value: GradioFileData[]): string {
|
override formatValue(value: GradioFileData[]): string {
|
||||||
|
|||||||
@@ -37,8 +37,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
let style: Styles = {
|
let style: Styles = {
|
||||||
grid_cols: [4],
|
grid_cols: [3],
|
||||||
grid_rows: [4],
|
|
||||||
object_fit: "cover",
|
object_fit: "cover",
|
||||||
}
|
}
|
||||||
let element: HTMLDivElement;
|
let element: HTMLDivElement;
|
||||||
@@ -125,11 +124,11 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if widget && node && nodeValue && $nodeValue != null}
|
{#if widget && node && nodeValue}
|
||||||
{#if widget.attrs.variant === "image"}
|
{#if widget.attrs.variant === "image"}
|
||||||
<div class="wrapper comfy-image-widget" style={widget.attrs.style || ""} bind:this={element}>
|
<div class="wrapper comfy-image-widget" style={widget.attrs.style || ""} bind:this={element}>
|
||||||
<Block variant="solid" padding={false}>
|
<Block variant="solid" padding={false}>
|
||||||
{#if $nodeValue.length > 0}
|
{#if $nodeValue && $nodeValue.length > 0}
|
||||||
<StaticImage
|
<StaticImage
|
||||||
value={$nodeValue[$nodeValue.length-1].data}
|
value={$nodeValue[$nodeValue.length-1].data}
|
||||||
show_label={widget.attrs.title != ""}
|
show_label={widget.attrs.title != ""}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
import UploadText from "$lib/components/gradio/app/UploadText.svelte";
|
import UploadText from "$lib/components/gradio/app/UploadText.svelte";
|
||||||
import { tick } from "svelte";
|
import { tick } from "svelte";
|
||||||
import notify from "$lib/notify";
|
import notify from "$lib/notify";
|
||||||
|
import type { Vector2 } from "@litegraph-ts/core";
|
||||||
|
|
||||||
export let widget: WidgetLayout | null = null;
|
export let widget: WidgetLayout | null = null;
|
||||||
export let isMobile: boolean = false;
|
export let isMobile: boolean = false;
|
||||||
@@ -18,6 +19,9 @@
|
|||||||
let dragging = false;
|
let dragging = false;
|
||||||
let pending_upload = false;
|
let pending_upload = false;
|
||||||
let old_value: Array<GradioFileData> | null = null;
|
let old_value: Array<GradioFileData> | null = null;
|
||||||
|
let imgElem: HTMLImageElement | null = null
|
||||||
|
let imgWidth: number = 1;
|
||||||
|
let imgHeight: number = 1;
|
||||||
|
|
||||||
$: widget && setNodeValue(widget);
|
$: widget && setNodeValue(widget);
|
||||||
|
|
||||||
@@ -35,6 +39,18 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$: if (!(node && _value && _value.length > 0 && imgElem)) {
|
||||||
|
imgWidth = 1
|
||||||
|
imgHeight = 1
|
||||||
|
node.imageSize = [1, 1]
|
||||||
|
}
|
||||||
|
else if (imgWidth > 1 || imgHeight > 1) {
|
||||||
|
node.imageSize = [imgWidth, imgHeight]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.imageSize = [1, 1]
|
||||||
|
}
|
||||||
|
|
||||||
function onChange() {
|
function onChange() {
|
||||||
console.warn("CHANGED", _value)
|
console.warn("CHANGED", _value)
|
||||||
$nodeValue = _value || []
|
$nodeValue = _value || []
|
||||||
@@ -191,7 +207,12 @@
|
|||||||
{#if _value && _value.length > 0 && !pending_upload}
|
{#if _value && _value.length > 0 && !pending_upload}
|
||||||
{@const firstImage = _value[0]}
|
{@const firstImage = _value[0]}
|
||||||
<ModifyUpload on:clear={handle_clear} absolute />
|
<ModifyUpload on:clear={handle_clear} absolute />
|
||||||
<img src={getImageUrl(firstImage)} alt={firstImage.orig_name} />
|
<img src={getImageUrl(firstImage)}
|
||||||
|
alt={firstImage.orig_name}
|
||||||
|
bind:this={imgElem}
|
||||||
|
bind:naturalWidth={imgWidth}
|
||||||
|
bind:naturalHeight={imgHeight}
|
||||||
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<Upload
|
<Upload
|
||||||
file_count={node.properties.fileCount}
|
file_count={node.properties.fileCount}
|
||||||
|
|||||||
Reference in New Issue
Block a user