diff --git a/src/LGraphNode.ts b/src/LGraphNode.ts index 6557ce5ed..7c143e3d9 100644 --- a/src/LGraphNode.ts +++ b/src/LGraphNode.ts @@ -3521,7 +3521,7 @@ export class LGraphNode implements Positionable, IPinnable, IColorable { isValidTarget || !slot.isWidgetInputSlot || this.#isMouseOverWidget(this.getWidgetFromSlot(slot)) || - slot.isConnected() + slot.isConnected ) { ctx.globalAlpha = isValid ? editorAlpha : 0.4 * editorAlpha slot.draw(ctx, { diff --git a/src/interfaces.ts b/src/interfaces.ts index cb5db0f51..6f615f98b 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -38,7 +38,7 @@ export interface HasBoundingRect { * * Used for various calculations, such as overlap, selective rendering, and click checks. * For most items, this is cached position & size as `x, y, width, height`. - * Some items (such as nodes) may extend above and/or to the left of their {@link pos}. + * Some items (such as nodes and slots) may extend above and/or to the left of their {@link pos}. * @readonly * @see {@link move} */ diff --git a/src/node/NodeInputSlot.ts b/src/node/NodeInputSlot.ts index baf4e3f76..2f7fd9f31 100644 --- a/src/node/NodeInputSlot.ts +++ b/src/node/NodeInputSlot.ts @@ -22,7 +22,7 @@ export class NodeInputSlot extends NodeSlot implements INodeInputSlot { this.link = slot.link } - override isConnected(): boolean { + override get isConnected(): boolean { return this.link != null } @@ -31,7 +31,7 @@ export class NodeInputSlot extends NodeSlot implements INodeInputSlot { } override draw(ctx: CanvasRenderingContext2D, options: Omit) { - const originalTextAlign = ctx.textAlign + const { textAlign } = ctx ctx.textAlign = "left" super.draw(ctx, { @@ -40,6 +40,6 @@ export class NodeInputSlot extends NodeSlot implements INodeInputSlot { doStroke: false, }) - ctx.textAlign = originalTextAlign + ctx.textAlign = textAlign } } diff --git a/src/node/NodeOutputSlot.ts b/src/node/NodeOutputSlot.ts index 6f3e1de1b..1afd427f6 100644 --- a/src/node/NodeOutputSlot.ts +++ b/src/node/NodeOutputSlot.ts @@ -36,13 +36,12 @@ export class NodeOutputSlot extends NodeSlot implements INodeOutputSlot { return "link" in fromSlot && LiteGraph.isValidConnection(this.type, fromSlot.type) } - override isConnected(): boolean { + override get isConnected(): boolean { return this.links != null && this.links.length > 0 } override draw(ctx: CanvasRenderingContext2D, options: Omit) { - const originalTextAlign = ctx.textAlign - const originalStrokeStyle = ctx.strokeStyle + const { textAlign, strokeStyle } = ctx ctx.textAlign = "right" ctx.strokeStyle = "black" @@ -52,7 +51,7 @@ export class NodeOutputSlot extends NodeSlot implements INodeOutputSlot { doStroke: true, }) - ctx.textAlign = originalTextAlign - ctx.strokeStyle = originalStrokeStyle + ctx.textAlign = textAlign + ctx.strokeStyle = strokeStyle } } diff --git a/src/node/NodeSlot.ts b/src/node/NodeSlot.ts index 93e1c4f1e..b4279aaac 100644 --- a/src/node/NodeSlot.ts +++ b/src/node/NodeSlot.ts @@ -1,4 +1,4 @@ -import type { CanvasColour, DefaultConnectionColors, INodeInputSlot, INodeOutputSlot, INodeSlot, ISlotType, IWidgetLocator, OptionalProps, Point, ReadOnlyPoint, Rect } from "@/interfaces" +import type { CanvasColour, DefaultConnectionColors, INodeInputSlot, INodeOutputSlot, INodeSlot, OptionalProps, Point, ReadOnlyPoint } from "@/interfaces" import type { LGraphNode } from "@/LGraphNode" import { LabelPosition, SlotShape, SlotType } from "@/draw" @@ -7,6 +7,7 @@ import { getCentre } from "@/measure" import { LinkDirection, RenderShape } from "@/types/globalEnums" import { NodeInputSlot } from "./NodeInputSlot" +import { SlotBase } from "./SlotBase" export interface IDrawOptions { colorContext: DefaultConnectionColors @@ -16,22 +17,9 @@ export interface IDrawOptions { highlight?: boolean } -export abstract class NodeSlot implements INodeSlot { - name: string - localized_name?: string - label?: string - type: ISlotType - dir?: LinkDirection - removable?: boolean - shape?: RenderShape - color_off?: CanvasColour - color_on?: CanvasColour - locked?: boolean - nameLocked?: boolean +/** Shared base class for {@link LGraphNode} input and output slots. */ +export abstract class NodeSlot extends SlotBase implements INodeSlot { pos?: Point - widget?: IWidgetLocator - hasErrors?: boolean - readonly boundingRect: Rect /** The offset from the parent node to the centre point of this slot. */ get #centreOffset(): ReadOnlyPoint { @@ -64,10 +52,9 @@ export abstract class NodeSlot implements INodeSlot { abstract get isWidgetInputSlot(): boolean constructor(slot: OptionalProps, node: LGraphNode) { + super(slot.name, slot.type, slot.boundingRect ?? [0, 0, 0, 0]) + Object.assign(this, slot) - this.name = slot.name - this.type = slot.type - this.boundingRect = slot.boundingRect ?? [0, 0, 0, 0] this.#node = node } @@ -84,14 +71,6 @@ export abstract class NodeSlot implements INodeSlot { return this.label || this.localized_name || this.name || "" } - abstract isConnected(): boolean - - renderingColor(colorContext: DefaultConnectionColors): CanvasColour { - return this.isConnected() - ? this.color_on || colorContext.getConnectedColor(this.type) - : this.color_off || colorContext.getDisconnectedColor(this.type) - } - draw( ctx: CanvasRenderingContext2D, { diff --git a/src/node/SlotBase.ts b/src/node/SlotBase.ts new file mode 100644 index 000000000..bee4b1916 --- /dev/null +++ b/src/node/SlotBase.ts @@ -0,0 +1,41 @@ +import type { CanvasColour, DefaultConnectionColors, INodeSlot, ISlotType, IWidgetLocator, Point, Rect } from "@/interfaces" +import type { LLink } from "@/LLink" +import type { RenderShape } from "@/types/globalEnums" +import type { LinkDirection } from "@/types/globalEnums" + +/** Base class for all input & output slots. */ + +export abstract class SlotBase implements INodeSlot { + name: string + localized_name?: string + label?: string + type: ISlotType + dir?: LinkDirection + removable?: boolean + shape?: RenderShape + color_off?: CanvasColour + color_on?: CanvasColour + locked?: boolean + nameLocked?: boolean + widget?: IWidgetLocator + _floatingLinks?: Set + hasErrors?: boolean + + /** The centre point of the slot. */ + abstract pos?: Point + readonly boundingRect: Rect + + constructor(name: string, type: ISlotType, boundingRect: Rect) { + this.name = name + this.type = type + this.boundingRect = boundingRect + } + + abstract get isConnected(): boolean + + renderingColor(colorContext: DefaultConnectionColors): CanvasColour { + return this.isConnected + ? this.color_on || colorContext.getConnectedColor(this.type) + : this.color_off || colorContext.getDisconnectedColor(this.type) + } +}