diff --git a/js/preferences/AudioPreferencesPanel.ts b/js/preferences/AudioPreferencesPanel.ts index 6c5518eb..35f21316 100644 --- a/js/preferences/AudioPreferencesPanel.ts +++ b/js/preferences/AudioPreferencesPanel.ts @@ -17,7 +17,6 @@ import VoicingPanelSection from './VoicingPanelSection.js'; import PreferencesPanelSection from './PreferencesPanelSection.js'; import PickRequired from '../../../phet-core/js/types/PickRequired.js'; import Emitter from '../../../axon/js/Emitter.js'; -import localeProperty from '../localeProperty.js'; // constants const audioFeaturesString = JoistStrings.preferences.tabs.audio.audioFeatures.titleStringProperty; @@ -42,17 +41,7 @@ class AudioPreferencesTabPanel extends VBox { const disposeEmitter = new Emitter(); if ( audioModel.supportsVoicing ) { - const voicingPanelSection = new VoicingPanelSection( audioModel ); - leftContent.addChild( voicingPanelSection ); - - // Voicing is only available in the 'en' locale. Strings for these controls are not translatable because the - // feature is not usable in other languages. If the locale is changed, Voicing is disabled and all related - // controls should be hidden. See https://github.com/phetsims/joist/issues/853. - const localeListener = ( locale: string ) => { - voicingPanelSection.visible = locale === 'en'; - }; - localeProperty.link( localeListener ); - disposeEmitter.addListener( () => localeProperty.unlink( localeListener ) ); + leftContent.addChild( new VoicingPanelSection( audioModel ) ); } if ( audioModel.supportsSound ) { diff --git a/js/preferences/PreferencesModel.ts b/js/preferences/PreferencesModel.ts index 483cf533..f57122db 100644 --- a/js/preferences/PreferencesModel.ts +++ b/js/preferences/PreferencesModel.ts @@ -320,10 +320,18 @@ export default class PreferencesModel extends PhetioObject { voicingManager.enabledProperty.value = phet.chipper.queryParameters.voicingInitiallyEnabled; // Voicing is only available in the 'en' locale currently. If the locale is changed away from english, Voicing is - // disabled. + // disabled. The next time Voicing returns to 'en', Voicing will be enabled again. + let voicingDisabledFromLocale = false; localeProperty.link( locale => { + + const englishLocale = locale.startsWith( 'en' ); if ( voicingManager.enabledProperty.value ) { - voicingManager.enabledProperty.value = locale === 'en'; + voicingManager.enabledProperty.value = englishLocale; + voicingDisabledFromLocale = true; + } + else if ( voicingDisabledFromLocale && englishLocale ) { + voicingManager.enabledProperty.value = true; + voicingDisabledFromLocale = false; } } ); diff --git a/js/preferences/PreferencesToggleSwitch.ts b/js/preferences/PreferencesToggleSwitch.ts index c1c9f3d1..a24e4dd4 100644 --- a/js/preferences/PreferencesToggleSwitch.ts +++ b/js/preferences/PreferencesToggleSwitch.ts @@ -12,7 +12,7 @@ import Dimension2 from '../../../dot/js/Dimension2.js'; import merge from '../../../phet-core/js/merge.js'; import optionize from '../../../phet-core/js/optionize.js'; import StrictOmit from '../../../phet-core/js/types/StrictOmit.js'; -import { GridBox, Node, NodeOptions, PDOMValueType } from '../../../scenery/js/imports.js'; +import { GridBox, Node, NodeOptions, PDOMValueType, SceneryConstants } from '../../../scenery/js/imports.js'; import ToggleSwitch, { ToggleSwitchOptions } from '../../../sun/js/ToggleSwitch.js'; import Tandem from '../../../tandem/js/Tandem.js'; import Utterance, { TAlertable } from '../../../utterance-queue/js/Utterance.js'; @@ -129,6 +129,14 @@ class PreferencesToggleSwitch extends Node { }; property.lazyLink( valueListener ); + // This component manages disabledOpacity, we don't want it to compound over subcomponents. + toggleSwitch.disabledOpacity = 1; + this.disabledOpacity = SceneryConstants.DISABLED_OPACITY; + + this.enabledProperty.link( enabled => { + toggleSwitch.enabled = enabled; + } ); + // Layout using GridBox and layoutOptions will accomplish the following when all components are available. // [[labelNode]] [[ToggleSwitch]] // [[descriptionNode ]] diff --git a/js/preferences/VoicingPanelSection.ts b/js/preferences/VoicingPanelSection.ts index 8563f715..f331dbfd 100644 --- a/js/preferences/VoicingPanelSection.ts +++ b/js/preferences/VoicingPanelSection.ts @@ -106,7 +106,7 @@ class VoicingPanelSection extends PreferencesPanelSection { // Voicing feature only works when running in English. If running in a version where you can change locale, // indicate through the title that the feature will only work in English. const titleString = ( localeProperty.validValues && localeProperty.validValues.length > 1 ) ? - voicingEnglishOnlyLabelString : voicingLabelString; + voicingEnglishOnlyLabelString : voicingLabelString; // the checkbox is the title for the section and totally enables/disables the feature const voicingLabel = new Text( titleString, PreferencesDialog.PANEL_SECTION_LABEL_OPTIONS ); @@ -234,6 +234,11 @@ class VoicingPanelSection extends PreferencesPanelSection { content.visible = enabled; } ); + const localeListener = ( locale: string ) => { + voicingEnabledSwitch.enabledProperty.value = locale.startsWith( 'en' ); + }; + localeProperty.link( localeListener ); + // Speak when voicing becomes initially enabled. First speech is done synchronously (not using utterance-queue) // in response to user input, otherwise all speech will be blocked on many platforms const voicingEnabledUtterance = new Utterance(); @@ -304,6 +309,7 @@ class VoicingPanelSection extends PreferencesPanelSection { pitchSlider.dispose(); rateSlider.dispose(); audioModel.voicingEnabledProperty.unlink( voicingEnabledPropertyListener ); + localeProperty.unlink( localeListener ); voicingEnabledSwitch.dispose(); expandCollapseButton.dispose(); toolbarEnabledSwitch.dispose();