[Refactor] Split node slot code out to base class (#994)

Foundational work for subgraph.
This commit is contained in:
filtered
2025-05-02 08:26:25 +10:00
committed by GitHub
parent 2e0267105e
commit 388a3d64cc
6 changed files with 56 additions and 37 deletions

View File

@@ -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<IDrawOptions, "doStroke" | "labelPosition">) {
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
}
}

View File

@@ -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<IDrawOptions, "doStroke" | "labelPosition">) {
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
}
}

View File

@@ -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<INodeSlot, "boundingRect">, 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,
{

41
src/node/SlotBase.ts Normal file
View File

@@ -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<LLink>
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)
}
}