mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-03 20:51: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:
@@ -12,6 +12,7 @@ import type { Ref } from 'vue'
|
||||
|
||||
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
|
||||
import { useNodeZIndex } from '@/renderer/extensions/vueNodes/composables/useNodeZIndex'
|
||||
|
||||
interface NodeManager {
|
||||
@@ -21,6 +22,7 @@ interface NodeManager {
|
||||
export function useNodeEventHandlers(nodeManager: Ref<NodeManager | null>) {
|
||||
const canvasStore = useCanvasStore()
|
||||
const { bringNodeToFront } = useNodeZIndex()
|
||||
const { shouldHandleNodePointerEvents } = useCanvasInteractions()
|
||||
|
||||
/**
|
||||
* Handle node selection events
|
||||
@@ -31,6 +33,8 @@ export function useNodeEventHandlers(nodeManager: Ref<NodeManager | null>) {
|
||||
nodeData: VueNodeData,
|
||||
wasDragging: boolean
|
||||
) => {
|
||||
if (!shouldHandleNodePointerEvents.value) return
|
||||
|
||||
if (!canvasStore.canvas || !nodeManager.value) return
|
||||
|
||||
const node = nodeManager.value.getNode(nodeData.id)
|
||||
@@ -69,6 +73,8 @@ export function useNodeEventHandlers(nodeManager: Ref<NodeManager | null>) {
|
||||
* Uses LiteGraph's native collapse method for proper state management
|
||||
*/
|
||||
const handleNodeCollapse = (nodeId: string, collapsed: boolean) => {
|
||||
if (!shouldHandleNodePointerEvents.value) return
|
||||
|
||||
if (!nodeManager.value) return
|
||||
|
||||
const node = nodeManager.value.getNode(nodeId)
|
||||
@@ -86,6 +92,8 @@ export function useNodeEventHandlers(nodeManager: Ref<NodeManager | null>) {
|
||||
* Updates the title in LiteGraph for persistence across sessions
|
||||
*/
|
||||
const handleNodeTitleUpdate = (nodeId: string, newTitle: string) => {
|
||||
if (!shouldHandleNodePointerEvents.value) return
|
||||
|
||||
if (!nodeManager.value) return
|
||||
|
||||
const node = nodeManager.value.getNode(nodeId)
|
||||
@@ -103,6 +111,8 @@ export function useNodeEventHandlers(nodeManager: Ref<NodeManager | null>) {
|
||||
event: PointerEvent,
|
||||
nodeData: VueNodeData
|
||||
) => {
|
||||
if (!shouldHandleNodePointerEvents.value) return
|
||||
|
||||
if (!canvasStore.canvas || !nodeManager.value) return
|
||||
|
||||
const node = nodeManager.value.getNode(nodeData.id)
|
||||
@@ -123,6 +133,8 @@ export function useNodeEventHandlers(nodeManager: Ref<NodeManager | null>) {
|
||||
* Integrates with LiteGraph's context menu system
|
||||
*/
|
||||
const handleNodeRightClick = (event: PointerEvent, nodeData: VueNodeData) => {
|
||||
if (!shouldHandleNodePointerEvents.value) return
|
||||
|
||||
if (!canvasStore.canvas || !nodeManager.value) return
|
||||
|
||||
const node = nodeManager.value.getNode(nodeData.id)
|
||||
@@ -145,6 +157,8 @@ export function useNodeEventHandlers(nodeManager: Ref<NodeManager | null>) {
|
||||
* Prepares node for dragging and sets appropriate visual state
|
||||
*/
|
||||
const handleNodeDragStart = (event: DragEvent, nodeData: VueNodeData) => {
|
||||
if (!shouldHandleNodePointerEvents.value) return
|
||||
|
||||
if (!canvasStore.canvas || !nodeManager.value) return
|
||||
|
||||
const node = nodeManager.value.getNode(nodeData.id)
|
||||
@@ -173,6 +187,8 @@ export function useNodeEventHandlers(nodeManager: Ref<NodeManager | null>) {
|
||||
* Useful for selection toolbox or area selection
|
||||
*/
|
||||
const selectNodes = (nodeIds: string[], addToSelection = false) => {
|
||||
if (!shouldHandleNodePointerEvents.value) return
|
||||
|
||||
if (!canvasStore.canvas || !nodeManager.value) return
|
||||
|
||||
if (!addToSelection) {
|
||||
@@ -193,6 +209,8 @@ export function useNodeEventHandlers(nodeManager: Ref<NodeManager | null>) {
|
||||
* Deselect specific nodes
|
||||
*/
|
||||
const deselectNodes = (nodeIds: string[]) => {
|
||||
if (!shouldHandleNodePointerEvents.value) return
|
||||
|
||||
if (!canvasStore.canvas || !nodeManager.value) return
|
||||
|
||||
nodeIds.forEach((nodeId) => {
|
||||
|
||||
Reference in New Issue
Block a user