arrows ignore locked shapes (#745)

This commit is contained in:
Steve Ruiz 2022-06-25 12:48:41 +01:00 committed by GitHub
parent 70e3c8bd45
commit 6183c41c18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 93 additions and 51 deletions

View file

@ -54,6 +54,18 @@ describe('Arrow session', () => {
})
describe('arrow binding', () => {
it('ignores locked shapes', () => {
const app = new TldrawTestApp()
.loadDocument(restoreDoc)
.select('target1')
.toggleLocked() // set target 1 to locked
.select('arrow1')
.movePointer([200, 200])
.startSession(SessionType.Arrow, 'arrow1', 'start')
.movePointer([50, 50])
expect(app.bindings.length).toBe(0)
})
it('points to the center', () => {
const app = new TldrawTestApp()
.loadDocument(restoreDoc)
@ -228,7 +240,6 @@ describe('When creating with an arrow session', () => {
)
.selectTool(TDShapeType.Arrow)
.pointShape('rect1', { x: 251, y: 251 })
.movePointer([350, 350])
.movePointer([450, 450])
.completeSession()
@ -240,6 +251,33 @@ describe('When creating with an arrow session', () => {
expect(app.bindings.length).toBe(2)
})
it('Does not creat a start binding inside of a locked shape', () => {
const app = new TldrawTestApp()
.selectAll()
.delete()
.createShapes(
{
type: TDShapeType.Rectangle,
id: 'rect1',
point: [200, 200],
size: [100, 100],
isLocked: true,
},
{ type: TDShapeType.Rectangle, id: 'rect2', point: [400, 400], size: [100, 100] }
)
.selectTool(TDShapeType.Arrow)
.pointShape('rect1', { x: 251, y: 251 })
.movePointer([450, 450])
.completeSession()
const arrow = app.shapes.find((shape) => shape.type === TDShapeType.Arrow) as ArrowShape
expect(arrow).toBeTruthy()
expect(arrow.handles.start.bindingId).toBe(undefined)
expect(arrow.handles.end.bindingId).toBeTruthy()
expect(app.bindings.length).toBe(1)
})
it('Creates a start binding if started in dead center', () => {
const app = new TldrawTestApp()
.selectAll()
@ -396,43 +434,43 @@ describe('When creating arrows inside of other shapes...', () => {
})
})
describe('When holding alt and dragging a handle', () => {
it('Applies a delta to both handles', () => {
const app = new TldrawTestApp()
.selectAll()
.delete()
.createShapes({ type: TDShapeType.Arrow, id: 'arrow1', point: [0, 0] })
.select('arrow1')
.movePointer([0, 0])
.startSession(SessionType.Arrow, 'arrow1', 'start')
.movePointer([-10, -10])
// describe('When holding alt and dragging a handle', () => {
// it('Applies a delta to both handles', () => {
// const app = new TldrawTestApp()
// .selectAll()
// .delete()
// .createShapes({ type: TDShapeType.Arrow, id: 'arrow1', point: [0, 0] })
// .select('arrow1')
// .movePointer([0, 0])
// .startSession(SessionType.Arrow, 'arrow1', 'start')
// .movePointer([-10, -10])
// Without alt...
expect(app.getShape('arrow1')).toMatchObject({
point: [-10, -10],
handles: {
start: {
point: [0, 0],
},
end: {
point: [11, 11],
},
},
})
// // Without alt...
// expect(app.getShape('arrow1')).toMatchObject({
// point: [-10, -10],
// handles: {
// start: {
// point: [0, 0],
// },
// end: {
// point: [11, 11],
// },
// },
// })
// With alt...
app.movePointer({ x: -10, y: -10, altKey: true })
// // With alt...
// app.movePointer({ x: -10, y: -10, altKey: true })
expect(app.getShape('arrow1')).toMatchObject({
point: [-10, -10],
handles: {
start: {
point: [0, 0],
},
end: {
point: [21, 21], // delta is applied to both handles
},
},
})
})
})
// expect(app.getShape('arrow1')).toMatchObject({
// point: [-10, -10],
// handles: {
// start: {
// point: [0, 0],
// },
// end: {
// point: [21, 21], // delta is applied to both handles
// },
// },
// })
// })
// })

View file

@ -68,8 +68,10 @@ export class ArrowSession extends BaseSession {
// bindable shape under the pointer.
this.startBindingShapeId = this.bindableShapeIds
.map((id) => page.shapes[id])
.filter((shape) =>
Utils.pointInBounds(originPoint, TLDR.getShapeUtil(shape).getBounds(shape))
.filter(
(shape) =>
!shape.isLocked &&
Utils.pointInBounds(originPoint, TLDR.getShapeUtil(shape).getBounds(shape))
)
.sort((a, b) => {
// TODO - We should be smarter here, what's the right logic?
@ -144,19 +146,19 @@ export class ArrowSession extends BaseSession {
},
}
if (altKey) {
// If the user is holding alt key, apply the inverse delta
// to the oppoosite handle.
const oppositeHandleId = handleId === 'start' ? 'end' : 'start'
// if (altKey) {
// // If the user is holding alt key, apply the inverse delta
// // to the oppoosite handle.
// const oppositeHandleId = handleId === 'start' ? 'end' : 'start'
const nextPoint = Vec.sub(handles[oppositeHandleId].point, delta)
// const nextPoint = Vec.sub(handles[oppositeHandleId].point, delta)
handleChanges[oppositeHandleId] = {
...handles[oppositeHandleId],
point: showGrid ? Vec.snap(nextPoint, currentGrid) : Vec.toFixed(nextPoint),
bindingId: undefined,
}
}
// handleChanges[oppositeHandleId] = {
// ...handles[oppositeHandleId],
// point: showGrid ? Vec.snap(nextPoint, currentGrid) : Vec.toFixed(nextPoint),
// bindingId: undefined,
// }
// }
const utils = shapeUtils[TDShapeType.Arrow]
const handleChange = utils.onHandleChange?.(initialShape, handleChanges)
@ -269,6 +271,7 @@ export class ArrowSession extends BaseSession {
.map((id) => this.app.page.shapes[id])
.sort((a, b) => b.childIndex - a.childIndex)
.filter((shape) => {
if (shape.isLocked) return false
const utils = TLDR.getShapeUtil(shape)
return ![startPoint, endPoint].every((point) => utils.hitTestPoint(shape, point))
})
@ -288,6 +291,7 @@ export class ArrowSession extends BaseSession {
if (draggedBinding) break
}
}
if (draggedBinding) {
// Create the dragged point binding
this.didBind = true