From 0939eba7d88de85f60403c99fed981b44e268d86 Mon Sep 17 00:00:00 2001 From: Benjamin Lu Date: Wed, 20 Aug 2025 16:30:40 -0400 Subject: [PATCH] Revert "feat: Add slot registration and spatial indexing for hit detection" This reverts commit 70fbfd0f5e1659305070761d6a4a0c0f597651df. --- src/lib/litegraph/src/LGraph.ts | 3 - src/lib/litegraph/src/LGraphCanvas.ts | 87 ++---- src/lib/litegraph/src/LGraphNode.ts | 10 +- src/lib/litegraph/src/LLink.ts | 5 - .../canvas/litegraph/LitegraphLinkAdapter.ts | 73 ----- .../core/canvas/litegraph/SlotCalculations.ts | 59 ---- src/renderer/core/layout/store/LayoutStore.ts | 266 +----------------- src/renderer/core/layout/types.ts | 53 +--- .../vueNodes/layout/useNodeLayout.ts | 32 --- 9 files changed, 26 insertions(+), 562 deletions(-) diff --git a/src/lib/litegraph/src/LGraph.ts b/src/lib/litegraph/src/LGraph.ts index 66448776c..1aba5881e 100644 --- a/src/lib/litegraph/src/LGraph.ts +++ b/src/lib/litegraph/src/LGraph.ts @@ -4,7 +4,6 @@ import { } from '@/lib/litegraph/src/constants' import type { UUID } from '@/lib/litegraph/src/utils/uuid' import { createUuidv4, zeroUuid } from '@/lib/litegraph/src/utils/uuid' -import { layoutStore } from '@/renderer/core/layout/store/LayoutStore' import type { DragAndScaleState } from './DragAndScale' import { LGraphCanvas } from './LGraphCanvas' @@ -1971,8 +1970,6 @@ export class LGraph // Drop broken links, and ignore reroutes with no valid links if (!reroute.validateLinks(this._links, this.floatingLinks)) { this.reroutes.delete(reroute.id) - // Clean up layout store - layoutStore.deleteRerouteLayout(String(reroute.id)) } } diff --git a/src/lib/litegraph/src/LGraphCanvas.ts b/src/lib/litegraph/src/LGraphCanvas.ts index e80e69e8e..9cfa57f33 100644 --- a/src/lib/litegraph/src/LGraphCanvas.ts +++ b/src/lib/litegraph/src/LGraphCanvas.ts @@ -3,7 +3,6 @@ import { type LinkRenderContext, LitegraphLinkAdapter } from '@/renderer/core/canvas/litegraph/LitegraphLinkAdapter' -import { layoutStore } from '@/renderer/core/layout/store/LayoutStore' import { CanvasPointer } from './CanvasPointer' import type { ContextMenu } from './ContextMenu' @@ -2195,14 +2194,11 @@ export class LGraphCanvas this.processSelect(node, e, true) } else if (this.links_render_mode !== LinkRenderType.HIDDEN_LINK) { // Reroutes - // Try layout store first, fallback to old method - const rerouteLayout = layoutStore.queryRerouteAtPoint({ - x: e.canvasX, - y: e.canvasY - }) - const reroute = rerouteLayout - ? graph.getReroute(Number(rerouteLayout.id)) - : graph.getRerouteOnPos(e.canvasX, e.canvasY, this.#visibleReroutes) + const reroute = graph.getRerouteOnPos( + e.canvasX, + e.canvasY, + this.#visibleReroutes + ) if (reroute) { if (e.altKey) { pointer.onClick = (upEvent) => { @@ -2401,21 +2397,16 @@ export class LGraphCanvas this.ctx.lineWidth = this.connections_width + 7 const dpi = window?.devicePixelRatio || 1 - // Try layout store for link hit testing first - const hitLinkId = layoutStore.queryLinkAtPoint({ x, y }, this.ctx) - for (const linkSegment of this.renderedPaths) { const centre = linkSegment._pos if (!centre) continue - // Check if this link was hit (using layout store or fallback to old method) - const isLinkHit = hitLinkId - ? String(linkSegment.id) === hitLinkId - : linkSegment.path && - this.ctx.isPointInStroke(linkSegment.path, x * dpi, y * dpi) - // If we shift click on a link then start a link from that input - if ((e.shiftKey || e.altKey) && isLinkHit) { + if ( + (e.shiftKey || e.altKey) && + linkSegment.path && + this.ctx.isPointInStroke(linkSegment.path, x * dpi, y * dpi) + ) { this.ctx.lineWidth = lineWidth if (e.shiftKey && !e.altKey) { @@ -3112,27 +3103,8 @@ export class LGraphCanvas // For input/output hovering // to store the output of isOverNodeInput const pos: Point = [0, 0] - - // Try to use layout store for hit testing first, fallback to old method - let inputId: number = -1 - let outputId: number = -1 - - const slotLayout = layoutStore.querySlotAtPoint({ x, y }) - if (slotLayout && slotLayout.nodeId === String(node.id)) { - if (slotLayout.type === 'input') { - inputId = slotLayout.index - pos[0] = slotLayout.position.x - pos[1] = slotLayout.position.y - } else { - outputId = slotLayout.index - pos[0] = slotLayout.position.x - pos[1] = slotLayout.position.y - } - } else { - // Fallback to old method - inputId = isOverNodeInput(node, x, y, pos) - outputId = isOverNodeOutput(node, x, y, pos) - } + const inputId = isOverNodeInput(node, x, y, pos) + const outputId = isOverNodeOutput(node, x, y, pos) const overWidget = node.getWidgetOnPos(x, y, true) ?? undefined if (!node.mouseOver) { @@ -5002,7 +4974,6 @@ export class LGraphCanvas node._setConcreteSlots() if (!node.collapsed) { node.arrange() - node.registerSlots() // Register slots for hit detection } // Skip all node body/widget/title rendering. Vue overlay handles visuals. return @@ -5094,7 +5065,6 @@ export class LGraphCanvas node._setConcreteSlots() if (!node.collapsed) { node.arrange() - node.registerSlots() // Register slots for hit detection node.drawSlots(ctx, { fromSlot: this.linkConnector.renderLinks[0]?.fromSlot as | INodeOutputSlot @@ -5109,7 +5079,6 @@ export class LGraphCanvas this.drawNodeWidgets(node, null, ctx) } else if (this.render_collapsed_slots) { - node.registerSlots() // Register slots for collapsed nodes too node.drawCollapsedSlots(ctx) } @@ -5501,19 +5470,6 @@ export class LGraphCanvas } reroute.draw(ctx, this._pattern) - // Register reroute layout with layout store for hit testing - layoutStore.updateRerouteLayout(String(reroute.id), { - id: String(reroute.id), - position: { x: reroute.pos[0], y: reroute.pos[1] }, - radius: 8, // Reroute.radius - bounds: { - x: reroute.pos[0] - 8, - y: reroute.pos[1] - 8, - width: 16, - height: 16 - } - }) - // Never draw slots when the pointer is down if (!this.pointer.isDown) reroute.drawSlots(ctx) } @@ -6026,8 +5982,6 @@ export class LGraphCanvas case 'Delete': graph.removeLink(segment.id) - // Clean up layout store - layoutStore.deleteLinkLayout(String(segment.id)) break default: } @@ -8072,18 +8026,11 @@ export class LGraphCanvas // Check for reroutes if (this.links_render_mode !== LinkRenderType.HIDDEN_LINK) { - // Try layout store first, fallback to old method - const rerouteLayout = layoutStore.queryRerouteAtPoint({ - x: event.canvasX, - y: event.canvasY - }) - const reroute = rerouteLayout - ? this.graph.getReroute(Number(rerouteLayout.id)) - : this.graph.getRerouteOnPos( - event.canvasX, - event.canvasY, - this.#visibleReroutes - ) + const reroute = this.graph.getRerouteOnPos( + event.canvasX, + event.canvasY, + this.#visibleReroutes + ) if (reroute) { menu_info.unshift( { diff --git a/src/lib/litegraph/src/LGraphNode.ts b/src/lib/litegraph/src/LGraphNode.ts index 04c16291e..36691dcff 100644 --- a/src/lib/litegraph/src/LGraphNode.ts +++ b/src/lib/litegraph/src/LGraphNode.ts @@ -3,8 +3,7 @@ import { type SlotPositionContext, calculateInputSlotPos, calculateInputSlotPosFromSlot, - calculateOutputSlotPos, - registerNodeSlots + calculateOutputSlotPos } from '@/renderer/core/canvas/litegraph/SlotCalculations' import type { DragAndScale } from './DragAndScale' @@ -4099,13 +4098,6 @@ export class LGraphNode this.#arrangeWidgetInputSlots() } - /** - * Register all slots with the layout store for hit detection - */ - registerSlots(): void { - registerNodeSlots(String(this.id), this.#getSlotPositionContext()) - } - /** * Draws a progress bar on the node. * @param ctx The canvas context to draw on diff --git a/src/lib/litegraph/src/LLink.ts b/src/lib/litegraph/src/LLink.ts index 55f97dc6d..c493a27a1 100644 --- a/src/lib/litegraph/src/LLink.ts +++ b/src/lib/litegraph/src/LLink.ts @@ -2,7 +2,6 @@ import { SUBGRAPH_INPUT_ID, SUBGRAPH_OUTPUT_ID } from '@/lib/litegraph/src/constants' -import { layoutStore } from '@/renderer/core/layout/store/LayoutStore' import type { LGraphNode, NodeId } from './LGraphNode' import type { Reroute, RerouteId } from './Reroute' @@ -448,13 +447,9 @@ export class LLink implements LinkSegment, Serialisable { reroute.linkIds.delete(this.id) if (!keepReroutes && !reroute.totalLinks) { network.reroutes.delete(reroute.id) - // Clean up layout store - layoutStore.deleteRerouteLayout(String(reroute.id)) } } network.links.delete(this.id) - // Clean up layout store - layoutStore.deleteLinkLayout(String(this.id)) } /** diff --git a/src/renderer/core/canvas/litegraph/LitegraphLinkAdapter.ts b/src/renderer/core/canvas/litegraph/LitegraphLinkAdapter.ts index ea22fa1f6..a5a28e72f 100644 --- a/src/renderer/core/canvas/litegraph/LitegraphLinkAdapter.ts +++ b/src/renderer/core/canvas/litegraph/LitegraphLinkAdapter.ts @@ -38,7 +38,6 @@ import { calculateOutputSlotPos } from '@/renderer/core/canvas/litegraph/SlotCalculations' import { layoutStore } from '@/renderer/core/layout/store/LayoutStore' -import type { LinkLayout } from '@/renderer/core/layout/types' export interface LinkRenderContext { // Canvas settings @@ -140,25 +139,6 @@ export class LitegraphLinkAdapter { // Store path for hit detection link.path = path - - // Register link layout with layout store - if (path && linkData.centerPos) { - const linkLayout: LinkLayout = { - id: String(link.id), - path, - bounds: this.calculateLinkBounds( - linkData.startPoint, - linkData.endPoint, - linkData.controlPoints - ), - centerPos: linkData.centerPos, - sourceNodeId: String(link.origin_id), - targetNodeId: String(link.target_id), - sourceSlot: link.origin_slot, - targetSlot: link.target_slot - } - layoutStore.updateLinkLayout(String(link.id), linkLayout) - } } /** @@ -454,25 +434,6 @@ export class LitegraphLinkAdapter { linkSegment._centreAngle = linkData.centerAngle } } - - // Register link layout with layout store if this is a real link - if (link && path && linkData.centerPos) { - const linkLayout: LinkLayout = { - id: String(link.id), - path, - bounds: this.calculateLinkBounds( - linkData.startPoint, - linkData.endPoint, - linkData.controlPoints - ), - centerPos: linkData.centerPos, - sourceNodeId: String(link.origin_id), - targetNodeId: String(link.target_id), - sourceSlot: link.origin_slot, - targetSlot: link.target_slot - } - layoutStore.updateLinkLayout(String(link.id), linkLayout) - } } } @@ -561,38 +522,4 @@ export class LitegraphLinkAdapter { // Render using pure renderer this.pathRenderer.drawDraggingLink(ctx, dragData, pathContext) } - - /** - * Calculate bounding box for a link - */ - private calculateLinkBounds( - startPoint: Point, - endPoint: Point, - controlPoints?: Point[] - ): { x: number; y: number; width: number; height: number } { - // Start with endpoints - let minX = Math.min(startPoint.x, endPoint.x) - let maxX = Math.max(startPoint.x, endPoint.x) - let minY = Math.min(startPoint.y, endPoint.y) - let maxY = Math.max(startPoint.y, endPoint.y) - - // Include control points if present (for spline links) - if (controlPoints) { - for (const cp of controlPoints) { - minX = Math.min(minX, cp.x) - maxX = Math.max(maxX, cp.x) - minY = Math.min(minY, cp.y) - maxY = Math.max(maxY, cp.y) - } - } - - // Add some padding for hit detection - const padding = 10 - return { - x: minX - padding, - y: minY - padding, - width: maxX - minX + 2 * padding, - height: maxY - minY + 2 * padding - } - } } diff --git a/src/renderer/core/canvas/litegraph/SlotCalculations.ts b/src/renderer/core/canvas/litegraph/SlotCalculations.ts index ca08ae685..5084028c5 100644 --- a/src/renderer/core/canvas/litegraph/SlotCalculations.ts +++ b/src/renderer/core/canvas/litegraph/SlotCalculations.ts @@ -13,8 +13,6 @@ import type { } from '@/lib/litegraph/src/interfaces' import { LiteGraph } from '@/lib/litegraph/src/litegraph' import { isWidgetInputSlot } from '@/lib/litegraph/src/node/slotUtils' -import { layoutStore } from '@/renderer/core/layout/store/LayoutStore' -import type { SlotLayout } from '@/renderer/core/layout/types' export interface SlotPositionContext { /** Node's X position in graph coordinates */ @@ -231,60 +229,3 @@ function calculateVueSlotPosition( return [nodeX + slotCenterX, nodeY + slotCenterY] } - -/** - * Register slot layout with the layout store for hit testing - * @param nodeId The node ID - * @param slotIndex The slot index - * @param isInput Whether this is an input slot - * @param position The slot position in graph coordinates - */ -export function registerSlotLayout( - nodeId: string, - slotIndex: number, - isInput: boolean, - position: Point -): void { - const slotKey = `${nodeId}-${isInput ? 'in' : 'out'}-${slotIndex}` - - // Calculate bounds for the slot (20x20 area around center) - const slotSize = 20 - const halfSize = slotSize / 2 - - const slotLayout: SlotLayout = { - nodeId, - index: slotIndex, - type: isInput ? 'input' : 'output', - position: { x: position[0], y: position[1] }, - bounds: { - x: position[0] - halfSize, - y: position[1] - halfSize, - width: slotSize, - height: slotSize - } - } - - layoutStore.updateSlotLayout(slotKey, slotLayout) -} - -/** - * Register all slots for a node - * @param nodeId The node ID - * @param context The slot position context - */ -export function registerNodeSlots( - nodeId: string, - context: SlotPositionContext -): void { - // Register input slots - context.inputs.forEach((_, index) => { - const position = calculateInputSlotPos(context, index) - registerSlotLayout(nodeId, index, true, position) - }) - - // Register output slots - context.outputs.forEach((_, index) => { - const position = calculateOutputSlotPos(context, index) - registerSlotLayout(nodeId, index, false, position) - }) -} diff --git a/src/renderer/core/layout/store/LayoutStore.ts b/src/renderer/core/layout/store/LayoutStore.ts index 2bf931ea2..c3c46fd9a 100644 --- a/src/renderer/core/layout/store/LayoutStore.ts +++ b/src/renderer/core/layout/store/LayoutStore.ts @@ -20,14 +20,9 @@ import type { Bounds, LayoutChange, LayoutStore, - LinkId, - LinkLayout, NodeId, NodeLayout, - Point, - RerouteId, - RerouteLayout, - SlotLayout + Point } from '@/renderer/core/layout/types' import { SpatialIndexManager } from '@/renderer/core/spatial/SpatialIndex' @@ -43,7 +38,7 @@ class LayoutStoreImpl implements LayoutStore { ACTOR_CONFIG.DEFAULT_SOURCE private currentActor = `${ACTOR_CONFIG.USER_PREFIX}${Math.random() .toString(36) - .substring(2, 2 + ACTOR_CONFIG.ID_LENGTH)}` + .substr(2, ACTOR_CONFIG.ID_LENGTH)}` // Change listeners private changeListeners = new Set<(change: LayoutChange) => void>() @@ -52,27 +47,16 @@ class LayoutStoreImpl implements LayoutStore { private nodeRefs = new Map>() private nodeTriggers = new Map void>() - // New data structures for hit testing - private linkLayouts = new Map() - private slotLayouts = new Map() - private rerouteLayouts = new Map() - - // Spatial index managers - private spatialIndex: SpatialIndexManager // For nodes - private linkSpatialIndex: SpatialIndexManager // For links - private slotSpatialIndex: SpatialIndexManager // For slots - private rerouteSpatialIndex: SpatialIndexManager // For reroutes + // Spatial index manager + private spatialIndex: SpatialIndexManager constructor() { // Initialize Yjs data structures this.ynodes = this.ydoc.getMap('nodes') this.yoperations = this.ydoc.getArray('operations') - // Initialize spatial index managers + // Initialize spatial index manager this.spatialIndex = new SpatialIndexManager() - this.linkSpatialIndex = new SpatialIndexManager() - this.slotSpatialIndex = new SpatialIndexManager() - this.rerouteSpatialIndex = new SpatialIndexManager() // Listen for Yjs changes and trigger Vue reactivity this.ynodes.observe((event) => { @@ -275,237 +259,6 @@ class LayoutStoreImpl implements LayoutStore { return this.spatialIndex.query(bounds) } - /** - * Update link layout data - */ - updateLinkLayout(linkId: LinkId, layout: LinkLayout): void { - const existing = this.linkLayouts.get(linkId) - - if (existing) { - // Update spatial index - this.linkSpatialIndex.update(linkId, layout.bounds) - } else { - // Insert into spatial index - this.linkSpatialIndex.insert(linkId, layout.bounds) - } - - this.linkLayouts.set(linkId, layout) - } - - /** - * Delete link layout data - */ - deleteLinkLayout(linkId: LinkId): void { - const deleted = this.linkLayouts.delete(linkId) - if (deleted) { - // Remove from spatial index - this.linkSpatialIndex.remove(linkId) - } - } - - /** - * Update slot layout data - */ - updateSlotLayout(key: string, layout: SlotLayout): void { - const existing = this.slotLayouts.get(key) - - if (existing) { - // Update spatial index - this.slotSpatialIndex.update(key, layout.bounds) - } else { - // Insert into spatial index - this.slotSpatialIndex.insert(key, layout.bounds) - } - - this.slotLayouts.set(key, layout) - } - - /** - * Delete slot layout data - */ - deleteSlotLayout(key: string): void { - const deleted = this.slotLayouts.delete(key) - if (deleted) { - // Remove from spatial index - this.slotSpatialIndex.remove(key) - } - } - - /** - * Delete all slot layouts for a node - */ - deleteNodeSlotLayouts(nodeId: NodeId): void { - const keysToDelete: string[] = [] - for (const [key, layout] of this.slotLayouts) { - if (layout.nodeId === nodeId) { - keysToDelete.push(key) - } - } - for (const key of keysToDelete) { - this.slotLayouts.delete(key) - // Remove from spatial index - this.slotSpatialIndex.remove(key) - } - } - - /** - * Update reroute layout data - */ - updateRerouteLayout(rerouteId: RerouteId, layout: RerouteLayout): void { - const existing = this.rerouteLayouts.get(rerouteId) - - if (existing) { - // Update spatial index - this.rerouteSpatialIndex.update(rerouteId, layout.bounds) - } else { - // Insert into spatial index - this.rerouteSpatialIndex.insert(rerouteId, layout.bounds) - } - - this.rerouteLayouts.set(rerouteId, layout) - } - - /** - * Delete reroute layout data - */ - deleteRerouteLayout(rerouteId: RerouteId): void { - const deleted = this.rerouteLayouts.delete(rerouteId) - if (deleted) { - // Remove from spatial index - this.rerouteSpatialIndex.remove(rerouteId) - } - } - - /** - * Get link layout data - */ - getLinkLayout(linkId: LinkId): LinkLayout | null { - return this.linkLayouts.get(linkId) || null - } - - /** - * Get slot layout data - */ - getSlotLayout(key: string): SlotLayout | null { - return this.slotLayouts.get(key) || null - } - - /** - * Get reroute layout data - */ - getRerouteLayout(rerouteId: RerouteId): RerouteLayout | null { - return this.rerouteLayouts.get(rerouteId) || null - } - - /** - * Query link at point - */ - queryLinkAtPoint( - point: Point, - ctx?: CanvasRenderingContext2D - ): LinkId | null { - // Use spatial index to get candidate links - const searchArea = { - x: point.x - 10, // Tolerance for line width - y: point.y - 10, - width: 20, - height: 20 - } - const candidateLinkIds = this.linkSpatialIndex.query(searchArea) - - // Precise hit test only on candidates - for (const linkId of candidateLinkIds) { - const linkLayout = this.linkLayouts.get(linkId) - if (!linkLayout) continue - - if (ctx && linkLayout.path) { - // Save and set appropriate line width for hit testing - const oldLineWidth = ctx.lineWidth - ctx.lineWidth = 10 // Hit test tolerance - - const hit = ctx.isPointInStroke(linkLayout.path, point.x, point.y) - ctx.lineWidth = oldLineWidth - - if (hit) return linkId - } else if (this.pointInBounds(point, linkLayout.bounds)) { - // Fallback to bounding box test - return linkId - } - } - - return null - } - - /** - * Query slot at point - */ - querySlotAtPoint(point: Point): SlotLayout | null { - // Use spatial index to get candidate slots - const searchArea = { - x: point.x - 10, // Tolerance for slot size - y: point.y - 10, - width: 20, - height: 20 - } - const candidateSlotKeys = this.slotSpatialIndex.query(searchArea) - - // Check precise bounds for candidates - for (const key of candidateSlotKeys) { - const slotLayout = this.slotLayouts.get(key) - if (slotLayout && this.pointInBounds(point, slotLayout.bounds)) { - return slotLayout - } - } - return null - } - - /** - * Query reroute at point - */ - queryRerouteAtPoint(point: Point): RerouteLayout | null { - // Use spatial index to get candidate reroutes - const maxRadius = 20 // Maximum expected reroute radius - const searchArea = { - x: point.x - maxRadius, - y: point.y - maxRadius, - width: maxRadius * 2, - height: maxRadius * 2 - } - const candidateRerouteIds = this.rerouteSpatialIndex.query(searchArea) - - // Check precise distance for candidates - for (const rerouteId of candidateRerouteIds) { - const rerouteLayout = this.rerouteLayouts.get(rerouteId) - if (rerouteLayout) { - const dx = point.x - rerouteLayout.position.x - const dy = point.y - rerouteLayout.position.y - const distance = Math.sqrt(dx * dx + dy * dy) - - if (distance <= rerouteLayout.radius) { - return rerouteLayout - } - } - } - return null - } - - /** - * Query all items in bounds - */ - queryItemsInBounds(bounds: Bounds): { - nodes: NodeId[] - links: LinkId[] - slots: string[] - reroutes: RerouteId[] - } { - return { - nodes: this.queryNodesInBounds(bounds), - links: this.linkSpatialIndex.query(bounds), // Use spatial index for links - slots: this.slotSpatialIndex.query(bounds), // Use spatial index for slots - reroutes: this.rerouteSpatialIndex.query(bounds) // Use spatial index for reroutes - } - } - /** * Apply a layout operation using Yjs transactions */ @@ -625,12 +378,6 @@ class LayoutStoreImpl implements LayoutStore { this.nodeRefs.clear() this.nodeTriggers.clear() this.spatialIndex.clear() - this.linkSpatialIndex.clear() - this.slotSpatialIndex.clear() - this.rerouteSpatialIndex.clear() - this.linkLayouts.clear() - this.slotLayouts.clear() - this.rerouteLayouts.clear() nodes.forEach((node, index) => { const layout: NodeLayout = { @@ -740,9 +487,6 @@ class LayoutStoreImpl implements LayoutStore { // Remove from spatial index this.spatialIndex.remove(operation.nodeId) - // Clean up associated slot layouts - this.deleteNodeSlotLayouts(operation.nodeId) - change.type = 'delete' change.nodeIds.push(operation.nodeId) } diff --git a/src/renderer/core/layout/types.ts b/src/renderer/core/layout/types.ts index 617b8a33e..c8c5da763 100644 --- a/src/renderer/core/layout/types.ts +++ b/src/renderer/core/layout/types.ts @@ -28,8 +28,6 @@ export interface Bounds { export type NodeId = string export type SlotId = string export type ConnectionId = string -export type LinkId = string -export type RerouteId = string // Layout data structures export interface NodeLayout { @@ -43,29 +41,11 @@ export interface NodeLayout { } export interface SlotLayout { + id: SlotId nodeId: NodeId - index: number + position: Point // Relative to node type: 'input' | 'output' - position: Point - bounds: Bounds -} - -export interface LinkLayout { - id: string - path: Path2D - bounds: Bounds - centerPos: Point - sourceNodeId: NodeId - targetNodeId: NodeId - sourceSlot: number - targetSlot: number -} - -export interface RerouteLayout { - id: RerouteId - position: Point - radius: number - bounds: Bounds + index: number } export interface ConnectionLayout { @@ -320,33 +300,6 @@ export interface LayoutStore { queryNodeAtPoint(point: Point): NodeId | null queryNodesInBounds(bounds: Bounds): NodeId[] - // Hit testing queries for links, slots, and reroutes - queryLinkAtPoint(point: Point, ctx?: CanvasRenderingContext2D): LinkId | null - querySlotAtPoint(point: Point): SlotLayout | null - queryRerouteAtPoint(point: Point): RerouteLayout | null - queryItemsInBounds(bounds: Bounds): { - nodes: NodeId[] - links: LinkId[] - slots: string[] - reroutes: RerouteId[] - } - - // Update methods for link, slot, and reroute layouts - updateLinkLayout(linkId: LinkId, layout: LinkLayout): void - updateSlotLayout(key: string, layout: SlotLayout): void - updateRerouteLayout(rerouteId: RerouteId, layout: RerouteLayout): void - - // Delete methods for cleanup - deleteLinkLayout(linkId: LinkId): void - deleteSlotLayout(key: string): void - deleteNodeSlotLayouts(nodeId: NodeId): void - deleteRerouteLayout(rerouteId: RerouteId): void - - // Get layout data - getLinkLayout(linkId: LinkId): LinkLayout | null - getSlotLayout(key: string): SlotLayout | null - getRerouteLayout(rerouteId: RerouteId): RerouteLayout | null - // Direct mutation API (CRDT-ready) applyOperation(operation: LayoutOperation): void diff --git a/src/renderer/extensions/vueNodes/layout/useNodeLayout.ts b/src/renderer/extensions/vueNodes/layout/useNodeLayout.ts index b197bc441..ff77c040c 100644 --- a/src/renderer/extensions/vueNodes/layout/useNodeLayout.ts +++ b/src/renderer/extensions/vueNodes/layout/useNodeLayout.ts @@ -6,12 +6,9 @@ */ import { computed, inject } from 'vue' -import { registerNodeSlots } from '@/renderer/core/canvas/litegraph/SlotCalculations' -import type { SlotPositionContext } from '@/renderer/core/canvas/litegraph/SlotCalculations' import { layoutMutations } from '@/renderer/core/layout/operations/LayoutMutations' import { layoutStore } from '@/renderer/core/layout/store/LayoutStore' import type { Point } from '@/renderer/core/layout/types' -import { app } from '@/scripts/app' /** * Composable for individual Vue node components @@ -139,34 +136,6 @@ export function useNodeLayout(nodeId: string) { mutations.resizeNode(nodeId, newSize) } - /** - * Update slot layouts for this node - * Should be called whenever the node's slots or position changes - */ - function updateSlotLayouts() { - if (!layoutRef.value || !app.graph) return - - const node = app.graph.getNodeById(Number(nodeId)) - if (!node) return - - // Create context for slot position calculation - const context: SlotPositionContext = { - nodeX: layoutRef.value.position.x, - nodeY: layoutRef.value.position.y, - nodeWidth: layoutRef.value.size.width, - nodeHeight: layoutRef.value.size.height, - collapsed: node.flags?.collapsed || false, - collapsedWidth: node._collapsed_width, - slotStartY: node.constructor.slot_start_y, - inputs: node.inputs || [], - outputs: node.outputs || [], - widgets: node.widgets - } - - // Register all slots for this node - registerNodeSlots(nodeId, context) - } - return { // Reactive state (via customRef) layoutRef, @@ -179,7 +148,6 @@ export function useNodeLayout(nodeId: string) { // Mutations moveTo, resize, - updateSlotLayouts, // Drag handlers startDrag,