Better selection usability (#4379)
* use pointer capture for selection boxes * fixed selection box behaviour * promoted modifier listeners to window level * selection should still happen when shift key is let go during selection * ported changes to svelte flow * review changes
This commit is contained in:
@@ -75,15 +75,24 @@
|
||||
$selectionKeyPressed || $selectionRect || (selectionOnDrag && _panOnDrag !== true);
|
||||
$: hasActiveSelection = $elementsSelectable && (isSelecting || $selectionRectMode === 'user');
|
||||
|
||||
function onClick(event: MouseEvent | TouchEvent) {
|
||||
dispatch('paneclick', { event });
|
||||
// Used to prevent click events when the user lets go of the selectionKey during a selection
|
||||
let selectionInProgress = false;
|
||||
|
||||
function onClick(event: MouseEvent | TouchEvent) {
|
||||
// We prevent click events when the user let go of the selectionKey during a selection
|
||||
if (selectionInProgress) {
|
||||
selectionInProgress = false;
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch('paneclick', { event });
|
||||
unselectNodesAndEdges();
|
||||
selectionRectMode.set(null);
|
||||
}
|
||||
|
||||
function onMouseDown(event: MouseEvent) {
|
||||
function onPointerDown(event: PointerEvent) {
|
||||
containerBounds = container.getBoundingClientRect();
|
||||
container.setPointerCapture(event.pointerId);
|
||||
|
||||
if (
|
||||
!elementsSelectable ||
|
||||
@@ -111,10 +120,13 @@
|
||||
// onSelectionStart?.(event);
|
||||
}
|
||||
|
||||
function onMouseMove(event: MouseEvent) {
|
||||
function onPointerMove(event: PointerEvent) {
|
||||
if (!isSelecting || !containerBounds || !$selectionRect) {
|
||||
return;
|
||||
}
|
||||
|
||||
selectionInProgress = true;
|
||||
|
||||
const mousePos = getEventPosition(event, containerBounds);
|
||||
const startX = $selectionRect.startX ?? 0;
|
||||
const startY = $selectionRect.startY ?? 0;
|
||||
@@ -157,11 +169,13 @@
|
||||
selectionRect.set(nextUserSelectRect);
|
||||
}
|
||||
|
||||
function onMouseUp(event: MouseEvent) {
|
||||
function onPointerUp(event: PointerEvent) {
|
||||
if (event.button !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
container.releasePointerCapture(event.pointerId);
|
||||
|
||||
// We only want to trigger click functions when in selection mode if
|
||||
// the user did not move the mouse.
|
||||
if (!isSelecting && $selectionRectMode === 'user' && event.target === container) {
|
||||
@@ -173,17 +187,14 @@
|
||||
$selectionRectMode = 'nodes';
|
||||
}
|
||||
|
||||
// onSelectionEnd?.(event);
|
||||
}
|
||||
|
||||
const onMouseLeave = () => {
|
||||
if ($selectionRectMode === 'user') {
|
||||
selectionRectMode.set(selectedNodes.length > 0 ? 'nodes' : null);
|
||||
// onSelectionEnd?.(event);
|
||||
// If the user kept holding the selectionKey during the selection,
|
||||
// we need to reset the selectionInProgress, so the next click event is not prevented
|
||||
if ($selectionKeyPressed) {
|
||||
selectionInProgress = false;
|
||||
}
|
||||
|
||||
selectionRect.set(null);
|
||||
};
|
||||
// onSelectionEnd?.(event);
|
||||
}
|
||||
|
||||
const onContextMenu = (event: MouseEvent) => {
|
||||
if (Array.isArray(_panOnDrag) && _panOnDrag?.includes(2)) {
|
||||
@@ -204,10 +215,9 @@
|
||||
class:dragging={$dragging}
|
||||
class:selection={isSelecting}
|
||||
on:click={hasActiveSelection ? undefined : wrapHandler(onClick, container)}
|
||||
on:mousedown={hasActiveSelection ? onMouseDown : undefined}
|
||||
on:mousemove={hasActiveSelection ? onMouseMove : undefined}
|
||||
on:mouseup={hasActiveSelection ? onMouseUp : undefined}
|
||||
on:mouseleave={hasActiveSelection ? onMouseLeave : undefined}
|
||||
on:pointerdown={hasActiveSelection ? onPointerDown : undefined}
|
||||
on:pointermove={hasActiveSelection ? onPointerMove : undefined}
|
||||
on:pointerup={hasActiveSelection ? onPointerUp : undefined}
|
||||
on:contextmenu={wrapHandler(onContextMenu, container)}
|
||||
>
|
||||
<slot />
|
||||
|
||||
Reference in New Issue
Block a user