From 997d673bd9997a3d1db2b5072d481dea33c643e0 Mon Sep 17 00:00:00 2001 From: Chenlei Hu Date: Sun, 9 Feb 2025 12:53:41 -0500 Subject: [PATCH] [Refactor] LgraphNode.drawSlots (#503) * wip * nit --- src/LGraphCanvas.ts | 77 ++++------------------------------------- src/LGraphNode.ts | 83 +++++++++++++++++++++++++++++++++++++++++++++ src/NodeSlot.ts | 2 +- 3 files changed, 91 insertions(+), 71 deletions(-) diff --git a/src/LGraphCanvas.ts b/src/LGraphCanvas.ts index 236638dd5..a09439eed 100644 --- a/src/LGraphCanvas.ts +++ b/src/LGraphCanvas.ts @@ -66,7 +66,7 @@ import { Reroute, type RerouteId } from "./Reroute" import { getAllNestedItems, findFirstNode } from "./utils/collections" import { CanvasPointer } from "./CanvasPointer" import { toClass } from "./utils/type" -import { NodeInputSlot, NodeOutputSlot, type ConnectionColorContext } from "./NodeSlot" +import { type ConnectionColorContext } from "./NodeSlot" import { WIDGET_TYPE_MAP } from "./widgets/widgetMap" interface IShowSearchOptions { @@ -4643,7 +4643,6 @@ export class LGraphCanvas implements ConnectionColorContext { const shape = node._shape || RenderShape.BOX const size = LGraphCanvas.#temp_vec2 LGraphCanvas.#temp_vec2.set(node.size) - const horizontal = node.horizontal // || node.flags.horizontal; if (node.flags.collapsed) { ctx.font = this.inner_text_font @@ -4697,76 +4696,14 @@ export class LGraphCanvas implements ConnectionColorContext { // connection slots ctx.font = this.inner_text_font - const render_text = !low_quality - const highlightColour = - LiteGraph.NODE_TEXT_HIGHLIGHT_COLOR ?? - LiteGraph.NODE_SELECTED_TITLE_COLOR ?? - LiteGraph.NODE_TEXT_COLOR - - let max_y = 0 - const slot_pos = new Float32Array(2) // to reuse - // render inputs and outputs if (!node.collapsed) { - // input connection slots - for (const [i, input] of (node.inputs ?? []).entries()) { - const slot = toClass(NodeInputSlot, input) - - // change opacity of incompatible slots when dragging a connection - const isValid = slot.isValidTarget(this.connecting_links?.[0]) - const highlight = isValid && node.mouseOver?.inputId === i - const label_color = highlight - ? highlightColour - : LiteGraph.NODE_TEXT_COLOR - ctx.globalAlpha = isValid ? editor_alpha : 0.4 * editor_alpha - - const pos = node.getConnectionPos(true, i, slot_pos) - pos[0] -= node.pos[0] - pos[1] -= node.pos[1] - if (max_y < pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5) { - max_y = pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5 - } - - slot.draw(ctx, { - pos, - colorContext: this, - labelColor: label_color, - horizontal, - lowQuality: low_quality, - renderText: render_text, - highlight, - }) - } - - // output connection slots - for (const [i, output] of (node.outputs ?? []).entries()) { - const slot = toClass(NodeOutputSlot, output) - - // change opacity of incompatible slots when dragging a connection - const isValid = slot.isValidTarget(this.connecting_links?.[0]) - const highlight = isValid && node.mouseOver?.outputId === i - const label_color = highlight - ? highlightColour - : LiteGraph.NODE_TEXT_COLOR - ctx.globalAlpha = isValid ? editor_alpha : 0.4 * editor_alpha - - const pos = node.getConnectionPos(false, i, slot_pos) - pos[0] -= node.pos[0] - pos[1] -= node.pos[1] - if (max_y < pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5) { - max_y = pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5 - } - - slot.draw(ctx, { - pos, - colorContext: this, - labelColor: label_color, - horizontal, - lowQuality: low_quality, - renderText: render_text, - highlight, - }) - } + const max_y = node.drawSlots(ctx, { + colorContext: this, + connectingLink: this.connecting_links?.[0], + editorAlpha: this.editor_alpha, + lowQuality: this.low_quality, + }) ctx.textAlign = "left" ctx.globalAlpha = 1 diff --git a/src/LGraphNode.ts b/src/LGraphNode.ts index 802840808..b1f7e6403 100644 --- a/src/LGraphNode.ts +++ b/src/LGraphNode.ts @@ -1,5 +1,7 @@ // @ts-strict-ignore import type { + CanvasColour, + ConnectingLink, Dictionary, IContextMenuValue, IFoundSlot, @@ -3195,4 +3197,85 @@ export class LGraphNode implements Positionable, IPinnable { }) } } + + get highlightColor(): CanvasColour { + return LiteGraph.NODE_TEXT_HIGHLIGHT_COLOR ?? LiteGraph.NODE_SELECTED_TITLE_COLOR ?? LiteGraph.NODE_TEXT_COLOR + } + + /** + * Draws the node's input and output slots. + * @returns The maximum y-coordinate of the slots. + * TODO: Calculate the bounding box of the slots and return it instead of the maximum y-coordinate. + */ + drawSlots(ctx: CanvasRenderingContext2D, options: { + colorContext: ConnectionColorContext + connectingLink: ConnectingLink | null + editorAlpha: number + lowQuality: boolean + }): number { + const { colorContext, connectingLink, editorAlpha, lowQuality } = options + let max_y = 0 + + // input connection slots + // Reuse slot_pos to avoid creating a new Float32Array on each iteration + const slot_pos = new Float32Array(2) + for (const [i, input] of (this.inputs ?? []).entries()) { + const slot = toClass(NodeInputSlot, input) + + // change opacity of incompatible slots when dragging a connection + const isValid = slot.isValidTarget(connectingLink) + const highlight = isValid && this.mouseOver?.inputId === i + const label_color = highlight + ? this.highlightColor + : LiteGraph.NODE_TEXT_COLOR + ctx.globalAlpha = isValid ? editorAlpha : 0.4 * editorAlpha + + const pos = this.getConnectionPos(true, i, /* out= */slot_pos) + pos[0] -= this.pos[0] + pos[1] -= this.pos[1] + + max_y = Math.max(max_y, pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5) + + slot.draw(ctx, { + pos, + colorContext, + labelColor: label_color, + horizontal: this.horizontal, + lowQuality, + renderText: !lowQuality, + highlight, + }) + } + + // output connection slots + for (const [i, output] of (this.outputs ?? []).entries()) { + const slot = toClass(NodeOutputSlot, output) + + // change opacity of incompatible slots when dragging a connection + const isValid = slot.isValidTarget(connectingLink) + const highlight = isValid && this.mouseOver?.outputId === i + const label_color = highlight + ? this.highlightColor + : LiteGraph.NODE_TEXT_COLOR + ctx.globalAlpha = isValid ? editorAlpha : 0.4 * editorAlpha + + const pos = this.getConnectionPos(false, i, /* out= */slot_pos) + pos[0] -= this.pos[0] + pos[1] -= this.pos[1] + + max_y = Math.max(max_y, pos[1] + LiteGraph.NODE_SLOT_HEIGHT * 0.5) + + slot.draw(ctx, { + pos, + colorContext, + labelColor: label_color, + horizontal: this.horizontal, + lowQuality, + renderText: !lowQuality, + highlight, + }) + } + + return max_y + } } diff --git a/src/NodeSlot.ts b/src/NodeSlot.ts index 8d5854604..4877a644f 100644 --- a/src/NodeSlot.ts +++ b/src/NodeSlot.ts @@ -19,7 +19,7 @@ export interface ConnectionColorContext { interface IDrawOptions { pos: Point colorContext: ConnectionColorContext - labelColor?: string + labelColor?: CanvasColour labelPosition?: LabelPosition horizontal?: boolean lowQuality?: boolean