From 266f8744ad3e7bbaca599f99294b08d2da313c9b Mon Sep 17 00:00:00 2001 From: Braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:25:24 +0200 Subject: [PATCH] chore(core): cleanup pane (#1507) * chore(core): cleanup pane * chore(core): cleanup actions --- packages/core/src/container/Pane/Pane.vue | 126 +++++++++++++--------- packages/core/src/store/actions.ts | 121 ++++++--------------- packages/core/src/types/hooks.ts | 6 +- packages/core/src/types/store.ts | 12 ++- packages/core/src/utils/changes.ts | 41 +++---- packages/core/src/utils/storage.ts | 2 + 6 files changed, 144 insertions(+), 164 deletions(-) diff --git a/packages/core/src/container/Pane/Pane.vue b/packages/core/src/container/Pane/Pane.vue index 40b98111..b9417950 100644 --- a/packages/core/src/container/Pane/Pane.vue +++ b/packages/core/src/container/Pane/Pane.vue @@ -2,9 +2,10 @@ import { ref, toRef, watch } from 'vue' import UserSelection from '../../components/UserSelection/UserSelection.vue' import NodesSelection from '../../components/NodesSelection/NodesSelection.vue' +import type { NodeChange } from '../../types' import { SelectionMode } from '../../types' import { useKeyPress, useVueFlow } from '../../composables' -import { getConnectedEdges, getNodesInside } from '../../utils' +import { getEventPosition, getNodesInside, getSelectionChanges } from '../../utils' import { getMousePosition } from './utils' const { isSelecting, selectionKeyPressed } = defineProps<{ isSelecting: boolean; selectionKeyPressed: boolean }>() @@ -12,7 +13,6 @@ const { isSelecting, selectionKeyPressed } = defineProps<{ isSelecting: boolean; const { vueFlowRef, getNodes, - getEdges, viewport, emits, userSelectionActive, @@ -21,7 +21,6 @@ const { userSelectionRect, elementsSelectable, nodesSelectionActive, - addSelectedElements, getSelectedEdges, getSelectedNodes, removeNodes, @@ -30,6 +29,8 @@ const { deleteKeyCode, multiSelectionKeyCode, multiSelectionActive, + edgeLookup, + nodeLookup, } = useVueFlow() const container = ref(null) @@ -40,6 +41,8 @@ const prevSelectedEdgesCount = ref(0) const containerBounds = ref() +const edgeIdLookup = ref>>(new Map()) + const hasActiveSelection = toRef(() => elementsSelectable.value && (isSelecting || userSelectionActive.value)) // Used to prevent click events when the user lets go of the selectionKey during a selection @@ -65,6 +68,16 @@ watch(multiSelectKeyPressed, (isKeyPressed) => { multiSelectionActive.value = isKeyPressed }) +function wrapHandler(handler: Function, containerRef: HTMLDivElement | null) { + return (event: MouseEvent) => { + if (event.target !== containerRef) { + return + } + + handler?.(event) + } +} + function resetUserSelection() { userSelectionActive.value = false userSelectionRect.value = null @@ -74,7 +87,7 @@ function resetUserSelection() { } function onClick(event: MouseEvent) { - if (selectionInProgress.value || event.target !== container.value || hasActiveSelection.value) { + if (selectionInProgress.value) { selectionInProgress.value = false return } @@ -87,10 +100,6 @@ function onClick(event: MouseEvent) { } function onContextMenu(event: MouseEvent) { - if (event.target !== container.value) { - return - } - if (Array.isArray(panOnDrag.value) && panOnDrag.value?.includes(2)) { event.preventDefault() return @@ -100,27 +109,32 @@ function onContextMenu(event: MouseEvent) { } function onWheel(event: WheelEvent) { - if (event.target !== container.value) { - return - } - emits.paneScroll(event) } function onPointerDown(event: PointerEvent) { - if (!hasActiveSelection.value) { - return emits.paneMouseMove(event) - } - containerBounds.value = vueFlowRef.value?.getBoundingClientRect() container.value?.setPointerCapture(event.pointerId) - if (!elementsSelectable || !isSelecting || event.button !== 0 || event.target !== container.value || !containerBounds.value) { + if ( + !elementsSelectable.value || + !isSelecting || + event.button !== 0 || + event.target !== container.value || + !containerBounds.value + ) { return } const { x, y } = getMousePosition(event, containerBounds.value) + edgeIdLookup.value = new Map() + + for (const [id, edge] of edgeLookup.value) { + edgeIdLookup.value.set(edge.source, edgeIdLookup.value.get(edge.source)?.add(id) || new Set([id])) + edgeIdLookup.value.set(edge.target, edgeIdLookup.value.get(edge.target)?.add(id) || new Set([id])) + } + removeSelectedElements() userSelectionRect.value = { @@ -138,43 +152,62 @@ function onPointerDown(event: PointerEvent) { } function onPointerMove(event: PointerEvent) { - if (!hasActiveSelection.value) { - return emits.paneMouseMove(event) - } - if (!containerBounds.value || !userSelectionRect.value) { return } selectionInProgress.value = true - const mousePos = getMousePosition(event, containerBounds.value) + const { x: mouseX, y: mouseY } = getEventPosition(event, containerBounds.value) const { startX = 0, startY = 0 } = userSelectionRect.value const nextUserSelectRect = { - ...userSelectionRect.value, - x: mousePos.x < startX ? mousePos.x : startX, - y: mousePos.y < startY ? mousePos.y : startY, - width: Math.abs(mousePos.x - startX), - height: Math.abs(mousePos.y - startY), + startX, + startY, + x: mouseX < startX ? mouseX : startX, + y: mouseY < startY ? mouseY : startY, + width: Math.abs(mouseX - startX), + height: Math.abs(mouseY - startY), } const selectedNodes = getNodesInside( getNodes.value, - userSelectionRect.value, + nextUserSelectRect, viewport.value, selectionMode.value === SelectionMode.Partial, true, ) - const selectedEdges = getConnectedEdges(selectedNodes, getEdges.value) + const selectedEdgeIds = new Set() + const selectedNodeIds = new Set() - prevSelectedNodesCount.value = selectedNodes.length - prevSelectedEdgesCount.value = selectedEdges.length + for (const selectedNode of selectedNodes) { + selectedNodeIds.add(selectedNode.id) + + const edgeIds = edgeIdLookup.value.get(selectedNode.id) + + if (edgeIds) { + for (const edgeId of edgeIds) { + selectedEdgeIds.add(edgeId) + } + } + } + + if (prevSelectedNodesCount.value !== selectedNodeIds.size) { + prevSelectedNodesCount.value = selectedNodeIds.size + const changes = getSelectionChanges(nodeLookup.value, selectedNodeIds, true) as NodeChange[] + emits.nodesChange(changes) + } + + if (prevSelectedEdgesCount.value !== selectedEdgeIds.size) { + prevSelectedEdgesCount.value = selectedEdgeIds.size + const changes = getSelectionChanges(edgeLookup.value, selectedEdgeIds) + emits.edgesChange(changes) + } userSelectionRect.value = nextUserSelectRect - - addSelectedElements([...selectedNodes, ...selectedEdges]) + userSelectionActive.value = true + nodesSelectionActive.value = false } function onPointerUp(event: PointerEvent) { @@ -184,10 +217,6 @@ function onPointerUp(event: PointerEvent) { container.value?.releasePointerCapture(event.pointerId) - if (!hasActiveSelection.value) { - return - } - // We only want to trigger click functions when in selection mode if // the user did not move the mouse. if (!userSelectionActive.value && userSelectionRect.value && event.target === container.value) { @@ -206,14 +235,6 @@ function onPointerUp(event: PointerEvent) { selectionInProgress.value = false } } - -function onPointerEnter(event: PointerEvent) { - if (hasActiveSelection.value) { - return - } - - emits.paneMouseEnter(event) -}