@@ -37,7 +37,7 @@ export class FieldBitmap extends Blockly.Field<number[][]> {
3737 private editorPixels : HTMLElement [ ] [ ] | null = null ;
3838 private blockDisplayPixels : SVGElement [ ] [ ] | null = null ;
3939 /** Stateful variables */
40- private mouseIsDown = false ;
40+ private pointerIsDown = false ;
4141 private valToPaintWith ?: number ;
4242 buttonOptions : Buttons ;
4343 pixelSize : number ;
@@ -292,9 +292,13 @@ export class FieldBitmap extends Blockly.Field<number[][]> {
292292 // This prevents the normal max-height from adding a scroll bar for large images.
293293 Blockly . DropDownDiv . getContentDiv ( ) . classList . add ( 'contains-bitmap-editor' ) ;
294294
295- this . bindEvent ( dropdownEditor , 'mouseup' , this . onMouseUp ) ;
296- this . bindEvent ( dropdownEditor , 'mouseleave' , this . onMouseUp ) ;
297- this . bindEvent ( dropdownEditor , 'dragstart' , ( e : Event ) => {
295+ this . bindEvent ( dropdownEditor , 'pointermove' , this . onPointerMove ) ;
296+ this . bindEvent ( dropdownEditor , 'pointerup' , this . onPointerEnd ) ;
297+ this . bindEvent ( dropdownEditor , 'pointerleave' , this . onPointerEnd ) ;
298+ this . bindEvent ( dropdownEditor , 'pointerdown' , this . onPointerStart ) ;
299+ this . bindEvent ( dropdownEditor , 'pointercancel' , this . onPointerEnd ) ;
300+ // Stop the browser from handling touch events and cancelling the event.
301+ this . bindEvent ( dropdownEditor , 'touchmove' , ( e : Event ) => {
298302 e . preventDefault ( ) ;
299303 } ) ;
300304
@@ -314,16 +318,9 @@ export class FieldBitmap extends Blockly.Field<number[][]> {
314318 ? this . pixelColours . filled
315319 : this . pixelColours . empty ;
316320
317- // Handle clicking a pixel
318- this . bindEvent ( button , 'mousedown' , ( ) => {
319- this . onMouseDownInPixel ( r , c ) ;
320- return true ;
321- } ) ;
322-
323- // Handle dragging into a pixel when mouse is down
324- this . bindEvent ( button , 'mouseenter' , ( ) => {
325- this . onMouseEnterPixel ( r , c ) ;
326- } ) ;
321+ // Set the custom data attributes for row and column indices
322+ button . setAttribute ( 'data-row' , r . toString ( ) ) ;
323+ button . setAttribute ( 'data-col' , c . toString ( ) ) ;
327324 }
328325 pixelContainer . appendChild ( rowDiv ) ;
329326 }
@@ -473,29 +470,63 @@ export class FieldBitmap extends Blockly.Field<number[][]> {
473470 }
474471
475472 /**
476- * Called when a mousedown event occurs within the bounds of a pixel.
473+ * Checks if a down event is on a pixel in this editor and if it is starts an
474+ * edit gesture.
475+ *
476+ * @param e The down event.
477+ */
478+ private onPointerStart ( e : PointerEvent ) {
479+ const currentElement = document . elementFromPoint ( e . clientX , e . clientY ) ;
480+ const rowIndex = currentElement ?. getAttribute ( 'data-row' ) ;
481+ const colIndex = currentElement ?. getAttribute ( 'data-col' ) ;
482+ if ( rowIndex && colIndex ) {
483+ this . onPointerDownInPixel ( parseInt ( rowIndex ) , parseInt ( colIndex ) ) ;
484+ this . pointerIsDown = true ;
485+ e . preventDefault ( ) ;
486+ }
487+ }
488+
489+ /**
490+ * Updates the editor if we're in an edit gesture and the pointer is over a
491+ * pixel.
492+ *
493+ * @param e The move event.
494+ */
495+ private onPointerMove ( e : PointerEvent ) {
496+ if ( ! this . pointerIsDown ) {
497+ return ;
498+ }
499+ const currentElement = document . elementFromPoint ( e . clientX , e . clientY ) ;
500+ const rowIndex = currentElement ?. getAttribute ( 'data-row' ) ;
501+ const colIndex = currentElement ?. getAttribute ( 'data-col' ) ;
502+ if ( rowIndex && colIndex ) {
503+ this . updatePixelValue ( parseInt ( rowIndex ) , parseInt ( colIndex ) ) ;
504+ }
505+ e . preventDefault ( ) ;
506+ }
507+
508+ /**
509+ * Starts an interaction with the bitmap dropdown when there's a pointerdown
510+ * within one of the pixels in the editor.
477511 *
478512 * @param r Row number of grid.
479513 * @param c Column number of grid.
480514 */
481- private onMouseDownInPixel ( r : number , c : number ) {
515+ private onPointerDownInPixel ( r : number , c : number ) {
482516 // Toggle that pixel to the opposite of its value
483517 const newPixelValue = 1 - this . getPixel ( r , c ) ;
484518 this . setPixel ( r , c , newPixelValue ) ;
485- this . mouseIsDown = true ;
519+ this . pointerIsDown = true ;
486520 this . valToPaintWith = newPixelValue ;
487521 }
488522
489523 /**
490- * Called when the mouse drags over a pixel in the editor.
524+ * Sets the specified pixel in the editor to the current value being painted .
491525 *
492526 * @param r Row number of grid.
493527 * @param c Column number of grid.
494528 */
495- private onMouseEnterPixel ( r : number , c : number ) {
496- if ( ! this . mouseIsDown ) {
497- return ;
498- }
529+ private updatePixelValue ( r : number , c : number ) {
499530 if (
500531 this . valToPaintWith !== undefined &&
501532 this . getPixel ( r , c ) !== this . valToPaintWith
@@ -505,11 +536,11 @@ export class FieldBitmap extends Blockly.Field<number[][]> {
505536 }
506537
507538 /**
508- * Resets mouse state (e.g. After either a mouseup event or if the mouse
509- * leaves the editor area ).
539+ * Resets pointer state (e.g. After either a pointerup event or if the
540+ * gesture is canceled ).
510541 */
511- private onMouseUp ( ) {
512- this . mouseIsDown = false ;
542+ private onPointerEnd ( ) {
543+ this . pointerIsDown = false ;
513544 this . valToPaintWith = undefined ;
514545 }
515546
@@ -594,10 +625,10 @@ export class FieldBitmap extends Blockly.Field<number[][]> {
594625 private bindEvent (
595626 element : HTMLElement ,
596627 eventName : string ,
597- callback : ( e : Event ) => void ,
628+ callback : ( e : PointerEvent ) => void ,
598629 ) {
599630 this . boundEvents . push (
600- Blockly . browserEvents . conditionalBind ( element , eventName , this , callback ) ,
631+ Blockly . browserEvents . bind ( element , eventName , this , callback ) ,
601632 ) ;
602633 }
603634
0 commit comments