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.
pull/2345/head
Mitja Bezenšek 2023-12-19 11:40:50 +01:00 zatwierdzone przez GitHub
rodzic ded56e953a
commit 6bd7f4fcc9
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
2 zmienionych plików z 57 dodań i 2 usunięć

Wyświetl plik

@ -57,7 +57,7 @@ export class Idle extends StateNode {
// 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
const hitShape = getHitShapeOnCanvasPointerDown(this.editor)
if (hitShape) {
if (hitShape && !hitShape.isLocked) {
this.onPointerDown({
...info,
shape: hitShape,
@ -140,7 +140,11 @@ export class Idle extends StateNode {
}
default: {
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({
...info,
shape: hoveredShape,

Wyświetl plik

@ -1750,3 +1750,54 @@ describe('When brushing close to the edges of the screen', () => {
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])
})
})