فهرست منبع

Command clicking should "xor" selection (#300)

* Command clicking should "xor" selection

* Only shift key should play a role

* Get rid of `isDraggingElements`

* Renamed someElementIsDragged to draggingOccured
Timur Khazamov 5 سال پیش
والد
کامیت
c253c0b635
1فایلهای تغییر یافته به همراه36 افزوده شده و 15 حذف شده
  1. 36 15
      src/index.tsx

+ 36 - 15
src/index.tsx

@@ -20,7 +20,6 @@ import {
   deleteSelectedElements,
   setSelection,
   isOverScrollBars,
-  someElementIsSelected,
   restoreFromLocalStorage,
   saveToLocalStorage,
   getElementAtPosition,
@@ -542,8 +541,10 @@ export class App extends React.Component<{}, AppState> {
             );
             type ResizeTestType = ReturnType<typeof resizeTest>;
             let resizeHandle: ResizeTestType = false;
-            let isDraggingElements = false;
             let isResizingElements = false;
+            let draggingOccured = false;
+            let hitElement: ExcalidrawElement | null = null;
+            let elementIsAddedToSelection = false;
             if (this.state.elementType === "selection") {
               const resizeElement = getElementWithResizeHandler(
                 elements,
@@ -569,7 +570,7 @@ export class App extends React.Component<{}, AppState> {
                 if (!selected && !e.shiftKey) {
                   elements = clearSelection(elements);
                 }
-                const hitElement = getElementAtPosition(elements, x, y);
+                hitElement = getElementAtPosition(elements, x, y);
 
                 // If we click on something
                 if (hitElement) {
@@ -577,7 +578,10 @@ export class App extends React.Component<{}, AppState> {
                   // if shift is not clicked, this will always return true
                   // otherwise, it will trigger selection based on current
                   // state of the box
-                  hitElement.isSelected = true;
+                  if (!hitElement.isSelected) {
+                    hitElement.isSelected = true;
+                    elementIsAddedToSelection = true;
+                  }
 
                   // No matter what, we select it
                   // We duplicate the selected element if alt is pressed on Mouse down
@@ -596,13 +600,9 @@ export class App extends React.Component<{}, AppState> {
                     ];
                   }
                 }
-
-                isDraggingElements = someElementIsSelected(elements);
-
-                if (isDraggingElements) {
-                  document.documentElement.style.cursor = "move";
-                }
               }
+            } else {
+              elements = clearSelection(elements);
             }
 
             if (isTextElement(element)) {
@@ -754,7 +754,10 @@ export class App extends React.Component<{}, AppState> {
                 }
               }
 
-              if (isDraggingElements) {
+              if (hitElement?.isSelected) {
+                // Marking that click was used for dragging to check
+                // if elements should be deselected on mouseup
+                draggingOccured = true;
                 const selectedElements = elements.filter(el => el.isSelected);
                 if (selectedElements.length) {
                   const { x, y } = viewportCoordsToSceneCoords(e, this.state);
@@ -809,17 +812,35 @@ export class App extends React.Component<{}, AppState> {
 
               resetCursor();
 
-              // if no element is clicked, clear the selection and redraw
+              // If click occured on already selected element
+              // it is needed to remove selection from other elements
+              // or if SHIFT or META key pressed remove selection
+              // from hitted element
+              //
+              // If click occured and elements were dragged or some element
+              // was added to selection (on mousedown phase) we need to keep
+              // selection unchanged
+              if (
+                hitElement &&
+                !draggingOccured &&
+                !elementIsAddedToSelection
+              ) {
+                if (e.shiftKey) {
+                  hitElement.isSelected = false;
+                } else {
+                  elements = clearSelection(elements);
+                  hitElement.isSelected = true;
+                }
+              }
+
               if (draggingElement === null) {
+                // if no element is clicked, clear the selection and redraw
                 elements = clearSelection(elements);
                 this.forceUpdate();
                 return;
               }
 
               if (elementType === "selection") {
-                if (isDraggingElements) {
-                  isDraggingElements = false;
-                }
                 elements = elements.slice(0, -1);
               } else {
                 draggingElement.isSelected = true;