From 2515980d196b51716603d7002e5e5d5ceb993669 Mon Sep 17 00:00:00 2001 From: zepumph Date: Thu, 11 Nov 2021 13:48:52 -0700 Subject: [PATCH] add prototype of alt-input for stopwatch in toolbox, https://github.com/phetsims/a11y-research/issues/166 --- js/StopwatchNode.js | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/js/StopwatchNode.js b/js/StopwatchNode.js index cc93edd6b..a2f7c1bcf 100644 --- a/js/StopwatchNode.js +++ b/js/StopwatchNode.js @@ -15,6 +15,7 @@ import InstanceRegistry from '../../phet-core/js/documentation/InstanceRegistry. import merge from '../../phet-core/js/merge.js'; import StringUtils from '../../phetcommon/js/util/StringUtils.js'; import DragListener from '../../scenery/js/listeners/DragListener.js'; +import KeyboardDragListener from '../../scenery/js/listeners/KeyboardDragListener.js'; import Circle from '../../scenery/js/nodes/Circle.js'; import HBox from '../../scenery/js/nodes/HBox.js'; import Node from '../../scenery/js/nodes/Node.js'; @@ -80,6 +81,10 @@ class StopwatchNode extends Node { // options propagated to the DragListener. dragListenerOptions: { start: _.noop + }, + keyboardDragListenerOptions: { + start: _.noop + } }, options ); assert && assert( !options.hasOwnProperty( 'maxValue' ), 'options.maxValue no longer supported' ); @@ -135,7 +140,10 @@ class StopwatchNode extends Node { const backgroundNode = new ShadedRectangle( new Bounds2( 0, 0, contents.width + 2 * options.xMargin, contents.height + 2 * options.yMargin ), { - baseColor: options.backgroundBaseColor + baseColor: options.backgroundBaseColor, + // pdom + tagName: 'div', + focusable: true } ); contents.center = backgroundNode.center; @@ -144,6 +152,8 @@ class StopwatchNode extends Node { super( options ); + this.backgroundNode = backgroundNode; + // Disable the reset button when time is zero, and enable the play/pause button when not at the max time const timeListener = time => { resetButton.enabled = time > 0; @@ -209,11 +219,25 @@ class StopwatchNode extends Node { optionsStart(); }; + const keyboardDragListenerOptions = merge( { + positionProperty: stopwatch.positionProperty, + dragBoundsProperty: adjustedDragBoundsProperty + }, options.keyboardDragListenerOptions ); + + // Add moveToFront to any start function that the client provided. + const keyboardOptionsStart = keyboardDragListenerOptions.start; + keyboardDragListenerOptions.start = () => { + this.moveToFront(); + keyboardOptionsStart(); + }; + // Dragging, added to background so that other UI components get input events on touch devices. // If added to 'this', touchSnag will lock out listeners for other UI components. this.dragListener = new DragListener( dragListenerOptions ); backgroundNode.addInputListener( this.dragListener ); + backgroundNode.addInputListener( new KeyboardDragListener( keyboardDragListenerOptions ) ); + // Move to front on pointer down, anywhere on this Node, including interactive subcomponents. this.addInputListener( { down: () => this.moveToFront() @@ -249,6 +273,15 @@ class StopwatchNode extends Node { assert && phet.chipper.queryParameters.binder && InstanceRegistry.registerDataURL( 'scenery-phet', 'StopwatchNode', this ); } + /** + * Forward to the background + * @override + * @public + */ + focus() { + this.backgroundNode.focus(); + } + /** * @param {function(number):string} numberFormatter * @public