diff --git a/js/HeaterCoolerFront.ts b/js/HeaterCoolerFront.ts index 4d75a9c4..44628572 100644 --- a/js/HeaterCoolerFront.ts +++ b/js/HeaterCoolerFront.ts @@ -17,7 +17,7 @@ import Dimension2 from '../../dot/js/Dimension2.js'; import Range from '../../dot/js/Range.js'; import { Shape } from '../../kite/js/imports.js'; import optionize, { combineOptions } from '../../phet-core/js/optionize.js'; -import { Color, Font, LinearGradient, Node, NodeOptions, Path, TColor, Text } from '../../scenery/js/imports.js'; +import { Color, Font, KeyboardListener, LinearGradient, Node, NodeOptions, Path, TColor, Text } from '../../scenery/js/imports.js'; import { SliderOptions } from '../../sun/js/Slider.js'; import VSlider from '../../sun/js/VSlider.js'; import Tandem from '../../tandem/js/Tandem.js'; @@ -208,6 +208,13 @@ export default class HeaterCoolerFront extends Node { blur: setSliderToZero } ); + // A shortcut to easily return the value to zero when using the keyboard. + const keyboardListener = new KeyboardListener( { + keys: [ '0' ], + fire: setSliderToZero + } ); + this.slider.addInputListener( keyboardListener ); + // Create the tick labels. const labelOptions = { font: options.labelFont, @@ -255,6 +262,7 @@ export default class HeaterCoolerFront extends Node { this.disposeHeaterCoolerFront = () => { heatTickText && heatTickText.dispose(); coolTickText && coolTickText.dispose(); + keyboardListener.dispose(); }; } diff --git a/js/SceneryPhetStrings.ts b/js/SceneryPhetStrings.ts index 84f1a745..01e5d693 100644 --- a/js/SceneryPhetStrings.ts +++ b/js/SceneryPhetStrings.ts @@ -66,12 +66,14 @@ type StringsType = { 'keyboardHelpDialog': { 'sliderControlsStringProperty': LocalizedStringProperty; 'adjustSliderStringProperty': LocalizedStringProperty; + 'spinnerControlsStringProperty': LocalizedStringProperty; 'adjustInSmallerStepsStringProperty': LocalizedStringProperty; 'adjustInLargerStepsStringProperty': LocalizedStringProperty; 'jumpToMinimumStringProperty': LocalizedStringProperty; 'jumpToMaximumStringProperty': LocalizedStringProperty; 'adjustStringProperty': LocalizedStringProperty; 'sliderStringProperty': LocalizedStringProperty; + 'spinnerStringProperty': LocalizedStringProperty; 'verbSliderPatternStringProperty': LocalizedStringProperty; 'verbInSmallerStepsPatternStringProperty': LocalizedStringProperty; 'verbInLargerStepsPatternStringProperty': LocalizedStringProperty; diff --git a/js/accessibility/group-sort/model/GroupSortInteractionModel.ts b/js/accessibility/group-sort/model/GroupSortInteractionModel.ts index d3119d25..ce37c721 100644 --- a/js/accessibility/group-sort/model/GroupSortInteractionModel.ts +++ b/js/accessibility/group-sort/model/GroupSortInteractionModel.ts @@ -73,7 +73,7 @@ type SelfOptions = { getGroupItemValue: ( itemModel: ItemModel ) => number | null; // Define the startup value of the mouseSortCue. False by default. - mouseSortCueVisibleAtStart?: boolean; + initialMouseSortCueVisible?: boolean; } & Pick; type ParentOptions = EnabledComponentOptions; @@ -135,7 +135,7 @@ export default class GroupSortInteractionModel extends EnabledCompone const options = optionize, SelfOptions, ParentOptions>()( { tandem: Tandem.REQUIRED, phetioEnabledPropertyInstrumented: false, - mouseSortCueVisibleAtStart: false + initialMouseSortCueVisible: false }, providedOptions ); super( options ); @@ -161,7 +161,7 @@ export default class GroupSortInteractionModel extends EnabledCompone } } ); - this.mouseSortCueVisibleProperty = new Property( options.mouseSortCueVisibleAtStart ); + this.mouseSortCueVisibleProperty = new Property( options.initialMouseSortCueVisible ); this.showMouseCueProperty = new BooleanProperty( true, { tandem: options.tandem.createTandem( 'showMouseCueProperty' ), diff --git a/js/demo/keyboard/KeyboardScreenView.ts b/js/demo/keyboard/KeyboardScreenView.ts index 2ecf9602..f9ade25b 100644 --- a/js/demo/keyboard/KeyboardScreenView.ts +++ b/js/demo/keyboard/KeyboardScreenView.ts @@ -17,6 +17,7 @@ import demoKeyNode from './demoKeyNode.js'; import demoKeyboardHelpSection from './demoKeyboardHelpSection.js'; import demoKeyboardHelpIconFactory from './demoKeyboardHelpIconFactory.js'; import demoFaucetControlsKeyboardHelpSection from './demoFaucetControlsKeyboardHelpSection.js'; +import demoSpinnerControlsKeyboardHelpSection from './demoSpinnerControlsKeyboardHelpSection.js'; type SelfOptions = EmptySelfOptions; type KeyboardScreenViewOptions = SelfOptions & PickRequired; @@ -37,6 +38,7 @@ export default class KeyboardScreenView extends DemosScreenView { { label: 'KeyboardHelpIconFactory', createNode: demoKeyboardHelpIconFactory }, { label: 'KeyboardHelpSection', createNode: demoKeyboardHelpSection }, { label: 'KeyNode', createNode: demoKeyNode }, + { label: 'SpinnerControlsKeyboardHelpSection', createNode: demoSpinnerControlsKeyboardHelpSection }, { label: 'SliderControlsKeyboardHelpSection', createNode: demoSliderControlsKeyboardHelpSection } ]; diff --git a/js/demo/keyboard/demoSpinnerControlsKeyboardHelpSection.ts b/js/demo/keyboard/demoSpinnerControlsKeyboardHelpSection.ts new file mode 100644 index 00000000..fb7ef98e --- /dev/null +++ b/js/demo/keyboard/demoSpinnerControlsKeyboardHelpSection.ts @@ -0,0 +1,17 @@ +// Copyright 2024, University of Colorado Boulder + +/** + * Demo for SpinnerControlsKeyboardHelpSection. + * + * @author Jesse Greenberg (PhET Interactive Simulations) + */ + +import Bounds2 from '../../../../dot/js/Bounds2.js'; +import { Node } from '../../../../scenery/js/imports.js'; +import SpinnerControlsKeyboardHelpSection from '../../keyboard/help/SpinnerControlsKeyboardHelpSection.js'; + +export default function demoSpinnerControlsKeyboardHelpSection( layoutBounds: Bounds2 ): Node { + const spinnerSection = new SpinnerControlsKeyboardHelpSection(); + spinnerSection.center = layoutBounds.center; + return spinnerSection; +} \ No newline at end of file diff --git a/js/keyboard/help/SliderControlsKeyboardHelpSection.ts b/js/keyboard/help/SliderControlsKeyboardHelpSection.ts index 23baa5b9..2a1bd78f 100644 --- a/js/keyboard/help/SliderControlsKeyboardHelpSection.ts +++ b/js/keyboard/help/SliderControlsKeyboardHelpSection.ts @@ -1,4 +1,4 @@ -// Copyright 2017-2023, University of Colorado Boulder +// Copyright 2017-2024, University of Colorado Boulder /** * Content for a KeyboardHelpDialog that describes how to use sliders. @@ -59,9 +59,11 @@ type SelfOptions = { maximumStringProperty?: TReadOnlyProperty; minimumStringProperty?: TReadOnlyProperty; - // This option determines whether this keyboard help section will have the - // "Adjust in Smaller Steps" row. The row includes the string and key icons. + // Determines whether this keyboard help section will have the "Adjust in Smaller Steps" row. includeSmallerStepsRow?: boolean; + + // Determines whether this keyboard help section will have the "Adjust in Larger Steps" row. + includeLargerStepsRow?: boolean; }; export type SliderControlsKeyboardHelpSectionOptions = SelfOptions & KeyboardHelpSectionOptions; @@ -91,7 +93,8 @@ export default class SliderControlsKeyboardHelpSection extends KeyboardHelpSecti adjustInSmallerStepsStringProperty: SceneryPhetStrings.keyboardHelpDialog.adjustInSmallerStepsStringProperty, adjustInLargerStepsStringProperty: SceneryPhetStrings.keyboardHelpDialog.adjustInLargerStepsStringProperty, - includeSmallerStepsRow: true + includeSmallerStepsRow: true, + includeLargerStepsRow: true }, providedOptions ); let adjustSliderStringProperty = options.adjustSliderStringProperty; @@ -216,7 +219,13 @@ export default class SliderControlsKeyboardHelpSection extends KeyboardHelpSecti } ); // assemble final content for KeyboardHelpSection - const content = [ adjustSliderRow, ...( options.includeSmallerStepsRow ? [ adjustSliderInSmallerStepsRow ] : [] ), adjustInLargerStepsRow, jumpToMinimumRow, jumpToMaximumRow ]; + const content = [ + adjustSliderRow, + ...( options.includeSmallerStepsRow ? [ adjustSliderInSmallerStepsRow ] : [] ), + ...( options.includeLargerStepsRow ? [ adjustInLargerStepsRow ] : [] ), + jumpToMinimumRow, + jumpToMaximumRow + ]; super( options.headingStringProperty, content, options ); } diff --git a/js/keyboard/help/SpinnerControlsKeyboardHelpSection.ts b/js/keyboard/help/SpinnerControlsKeyboardHelpSection.ts new file mode 100644 index 00000000..f32fec0a --- /dev/null +++ b/js/keyboard/help/SpinnerControlsKeyboardHelpSection.ts @@ -0,0 +1,36 @@ +// Copyright 2024, University of Colorado Boulder + +/** + * The keyboard help section that describes how to interact with a "spinner". + * + * @author Jesse Greenberg (PhET Interactive Simulations) + */ + +import SliderControlsKeyboardHelpSection, { SliderControlsKeyboardHelpSectionOptions } from './SliderControlsKeyboardHelpSection.js'; +import sceneryPhet from '../../sceneryPhet.js'; +import SceneryPhetStrings from '../../SceneryPhetStrings.js'; +import optionize, { EmptySelfOptions } from '../../../../phet-core/js/optionize.js'; + +const spinnerControlsStringProperty = SceneryPhetStrings.keyboardHelpDialog.spinnerControlsStringProperty; +const spinnerStringProperty = SceneryPhetStrings.keyboardHelpDialog.spinnerStringProperty; + +type SelfOptions = EmptySelfOptions; +type ParentOptions = SliderControlsKeyboardHelpSectionOptions; +export type SpinnerControlsKeyboardHelpSectionOptions = SelfOptions & ParentOptions; + +export default class SpinnerControlsKeyboardHelpSection extends SliderControlsKeyboardHelpSection { + public constructor( providedOptions?: SpinnerControlsKeyboardHelpSectionOptions ) { + + const options = optionize()( { + headingStringProperty: spinnerControlsStringProperty, + sliderStringProperty: spinnerStringProperty, + + // PhET 'spinners' usually do not support larger steps with the page up/page down keys. + includeLargerStepsRow: false + }, providedOptions ); + + super( options ); + } +} + +sceneryPhet.register( 'SpinnerControlsKeyboardHelpSection', SpinnerControlsKeyboardHelpSection ); \ No newline at end of file diff --git a/scenery-phet-strings_en.json b/scenery-phet-strings_en.json index 64096fd6..05a2ee8e 100644 --- a/scenery-phet-strings_en.json +++ b/scenery-phet-strings_en.json @@ -137,6 +137,9 @@ "keyboardHelpDialog.adjustSlider": { "value": "Adjust slider" }, + "keyboardHelpDialog.spinnerControls": { + "value": "Spinner Controls" + }, "keyboardHelpDialog.adjustInSmallerSteps": { "value": "Adjust in smaller steps" }, @@ -155,6 +158,9 @@ "keyboardHelpDialog.slider": { "value": "slider" }, + "keyboardHelpDialog.spinner": { + "value": "spinner" + }, "keyboardHelpDialog.verbSliderPattern": { "value": "{{verb}} {{slider}}" },