diff --git a/js/create/view/CreateScreenSummaryNode.ts b/js/create/view/CreateScreenSummaryNode.ts index ae67323d..cfdedc3a 100644 --- a/js/create/view/CreateScreenSummaryNode.ts +++ b/js/create/view/CreateScreenSummaryNode.ts @@ -1,7 +1,8 @@ // Copyright 2020-2022, University of Colorado Boulder /** - * Node that holds the PDOM content for the screen summary in the Create screen. + * Node that holds the PDOM content for the screen summary in the Create screen. It also creates content for the voicing + * overview buttons as appropriate. * * @author Michael Kauzmann (PhET Interactive Simulations) */ @@ -22,6 +23,14 @@ import EnumerationProperty from '../../../../axon/js/EnumerationProperty.js'; class CreateScreenSummaryNode extends Node { + private ratioDescriber: RatioDescriber; + private handPositionsDescriber: HandPositionsDescriber; + private ratioFitnessProperty: IReadOnlyProperty; + private ratioTupleProperty: Property; + private tickMarkViewProperty: EnumerationProperty; + private inProportionProperty: IReadOnlyProperty; + private myChallengeAccordionBox: MyChallengeAccordionBox; + constructor( ratioFitnessProperty: IReadOnlyProperty, ratioTupleProperty: Property, tickMarkViewProperty: EnumerationProperty, @@ -63,6 +72,14 @@ class CreateScreenSummaryNode extends Node { ] } ); + this.handPositionsDescriber = handPositionsDescriber; + this.ratioDescriber = ratioDescriber; + this.tickMarkViewProperty = tickMarkViewProperty; + this.ratioTupleProperty = ratioTupleProperty; + this.ratioFitnessProperty = ratioFitnessProperty; + this.inProportionProperty = inProportionProperty; + this.myChallengeAccordionBox = myChallengeAccordionBox; + myChallengeAccordionBox.expandedProperty.link( ( expanded: boolean ) => { if ( expanded ) { descriptionBullets.addChild( currentChallengeBullet ); @@ -83,22 +100,52 @@ class CreateScreenSummaryNode extends Node { ], ( tickMarkView: TickMarkView, targetAntecedent: number, targetConsequent: number, currentTuple: RAPRatioTuple, fitness: number, inProportion: boolean, tickMarkRange: number ) => { - stateOfSimNode.innerContent = StringUtils.fillIn( ratioAndProportionStrings.a11y.screenSummaryQualitativeStateOfSim, { - color: BackgroundColorHandler.getCurrentColorRegion( fitness, inProportion ), - ratioFitness: ratioDescriber.getRatioFitness( false ), - currentChallenge: ratioAndProportionStrings.a11y.create.challenge, - distance: handPositionsDescriber.getDistanceRegion( true ) - } ); + stateOfSimNode.innerContent = this.getStateOfSim(); + + leftHandBullet.innerContent = this.getLeftHandState(); + + rightHandBullet.innerContent = this.getLeftHandState(); + + currentChallengeBullet.innerContent = this.getCurrentChallengeState(); + } ); + } + + private getStateOfSim( currentChallenge: string = ratioAndProportionStrings.a11y.create.challenge ): string { + return StringUtils.fillIn( ratioAndProportionStrings.a11y.screenSummaryQualitativeStateOfSim, { + color: BackgroundColorHandler.getCurrentColorRegion( this.ratioFitnessProperty.value, this.inProportionProperty.value ), + ratioFitness: this.ratioDescriber.getRatioFitness( false ), + currentChallenge: currentChallenge, + distance: this.handPositionsDescriber.getDistanceRegion( true ) + } ); + } + + private getLeftHandState(): string { + return StringUtils.fillIn( ratioAndProportionStrings.a11y.leftHandBullet, { + position: this.handPositionsDescriber.getHandPositionDescription( this.ratioTupleProperty.value.antecedent, this.tickMarkViewProperty.value ) + } ); + } - leftHandBullet.innerContent = StringUtils.fillIn( ratioAndProportionStrings.a11y.leftHandBullet, { - position: handPositionsDescriber.getHandPositionDescription( currentTuple.antecedent, tickMarkView ) - } ); + private getRightHandState(): string { + return StringUtils.fillIn( ratioAndProportionStrings.a11y.rightHandBullet, { + position: this.handPositionsDescriber.getHandPositionDescription( this.ratioTupleProperty.value.consequent, this.tickMarkViewProperty.value ) + } ); + } - rightHandBullet.innerContent = StringUtils.fillIn( ratioAndProportionStrings.a11y.rightHandBullet, { - position: handPositionsDescriber.getHandPositionDescription( currentTuple.consequent, tickMarkView ) - } ); + private getCurrentChallengeState(): string { + return this.ratioDescriber.getCurrentChallengeSentence( this.myChallengeAccordionBox.targetAntecedentProperty.value, + this.myChallengeAccordionBox.targetConsequentProperty.value + ); + } - currentChallengeBullet.innerContent = ratioDescriber.getCurrentChallengeSentence( targetAntecedent, targetConsequent ); + getDetailsButtonState(): string { + const pattern = this.myChallengeAccordionBox.expandedProperty.value ? + ratioAndProportionStrings.a11y.detailsButtonWithCurrentChallengePattern : + ratioAndProportionStrings.a11y.detailsButtonPattern; + return StringUtils.fillIn( pattern, { + stateOfSim: this.getStateOfSim(), + leftHand: this.getLeftHandState(), + rightHand: this.getRightHandState(), + currentChallenge: this.getCurrentChallengeState() } ); } } diff --git a/js/create/view/CreateScreenView.ts b/js/create/view/CreateScreenView.ts index 8518c532..69d4d570 100644 --- a/js/create/view/CreateScreenView.ts +++ b/js/create/view/CreateScreenView.ts @@ -26,6 +26,7 @@ class CreateScreenView extends RAPScreenView { private tickMarkRangeComboBoxNode: TickMarkRangeComboBoxNode; private resetCreateScreenView: () => void; + private createScreenSummaryNode: CreateScreenSummaryNode; constructor( model: RAPModel, backgroundColorProperty: Property, tandem: Tandem ) { @@ -49,7 +50,7 @@ class CreateScreenView extends RAPScreenView { this.tickMarkRangeComboBoxNode = new TickMarkRangeComboBoxNode( this.tickMarkRangeProperty, tickMarkRangeComboBoxParent, this.tickMarkViewProperty ); // set this after the supertype has initialized the view code needed to create the screen summary - this.setScreenSummaryContent( new CreateScreenSummaryNode( + this.createScreenSummaryNode = new CreateScreenSummaryNode( model.ratioFitnessProperty, model.ratio.tupleProperty, this.tickMarkViewProperty, @@ -58,7 +59,8 @@ class CreateScreenView extends RAPScreenView { this.handPositionsDescriber, this.tickMarkRangeProperty, myChallengeAccordionBox - ) ); + ); + this.setScreenSummaryContent( this.createScreenSummaryNode ); const ratioLockedUtterance = new ActivationUtterance(); @@ -173,6 +175,15 @@ class CreateScreenView extends RAPScreenView { return ratioAndProportionStrings.a11y.create.overviewSentence; } + /** + * To support voicing. + * @override + * @public + */ + public getVoicingDetailsContent(): string { + return this.createScreenSummaryNode.getDetailsButtonState(); + } + /** * To support voicing. * @override diff --git a/js/discover/view/DiscoverScreenSummaryNode.ts b/js/discover/view/DiscoverScreenSummaryNode.ts index c7421b74..bccfadd9 100644 --- a/js/discover/view/DiscoverScreenSummaryNode.ts +++ b/js/discover/view/DiscoverScreenSummaryNode.ts @@ -1,7 +1,8 @@ // Copyright 2020-2022, University of Colorado Boulder /** - * Node that holds the PDOM content for the screen summary in Ratio and Proportion. + * Node that holds the PDOM content for the screen summary in Ratio and Proportion. It also creates content for the voicing + * overview buttons as appropriate. * * @author Michael Kauzmann (PhET Interactive Simulations) */ @@ -19,12 +20,22 @@ import RatioDescriber from '../../common/view/describers/RatioDescriber.js'; import IReadOnlyProperty from '../../../../axon/js/IReadOnlyProperty.js'; import EnumerationProperty from '../../../../axon/js/EnumerationProperty.js'; +type RatioToChallengeNameMap = Map; + class DiscoverScreenSummaryNode extends Node { + private ratioDescriber: RatioDescriber; + private handPositionsDescriber: HandPositionsDescriber; + private ratioFitnessProperty: IReadOnlyProperty; + private ratioTupleProperty: Property; + private targetRatioProperty: Property; + private tickMarkViewProperty: EnumerationProperty; + private inProportionProperty: IReadOnlyProperty; + private ratioToChallengeNameMap: RatioToChallengeNameMap; constructor( ratioFitnessProperty: IReadOnlyProperty, ratioTupleProperty: Property, targetRatioProperty: Property, tickMarkViewProperty: EnumerationProperty, ratioDescriber: RatioDescriber, inProportionProperty: IReadOnlyProperty, handPositionsDescriber: HandPositionsDescriber, - ratioToChallengeNameMap: Map ) { + ratioToChallengeNameMap: RatioToChallengeNameMap ) { const stateOfSimNode = new Node( { tagName: 'p' @@ -60,6 +71,15 @@ class DiscoverScreenSummaryNode extends Node { ] } ); + this.handPositionsDescriber = handPositionsDescriber; + this.ratioDescriber = ratioDescriber; + this.targetRatioProperty = targetRatioProperty; + this.tickMarkViewProperty = tickMarkViewProperty; + this.ratioTupleProperty = ratioTupleProperty; + this.ratioFitnessProperty = ratioFitnessProperty; + this.inProportionProperty = inProportionProperty; + this.ratioToChallengeNameMap = ratioToChallengeNameMap; + // This derivedProperty is already dependent on all other dependencies for getStateOfSimString Property.multilink( [ targetRatioProperty, @@ -69,20 +89,40 @@ class DiscoverScreenSummaryNode extends Node { inProportionProperty ], ( currentTargetRatio: number, tickMarkView: TickMarkView, currentTuple: RAPRatioTuple, fitness: number, inProportion: boolean ) => { - stateOfSimNode.innerContent = StringUtils.fillIn( ratioAndProportionStrings.a11y.screenSummaryQualitativeStateOfSim, { - color: BackgroundColorHandler.getCurrentColorRegion( fitness, inProportion ), - ratioFitness: ratioDescriber.getRatioFitness( false ), - currentChallenge: ratioToChallengeNameMap.get( currentTargetRatio )!.lowercase, - distance: handPositionsDescriber.getDistanceRegion( true ) - } ); + stateOfSimNode.innerContent = this.getStateOfSim(); + + leftHandBullet.innerContent = this.getLeftHandState(); + + rightHandBullet.innerContent = this.getRightHandState(); + } ); + } + + private getStateOfSim(): string { + return StringUtils.fillIn( ratioAndProportionStrings.a11y.screenSummaryQualitativeStateOfSim, { + color: BackgroundColorHandler.getCurrentColorRegion( this.ratioFitnessProperty.value, this.inProportionProperty.value ), + ratioFitness: this.ratioDescriber.getRatioFitness( false ), + currentChallenge: this.ratioToChallengeNameMap.get( this.targetRatioProperty.value )!.lowercase, + distance: this.handPositionsDescriber.getDistanceRegion( true ) + } ); + } - leftHandBullet.innerContent = StringUtils.fillIn( ratioAndProportionStrings.a11y.leftHandBullet, { - position: handPositionsDescriber.getHandPositionDescription( currentTuple.antecedent, tickMarkView ) - } ); + private getLeftHandState(): string { + return StringUtils.fillIn( ratioAndProportionStrings.a11y.leftHandBullet, { + position: this.handPositionsDescriber.getHandPositionDescription( this.ratioTupleProperty.value.antecedent, this.tickMarkViewProperty.value ) + } ); + } + + private getRightHandState(): string { + return StringUtils.fillIn( ratioAndProportionStrings.a11y.rightHandBullet, { + position: this.handPositionsDescriber.getHandPositionDescription( this.ratioTupleProperty.value.consequent, this.tickMarkViewProperty.value ) + } ); + } - rightHandBullet.innerContent = StringUtils.fillIn( ratioAndProportionStrings.a11y.rightHandBullet, { - position: handPositionsDescriber.getHandPositionDescription( currentTuple.consequent, tickMarkView ) - } ); + getDetailsButtonState(): string { + return StringUtils.fillIn( ratioAndProportionStrings.a11y.detailsButtonPattern, { + stateOfSim: this.getStateOfSim(), + leftHand: this.getLeftHandState(), + rightHand: this.getRightHandState() } ); } } diff --git a/js/discover/view/DiscoverScreenView.ts b/js/discover/view/DiscoverScreenView.ts index 25bb0324..27c4e85a 100644 --- a/js/discover/view/DiscoverScreenView.ts +++ b/js/discover/view/DiscoverScreenView.ts @@ -18,6 +18,7 @@ import Bounds2 from '../../../../dot/js/Bounds2.js'; class DiscoverScreenView extends RAPScreenView { private comboBoxContainer: ChallengeRatioComboBoxNode; + private discoverScreenSummaryNode: DiscoverScreenSummaryNode; constructor( model: RAPModel, backgroundColorProperty: Property, tandem: Tandem ) { @@ -47,7 +48,7 @@ class DiscoverScreenView extends RAPScreenView { this.pdomPlayAreaNode.pdomOrder = this.pdomPlayAreaNode.pdomOrder!.concat( [ this.comboBoxContainer, comboBoxListBoxParent ] ); // set this after the supertype has initialized the view code needed to create the screen summary - this.setScreenSummaryContent( new DiscoverScreenSummaryNode( + this.discoverScreenSummaryNode = new DiscoverScreenSummaryNode( model.ratioFitnessProperty, model.ratio.tupleProperty, model.targetRatioProperty, @@ -56,7 +57,8 @@ class DiscoverScreenView extends RAPScreenView { model.inProportionProperty, this.handPositionsDescriber, this.comboBoxContainer.ratioToChallengeNameMap - ) ); + ); + this.setScreenSummaryContent( this.discoverScreenSummaryNode ); // layout this.comboBoxContainer.right = this.tickMarkViewRadioButtonGroup.right; @@ -82,6 +84,15 @@ class DiscoverScreenView extends RAPScreenView { return ratioAndProportionStrings.a11y.discover.overviewSentence; } + /** + * To support voicing. + * @override + * @public + */ + public getVoicingDetailsContent(): string { + return this.discoverScreenSummaryNode.getDetailsButtonState(); + } + /** * To support voicing. * @override diff --git a/js/ratioAndProportionStrings.ts b/js/ratioAndProportionStrings.ts index ea44f372..cd98b4e3 100644 --- a/js/ratioAndProportionStrings.ts +++ b/js/ratioAndProportionStrings.ts @@ -1,4 +1,4 @@ -// Copyright 2020-2021, University of Colorado Boulder +// Copyright 2020-2022, University of Colorado Boulder /** * Auto-generated from modulify, DO NOT manually modify. @@ -131,6 +131,8 @@ type StringsType = { 'ratioNoLongerLocked': string, 'screenSummaryControlAreaParagraph': string, 'screenSummaryQualitativeStateOfSim': string, + 'detailsButtonPattern': string, + 'detailsButtonWithCurrentChallengePattern': string, 'discover': { 'homeScreenDescription': string, 'screenSummary': { diff --git a/ratio-and-proportion-strings_en.json b/ratio-and-proportion-strings_en.json index 58a1a891..c659450c 100644 --- a/ratio-and-proportion-strings_en.json +++ b/ratio-and-proportion-strings_en.json @@ -334,6 +334,12 @@ "screenSummaryQualitativeStateOfSim": { "value": "Currently, the screen is {{color}}, hands are {{ratioFitness}} the {{currentChallenge}} ratio and {{distance}} each other:" }, + "detailsButtonPattern": { + "value": "{{stateOfSim}} {{leftHand}} {{rightHand}}" + }, + "detailsButtonWithCurrentChallengePattern": { + "value": "{{stateOfSim}} {{leftHand}} {{rightHand}} {{currentChallenge}}" + }, "discover": { "homeScreenDescription": { "value": "Explore and discover set challenge ratios."