Allow dragging on top of locked shapes. (#2337)
This PR allows dragging a selection on top of a locked shape. This should work when clicking inside of the selection, but not directly on a shape. Before: https://github.com/tldraw/tldraw/assets/2523721/53583ae9-9ed7-455e-bdc4-ba13804dd8a3 After: https://github.com/tldraw/tldraw/assets/2523721/81d8f8bf-5474-4a09-abac-75059a089851 Fixes https://github.com/tldraw/tldraw/issues/2316 Fixes https://github.com/tldraw/tldraw/issues/2315 ### Change Type - [x] `patch` — Bug fix - [ ] `minor` — New feature - [ ] `major` — Breaking change - [ ] `dependencies` — Changes to package dependencies[^1] - [ ] `documentation` — Changes to the documentation only[^2] - [ ] `tests` — Changes to any test code only[^2] - [ ] `internal` — Any other changes that don't affect the published package[^2] - [ ] I don't know [^1]: publishes a `patch` release, for devDependencies use `internal` [^2]: will not publish a new version ### Test Plan 1. Create a big shape and lock it. 2. Create two shapes on top of the locked shape and select them. 3. Start dragging the selected shapes by clicking inside the selection (but not directly on any of the shapes). This should allow you to translate the selection. 4. Should also work if the shapes are behind the locked shape. - [x] Unit Tests - [ ] End to end tests ### Release Notes - Allow translating of shapes on top of a locked shape by clicking inside of selection and moving the mouse.
This commit is contained in:
parent
ded56e953a
commit
6bd7f4fcc9
2 changed files with 57 additions and 2 deletions
|
@ -57,7 +57,7 @@ export class Idle extends StateNode {
|
||||||
// Check to see if we hit any shape under the pointer; if so,
|
// Check to see if we hit any shape under the pointer; if so,
|
||||||
// handle this as a pointer down on the shape instead of the canvas
|
// handle this as a pointer down on the shape instead of the canvas
|
||||||
const hitShape = getHitShapeOnCanvasPointerDown(this.editor)
|
const hitShape = getHitShapeOnCanvasPointerDown(this.editor)
|
||||||
if (hitShape) {
|
if (hitShape && !hitShape.isLocked) {
|
||||||
this.onPointerDown({
|
this.onPointerDown({
|
||||||
...info,
|
...info,
|
||||||
shape: hitShape,
|
shape: hitShape,
|
||||||
|
@ -140,7 +140,11 @@ export class Idle extends StateNode {
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
const hoveredShape = this.editor.getHoveredShape()
|
const hoveredShape = this.editor.getHoveredShape()
|
||||||
if (hoveredShape && !this.editor.getSelectedShapeIds().includes(hoveredShape.id)) {
|
if (
|
||||||
|
hoveredShape &&
|
||||||
|
!this.editor.getSelectedShapeIds().includes(hoveredShape.id) &&
|
||||||
|
!hoveredShape.isLocked
|
||||||
|
) {
|
||||||
this.onPointerDown({
|
this.onPointerDown({
|
||||||
...info,
|
...info,
|
||||||
shape: hoveredShape,
|
shape: hoveredShape,
|
||||||
|
|
|
@ -1750,3 +1750,54 @@ describe('When brushing close to the edges of the screen', () => {
|
||||||
editor.pointerUp()
|
editor.pointerUp()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('When a shape is locked', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
editor.createShape({
|
||||||
|
id: ids.box1,
|
||||||
|
type: 'geo',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
isLocked: true,
|
||||||
|
props: { w: 300, h: 300 },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not select the shape', () => {
|
||||||
|
editor.pointerDown(50, 50)
|
||||||
|
editor.expectToBeIn('select.pointing_canvas')
|
||||||
|
editor.pointerUp()
|
||||||
|
editor.expectToBeIn('select.idle')
|
||||||
|
expect(editor.getSelectedShapeIds()).toEqual([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('allows translating shapes on top of the locked shape', () => {
|
||||||
|
editor.createShape({ id: ids.box2, x: 50, y: 50, type: 'geo', props: { w: 50, h: 50 } })
|
||||||
|
editor.createShape({ id: ids.box3, x: 200, y: 200, type: 'geo', props: { w: 50, h: 50 } })
|
||||||
|
|
||||||
|
// Select the first shape
|
||||||
|
editor.pointerMove(60, 60)
|
||||||
|
editor.pointerDown()
|
||||||
|
editor.pointerUp()
|
||||||
|
expect(editor.getSelectedShapeIds()).toEqual([ids.box2])
|
||||||
|
|
||||||
|
// Shift select the second shape
|
||||||
|
editor.pointerMove(210, 210)
|
||||||
|
editor.keyDown('Shift')
|
||||||
|
editor.pointerDown()
|
||||||
|
editor.pointerUp()
|
||||||
|
editor.keyUp('Shift')
|
||||||
|
editor.expectToBeIn('select.idle')
|
||||||
|
expect(editor.getSelectedShapeIds()).toEqual([ids.box2, ids.box3])
|
||||||
|
|
||||||
|
// Click between them and start dragging
|
||||||
|
editor.pointerMove(150, 150)
|
||||||
|
editor.pointerDown()
|
||||||
|
editor.expectToBeIn('select.pointing_selection')
|
||||||
|
editor.pointerMove(100, 150)
|
||||||
|
editor.expectToBeIn('select.translating')
|
||||||
|
editor.pointerUp()
|
||||||
|
editor.expectToBeIn('select.idle')
|
||||||
|
expect(editor.getSelectedShapeIds()).toEqual([ids.box2, ids.box3])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in a new issue