import { BuiltInSlotType, LiteGraph, type SlotLayout } from "@litegraph-ts/core"; import ComfyGraphNode, { type ComfyGraphNodeProperties, type DefaultWidgetLayout } from "./ComfyGraphNode"; import { clamp } from "$lib/utils"; import ComboWidget from "$lib/widgets/ComboWidget.svelte"; import { ComfyComboNode } from "./widgets"; export interface ComfyValueControlProperties extends ComfyGraphNodeProperties { value: any, action: "fixed" | "increment" | "decrement" | "randomize", min: number, max: number, step: number, ignoreStepWhenRandom: boolean } const INT_MAX = 1125899906842624; export default class ComfyValueControl extends ComfyGraphNode { override properties: ComfyValueControlProperties = { tags: [], value: null, action: "randomize", min: -INT_MAX, max: INT_MAX, step: 1, ignoreStepWhenRandom: false } static slotLayout: SlotLayout = { inputs: [ { name: "value", type: "number" }, { name: "trigger", type: BuiltInSlotType.ACTION }, { name: "action", type: "string" }, { name: "min", type: "number" }, { name: "max", type: "number" }, { name: "step", type: "number" } ], outputs: [ { name: "value", type: "*" }, { name: "changed", type: BuiltInSlotType.EVENT } ], } override defaultWidgets: DefaultWidgetLayout = { inputs: { 2: { defaultWidgetNode: ComfyComboNode, config: { defaultValue: "randomize", values: ["fixed", "increment", "decrement", "randomize"] } } } } delayChangeEvent: boolean = true; private _aboutToChange: number = 0; private _aboutToChangeValue: any = null; constructor(title?: string) { super(title); } override onExecute() { if (this._aboutToChange > 0) { this._aboutToChange -= 1; if (this._aboutToChange <= 0) { const value = this._aboutToChangeValue; console.warn("ABOUTTOCHANGE", value) this._aboutToChange = 0; this._aboutToChangeValue = null; this.triggerSlot(1, value) } } } override onAction(action: any, param: any) { var v = this.getInputData(0) if (typeof v !== "number") return let action_ = this.getInputData(2); if (action_ == null) action_ = "fixed" let min = this.getInputData(3); if (min == null) min = -INT_MAX let max = this.getInputData(4); if (max == null) max = INT_MAX let step = this.getInputData(5); if (step == null) step = 1 this.setProperty("action", action_) this.setProperty("min", min) this.setProperty("max", max) this.setProperty("step", step) min = this.properties.min max = this.properties.max if (min == null) min = -INT_MAX if (max == null) max = INT_MAX // limit to something that javascript can handle min = Math.max(-INT_MAX, this.properties.min); max = Math.min(INT_MAX, this.properties.max); let range = (max - min) / (this.properties.step); //adjust values based on valueControl Behaviour switch (this.properties.action) { case "fixed": break; case "increment": v += this.properties.step; break; case "decrement": v -= this.properties.step; break; case "randomize": const step = this.properties.ignoreStepWhenRandom ? 1 : this.properties.step v = Math.floor(Math.random() * range) * step + min; default: break; } v = clamp(v, min, max) this.setProperty("value", v) this.setOutputData(0, v) if (this.delayChangeEvent) { this._aboutToChange = 2; this._aboutToChangeValue = v; } else { this.triggerSlot(1, v) } console.debug("ValueControl", v, this.properties) }; } LiteGraph.registerNodeType({ class: ComfyValueControl, title: "Comfy.ValueControl", desc: "Adjusts an incoming value based on behavior", type: "utils/value_control" })