Skip to content

Commit

Permalink
Brief responses for self voicing prototype, see #196
Browse files Browse the repository at this point in the history
  • Loading branch information
jessegreenberg committed Mar 25, 2020
1 parent e7bb820 commit b24a093
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 9 deletions.
35 changes: 35 additions & 0 deletions gravity-force-lab-strings_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,41 @@
"value": "Behind mass controls."
}
}
},
"selfVoicing": {
"briefPositionChangeInteractionPattern": {
"value": "{{valueText}}. {{forceAlert}}"
},
"briefMassChangeForceAlertPattern": {
"value": "{{massChange}} mass, {{forceChange}} forces."
},
"briefDensityChangeForceAlertPattern": {
"value": "{{densityChange}} density, {{forceChange}} forces."
},
"briefNewForcePattern": {
"value": "Forces now {{value}} newtons."
},
"briefMassPushAlertPattern": {
"value": "{{massChange}} mass moves {{object}} {{direction}}."
},
"briefMassChangeWithPushAlertPattern": {
"value": "{{pushAlert}} {{forceAlert}}"
},
"briefMassChangeAlertPattern": {
"value": "{{propertyChange}} {{forceChange}}"
},
"biggerCapitalized": {
"value": "Bigger"
},
"smallerCapitalized": {
"value": "Smaller"
},
"more": {
"value": "More"
},
"less": {
"value": "Less"
}
}
}
}
130 changes: 130 additions & 0 deletions js/view/GravityForceLabAlertManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
* @author Michael Kauzmann (PhET Interactive Simulations)
*/

import inverseSquareLawCommonStrings from '../../../inverse-square-law-common/js/inverse-square-law-common-strings.js';
import ISLCQueryParameters from '../../../inverse-square-law-common/js/ISLCQueryParameters.js';
import ForceValuesDisplayEnum from '../../../inverse-square-law-common/js/model/ForceValuesDisplayEnum.js';
import ISLCAlertManager from '../../../inverse-square-law-common/js/view/ISLCAlertManager.js';
import ISLCObjectEnum from '../../../inverse-square-law-common/js/view/ISLCObjectEnum.js';
import webSpeaker from '../../../inverse-square-law-common/js/view/webSpeaker.js';
import merge from '../../../phet-core/js/merge.js';
import StringUtils from '../../../phetcommon/js/util/StringUtils.js';
import ActivationUtterance from '../../../utterance-queue/js/ActivationUtterance.js';
Expand All @@ -20,6 +24,21 @@ import GravityForceLabModel from '../model/GravityForceLabModel.js';
const constantRadiusThinkDensityPatternString = gravityForceLabStrings.a11y.controls.constantRadiusThinkDensityPattern;
const massAndForceClausesPatternString = gravityForceLabStrings.a11y.qualitative.massAndForceClausesPattern;
const sentencePatternString = gravityForceLabStrings.a11y.sentencePattern;
const selfVoicingBriefMassChangeForceAlertPatternString = gravityForceLabStrings.a11y.selfVoicing.briefMassChangeForceAlertPattern;
const selfVoicingBriefNewForceAlertPatternString = inverseSquareLawCommonStrings.a11y.selfVoicing.briefNewForceAlertPattern;
const selfVoicingBiggerString = inverseSquareLawCommonStrings.a11y.selfVoicing.bigger;
const selfVoicingSmallerString = inverseSquareLawCommonStrings.a11y.selfVoicing.smaller;
const selfVoicingBiggerCapitalizedString = gravityForceLabStrings.a11y.selfVoicing.biggerCapitalized;
const selfVoicingSmallerCapitalizedString = gravityForceLabStrings.a11y.selfVoicing.smallerCapitalized;
const selfVoicingBriefMassPushAlertPatternString = gravityForceLabStrings.a11y.selfVoicing.briefMassPushAlertPattern;
const briefMassChangeWithPushAlertPatternString = gravityForceLabStrings.a11y.selfVoicing.briefMassChangeWithPushAlertPattern;
const briefDensityChangeForceAlertPatternString = gravityForceLabStrings.a11y.selfVoicing.briefDensityChangeForceAlertPattern;
const briefNewForcePatternString = gravityForceLabStrings.a11y.selfVoicing.briefNewForcePattern;
const selfVoicingMoreString = gravityForceLabStrings.a11y.selfVoicing.more;
const selfVoicingLessString = gravityForceLabStrings.a11y.selfVoicing.less;
const briefMassChangeAlertPatternString = gravityForceLabStrings.a11y.selfVoicing.briefMassChangeAlertPattern;
const briefNewForceNoValuesAlertString = inverseSquareLawCommonStrings.a11y.selfVoicing.briefNewForceNoValuesAlert;
const selfVoicingBriefNewForcePatternString = gravityForceLabStrings.a11y.selfVoicing.briefNewForcePattern;

class GravityForceLabAlertManager extends ISLCAlertManager {

Expand Down Expand Up @@ -92,6 +111,12 @@ class GravityForceLabAlertManager extends ISLCAlertManager {
}
else { // value specific assumption
this.alertMassValueChanged( objectEnum, true );

if ( ISLCQueryParameters.selfVoicing ) {
if ( webSpeaker.getInteractiveModeBrief() ) {
webSpeaker.speak( this.getSelfVoicingForceChangeFromMassWithPushAlert( objectEnum ) );
}
}
}
};
model.object1.positionChangedFromSecondarySourceEmitter.addListener( secondaryPositionChangedListener );
Expand Down Expand Up @@ -143,6 +168,111 @@ class GravityForceLabAlertManager extends ISLCAlertManager {
return this.massChangedUtterance;
}

/**
* PROTOTYPE CODE: Get an alert that describes the changing mass value, with varying information depending on whether
* force values are visible and masses are at constant size. To be used on the "brief interactive" mode of
* self voicing output.
* @public
*
* @param {ISLCObjectEnum} objectEnum
* @param {number} currentMass
* @param {number} oldMass
* @param {string} otherObjectLabel
* @returns {string}
*/
getSelfVoicingForceChangeFromMassAlert( objectEnum, currentMass, oldMass, otherObjectLabel ) {
let alert;

const biggerSmallerChangeString = currentMass > oldMass ? selfVoicingBiggerString : selfVoicingSmallerString;
const changeStringCapitalized = currentMass > oldMass ? selfVoicingBiggerCapitalizedString : selfVoicingSmallerCapitalizedString;
const valueString = this.forceDescriber.getFormattedForce();

const constantSize = this.model.constantRadiusProperty.get();
const forceValuesShown = this.model.showForceValuesProperty.get();

if ( constantSize ) {
const moreLessChangeString = currentMass > oldMass ? selfVoicingMoreString : selfVoicingLessString;
const densityChangeString = StringUtils.fillIn( briefDensityChangeForceAlertPatternString, {
densityChange: moreLessChangeString,
forceChange: biggerSmallerChangeString
} );
if ( !forceValuesShown ) {

// forces are not shown, show just describe impact on forces
alert = densityChangeString;
}
else {

// forces are shown, read the new force value too
const newForceString = StringUtils.fillIn( briefNewForcePatternString, {
value: valueString
} );
alert = StringUtils.fillIn( briefMassChangeAlertPatternString, {
propertyChange: densityChangeString,
forceChange: newForceString
} );
}
}
else {
const massChangeString = StringUtils.fillIn( selfVoicingBriefMassChangeForceAlertPatternString, {
massChange: changeStringCapitalized,
forceChange: biggerSmallerChangeString
} );

if ( forceValuesShown ) {
const newForceString = StringUtils.fillIn( selfVoicingBriefNewForcePatternString, {
value: valueString
} );

alert = StringUtils.fillIn( briefMassChangeWithPushAlertPatternString, {
pushAlert: massChangeString,
forceAlert: newForceString
} );
}
else {
alert = massChangeString;
}
}

return alert;
}

/**
* PROTOTYPE CODE: Gets an alert to be read when the mass changes AND due to increasing size pushes the other mass a bit.
* This is used in the self voicing prototype, when in "brief interactive" output.
*
* @param {ISLCObjectEnum} objectEnum
* @returns {string}
*/
getSelfVoicingForceChangeFromMassWithPushAlert( objectEnum ) {
const forceValuesShown = this.model.showForceValuesProperty.get();
const valueString = this.forceDescriber.getFormattedForce();

let newForceString;
if ( forceValuesShown ) {
newForceString = StringUtils.fillIn( selfVoicingBriefNewForceAlertPatternString, {
change: selfVoicingBiggerString,
value: valueString
} );
}
else {
newForceString = StringUtils.fillIn( briefNewForceNoValuesAlertString, {
change: selfVoicingBiggerString
} );
}

const pushAlertString = StringUtils.fillIn( selfVoicingBriefMassPushAlertPatternString, {
massChange: selfVoicingBiggerCapitalizedString,
object: this.forceDescriber.getOtherObjectLabelFromEnum( objectEnum ),
direction: this.massDescriber.getPushDirectionText( ISLCObjectEnum.getOtherObjectEnum( objectEnum ) )
} );

return StringUtils.fillIn( briefMassChangeWithPushAlertPatternString, {
pushAlert: pushAlertString,
forceAlert: newForceString
} );
}

/**
* Get an alert for when masses radius becomes constant or dynamic.
* @public
Expand Down
22 changes: 13 additions & 9 deletions js/view/describers/MassDescriber.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ class MassDescriber extends ISLCDescriber {
*/
getMassChangesAndMovesClause( thisObjectEnum ) {
const changeDirectionPhrase = this.getMassOrDensityChangeDirectionPhrase( thisObjectEnum );
const leftOrRight = getPushDirection( thisObjectEnum );
const leftOrRight = this.getPushDirectionText( thisObjectEnum );
return StringUtils.fillIn( massChangesAndMovesClausePatternString, {
changeDirectionPhrase: changeDirectionPhrase,
leftOrRight: leftOrRight
Expand All @@ -293,7 +293,7 @@ class MassDescriber extends ISLCDescriber {
getMassChangesAndMovesOtherClause( thisObjectEnum ) {
const changeDirectionPhrase = this.getMassOrDensityChangeDirectionPhrase( thisObjectEnum );
const otherObjectLabel = this.getOtherObjectLabelFromEnum( thisObjectEnum );
const leftOrRight = getPushDirection( ISLCObjectEnum.getOtherObjectEnum( thisObjectEnum ) );
const leftOrRight = this.getPushDirectionText( ISLCObjectEnum.getOtherObjectEnum( thisObjectEnum ) );
return StringUtils.fillIn( massChangesMovesOtherClausePatternString, {
changeDirectionPhrase: changeDirectionPhrase,
otherObjectLabel: otherObjectLabel,
Expand Down Expand Up @@ -351,14 +351,18 @@ class MassDescriber extends ISLCDescriber {
unit: this.forceDescriber.units
} );
}
}

/**
* Each object can only be pushed in one direction. Returns 'left' or 'right' based on the object passed in.
* @param {ISLCObjectEnum} objectEnum
* @returns {string}
*/
const getPushDirection = objectEnum => ISLCObjectEnum.isObject1( objectEnum ) ? leftString : rightString;
/**
* Each object can only be pushed in one direction. Returns 'left' or 'right' based on the object passed in.
* @public
*
* @param {ISLCObjectEnum} objectEnum
* @returns {string}
*/
getPushDirectionText( objectEnum ) {
return ISLCObjectEnum.isObject1( objectEnum ) ? leftString : rightString;
}
}

/**
* @param {number} index - should be an index
Expand Down

0 comments on commit b24a093

Please sign in to comment.