mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
Add LGraphNode.strokeStyles API (#868)
This should allow frontend drop the stroke logic in hijack of
`drawNodeShape`. Example usage:
```ts
node.strokeStyles["executionError"] = (this: LGraphNode) =>
app.lastNodeErrors?.[this.id] ? { colour: 'red', thickness: 2 } : undefined
```
This commit is contained in:
@@ -4390,7 +4390,7 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
* @param size Size of the background to draw, in graph units. Differs from node size if collapsed, etc.
|
||||
* @param fgcolor Foreground colour - used for text
|
||||
* @param bgcolor Background colour of the node
|
||||
* @param selected Whether to render the node as selected. Likely to be removed in future, as current usage is simply the selected property of the node.
|
||||
* @param _selected Whether to render the node as selected. Likely to be removed in future, as current usage is simply the selected property of the node.
|
||||
*/
|
||||
drawNodeShape(
|
||||
node: LGraphNode,
|
||||
@@ -4398,7 +4398,7 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
size: Size,
|
||||
fgcolor: CanvasColour,
|
||||
bgcolor: CanvasColour,
|
||||
selected: boolean,
|
||||
_selected: boolean,
|
||||
): void {
|
||||
// Rendering options
|
||||
ctx.strokeStyle = fgcolor
|
||||
@@ -4442,18 +4442,6 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
}
|
||||
ctx.fill()
|
||||
|
||||
if (node.has_errors) {
|
||||
strokeShape(ctx, area, {
|
||||
shape,
|
||||
title_mode,
|
||||
title_height,
|
||||
padding: 12,
|
||||
colour: LiteGraph.NODE_ERROR_COLOUR,
|
||||
collapsed,
|
||||
thickness: 10,
|
||||
})
|
||||
}
|
||||
|
||||
// Separator - title bar <-> body
|
||||
if (!collapsed && render_title) {
|
||||
ctx.shadowColor = "transparent"
|
||||
@@ -4491,19 +4479,18 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
node.onDrawTitle?.(ctx)
|
||||
}
|
||||
|
||||
// render selection marker
|
||||
if (selected) {
|
||||
node.onBounding?.(area)
|
||||
|
||||
const padding = node.has_errors ? 20 : undefined
|
||||
|
||||
strokeShape(ctx, area, {
|
||||
shape,
|
||||
title_height,
|
||||
title_mode,
|
||||
padding,
|
||||
collapsed: node.flags?.collapsed,
|
||||
})
|
||||
// Draw stroke styles
|
||||
for (const getStyle of Object.values(node.strokeStyles)) {
|
||||
const strokeStyle = getStyle.call(node)
|
||||
if (strokeStyle) {
|
||||
strokeShape(ctx, area, {
|
||||
shape,
|
||||
title_height,
|
||||
title_mode,
|
||||
collapsed,
|
||||
...strokeStyle,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// these counter helps in conditioning drawing based on if the node has been executed or an action occurred
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { DragAndScale } from "./DragAndScale"
|
||||
import type { IDrawBoundingOptions } from "./draw"
|
||||
import type {
|
||||
CanvasColour,
|
||||
ColorOption,
|
||||
@@ -256,6 +257,11 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
|
||||
) ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
* The stroke styles that should be applied to the node.
|
||||
*/
|
||||
strokeStyles: Record<string, (this: LGraphNode) => IDrawBoundingOptions | undefined>
|
||||
|
||||
exec_version?: number
|
||||
action_call?: string
|
||||
execute_triggered?: number
|
||||
@@ -586,12 +592,34 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
|
||||
overWidget: IWidget,
|
||||
): boolean | undefined
|
||||
|
||||
#getErrorStrokeStyle(this: LGraphNode): IDrawBoundingOptions | undefined {
|
||||
if (this.has_errors) {
|
||||
return {
|
||||
padding: 12,
|
||||
thickness: 10,
|
||||
colour: LiteGraph.NODE_ERROR_COLOUR,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#getSelectedStrokeStyle(this: LGraphNode): IDrawBoundingOptions | undefined {
|
||||
if (this.selected) {
|
||||
return {
|
||||
padding: this.has_errors ? 20 : undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor(title: string, type?: string) {
|
||||
this.id = LiteGraph.use_uuids ? LiteGraph.uuidv4() : -1
|
||||
this.title = title || "Unnamed"
|
||||
this.type = type ?? ""
|
||||
this.size = [LiteGraph.NODE_WIDTH, 60]
|
||||
this.pos = [10, 10]
|
||||
this.strokeStyles = {
|
||||
error: this.#getErrorStrokeStyle,
|
||||
selected: this.#getSelectedStrokeStyle,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,7 +30,7 @@ export enum LabelPosition {
|
||||
Right = "right",
|
||||
}
|
||||
|
||||
interface IDrawSelectionBoundingOptions {
|
||||
export interface IDrawBoundingOptions {
|
||||
/** The shape to render */
|
||||
shape?: RenderShape
|
||||
/** The radius of the rounded corners for {@link RenderShape.ROUND} and {@link RenderShape.CARD} */
|
||||
@@ -67,7 +67,7 @@ export function strokeShape(
|
||||
padding = 6,
|
||||
collapsed = false,
|
||||
thickness = 1,
|
||||
}: IDrawSelectionBoundingOptions = {},
|
||||
}: IDrawBoundingOptions = {},
|
||||
): void {
|
||||
// These param defaults are not compile-time static, and must be re-evaluated at runtime
|
||||
round_radius ??= LiteGraph.ROUND_RADIUS
|
||||
|
||||
@@ -92,6 +92,10 @@ LGraph {
|
||||
"selected": undefined,
|
||||
"serialize_widgets": undefined,
|
||||
"showAdvanced": undefined,
|
||||
"strokeStyles": {
|
||||
"error": [Function],
|
||||
"selected": [Function],
|
||||
},
|
||||
"title": "LGraphNode",
|
||||
"type": "mustBeSet",
|
||||
"widgets": undefined,
|
||||
@@ -156,6 +160,10 @@ LGraph {
|
||||
"selected": undefined,
|
||||
"serialize_widgets": undefined,
|
||||
"showAdvanced": undefined,
|
||||
"strokeStyles": {
|
||||
"error": [Function],
|
||||
"selected": [Function],
|
||||
},
|
||||
"title": "LGraphNode",
|
||||
"type": "mustBeSet",
|
||||
"widgets": undefined,
|
||||
@@ -221,6 +229,10 @@ LGraph {
|
||||
"selected": undefined,
|
||||
"serialize_widgets": undefined,
|
||||
"showAdvanced": undefined,
|
||||
"strokeStyles": {
|
||||
"error": [Function],
|
||||
"selected": [Function],
|
||||
},
|
||||
"title": "LGraphNode",
|
||||
"type": "mustBeSet",
|
||||
"widgets": undefined,
|
||||
|
||||
@@ -94,6 +94,10 @@ LGraph {
|
||||
"selected": undefined,
|
||||
"serialize_widgets": undefined,
|
||||
"showAdvanced": undefined,
|
||||
"strokeStyles": {
|
||||
"error": [Function],
|
||||
"selected": [Function],
|
||||
},
|
||||
"title": undefined,
|
||||
"type": "",
|
||||
"widgets": undefined,
|
||||
@@ -160,6 +164,10 @@ LGraph {
|
||||
"selected": undefined,
|
||||
"serialize_widgets": undefined,
|
||||
"showAdvanced": undefined,
|
||||
"strokeStyles": {
|
||||
"error": [Function],
|
||||
"selected": [Function],
|
||||
},
|
||||
"title": undefined,
|
||||
"type": "",
|
||||
"widgets": undefined,
|
||||
@@ -227,6 +235,10 @@ LGraph {
|
||||
"selected": undefined,
|
||||
"serialize_widgets": undefined,
|
||||
"showAdvanced": undefined,
|
||||
"strokeStyles": {
|
||||
"error": [Function],
|
||||
"selected": [Function],
|
||||
},
|
||||
"title": undefined,
|
||||
"type": "",
|
||||
"widgets": undefined,
|
||||
|
||||
@@ -92,6 +92,10 @@ LGraph {
|
||||
"selected": undefined,
|
||||
"serialize_widgets": undefined,
|
||||
"showAdvanced": undefined,
|
||||
"strokeStyles": {
|
||||
"error": [Function],
|
||||
"selected": [Function],
|
||||
},
|
||||
"title": "LGraphNode",
|
||||
"type": "mustBeSet",
|
||||
"widgets": undefined,
|
||||
@@ -156,6 +160,10 @@ LGraph {
|
||||
"selected": undefined,
|
||||
"serialize_widgets": undefined,
|
||||
"showAdvanced": undefined,
|
||||
"strokeStyles": {
|
||||
"error": [Function],
|
||||
"selected": [Function],
|
||||
},
|
||||
"title": "LGraphNode",
|
||||
"type": "mustBeSet",
|
||||
"widgets": undefined,
|
||||
@@ -221,6 +229,10 @@ LGraph {
|
||||
"selected": undefined,
|
||||
"serialize_widgets": undefined,
|
||||
"showAdvanced": undefined,
|
||||
"strokeStyles": {
|
||||
"error": [Function],
|
||||
"selected": [Function],
|
||||
},
|
||||
"title": "LGraphNode",
|
||||
"type": "mustBeSet",
|
||||
"widgets": undefined,
|
||||
|
||||
Reference in New Issue
Block a user