6
6
type LinkRenderContext ,
7
7
LitegraphLinkAdapter
8
8
} from '@/renderer/core/canvas/litegraph/LitegraphLinkAdapter'
9
+ import { layoutStore } from '@/renderer/core/layout/store/LayoutStore'
9
10
10
11
import { CanvasPointer } from './CanvasPointer'
11
12
import type { ContextMenu } from './ContextMenu'
@@ -2197,11 +2198,14 @@ export class LGraphCanvas
2197
2198
this . processSelect ( node , e , true )
2198
2199
} else if ( this . links_render_mode !== LinkRenderType . HIDDEN_LINK ) {
2199
2200
// Reroutes
2200
- const reroute = graph . getRerouteOnPos (
2201
- e . canvasX ,
2202
- e . canvasY ,
2203
- this . #visibleReroutes
2204
- )
2201
+ // Try layout store first, fallback to old method
2202
+ const rerouteLayout = layoutStore . queryRerouteAtPoint ( {
2203
+ x : e . canvasX ,
2204
+ y : e . canvasY
2205
+ } )
2206
+ const reroute = rerouteLayout
2207
+ ? graph . getReroute ( Number ( rerouteLayout . id ) )
2208
+ : graph . getRerouteOnPos ( e . canvasX , e . canvasY , this . #visibleReroutes)
2205
2209
if ( reroute ) {
2206
2210
if ( e . altKey ) {
2207
2211
pointer . onClick = ( upEvent ) => {
@@ -2402,16 +2406,21 @@ export class LGraphCanvas
2402
2406
this . ctx . lineWidth = this . connections_width + 7
2403
2407
const dpi = Math . max ( window ?. devicePixelRatio ?? 1 , 1 )
2404
2408
2409
+ // Try layout store for link hit testing first
2410
+ const hitLinkId = layoutStore . queryLinkAtPoint ( { x, y } , this . ctx )
2411
+
2405
2412
for ( const linkSegment of this . renderedPaths ) {
2406
2413
const centre = linkSegment . _pos
2407
2414
if ( ! centre ) continue
2408
2415
2416
+ // Check if this link was hit (using layout store or fallback to old method)
2417
+ const isLinkHit = hitLinkId
2418
+ ? String ( linkSegment . id ) === hitLinkId
2419
+ : linkSegment . path &&
2420
+ this . ctx . isPointInStroke ( linkSegment . path , x * dpi , y * dpi )
2421
+
2409
2422
// If we shift click on a link then start a link from that input
2410
- if (
2411
- ( e . shiftKey || e . altKey ) &&
2412
- linkSegment . path &&
2413
- this . ctx . isPointInStroke ( linkSegment . path , x * dpi , y * dpi )
2414
- ) {
2423
+ if ( ( e . shiftKey || e . altKey ) && isLinkHit ) {
2415
2424
this . ctx . lineWidth = lineWidth
2416
2425
2417
2426
if ( e . shiftKey && ! e . altKey ) {
@@ -3139,8 +3148,27 @@ export class LGraphCanvas
3139
3148
// For input/output hovering
3140
3149
// to store the output of isOverNodeInput
3141
3150
const pos : Point = [ 0 , 0 ]
3142
- const inputId = isOverNodeInput ( node , x , y , pos )
3143
- const outputId = isOverNodeOutput ( node , x , y , pos )
3151
+
3152
+ // Try to use layout store for hit testing first, fallback to old method
3153
+ let inputId : number = - 1
3154
+ let outputId : number = - 1
3155
+
3156
+ const slotLayout = layoutStore . querySlotAtPoint ( { x, y } )
3157
+ if ( slotLayout && slotLayout . nodeId === String ( node . id ) ) {
3158
+ if ( slotLayout . type === 'input' ) {
3159
+ inputId = slotLayout . index
3160
+ pos [ 0 ] = slotLayout . position . x
3161
+ pos [ 1 ] = slotLayout . position . y
3162
+ } else {
3163
+ outputId = slotLayout . index
3164
+ pos [ 0 ] = slotLayout . position . x
3165
+ pos [ 1 ] = slotLayout . position . y
3166
+ }
3167
+ } else {
3168
+ // Fallback to old method
3169
+ inputId = isOverNodeInput ( node , x , y , pos )
3170
+ outputId = isOverNodeOutput ( node , x , y , pos )
3171
+ }
3144
3172
const overWidget = node . getWidgetOnPos ( x , y , true ) ?? undefined
3145
3173
3146
3174
if ( ! node . mouseOver ) {
@@ -5026,6 +5054,7 @@ export class LGraphCanvas
5026
5054
node . _setConcreteSlots ( )
5027
5055
if ( ! node . collapsed ) {
5028
5056
node . arrange ( )
5057
+ node . registerSlots ( ) // Register slots for hit detection
5029
5058
}
5030
5059
// Skip all node body/widget/title rendering. Vue overlay handles visuals.
5031
5060
return
@@ -5117,6 +5146,7 @@ export class LGraphCanvas
5117
5146
node . _setConcreteSlots ( )
5118
5147
if ( ! node . collapsed ) {
5119
5148
node . arrange ( )
5149
+ node . registerSlots ( ) // Register slots for hit detection
5120
5150
node . drawSlots ( ctx , {
5121
5151
fromSlot : this . linkConnector . renderLinks [ 0 ] ?. fromSlot as
5122
5152
| INodeOutputSlot
@@ -5131,6 +5161,7 @@ export class LGraphCanvas
5131
5161
5132
5162
this . drawNodeWidgets ( node , null , ctx )
5133
5163
} else if ( this . render_collapsed_slots ) {
5164
+ node . registerSlots ( ) // Register slots for collapsed nodes too
5134
5165
node . drawCollapsedSlots ( ctx )
5135
5166
}
5136
5167
@@ -5522,6 +5553,19 @@ export class LGraphCanvas
5522
5553
}
5523
5554
reroute . draw ( ctx , this . _pattern )
5524
5555
5556
+ // Register reroute layout with layout store for hit testing
5557
+ layoutStore . updateRerouteLayout ( String ( reroute . id ) , {
5558
+ id : String ( reroute . id ) ,
5559
+ position : { x : reroute . pos [ 0 ] , y : reroute . pos [ 1 ] } ,
5560
+ radius : 8 , // Reroute.radius
5561
+ bounds : {
5562
+ x : reroute . pos [ 0 ] - 8 ,
5563
+ y : reroute . pos [ 1 ] - 8 ,
5564
+ width : 16 ,
5565
+ height : 16
5566
+ }
5567
+ } )
5568
+
5525
5569
// Never draw slots when the pointer is down
5526
5570
if ( ! this . pointer . isDown ) reroute . drawSlots ( ctx )
5527
5571
}
@@ -6040,6 +6084,8 @@ export class LGraphCanvas
6040
6084
: segment . id
6041
6085
if ( linkId !== undefined ) {
6042
6086
graph . removeLink ( linkId )
6087
+ // Clean up layout store
6088
+ layoutStore . deleteLinkLayout ( String ( linkId ) )
6043
6089
}
6044
6090
break
6045
6091
}
@@ -8117,11 +8163,18 @@ export class LGraphCanvas
8117
8163
8118
8164
// Check for reroutes
8119
8165
if ( this . links_render_mode !== LinkRenderType . HIDDEN_LINK ) {
8120
- const reroute = this . graph . getRerouteOnPos (
8121
- event . canvasX ,
8122
- event . canvasY ,
8123
- this . #visibleReroutes
8124
- )
8166
+ // Try layout store first, fallback to old method
8167
+ const rerouteLayout = layoutStore . queryRerouteAtPoint ( {
8168
+ x : event . canvasX ,
8169
+ y : event . canvasY
8170
+ } )
8171
+ const reroute = rerouteLayout
8172
+ ? this . graph . getReroute ( Number ( rerouteLayout . id ) )
8173
+ : this . graph . getRerouteOnPos (
8174
+ event . canvasX ,
8175
+ event . canvasY ,
8176
+ this . #visibleReroutes
8177
+ )
8125
8178
if ( reroute ) {
8126
8179
menu_info . unshift (
8127
8180
{
0 commit comments