mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-02 19:49:58 +00:00
Make Vue nodes read-only when in panning mode (#5574)
## Summary Integrated Vue node components with canvas panning mode to prevent UI interference during navigation. ## Changes - **What**: Added [canCapturePointerEvents](https://docs.comfy.org/guide/vue-nodes) computed property to `useCanvasInteractions` composable that checks canvas read-only state - **What**: Modified Vue node components (LGraphNode, NodeWidgets) to conditionally handle pointer events based on canvas navigation mode - **What**: Updated node event handlers to respect panning mode and forward events to canvas when appropriate ## Review Focus Event forwarding logic in panning mode and pointer event capture state management across Vue node hierarchy. ```mermaid graph TD A[User Interaction] --> B{Canvas in Panning Mode?} B -->|Yes| C[Forward to Canvas] B -->|No| D[Handle in Vue Component] C --> E[Canvas Navigation] D --> F[Node Selection/Widget Interaction] G[canCapturePointerEvents] --> H{read_only === false} H -->|Yes| I[Allow Vue Events] H -->|No| J[Block Vue Events] style A fill:#f9f9f9,stroke:#333,color:#000 style E fill:#f9f9f9,stroke:#333,color:#000 style F fill:#f9f9f9,stroke:#333,color:#000 style I fill:#e1f5fe,stroke:#01579b,color:#000 style J fill:#ffebee,stroke:#c62828,color:#000 ``` ## Screenshots https://github.com/user-attachments/assets/00dc5e4a-2b56-43be-b92e-eaf511e52542 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5574-Make-Vue-nodes-read-only-when-in-panning-mode-26f6d73d3650818c951cd82c8fe58972) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
@@ -10,7 +10,9 @@
|
||||
'bg-white dark-theme:bg-charcoal-800',
|
||||
'lg-node absolute rounded-2xl',
|
||||
'border border-solid border-sand-100 dark-theme:border-charcoal-600',
|
||||
'hover:ring-7 ring-gray-500/50 dark-theme:ring-gray-500/20',
|
||||
// hover (only when node should handle events)
|
||||
shouldHandleNodePointerEvents &&
|
||||
'hover:ring-7 ring-gray-500/50 dark-theme:ring-gray-500/20',
|
||||
'outline-transparent -outline-offset-2 outline-2',
|
||||
borderClass,
|
||||
outlineClass,
|
||||
@@ -21,7 +23,9 @@
|
||||
'will-change-transform': isDragging
|
||||
},
|
||||
lodCssClass,
|
||||
'pointer-events-auto'
|
||||
shouldHandleNodePointerEvents
|
||||
? 'pointer-events-auto'
|
||||
: 'pointer-events-none'
|
||||
)
|
||||
"
|
||||
:style="[
|
||||
@@ -34,6 +38,7 @@
|
||||
@pointerdown="handlePointerDown"
|
||||
@pointermove="handlePointerMove"
|
||||
@pointerup="handlePointerUp"
|
||||
@wheel="handleWheel"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<template v-if="isCollapsed">
|
||||
@@ -147,6 +152,7 @@ import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
|
||||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { SelectedNodeIdsKey } from '@/renderer/core/canvas/injectionKeys'
|
||||
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
|
||||
import { TransformStateKey } from '@/renderer/core/layout/injectionKeys'
|
||||
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
|
||||
import { useNodeExecutionState } from '@/renderer/extensions/vueNodes/execution/useNodeExecutionState'
|
||||
@@ -237,6 +243,14 @@ const hasAnyError = computed(
|
||||
|
||||
const bypassed = computed((): boolean => nodeData.mode === 4)
|
||||
|
||||
// Use canvas interactions for proper wheel event handling and pointer event capture control
|
||||
const {
|
||||
handleWheel,
|
||||
handlePointer,
|
||||
forwardEventToCanvas,
|
||||
shouldHandleNodePointerEvents
|
||||
} = useCanvasInteractions()
|
||||
|
||||
// LOD (Level of Detail) system based on zoom level
|
||||
const zoomRef = toRef(() => zoomLevel)
|
||||
const {
|
||||
@@ -362,6 +376,12 @@ const handlePointerDown = (event: PointerEvent) => {
|
||||
return
|
||||
}
|
||||
|
||||
// Don't handle pointer events when canvas is in panning mode - forward to canvas instead
|
||||
if (!shouldHandleNodePointerEvents.value) {
|
||||
forwardEventToCanvas(event)
|
||||
return
|
||||
}
|
||||
|
||||
// Start drag using layout system
|
||||
isDragging.value = true
|
||||
|
||||
@@ -374,6 +394,9 @@ const handlePointerDown = (event: PointerEvent) => {
|
||||
}
|
||||
|
||||
const handlePointerMove = (event: PointerEvent) => {
|
||||
// Check if this should be forwarded to canvas (e.g., space panning, middle mouse)
|
||||
handlePointer(event)
|
||||
|
||||
if (isDragging.value) {
|
||||
void handleLayoutDrag(event)
|
||||
}
|
||||
@@ -387,6 +410,13 @@ const handlePointerUp = (event: PointerEvent) => {
|
||||
// Clear Vue node dragging state for selection toolbox
|
||||
layoutStore.isDraggingVueNodes.value = false
|
||||
}
|
||||
|
||||
// Don't emit node-click when canvas is in panning mode - forward to canvas instead
|
||||
if (!shouldHandleNodePointerEvents.value) {
|
||||
forwardEventToCanvas(event)
|
||||
return
|
||||
}
|
||||
|
||||
// Emit node-click for selection handling in GraphCanvas
|
||||
const dx = event.clientX - lastX.value
|
||||
const dy = event.clientY - lastY.value
|
||||
@@ -409,6 +439,12 @@ const handleSlotClick = (
|
||||
console.warn('LGraphNode: nodeData is null/undefined in handleSlotClick')
|
||||
return
|
||||
}
|
||||
|
||||
// Don't handle slot clicks when canvas is in panning mode
|
||||
if (!shouldHandleNodePointerEvents.value) {
|
||||
return
|
||||
}
|
||||
|
||||
emit('slot-click', event, nodeData, slotIndex, isInput)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user