mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-07 14:09:59 +00:00
Reduce input socket hitbox for widgets (#966)
Restores the full left-arrow button click area for widgets. Previously lost ~5 canvas pixels to clicks intercepted by input sockets. Supporting refactors: - Maps concrete node slot impls. to private array, once per frame - Converts slot boundingRect to use absolute canvas pos (same as other elements) - Stores parent node ref in concrete slot classes
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { INodeInputSlot, INodeOutputSlot, OptionalProps } from "@/interfaces"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
import type { LinkId } from "@/LLink"
|
||||
|
||||
import { LabelPosition } from "@/draw"
|
||||
@@ -12,8 +13,8 @@ export class NodeInputSlot extends NodeSlot implements INodeInputSlot {
|
||||
return !!this.widget
|
||||
}
|
||||
|
||||
constructor(slot: OptionalProps<INodeInputSlot, "boundingRect">) {
|
||||
super(slot)
|
||||
constructor(slot: OptionalProps<INodeInputSlot, "boundingRect">, node: LGraphNode) {
|
||||
super(slot, node)
|
||||
this.link = slot.link
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { INodeInputSlot, INodeOutputSlot, OptionalProps } from "@/interfaces"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
import type { LinkId } from "@/LLink"
|
||||
|
||||
import { LabelPosition } from "@/draw"
|
||||
@@ -14,8 +15,8 @@ export class NodeOutputSlot extends NodeSlot implements INodeOutputSlot {
|
||||
return false
|
||||
}
|
||||
|
||||
constructor(slot: OptionalProps<INodeOutputSlot, "boundingRect">) {
|
||||
super(slot)
|
||||
constructor(slot: OptionalProps<INodeOutputSlot, "boundingRect">, node: LGraphNode) {
|
||||
super(slot, node)
|
||||
this.links = slot.links
|
||||
this._data = slot._data
|
||||
this.slot_index = slot.slot_index
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { CanvasColour, Dictionary, INodeInputSlot, INodeOutputSlot, INodeSlot, ISlotType, IWidgetLocator, OptionalProps, Point, Rect } from "@/interfaces"
|
||||
import type { CanvasColour, Dictionary, INodeInputSlot, INodeOutputSlot, INodeSlot, ISlotType, IWidgetLocator, OptionalProps, Point, ReadOnlyPoint, Rect } from "@/interfaces"
|
||||
import type { LGraphNode } from "@/LGraphNode"
|
||||
|
||||
import { LabelPosition, SlotShape, SlotType } from "@/draw"
|
||||
import { LiteGraph } from "@/litegraph"
|
||||
@@ -41,7 +42,28 @@ export abstract class NodeSlot implements INodeSlot {
|
||||
pos?: Point
|
||||
widget?: IWidgetLocator
|
||||
hasErrors?: boolean
|
||||
boundingRect: Rect
|
||||
readonly boundingRect: Rect
|
||||
|
||||
/** The offset from the parent node to the centre point of this slot. */
|
||||
get #centreOffset(): ReadOnlyPoint {
|
||||
const nodePos = this.node.pos
|
||||
const { boundingRect } = this
|
||||
|
||||
// Use height; widget input slots may be thinner.
|
||||
const diameter = boundingRect[3]
|
||||
|
||||
return getCentre([
|
||||
boundingRect[0] - nodePos[0],
|
||||
boundingRect[1] - nodePos[1],
|
||||
diameter,
|
||||
diameter,
|
||||
])
|
||||
}
|
||||
|
||||
#node: LGraphNode
|
||||
get node(): LGraphNode {
|
||||
return this.#node
|
||||
}
|
||||
|
||||
get highlightColor(): CanvasColour {
|
||||
return LiteGraph.NODE_TEXT_HIGHLIGHT_COLOR ?? LiteGraph.NODE_SELECTED_TITLE_COLOR ?? LiteGraph.NODE_TEXT_COLOR
|
||||
@@ -49,11 +71,12 @@ export abstract class NodeSlot implements INodeSlot {
|
||||
|
||||
abstract get isWidgetInputSlot(): boolean
|
||||
|
||||
constructor(slot: OptionalProps<INodeSlot, "boundingRect">) {
|
||||
constructor(slot: OptionalProps<INodeSlot, "boundingRect">, node: LGraphNode) {
|
||||
Object.assign(this, slot)
|
||||
this.name = slot.name
|
||||
this.type = slot.type
|
||||
this.boundingRect = slot.boundingRect ?? [0, 0, 0, 0]
|
||||
this.#node = node
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +132,7 @@ export abstract class NodeSlot implements INodeSlot {
|
||||
? this.highlightColor
|
||||
: LiteGraph.NODE_TEXT_COLOR
|
||||
|
||||
const pos = getCentre(this.boundingRect)
|
||||
const pos = this.#centreOffset
|
||||
const slot_type = this.type
|
||||
const slot_shape = (
|
||||
slot_type === SlotType.Array ? SlotShape.Grid : this.shape
|
||||
|
||||
@@ -2,9 +2,6 @@ import type { IWidgetInputSlot, SharedIntersection } from "@/interfaces"
|
||||
import type { INodeInputSlot, INodeOutputSlot, INodeSlot, IWidget } from "@/litegraph"
|
||||
import type { ISerialisableNodeInput, ISerialisableNodeOutput } from "@/types/serialisation"
|
||||
|
||||
import { NodeInputSlot } from "./NodeInputSlot"
|
||||
import { NodeOutputSlot } from "./NodeOutputSlot"
|
||||
|
||||
type CommonIoSlotProps = SharedIntersection<ISerialisableNodeInput, ISerialisableNodeOutput>
|
||||
|
||||
export function shallowCloneCommonProps(slot: CommonIoSlotProps): CommonIoSlotProps {
|
||||
@@ -57,11 +54,3 @@ export function isINodeOutputSlot(slot: INodeSlot): slot is INodeOutputSlot {
|
||||
export function isWidgetInputSlot(slot: INodeInputSlot): slot is IWidgetInputSlot {
|
||||
return !!slot.widget
|
||||
}
|
||||
|
||||
export function toNodeSlotClass(slot: INodeInputSlot | INodeOutputSlot): NodeInputSlot | NodeOutputSlot {
|
||||
if (slot instanceof NodeInputSlot || slot instanceof NodeOutputSlot) return slot
|
||||
|
||||
return "link" in slot
|
||||
? new NodeInputSlot(slot)
|
||||
: new NodeOutputSlot(slot)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user