Skip to content

Commit 266f874

Browse files
committed
chore(core): cleanup pane (#1507)
* chore(core): cleanup pane * chore(core): cleanup actions
1 parent e57f22c commit 266f874

File tree

6 files changed

+145
-165
lines changed

6 files changed

+145
-165
lines changed

packages/core/src/container/Pane/Pane.vue

Lines changed: 74 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
import { ref, toRef, watch } from 'vue'
33
import UserSelection from '../../components/UserSelection/UserSelection.vue'
44
import NodesSelection from '../../components/NodesSelection/NodesSelection.vue'
5+
import type { NodeChange } from '../../types'
56
import { SelectionMode } from '../../types'
67
import { useKeyPress, useVueFlow } from '../../composables'
7-
import { getConnectedEdges, getNodesInside } from '../../utils'
8+
import { getEventPosition, getNodesInside, getSelectionChanges } from '../../utils'
89
import { getMousePosition } from './utils'
910
1011
const { isSelecting, selectionKeyPressed } = defineProps<{ isSelecting: boolean; selectionKeyPressed: boolean }>()
1112
1213
const {
1314
vueFlowRef,
1415
getNodes,
15-
getEdges,
1616
viewport,
1717
emits,
1818
userSelectionActive,
@@ -21,7 +21,6 @@ const {
2121
userSelectionRect,
2222
elementsSelectable,
2323
nodesSelectionActive,
24-
addSelectedElements,
2524
getSelectedEdges,
2625
getSelectedNodes,
2726
removeNodes,
@@ -30,6 +29,8 @@ const {
3029
deleteKeyCode,
3130
multiSelectionKeyCode,
3231
multiSelectionActive,
32+
edgeLookup,
33+
nodeLookup,
3334
} = useVueFlow()
3435
3536
const container = ref<HTMLDivElement | null>(null)
@@ -40,6 +41,8 @@ const prevSelectedEdgesCount = ref(0)
4041
4142
const containerBounds = ref<DOMRect>()
4243
44+
const edgeIdLookup = ref<Map<string, Set<string>>>(new Map())
45+
4346
const hasActiveSelection = toRef(() => elementsSelectable.value && (isSelecting || userSelectionActive.value))
4447
4548
// Used to prevent click events when the user lets go of the selectionKey during a selection
@@ -65,6 +68,16 @@ watch(multiSelectKeyPressed, (isKeyPressed) => {
6568
multiSelectionActive.value = isKeyPressed
6669
})
6770
71+
function wrapHandler(handler: Function, containerRef: HTMLDivElement | null) {
72+
return (event: MouseEvent) => {
73+
if (event.target !== containerRef) {
74+
return
75+
}
76+
77+
handler?.(event)
78+
}
79+
}
80+
6881
function resetUserSelection() {
6982
userSelectionActive.value = false
7083
userSelectionRect.value = null
@@ -74,7 +87,7 @@ function resetUserSelection() {
7487
}
7588
7689
function onClick(event: MouseEvent) {
77-
if (selectionInProgress.value || event.target !== container.value || hasActiveSelection.value) {
90+
if (selectionInProgress.value) {
7891
selectionInProgress.value = false
7992
return
8093
}
@@ -87,10 +100,6 @@ function onClick(event: MouseEvent) {
87100
}
88101
89102
function onContextMenu(event: MouseEvent) {
90-
if (event.target !== container.value) {
91-
return
92-
}
93-
94103
if (Array.isArray(panOnDrag.value) && panOnDrag.value?.includes(2)) {
95104
event.preventDefault()
96105
return
@@ -100,27 +109,32 @@ function onContextMenu(event: MouseEvent) {
100109
}
101110
102111
function onWheel(event: WheelEvent) {
103-
if (event.target !== container.value) {
104-
return
105-
}
106-
107112
emits.paneScroll(event)
108113
}
109114
110115
function onPointerDown(event: PointerEvent) {
111-
if (!hasActiveSelection.value) {
112-
return emits.paneMouseMove(event)
113-
}
114-
115116
containerBounds.value = vueFlowRef.value?.getBoundingClientRect()
116117
container.value?.setPointerCapture(event.pointerId)
117118
118-
if (!elementsSelectable || !isSelecting || event.button !== 0 || event.target !== container.value || !containerBounds.value) {
119+
if (
120+
!elementsSelectable.value ||
121+
!isSelecting ||
122+
event.button !== 0 ||
123+
event.target !== container.value ||
124+
!containerBounds.value
125+
) {
119126
return
120127
}
121128
122129
const { x, y } = getMousePosition(event, containerBounds.value)
123130
131+
edgeIdLookup.value = new Map()
132+
133+
for (const [id, edge] of edgeLookup.value) {
134+
edgeIdLookup.value.set(edge.source, edgeIdLookup.value.get(edge.source)?.add(id) || new Set([id]))
135+
edgeIdLookup.value.set(edge.target, edgeIdLookup.value.get(edge.target)?.add(id) || new Set([id]))
136+
}
137+
124138
removeSelectedElements()
125139
126140
userSelectionRect.value = {
@@ -138,43 +152,62 @@ function onPointerDown(event: PointerEvent) {
138152
}
139153
140154
function onPointerMove(event: PointerEvent) {
141-
if (!hasActiveSelection.value) {
142-
return emits.paneMouseMove(event)
143-
}
144-
145155
if (!containerBounds.value || !userSelectionRect.value) {
146156
return
147157
}
148158
149159
selectionInProgress.value = true
150160
151-
const mousePos = getMousePosition(event, containerBounds.value)
161+
const { x: mouseX, y: mouseY } = getEventPosition(event, containerBounds.value)
152162
const { startX = 0, startY = 0 } = userSelectionRect.value
153163
154164
const nextUserSelectRect = {
155-
...userSelectionRect.value,
156-
x: mousePos.x < startX ? mousePos.x : startX,
157-
y: mousePos.y < startY ? mousePos.y : startY,
158-
width: Math.abs(mousePos.x - startX),
159-
height: Math.abs(mousePos.y - startY),
165+
startX,
166+
startY,
167+
x: mouseX < startX ? mouseX : startX,
168+
y: mouseY < startY ? mouseY : startY,
169+
width: Math.abs(mouseX - startX),
170+
height: Math.abs(mouseY - startY),
160171
}
161172
162173
const selectedNodes = getNodesInside(
163174
getNodes.value,
164-
userSelectionRect.value,
175+
nextUserSelectRect,
165176
viewport.value,
166177
selectionMode.value === SelectionMode.Partial,
167178
true,
168179
)
169180
170-
const selectedEdges = getConnectedEdges(selectedNodes, getEdges.value)
181+
const selectedEdgeIds = new Set<string>()
182+
const selectedNodeIds = new Set<string>()
171183
172-
prevSelectedNodesCount.value = selectedNodes.length
173-
prevSelectedEdgesCount.value = selectedEdges.length
184+
for (const selectedNode of selectedNodes) {
185+
selectedNodeIds.add(selectedNode.id)
174186
175-
userSelectionRect.value = nextUserSelectRect
187+
const edgeIds = edgeIdLookup.value.get(selectedNode.id)
188+
189+
if (edgeIds) {
190+
for (const edgeId of edgeIds) {
191+
selectedEdgeIds.add(edgeId)
192+
}
193+
}
194+
}
195+
196+
if (prevSelectedNodesCount.value !== selectedNodeIds.size) {
197+
prevSelectedNodesCount.value = selectedNodeIds.size
198+
const changes = getSelectionChanges(nodeLookup.value, selectedNodeIds, true) as NodeChange[]
199+
emits.nodesChange(changes)
200+
}
176201
177-
addSelectedElements([...selectedNodes, ...selectedEdges])
202+
if (prevSelectedEdgesCount.value !== selectedEdgeIds.size) {
203+
prevSelectedEdgesCount.value = selectedEdgeIds.size
204+
const changes = getSelectionChanges(edgeLookup.value, selectedEdgeIds)
205+
emits.edgesChange(changes)
206+
}
207+
208+
userSelectionRect.value = nextUserSelectRect
209+
userSelectionActive.value = true
210+
nodesSelectionActive.value = false
178211
}
179212
180213
function onPointerUp(event: PointerEvent) {
@@ -184,10 +217,6 @@ function onPointerUp(event: PointerEvent) {
184217
185218
container.value?.releasePointerCapture(event.pointerId)
186219
187-
if (!hasActiveSelection.value) {
188-
return
189-
}
190-
191220
// We only want to trigger click functions when in selection mode if
192221
// the user did not move the mouse.
193222
if (!userSelectionActive.value && userSelectionRect.value && event.target === container.value) {
@@ -206,14 +235,6 @@ function onPointerUp(event: PointerEvent) {
206235
selectionInProgress.value = false
207236
}
208237
}
209-
210-
function onPointerEnter(event: PointerEvent) {
211-
if (hasActiveSelection.value) {
212-
return
213-
}
214-
215-
emits.paneMouseEnter(event)
216-
}
217238
</script>
218239

219240
<script lang="ts">
@@ -228,13 +249,14 @@ export default {
228249
ref="container"
229250
class="vue-flow__pane vue-flow__container"
230251
:class="{ selection: isSelecting }"
231-
@click="onClick"
232-
@contextmenu="onContextMenu"
233-
@wheel.passive="onWheel"
234-
@pointerenter="onPointerEnter"
235-
@pointerdown="onPointerDown"
236-
@pointermove="onPointerMove"
237-
@pointerup="onPointerUp"
252+
@click="(event) => (hasActiveSelection ? undefined : wrapHandler(onClick, container)(event))"
253+
@contextmenu="wrapHandler(onContextMenu, container)($event)"
254+
@wheel.passive="wrapHandler(onWheel, container)($event)"
255+
@pointerenter="(event) => (hasActiveSelection ? undefined : emits.paneMouseEnter(event))"
256+
@pointerdown="(event) => (hasActiveSelection ? onPointerDown(event) : emits.paneMouseMove(event))"
257+
@pointermove="(event) => (hasActiveSelection ? onPointerMove(event) : emits.paneMouseMove(event))"
258+
@pointerup="(event) => (hasActiveSelection ? onPointerUp(event) : undefined)"
259+
@pointerleave="emits.paneMouseLeave($event)"
238260
>
239261
<slot />
240262
<UserSelection v-if="userSelectionActive && userSelectionRect" :user-selection-rect="userSelectionRect" />

0 commit comments

Comments
 (0)