ソースを参照

fix some element types reset to selection when the lock is active (#746)

* keep arrows and lines selected if locked

* keep element type selected if locked after inserting text

* ensure clicking outside doesn't create new text

* esc should switch to selection even if locked

* reset cursor when creating text via doubleClick

Co-authored-by: David Luzar <luzar.david@gmail.com>
lissitz 5 年 前
コミット
fa12125db0
3 ファイル変更46 行追加15 行削除
  1. 8 1
      src/actions/actionFinalize.tsx
  2. 34 14
      src/index.tsx
  3. 4 0
      src/utils.ts

+ 8 - 1
src/actions/actionFinalize.tsx

@@ -2,6 +2,7 @@ import { Action } from "./types";
 import { KEYS } from "../keys";
 import { clearSelection } from "../scene";
 import { isInvisiblySmallElement } from "../element";
+import { resetCursor } from "../utils";
 
 export const actionFinalize: Action = {
   name: "finalize",
@@ -20,11 +21,17 @@ export const actionFinalize: Action = {
       }
       appState.multiElement.shape = null;
     }
+    if (!appState.elementLocked || !appState.multiElement) {
+      resetCursor();
+    }
     return {
       elements: newElements,
       appState: {
         ...appState,
-        elementType: "selection",
+        elementType:
+          appState.elementLocked && appState.multiElement
+            ? appState.elementType
+            : "selection",
         draggingElement: null,
         multiElement: null,
       },

+ 34 - 14
src/index.tsx

@@ -48,6 +48,7 @@ import {
   capitalizeString,
   distance,
   distance2d,
+  resetCursor,
 } from "./utils";
 import { KEYS, isArrowKey } from "./keys";
 
@@ -102,10 +103,6 @@ import { copyToAppClipboard, getClipboardContent } from "./clipboard";
 let { elements } = createScene();
 const { history } = createHistory();
 
-function resetCursor() {
-  document.documentElement.style.cursor = "";
-}
-
 function setCursorForShape(shape: string) {
   if (shape === "selection") {
     resetCursor();
@@ -1014,6 +1011,12 @@ export class App extends React.Component<any, AppState> {
               }
 
               if (isTextElement(element)) {
+                // if we're currently still editing text, clicking outside
+                //  should only finalize it, not create another (irrespective
+                //  of state.elementLocked)
+                if (this.state.editingElement?.type === "text") {
+                  return;
+                }
                 let textX = e.clientX;
                 let textY = e.clientY;
                 if (!e.altKey) {
@@ -1033,7 +1036,6 @@ export class App extends React.Component<any, AppState> {
                   this.setState({
                     draggingElement: null,
                     editingElement: null,
-                    elementType: "selection",
                   });
                 };
 
@@ -1058,6 +1060,9 @@ export class App extends React.Component<any, AppState> {
                         },
                       ];
                     }
+                    if (this.state.elementLocked) {
+                      setCursorForShape(this.state.elementType);
+                    }
                     history.resumeRecording();
                     resetSelection();
                   },
@@ -1065,10 +1070,17 @@ export class App extends React.Component<any, AppState> {
                     resetSelection();
                   },
                 });
-                this.setState({
-                  elementType: "selection",
-                  editingElement: element,
-                });
+                resetCursor();
+                if (!this.state.elementLocked) {
+                  this.setState({
+                    editingElement: element,
+                    elementType: "selection",
+                  });
+                } else {
+                  this.setState({
+                    editingElement: element,
+                  });
+                }
                 return;
               } else if (
                 this.state.elementType === "arrow" ||
@@ -1563,10 +1575,17 @@ export class App extends React.Component<any, AppState> {
                     this.setState({ multiElement: this.state.draggingElement });
                   } else if (draggingOccurred && !multiElement) {
                     this.state.draggingElement!.isSelected = true;
-                    this.setState({
-                      draggingElement: null,
-                      elementType: "selection",
-                    });
+                    if (!elementLocked) {
+                      resetCursor();
+                      this.setState({
+                        draggingElement: null,
+                        elementType: "selection",
+                      });
+                    } else {
+                      this.setState({
+                        draggingElement: null,
+                      });
+                    }
                   }
                   return;
                 }
@@ -1660,6 +1679,8 @@ export class App extends React.Component<any, AppState> {
               window.addEventListener("mouseup", onMouseUp);
             }}
             onDoubleClick={e => {
+              resetCursor();
+
               const { x, y } = viewportCoordsToSceneCoords(e, this.state);
 
               const elementAtPosition = getElementAtPosition(elements, x, y);
@@ -1724,7 +1745,6 @@ export class App extends React.Component<any, AppState> {
                 this.setState({
                   draggingElement: null,
                   editingElement: null,
-                  elementType: "selection",
                 });
               };
 

+ 4 - 0
src/utils.ts

@@ -126,3 +126,7 @@ export function distance2d(x1: number, y1: number, x2: number, y2: number) {
   const yd = y2 - y1;
   return Math.sqrt(xd * xd + yd * yd);
 }
+
+export function resetCursor() {
+  document.documentElement.style.cursor = "";
+}