import { HIT_TEST_MARGIN, StateNode, TLEventHandlers, TLFrameShape, TLGroupShape, TLShapeId, } from '@bigbluebutton/editor' export class Pointing extends StateNode { static override id = 'pointing' override onEnter = () => { const zoomLevel = this.editor.getZoomLevel() const currentPageShapesSorted = this.editor.getCurrentPageShapesSorted() const { inputs: { currentPagePoint }, } = this.editor const erasing = new Set() const initialSize = erasing.size for (let n = currentPageShapesSorted.length, i = n - 1; i >= 0; i--) { const shape = currentPageShapesSorted[i] if ( this.editor.isShapeOrAncestorLocked(shape) || this.editor.isShapeOfType(shape, 'group') ) { continue } if ( this.editor.isPointInShape(shape, currentPagePoint, { hitInside: false, margin: HIT_TEST_MARGIN / zoomLevel, }) ) { const hitShape = this.editor.getOutermostSelectableShape(shape) // If we've hit a frame after hitting any other shape, stop here if ( this.editor.isShapeOfType(hitShape, 'frame') && erasing.size > initialSize ) { break } erasing.add(hitShape.id) } } this.editor.setErasingShapes([...erasing]) } override onPointerMove: TLEventHandlers['onPointerMove'] = (info) => { if (this.editor.inputs.isDragging) { this.parent.transition('erasing', info) } } override onPointerUp: TLEventHandlers['onPointerUp'] = () => { this.complete() } override onCancel: TLEventHandlers['onCancel'] = () => { this.cancel() } override onComplete: TLEventHandlers['onComplete'] = () => { this.complete() } override onInterrupt: TLEventHandlers['onInterrupt'] = () => { this.cancel() } complete() { const erasingShapeIds = this.editor.getErasingShapeIds() if (erasingShapeIds.length) { this.editor.mark('erase end') this.editor.deleteShapes(erasingShapeIds) } this.editor.setErasingShapes([]) this.parent.transition('idle') } cancel() { this.editor.setErasingShapes([]) this.parent.transition('idle') } }