mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-24 00:34:09 +00:00
Implement ButtonWidget (#483)
This commit is contained in:
@@ -70,6 +70,7 @@ import { toClass } from "./utils/type"
|
||||
import { NodeInputSlot, NodeOutputSlot, type ConnectionColorContext } from "./NodeSlot"
|
||||
import { ComboWidget } from "./widgets/ComboWidget"
|
||||
import { NumberWidget } from "./widgets/NumberWidget"
|
||||
import { ButtonWidget } from "./widgets/ButtonWidget"
|
||||
|
||||
interface IShowSearchOptions {
|
||||
node_to?: LGraphNode
|
||||
@@ -2564,9 +2565,11 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
switch (widget.type) {
|
||||
case "button":
|
||||
pointer.onClick = () => {
|
||||
widget.callback?.(widget, this, node, pos, e)
|
||||
widget.clicked = true
|
||||
this.dirty_canvas = true
|
||||
toClass(ButtonWidget, widget).onClick({
|
||||
e,
|
||||
node,
|
||||
canvas: this,
|
||||
})
|
||||
}
|
||||
break
|
||||
case "slider": {
|
||||
@@ -5838,20 +5841,7 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
|
||||
switch (w.type) {
|
||||
case "button":
|
||||
ctx.fillStyle = background_color
|
||||
if (w.clicked) {
|
||||
ctx.fillStyle = "#AAA"
|
||||
w.clicked = false
|
||||
this.dirty_canvas = true
|
||||
}
|
||||
ctx.fillRect(margin, y, widget_width - margin * 2, H)
|
||||
if (show_text && !w.disabled)
|
||||
ctx.strokeRect(margin, y, widget_width - margin * 2, H)
|
||||
if (show_text) {
|
||||
ctx.textAlign = "center"
|
||||
ctx.fillStyle = text_color
|
||||
ctx.fillText(w.label || w.name, widget_width * 0.5, y + H * 0.7)
|
||||
}
|
||||
toClass(ButtonWidget, w).drawWidget(ctx, { y, width: widget_width, show_text, margin })
|
||||
break
|
||||
case "toggle":
|
||||
toClass(BooleanWidget, w).drawWidget(ctx, { y, width: widget_width, show_text, margin })
|
||||
|
||||
@@ -35,6 +35,7 @@ import { LLink } from "./LLink"
|
||||
import { BooleanWidget } from "./widgets/BooleanWidget"
|
||||
import { ComboWidget } from "./widgets/ComboWidget"
|
||||
import { NumberWidget } from "./widgets/NumberWidget"
|
||||
import { ButtonWidget } from "./widgets/ButtonWidget"
|
||||
import { NodeInputSlot, NodeOutputSlot } from "./NodeSlot"
|
||||
|
||||
export type NodeId = number | string
|
||||
@@ -1679,6 +1680,9 @@ export class LGraphNode implements Positionable, IPinnable {
|
||||
case "number":
|
||||
widget = new NumberWidget(custom_widget)
|
||||
break
|
||||
case "button":
|
||||
widget = new ButtonWidget(custom_widget)
|
||||
break
|
||||
default:
|
||||
widget = custom_widget
|
||||
}
|
||||
|
||||
85
src/widgets/ButtonWidget.ts
Normal file
85
src/widgets/ButtonWidget.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import type { IStringWidget, IWidgetOptions } from "@/types/widgets"
|
||||
import { BaseWidget } from "./BaseWidget"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
import type { CanvasMouseEvent } from "@/types/events"
|
||||
import type { LGraphCanvas } from "@/LGraphCanvas"
|
||||
|
||||
export class ButtonWidget extends BaseWidget implements IStringWidget {
|
||||
// IStringWidget properties
|
||||
declare type: "button"
|
||||
declare value: string
|
||||
declare options: IWidgetOptions<boolean>
|
||||
|
||||
constructor(widget: IStringWidget) {
|
||||
super(widget)
|
||||
this.type = "button"
|
||||
this.value = widget.value ?? ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the widget
|
||||
* @param ctx - The canvas context
|
||||
* @param options - The options for drawing the widget
|
||||
*/
|
||||
override drawWidget(ctx: CanvasRenderingContext2D, options: {
|
||||
y: number
|
||||
width: number
|
||||
show_text?: boolean
|
||||
margin?: number
|
||||
}) {
|
||||
// Store original context attributes
|
||||
const originalTextAlign = ctx.textAlign
|
||||
const originalStrokeStyle = ctx.strokeStyle
|
||||
const originalFillStyle = ctx.fillStyle
|
||||
|
||||
const { y, width, show_text = true, margin = 15 } = options
|
||||
const widget_width = width
|
||||
const H = this.height
|
||||
|
||||
// Draw button background
|
||||
ctx.fillStyle = this.background_color
|
||||
if (this.clicked) {
|
||||
ctx.fillStyle = "#AAA"
|
||||
this.clicked = false
|
||||
}
|
||||
ctx.fillRect(margin, y, widget_width - margin * 2, H)
|
||||
|
||||
// Draw button outline if not disabled
|
||||
if (show_text && !this.disabled) {
|
||||
ctx.strokeStyle = this.outline_color
|
||||
ctx.strokeRect(margin, y, widget_width - margin * 2, H)
|
||||
}
|
||||
|
||||
// Draw button text
|
||||
if (show_text) {
|
||||
ctx.textAlign = "center"
|
||||
ctx.fillStyle = this.text_color
|
||||
ctx.fillText(
|
||||
this.label || this.name || "",
|
||||
widget_width * 0.5,
|
||||
y + H * 0.7,
|
||||
)
|
||||
}
|
||||
|
||||
// Restore original context attributes
|
||||
ctx.textAlign = originalTextAlign
|
||||
ctx.strokeStyle = originalStrokeStyle
|
||||
ctx.fillStyle = originalFillStyle
|
||||
}
|
||||
|
||||
override onClick(options: {
|
||||
e: CanvasMouseEvent
|
||||
node: LGraphNode
|
||||
canvas: LGraphCanvas
|
||||
}) {
|
||||
const { e, node, canvas } = options
|
||||
const pos = canvas.graph_mouse
|
||||
|
||||
// Set clicked state and mark canvas as dirty
|
||||
this.clicked = true
|
||||
canvas.setDirty(true)
|
||||
|
||||
// Call the callback with widget instance and other context
|
||||
this.callback?.(this, canvas, node, pos, e)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user