From 625c819817d0bf1e47470e2eb99227c7c5bc0a80 Mon Sep 17 00:00:00 2001 From: Steve Ruiz Date: Fri, 3 Sep 2021 11:07:52 +0100 Subject: [PATCH] Fixes meta-shift-select for grouped shapes --- packages/tldraw/src/state/tlstate.spec.ts | 1 - packages/tldraw/src/state/tlstate.ts | 88 +++++++++++++---------- packages/tldraw/src/test/state-utils.tsx | 4 +- 3 files changed, 52 insertions(+), 41 deletions(-) diff --git a/packages/tldraw/src/state/tlstate.spec.ts b/packages/tldraw/src/state/tlstate.spec.ts index 2d153d97f..ce5bd34cf 100644 --- a/packages/tldraw/src/state/tlstate.spec.ts +++ b/packages/tldraw/src/state/tlstate.spec.ts @@ -316,7 +316,6 @@ describe('TLDrawState', () => { .group(['rect1', 'rect2'], 'groupA') const tlu = new TLStateUtils(tlstate) - tlu.hoverShape('rect1') tlu.clickShape('rect1', { ctrlKey: true, shiftKey: true }) expect(tlstate.selectedIds).toStrictEqual(['rect1']) diff --git a/packages/tldraw/src/state/tlstate.ts b/packages/tldraw/src/state/tlstate.ts index 0e7eeb27d..d5ed22ae8 100644 --- a/packages/tldraw/src/state/tlstate.ts +++ b/packages/tldraw/src/state/tlstate.ts @@ -2132,12 +2132,14 @@ export class TLDrawState extends StateManager { switch (this.appState.status.current) { case TLDrawStatus.PointingBounds: { if (info.target === 'bounds') { - // If we just clicked the selecting bounds's background, clear the selection + // If we just clicked the selecting bounds's background, + // clear the selection this.deselectAll() } else if (this.selectedIds.includes(info.target)) { // If we're holding shift... if (info.shiftKey) { - // unless we just shift-selected the shape, remove it from the selected shapes + // unless we just shift-selected the shape, remove it from + // the selected shapes if (this.pointedId !== info.target) { this.select(...this.selectedIds.filter((id) => id !== info.target)) } @@ -2250,27 +2252,39 @@ export class TLDrawState extends StateManager { // Shape onPointShape: TLPointerEventHandler = (info) => { - switch (this.appState.status.current) { + const { activeTool, status } = this.appState + + // While holding command and shift, select or deselect + // the shape, ignoring any group that may contain it. Yikes! + if ( + activeTool === 'select' && + (status.current === TLDrawStatus.Idle || status.current === TLDrawStatus.PointingBounds) && + info.metaKey && + info.shiftKey && + this.pageState.hoveredId + ) { + const targetId = this.pageState.hoveredId + this.pointedId = targetId + + if (this.selectedIds.includes(targetId)) { + // Deselect if selected + this.select(...this.selectedIds.filter((id) => id !== targetId)) + } else { + const shape = this.getShape(this.pageState.hoveredId) + // Push select the shape, deselecting the shape's parent if selected + this.select(...this.selectedIds.filter((id) => id !== shape.parentId), targetId) + } + + return + } + + switch (status.current) { case TLDrawStatus.Idle: { - switch (this.appState.activeTool) { + switch (activeTool) { case 'select': { if (info.metaKey) { - if (info.shiftKey) { - // While holding command and shift, select or deselect - // the shape, ignoring any group that may contain it - this.pointedId = info.target - - if (this.selectedIds.includes(info.target)) { - // Deselect if selected - this.select(...this.selectedIds.filter((id) => id !== info.target)) - } else { - // Otherwise, push select the shape - this.select(...this.selectedIds, info.target) - } - } else { - // While holding just command key, start a brush session - this.startBrushSession(this.getPagePoint(info.point)) - } + // While holding just command key, start a brush session + this.startBrushSession(this.getPagePoint(info.point)) return } @@ -2320,23 +2334,23 @@ export class TLDrawState extends StateManager { // If we've clicked on a shape that is inside of a group, // then select the group rather than the shape. - if (info.metaKey && info.shiftKey) { - const targetId = this.pageState.hoveredId - if (targetId) { - this.pointedId = targetId - const shape = this.getShape(targetId) - if (this.selectedIds.includes(targetId)) { - this.select(...this.selectedIds.filter((id) => id !== targetId)) - } else { - if (this.selectedIds.includes(shape.parentId)) { - this.select(targetId) - } else { - this.select(...this.selectedIds, targetId) - } - } - return - } - } + // if (info.metaKey && info.shiftKey) { + // const targetId = this.pageState.hoveredId + // if (targetId) { + // this.pointedId = targetId + // const shape = this.getShape(targetId) + // if (this.selectedIds.includes(targetId)) { + // this.select(...this.selectedIds.filter((id) => id !== targetId)) + // } else { + // if (this.selectedIds.includes(shape.parentId)) { + // this.select(targetId) + // } else { + // this.select(...this.selectedIds, targetId) + // } + // } + // return + // } + // } const { parentId } = this.getShape(info.target) this.pointedId = parentId === this.currentPageId ? info.target : parentId diff --git a/packages/tldraw/src/test/state-utils.tsx b/packages/tldraw/src/test/state-utils.tsx index 68d01bbe0..4221af965 100644 --- a/packages/tldraw/src/test/state-utils.tsx +++ b/packages/tldraw/src/test/state-utils.tsx @@ -80,9 +80,7 @@ export class TLStateUtils { } clickShape = (id: string, options: PointerOptions = {}) => { - if (this.tlstate.selectedIds.includes(id)) { - this.pointBounds(options) - } + this.hoverShape(id) this.pointShape(id, options) this.stopPointing(id, options) return this