From 58fe639b8d888bb960f8a7a4e301ed94a7b939e0 Mon Sep 17 00:00:00 2001 From: David Luzar Date: Thu, 7 Apr 2022 17:53:55 +0200 Subject: [PATCH] fix: select whole group on righclick & few lock-related fixes (#5022) --- src/components/App.tsx | 24 ++- src/renderer/renderScene.ts | 4 +- .../__snapshots__/contextmenu.test.tsx.snap | 172 ++++++++++++++++++ src/tests/contextmenu.test.tsx | 25 +++ 4 files changed, 218 insertions(+), 7 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index ea3969d8..8a0a5643 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -3976,13 +3976,16 @@ class App extends React.Component { pointerDownState.hit.element?.id || pointerDownState.hit.hasHitElementInside) ) { - // Marking that click was used for dragging to check - // if elements should be deselected on pointerup - pointerDownState.drag.hasOccurred = true; const selectedElements = getSelectedElements( this.scene.getElements(), this.state, ); + if (selectedElements.every((element) => element.locked)) { + return; + } + // Marking that click was used for dragging to check + // if elements should be deselected on pointerup + pointerDownState.drag.hasOccurred = true; // prevent dragging even if we're no longer holding cmd/ctrl otherwise // it would have weird results (stuff jumping all over the screen) if (selectedElements.length > 0 && !pointerDownState.withCmdOrCtrl) { @@ -5337,9 +5340,18 @@ class App extends React.Component { const top = event.clientY - offsetTop; if (element && !this.state.selectedElementIds[element.id]) { - this.setState({ selectedElementIds: { [element.id]: true } }, () => { - this._openContextMenu({ top, left }, type); - }); + this.setState( + selectGroupsForSelectedElements( + { + ...this.state, + selectedElementIds: { [element.id]: true }, + }, + this.scene.getElements(), + ), + () => { + this._openContextMenu({ top, left }, type); + }, + ); } else { this._openContextMenu({ top, left }, type); } diff --git a/src/renderer/renderScene.ts b/src/renderer/renderScene.ts index 00557aeb..9b2d7cd4 100644 --- a/src/renderer/renderScene.ts +++ b/src/renderer/renderScene.ts @@ -413,7 +413,9 @@ export const renderScene = ( "mouse", OMIT_SIDES_FOR_MULTIPLE_ELEMENTS, ); - renderTransformHandles(context, renderConfig, transformHandles, 0); + if (locallySelectedElements.some((element) => !element.locked)) { + renderTransformHandles(context, renderConfig, transformHandles, 0); + } } context.restore(); } diff --git a/src/tests/__snapshots__/contextmenu.test.tsx.snap b/src/tests/__snapshots__/contextmenu.test.tsx.snap index 9451f7dc..9fadf47f 100644 --- a/src/tests/__snapshots__/contextmenu.test.tsx.snap +++ b/src/tests/__snapshots__/contextmenu.test.tsx.snap @@ -1,5 +1,177 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`contextMenu element right-clicking on a group should select whole group: [end of test] appState 1`] = ` +Object { + "activeTool": Object { + "lastActiveToolBeforeEraser": null, + "locked": false, + "type": "selection", + }, + "collaborators": Map {}, + "currentChartType": "bar", + "currentItemBackgroundColor": "transparent", + "currentItemEndArrowhead": "arrow", + "currentItemFillStyle": "hachure", + "currentItemFontFamily": 1, + "currentItemFontSize": 20, + "currentItemLinearStrokeSharpness": "round", + "currentItemOpacity": 100, + "currentItemRoughness": 1, + "currentItemStartArrowhead": null, + "currentItemStrokeColor": "#000000", + "currentItemStrokeSharpness": "sharp", + "currentItemStrokeStyle": "solid", + "currentItemStrokeWidth": 1, + "currentItemTextAlign": "left", + "cursorButton": "up", + "draggingElement": null, + "editingElement": null, + "editingGroupId": null, + "editingLinearElement": null, + "errorMessage": null, + "exportBackground": true, + "exportEmbedScene": false, + "exportScale": 1, + "exportWithDarkMode": false, + "fileHandle": null, + "gridSize": null, + "height": 100, + "isBindingEnabled": true, + "isLibraryOpen": false, + "isLoading": false, + "isResizing": false, + "isRotating": false, + "lastPointerDownWith": "mouse", + "multiElement": null, + "name": "Untitled-201933152653", + "offsetLeft": 20, + "offsetTop": 10, + "openMenu": null, + "openPopup": null, + "pasteDialog": Object { + "data": null, + "shown": false, + }, + "penDetected": false, + "penMode": false, + "pendingImageElement": null, + "previousSelectedElementIds": Object {}, + "resizingElement": null, + "scrollX": 0, + "scrollY": 0, + "scrolledOutside": false, + "selectedElementIds": Object { + "id0": true, + "id1": true, + }, + "selectedGroupIds": Object { + "g1": true, + }, + "selectionElement": null, + "shouldCacheIgnoreZoom": false, + "showHelpDialog": false, + "showHyperlinkPopup": false, + "showStats": false, + "startBoundElement": null, + "suggestedBindings": Array [], + "theme": "light", + "toastMessage": null, + "viewBackgroundColor": "#ffffff", + "viewModeEnabled": false, + "width": 200, + "zenModeEnabled": false, + "zoom": Object { + "value": 1, + }, +} +`; + +exports[`contextMenu element right-clicking on a group should select whole group: [end of test] element 0 1`] = ` +Object { + "angle": 0, + "backgroundColor": "red", + "boundElements": null, + "fillStyle": "solid", + "groupIds": Array [ + "g1", + ], + "height": 100, + "id": "id0", + "isDeleted": false, + "link": null, + "locked": false, + "opacity": 100, + "roughness": 1, + "seed": 337897, + "strokeColor": "#000000", + "strokeSharpness": "sharp", + "strokeStyle": "solid", + "strokeWidth": 1, + "type": "rectangle", + "updated": 1, + "version": 1, + "versionNonce": 0, + "width": 100, + "x": 0, + "y": 0, +} +`; + +exports[`contextMenu element right-clicking on a group should select whole group: [end of test] element 1 1`] = ` +Object { + "angle": 0, + "backgroundColor": "red", + "boundElements": null, + "fillStyle": "solid", + "groupIds": Array [ + "g1", + ], + "height": 100, + "id": "id1", + "isDeleted": false, + "link": null, + "locked": false, + "opacity": 100, + "roughness": 1, + "seed": 1278240551, + "strokeColor": "#000000", + "strokeSharpness": "sharp", + "strokeStyle": "solid", + "strokeWidth": 1, + "type": "rectangle", + "updated": 1, + "version": 1, + "versionNonce": 0, + "width": 100, + "x": 0, + "y": 0, +} +`; + +exports[`contextMenu element right-clicking on a group should select whole group: [end of test] history 1`] = ` +Object { + "recording": false, + "redoStack": Array [], + "stateHistory": Array [ + Object { + "appState": Object { + "editingGroupId": null, + "editingLinearElement": null, + "name": "Untitled-201933152653", + "selectedElementIds": Object {}, + "selectedGroupIds": Object {}, + "viewBackgroundColor": "#ffffff", + }, + "elements": Array [], + }, + ], +} +`; + +exports[`contextMenu element right-clicking on a group should select whole group: [end of test] number of elements 1`] = `2`; + +exports[`contextMenu element right-clicking on a group should select whole group: [end of test] number of renders 1`] = `5`; + exports[`contextMenu element selecting 'Add to library' in context menu adds element to library: [end of test] appState 1`] = ` Object { "activeTool": Object { diff --git a/src/tests/contextmenu.test.tsx b/src/tests/contextmenu.test.tsx index 8f5f3263..9cb7267f 100644 --- a/src/tests/contextmenu.test.tsx +++ b/src/tests/contextmenu.test.tsx @@ -557,4 +557,29 @@ describe("contextMenu element", () => { expect(h.elements[0].groupIds).toHaveLength(0); expect(h.elements[1].groupIds).toHaveLength(0); }); + + it("right-clicking on a group should select whole group", () => { + const rectangle1 = API.createElement({ + type: "rectangle", + width: 100, + backgroundColor: "red", + fillStyle: "solid", + groupIds: ["g1"], + }); + const rectangle2 = API.createElement({ + type: "rectangle", + width: 100, + backgroundColor: "red", + fillStyle: "solid", + groupIds: ["g1"], + }); + h.elements = [rectangle1, rectangle2]; + + mouse.rightClickAt(50, 50); + expect(API.getSelectedElements().length).toBe(2); + expect(API.getSelectedElements()).toEqual([ + expect.objectContaining({ id: rectangle1.id }), + expect.objectContaining({ id: rectangle2.id }), + ]); + }); });