mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-29 02:32:18 +00:00
Line Selection toolbox up with Vue Nodes (#5601)
This pull request improves the selection toolbox behavior during node dragging by ensuring that it correctly responds to both LiteGraph and Vue node drag events. The main changes introduce a reactive drag state for Vue nodes in the layout store and update the selection toolbox composable and Vue node component to use this state. **Selection toolbox behavior improvements:** * Added a helper function and separate watchers in `useSelectionToolboxPosition.ts` to hide the selection toolbox when either LiteGraph or Vue nodes are being dragged. This ensures consistent UI feedback regardless of node type. [[1]](diffhunk://#diff-57a51ac5e656e64ae7fd276d71b115058631621755de33b1eb8e8a4731d48713L171-R172) [[2]](diffhunk://#diff-57a51ac5e656e64ae7fd276d71b115058631621755de33b1eb8e8a4731d48713R212-R224) **Vue node drag state management:** * Added a reactive `isDraggingVueNodes` property to the `LayoutStoreImpl` class, along with getter and setter methods to manage Vue node drag state. This allows other components to reactively track when Vue nodes are being dragged. [[1]](diffhunk://#diff-80d32fe0fb72730c16cf7259adef8b20732ff214df240b1d39ae516737beaf3bR133-R135) [[2]](diffhunk://#diff-80d32fe0fb72730c16cf7259adef8b20732ff214df240b1d39ae516737beaf3bR354-R367) * Updated `LGraphNode.vue` to set and clear the Vue node dragging state in the layout store during pointer down and up events, ensuring the selection toolbox is hidden while dragging Vue nodes. [[1]](diffhunk://#diff-a7744614cf842e54416047326db79ad81f7c7ab7bfb66ae2b46f5c73ac7d47f2R357-R360) [[2]](diffhunk://#diff-a7744614cf842e54416047326db79ad81f7c7ab7bfb66ae2b46f5c73ac7d47f2R376-R378) **Dependency updates:** * Imported the `layoutStore` in `LGraphNode.vue` to access the new drag state management methods. * Added missing `ref` import in `layoutStore.ts` to support the new reactive property. https://github.com/user-attachments/assets/d6e9c15e-63b5-4de2-9688-ebbc6a3be545 --------- Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
committed by
GitHub
parent
09e7d1040e
commit
4789d86fe8
@@ -1,4 +1,4 @@
|
|||||||
import { onUnmounted, ref, watch } from 'vue'
|
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
|
|
||||||
import { useCanvasTransformSync } from '@/composables/canvas/useCanvasTransformSync'
|
import { useCanvasTransformSync } from '@/composables/canvas/useCanvasTransformSync'
|
||||||
@@ -170,50 +170,75 @@ export function useSelectionToolboxPosition(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Watch for dragging state
|
const handleDragStateChange = (dragging: boolean) => {
|
||||||
watch(
|
if (dragging) {
|
||||||
() => canvasStore.canvas?.state?.draggingItems,
|
handleDragStart()
|
||||||
(dragging) => {
|
return
|
||||||
if (dragging) {
|
|
||||||
visible.value = false
|
|
||||||
|
|
||||||
if (moreOptionsOpen.value) {
|
|
||||||
const currentSig = buildSelectionSignature(canvasStore)
|
|
||||||
if (currentSig !== moreOptionsSelectionSignature) {
|
|
||||||
moreOptionsSelectionSignature = null
|
|
||||||
}
|
|
||||||
moreOptionsWasOpenBeforeDrag = true
|
|
||||||
moreOptionsOpen.value = false
|
|
||||||
moreOptionsRestorePending.value = !!moreOptionsSelectionSignature
|
|
||||||
if (moreOptionsRestorePending.value) {
|
|
||||||
forceCloseMoreOptionsSignal.value++
|
|
||||||
} else {
|
|
||||||
moreOptionsWasOpenBeforeDrag = false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
moreOptionsRestorePending.value = false
|
|
||||||
moreOptionsWasOpenBeforeDrag = false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
updateSelectionBounds()
|
|
||||||
const selectionMatches = currentSelectionMatchesSignature(canvasStore)
|
|
||||||
const shouldRestore =
|
|
||||||
moreOptionsWasOpenBeforeDrag &&
|
|
||||||
visible.value &&
|
|
||||||
moreOptionsRestorePending.value &&
|
|
||||||
selectionMatches
|
|
||||||
|
|
||||||
if (shouldRestore) {
|
|
||||||
restoreMoreOptionsSignal.value++
|
|
||||||
} else {
|
|
||||||
moreOptionsRestorePending.value = false
|
|
||||||
}
|
|
||||||
moreOptionsWasOpenBeforeDrag = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
handleDragEnd()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDragStart = () => {
|
||||||
|
visible.value = false
|
||||||
|
|
||||||
|
// Early return if more options wasn't open
|
||||||
|
if (!moreOptionsOpen.value) {
|
||||||
|
moreOptionsRestorePending.value = false
|
||||||
|
moreOptionsWasOpenBeforeDrag = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle more options cleanup
|
||||||
|
const currentSig = buildSelectionSignature(canvasStore)
|
||||||
|
const selectionChanged = currentSig !== moreOptionsSelectionSignature
|
||||||
|
|
||||||
|
if (selectionChanged) {
|
||||||
|
moreOptionsSelectionSignature = null
|
||||||
|
}
|
||||||
|
moreOptionsOpen.value = false
|
||||||
|
moreOptionsWasOpenBeforeDrag = true
|
||||||
|
moreOptionsRestorePending.value = !!moreOptionsSelectionSignature
|
||||||
|
|
||||||
|
if (moreOptionsRestorePending.value) {
|
||||||
|
forceCloseMoreOptionsSignal.value++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
moreOptionsWasOpenBeforeDrag = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDragEnd = () => {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
updateSelectionBounds()
|
||||||
|
|
||||||
|
const selectionMatches = currentSelectionMatchesSignature(canvasStore)
|
||||||
|
const shouldRestore =
|
||||||
|
moreOptionsWasOpenBeforeDrag &&
|
||||||
|
visible.value &&
|
||||||
|
moreOptionsRestorePending.value &&
|
||||||
|
selectionMatches
|
||||||
|
|
||||||
|
// Single point of assignment for each ref
|
||||||
|
moreOptionsRestorePending.value =
|
||||||
|
shouldRestore && moreOptionsRestorePending.value
|
||||||
|
moreOptionsWasOpenBeforeDrag = false
|
||||||
|
|
||||||
|
if (shouldRestore) {
|
||||||
|
restoreMoreOptionsSignal.value++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unified dragging state - combines both LiteGraph and Vue node dragging
|
||||||
|
const isDragging = computed((): boolean => {
|
||||||
|
const litegraphDragging = canvasStore.canvas?.state?.draggingItems ?? false
|
||||||
|
const vueNodeDragging =
|
||||||
|
shouldRenderVueNodes.value && layoutStore.isDraggingVueNodes.value
|
||||||
|
return litegraphDragging || vueNodeDragging
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(isDragging, handleDragStateChange)
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
resetMoreOptionsState()
|
resetMoreOptionsState()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* CRDT ensures conflict-free operations for both single and multi-user scenarios.
|
* CRDT ensures conflict-free operations for both single and multi-user scenarios.
|
||||||
*/
|
*/
|
||||||
import log from 'loglevel'
|
import log from 'loglevel'
|
||||||
import { type ComputedRef, type Ref, computed, customRef } from 'vue'
|
import { type ComputedRef, type Ref, computed, customRef, ref } from 'vue'
|
||||||
import * as Y from 'yjs'
|
import * as Y from 'yjs'
|
||||||
|
|
||||||
import { ACTOR_CONFIG } from '@/renderer/core/layout/constants'
|
import { ACTOR_CONFIG } from '@/renderer/core/layout/constants'
|
||||||
@@ -134,6 +134,9 @@ class LayoutStoreImpl implements LayoutStore {
|
|||||||
private slotSpatialIndex: SpatialIndexManager // For slots
|
private slotSpatialIndex: SpatialIndexManager // For slots
|
||||||
private rerouteSpatialIndex: SpatialIndexManager // For reroutes
|
private rerouteSpatialIndex: SpatialIndexManager // For reroutes
|
||||||
|
|
||||||
|
// Vue dragging state for selection toolbox (public ref for direct mutation)
|
||||||
|
public isDraggingVueNodes = ref(false)
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// Initialize Yjs data structures
|
// Initialize Yjs data structures
|
||||||
this.ynodes = this.ydoc.getMap('nodes')
|
this.ynodes = this.ydoc.getMap('nodes')
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ import { useErrorHandling } from '@/composables/useErrorHandling'
|
|||||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||||
import { SelectedNodeIdsKey } from '@/renderer/core/canvas/injectionKeys'
|
import { SelectedNodeIdsKey } from '@/renderer/core/canvas/injectionKeys'
|
||||||
import { TransformStateKey } from '@/renderer/core/layout/injectionKeys'
|
import { TransformStateKey } from '@/renderer/core/layout/injectionKeys'
|
||||||
|
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
|
||||||
import { useNodeExecutionState } from '@/renderer/extensions/vueNodes/execution/useNodeExecutionState'
|
import { useNodeExecutionState } from '@/renderer/extensions/vueNodes/execution/useNodeExecutionState'
|
||||||
import { useNodeLayout } from '@/renderer/extensions/vueNodes/layout/useNodeLayout'
|
import { useNodeLayout } from '@/renderer/extensions/vueNodes/layout/useNodeLayout'
|
||||||
import { LODLevel, useLOD } from '@/renderer/extensions/vueNodes/lod/useLOD'
|
import { LODLevel, useLOD } from '@/renderer/extensions/vueNodes/lod/useLOD'
|
||||||
@@ -363,6 +364,10 @@ const handlePointerDown = (event: PointerEvent) => {
|
|||||||
|
|
||||||
// Start drag using layout system
|
// Start drag using layout system
|
||||||
isDragging.value = true
|
isDragging.value = true
|
||||||
|
|
||||||
|
// Set Vue node dragging state for selection toolbox
|
||||||
|
layoutStore.isDraggingVueNodes.value = true
|
||||||
|
|
||||||
startDrag(event)
|
startDrag(event)
|
||||||
lastY.value = event.clientY
|
lastY.value = event.clientY
|
||||||
lastX.value = event.clientX
|
lastX.value = event.clientX
|
||||||
@@ -378,6 +383,9 @@ const handlePointerUp = (event: PointerEvent) => {
|
|||||||
if (isDragging.value) {
|
if (isDragging.value) {
|
||||||
isDragging.value = false
|
isDragging.value = false
|
||||||
void endDrag(event)
|
void endDrag(event)
|
||||||
|
|
||||||
|
// Clear Vue node dragging state for selection toolbox
|
||||||
|
layoutStore.isDraggingVueNodes.value = false
|
||||||
}
|
}
|
||||||
// Emit node-click for selection handling in GraphCanvas
|
// Emit node-click for selection handling in GraphCanvas
|
||||||
const dx = event.clientX - lastX.value
|
const dx = event.clientX - lastX.value
|
||||||
|
|||||||
Reference in New Issue
Block a user