From da82c96a7f02fbfd1697282d35b6caa98599ed8e Mon Sep 17 00:00:00 2001 From: Jonathan Olson Date: Fri, 12 Aug 2022 20:18:41 -0600 Subject: [PATCH] stringProperties experimentation --- js/common/model/ElectronGeometry.js | 30 +++--- js/common/model/MoleculeGeometry.js | 48 ++++----- js/common/model/VSEPRConfiguration.js | 94 ------------------ js/common/view/GeometryNamePanel.js | 134 ++++++++++++-------------- js/common/view/GlobalOptionsNode.js | 7 +- js/common/view/MoleculeShapesPanel.js | 9 +- js/common/view/OptionsNode.js | 13 ++- js/model/BondGroupNode.js | 4 +- js/model/ModelMoleculesScreen.js | 2 +- js/model/ModelMoleculesScreenView.js | 18 ++-- js/molecule-shapes-main.js | 4 +- js/moleculeShapesStrings.ts | 36 +++++++ js/real/RealMoleculesScreen.js | 2 +- js/real/RealMoleculesScreenView.js | 25 +++-- 14 files changed, 163 insertions(+), 263 deletions(-) diff --git a/js/common/model/ElectronGeometry.js b/js/common/model/ElectronGeometry.js index 89abf1d..80e753f 100644 --- a/js/common/model/ElectronGeometry.js +++ b/js/common/model/ElectronGeometry.js @@ -13,25 +13,17 @@ import EnumerationDeprecated from '../../../../phet-core/js/EnumerationDeprecate import moleculeShapes from '../../moleculeShapes.js'; import moleculeShapesStrings from '../../moleculeShapesStrings.js'; -const geometryDiatomicString = moleculeShapesStrings.geometry.diatomic; -const geometryEmptyString = moleculeShapesStrings.geometry.empty; -const geometryLinearString = moleculeShapesStrings.geometry.linear; -const geometryOctahedralString = moleculeShapesStrings.geometry.octahedral; -const geometryTetrahedralString = moleculeShapesStrings.geometry.tetrahedral; -const geometryTrigonalBipyramidalString = moleculeShapesStrings.geometry.trigonalBipyramidal; -const geometryTrigonalPlanarString = moleculeShapesStrings.geometry.trigonalPlanar; - // Constant for the tetrahedral shape const TETRA_CONST = Math.PI * -19.471220333 / 180; class ElectronGeometryValue { /* - * @param {string} string + * @param {IProperty} stringProperty * @param {Array.} unitVectors - Ordered list of orientations taken by an ideal configuration */ - constructor( string, unitVectors ) { - // @public {string} - this.string = string; + constructor( stringProperty, unitVectors ) { + // @public {IProperty} + this.stringProperty = stringProperty; // @public {Array.} this.unitVectors = unitVectors; @@ -39,22 +31,22 @@ class ElectronGeometryValue { } const ElectronGeometry = EnumerationDeprecated.byMap( { - EMPTY: new ElectronGeometryValue( geometryEmptyString, [] ), + EMPTY: new ElectronGeometryValue( moleculeShapesStrings.geometry.emptyProperty, [] ), DIATOMIC: new ElectronGeometryValue( - geometryDiatomicString, + moleculeShapesStrings.geometry.diatomicProperty, [ new Vector3( 1, 0, 0 ) ] ), LINEAR: new ElectronGeometryValue( - geometryLinearString, + moleculeShapesStrings.geometry.linearProperty, [ new Vector3( 1, 0, 0 ), new Vector3( -1, 0, 0 ) ] ), TRIGONAL_PLANAR: new ElectronGeometryValue( - geometryTrigonalPlanarString, + moleculeShapesStrings.geometry.trigonalPlanarProperty, [ new Vector3( 1, 0, 0 ), new Vector3( Math.cos( Math.PI * 2 / 3 ), Math.sin( Math.PI * 2 / 3 ), 0 ), @@ -62,7 +54,7 @@ const ElectronGeometry = EnumerationDeprecated.byMap( { ] ), TETRAHEDRAL: new ElectronGeometryValue( - geometryTetrahedralString, + moleculeShapesStrings.geometry.tetrahedralProperty, [ new Vector3( 0, 0, 1 ), new Vector3( Math.cos( 0 ) * Math.cos( TETRA_CONST ), Math.sin( 0 ) * Math.cos( TETRA_CONST ), Math.sin( TETRA_CONST ) ), @@ -71,7 +63,7 @@ const ElectronGeometry = EnumerationDeprecated.byMap( { ] ), TRIGONAL_BIPYRAMIDAL: new ElectronGeometryValue( - geometryTrigonalBipyramidalString, + moleculeShapesStrings.geometry.trigonalBipyramidalProperty, [ // equitorial (fills up with lone pairs first) new Vector3( 0, 1, 0 ), @@ -84,7 +76,7 @@ const ElectronGeometry = EnumerationDeprecated.byMap( { ] ), OCTAHEDRAL: new ElectronGeometryValue( - geometryOctahedralString, + moleculeShapesStrings.geometry.octahedralProperty, [ // opposites first new Vector3( 0, 0, 1 ), diff --git a/js/common/model/MoleculeGeometry.js b/js/common/model/MoleculeGeometry.js index 9607a12..8844d38 100644 --- a/js/common/model/MoleculeGeometry.js +++ b/js/common/model/MoleculeGeometry.js @@ -10,48 +10,34 @@ import EnumerationDeprecated from '../../../../phet-core/js/EnumerationDeprecate import moleculeShapes from '../../moleculeShapes.js'; import moleculeShapesStrings from '../../moleculeShapesStrings.js'; -const shapeBentString = moleculeShapesStrings.shape.bent; -const shapeDiatomicString = moleculeShapesStrings.shape.diatomic; -const shapeEmptyString = moleculeShapesStrings.shape.empty; -const shapeLinearString = moleculeShapesStrings.shape.linear; -const shapeOctahedralString = moleculeShapesStrings.shape.octahedral; -const shapeSeesawString = moleculeShapesStrings.shape.seesaw; -const shapeSquarePlanarString = moleculeShapesStrings.shape.squarePlanar; -const shapeSquarePyramidalString = moleculeShapesStrings.shape.squarePyramidal; -const shapeTetrahedralString = moleculeShapesStrings.shape.tetrahedral; -const shapeTrigonalBipyramidalString = moleculeShapesStrings.shape.trigonalBipyramidal; -const shapeTrigonalPlanarString = moleculeShapesStrings.shape.trigonalPlanar; -const shapeTrigonalPyramidalString = moleculeShapesStrings.shape.trigonalPyramidal; -const shapeTShapedString = moleculeShapesStrings.shape.tShaped; - class MoleculeGeometryValue { /* * @param {number} x - * @param {string} string + * @param {IProperty} stringProperty */ - constructor( x, string ) { + constructor( x, stringProperty ) { // @public {number} this.x = x; - // @public {string} - this.string = string; + // @public {IProperty} + this.stringProperty = stringProperty; } } const MoleculeGeometry = EnumerationDeprecated.byMap( { - EMPTY: new MoleculeGeometryValue( 0, shapeEmptyString ), - DIATOMIC: new MoleculeGeometryValue( 1, shapeDiatomicString ), - LINEAR: new MoleculeGeometryValue( 2, shapeLinearString ), // e = 0,3,4 - BENT: new MoleculeGeometryValue( 2, shapeBentString ), // e = 1,2 - TRIGONAL_PLANAR: new MoleculeGeometryValue( 3, shapeTrigonalPlanarString ), // e = 0 - TRIGONAL_PYRAMIDAL: new MoleculeGeometryValue( 3, shapeTrigonalPyramidalString ), // e = 1 - T_SHAPED: new MoleculeGeometryValue( 3, shapeTShapedString ), // e = 2,3 - TETRAHEDRAL: new MoleculeGeometryValue( 4, shapeTetrahedralString ), // e = 0 - SEESAW: new MoleculeGeometryValue( 4, shapeSeesawString ), // e = 1 - SQUARE_PLANAR: new MoleculeGeometryValue( 4, shapeSquarePlanarString ), // e = 2 - TRIGONAL_BIPYRAMIDAL: new MoleculeGeometryValue( 5, shapeTrigonalBipyramidalString ), // e = 0 - SQUARE_PYRAMIDAL: new MoleculeGeometryValue( 5, shapeSquarePyramidalString ), // e = 1 - OCTAHEDRAL: new MoleculeGeometryValue( 6, shapeOctahedralString ) // e = 0 + EMPTY: new MoleculeGeometryValue( 0, moleculeShapesStrings.shape.emptyProperty ), + DIATOMIC: new MoleculeGeometryValue( 1, moleculeShapesStrings.shape.diatomicProperty ), + LINEAR: new MoleculeGeometryValue( 2, moleculeShapesStrings.shape.linearProperty ), // e = 0,3,4 + BENT: new MoleculeGeometryValue( 2, moleculeShapesStrings.shape.bentProperty ), // e = 1,2 + TRIGONAL_PLANAR: new MoleculeGeometryValue( 3, moleculeShapesStrings.shape.trigonalPlanarProperty ), // e = 0 + TRIGONAL_PYRAMIDAL: new MoleculeGeometryValue( 3, moleculeShapesStrings.shape.trigonalPyramidalProperty ), // e = 1 + T_SHAPED: new MoleculeGeometryValue( 3, moleculeShapesStrings.shape.tShapedProperty ), // e = 2,3 + TETRAHEDRAL: new MoleculeGeometryValue( 4, moleculeShapesStrings.shape.tetrahedralProperty ), // e = 0 + SEESAW: new MoleculeGeometryValue( 4, moleculeShapesStrings.shape.seesawProperty ), // e = 1 + SQUARE_PLANAR: new MoleculeGeometryValue( 4, moleculeShapesStrings.shape.squarePlanarProperty ), // e = 2 + TRIGONAL_BIPYRAMIDAL: new MoleculeGeometryValue( 5, moleculeShapesStrings.shape.trigonalBipyramidalProperty ), // e = 0 + SQUARE_PYRAMIDAL: new MoleculeGeometryValue( 5, moleculeShapesStrings.shape.squarePyramidalProperty ), // e = 1 + OCTAHEDRAL: new MoleculeGeometryValue( 6, moleculeShapesStrings.shape.octahedralProperty ) // e = 0 }, { beforeFreeze: MoleculeGeometry => { /* diff --git a/js/common/model/VSEPRConfiguration.js b/js/common/model/VSEPRConfiguration.js index 20db185..bede6f1 100644 --- a/js/common/model/VSEPRConfiguration.js +++ b/js/common/model/VSEPRConfiguration.js @@ -11,26 +11,11 @@ import Permutation from '../../../../dot/js/Permutation.js'; import moleculeShapes from '../../moleculeShapes.js'; -import moleculeShapesStrings from '../../moleculeShapesStrings.js'; import AttractorModel from './AttractorModel.js'; import ElectronGeometry from './ElectronGeometry.js'; import LocalShape from './LocalShape.js'; import MoleculeGeometry from './MoleculeGeometry.js'; -const shapeBentString = moleculeShapesStrings.shape.bent; -const shapeDiatomicString = moleculeShapesStrings.shape.diatomic; -const shapeEmptyString = moleculeShapesStrings.shape.empty; -const shapeLinearString = moleculeShapesStrings.shape.linear; -const shapeOctahedralString = moleculeShapesStrings.shape.octahedral; -const shapeSeesawString = moleculeShapesStrings.shape.seesaw; -const shapeSquarePlanarString = moleculeShapesStrings.shape.squarePlanar; -const shapeSquarePyramidalString = moleculeShapesStrings.shape.squarePyramidal; -const shapeTetrahedralString = moleculeShapesStrings.shape.tetrahedral; -const shapeTrigonalBipyramidalString = moleculeShapesStrings.shape.trigonalBipyramidal; -const shapeTrigonalPlanarString = moleculeShapesStrings.shape.trigonalPlanar; -const shapeTrigonalPyramidalString = moleculeShapesStrings.shape.trigonalPyramidal; -const shapeTShapedString = moleculeShapesStrings.shape.tShaped; - // for looking up VSEPRConfiguration instances const configurationMap = {}; // x+','+e => {VSEPRConfiguration} @@ -97,85 +82,6 @@ class VSEPRConfiguration { Permutation.permutations( this.bondOrientations.length ) ); } - /** - * Returns the "geometry" name. - * @public - * - * @param {number} x - Number of radial atoms connected to the central atom - * @param {number} e - Number of radial lone pairs connected to the central atom - * @returns {string} - */ - static getName( x, e ) { - // figure out what the name is - if ( x === 0 ) { - return shapeEmptyString; - } - else if ( x === 1 ) { - return shapeDiatomicString; - } - else if ( x === 2 ) { - if ( e === 0 || e === 3 || e === 4 ) { - return shapeLinearString; - } - else if ( e === 1 || e === 2 ) { - return shapeBentString; - } - else { - throw new Error( `invalid x: ${x}, e: ${e}` ); - } - } - else if ( x === 3 ) { - if ( e === 0 ) { - return shapeTrigonalPlanarString; - } - else if ( e === 1 ) { - return shapeTrigonalPyramidalString; - } - else if ( e === 2 || e === 3 ) { - return shapeTShapedString; - } - else { - throw new Error( `invalid x: ${x}, e: ${e}` ); - } - } - else if ( x === 4 ) { - if ( e === 0 ) { - return shapeTetrahedralString; - } - else if ( e === 1 ) { - return shapeSeesawString; - } - else if ( e === 2 ) { - return shapeSquarePlanarString; - } - else { - throw new Error( `invalid x: ${x}, e: ${e}` ); - } - } - else if ( x === 5 ) { - if ( e === 0 ) { - return shapeTrigonalBipyramidalString; - } - else if ( e === 1 ) { - return shapeSquarePyramidalString; - } - else { - throw new Error( `invalid x: ${x}, e: ${e}` ); - } - } - else if ( x === 6 ) { - if ( e === 0 ) { - return shapeOctahedralString; - } - else { - throw new Error( `invalid x: ${x}, e: ${e}` ); - } - } - else { - throw new Error( `unknown VSEPR configuration x: ${x}, e: ${e}` ); - } - } - /* * Returns cached VSEPRConfigurations based on radial atom/lone-pair counts. * @public diff --git a/js/common/view/GeometryNamePanel.js b/js/common/view/GeometryNamePanel.js index bccfaea..b8d19db 100644 --- a/js/common/view/GeometryNamePanel.js +++ b/js/common/view/GeometryNamePanel.js @@ -6,6 +6,7 @@ * @author Jonathan Olson */ +import DerivedProperty from '../../../../axon/js/DerivedProperty.js'; import Multilink from '../../../../axon/js/Multilink.js'; import merge from '../../../../phet-core/js/merge.js'; import PhetFont from '../../../../scenery-phet/js/PhetFont.js'; @@ -17,72 +18,46 @@ import MoleculeShapesCheckbox from './MoleculeShapesCheckbox.js'; import MoleculeShapesColors from './MoleculeShapesColors.js'; import MoleculeShapesPanel from './MoleculeShapesPanel.js'; -const controlElectronGeometryString = moleculeShapesStrings.control.electronGeometry; -const controlGeometryNameString = moleculeShapesStrings.control.geometryName; -const controlMoleculeGeometryString = moleculeShapesStrings.control.moleculeGeometry; - -const geometryDiatomicString = moleculeShapesStrings.geometry.diatomic; -const geometryEmptyString = moleculeShapesStrings.geometry.empty; -const geometryLinearString = moleculeShapesStrings.geometry.linear; -const geometryOctahedralString = moleculeShapesStrings.geometry.octahedral; -const geometryTetrahedralString = moleculeShapesStrings.geometry.tetrahedral; -const geometryTrigonalBipyramidalString = moleculeShapesStrings.geometry.trigonalBipyramidal; -const geometryTrigonalPlanarString = moleculeShapesStrings.geometry.trigonalPlanar; - -const shapeBentString = moleculeShapesStrings.shape.bent; -const shapeDiatomicString = moleculeShapesStrings.shape.diatomic; -const shapeEmptyString = moleculeShapesStrings.shape.empty; -const shapeLinearString = moleculeShapesStrings.shape.linear; -const shapeOctahedralString = moleculeShapesStrings.shape.octahedral; -const shapeSeesawString = moleculeShapesStrings.shape.seesaw; -const shapeSquarePlanarString = moleculeShapesStrings.shape.squarePlanar; -const shapeSquarePyramidalString = moleculeShapesStrings.shape.squarePyramidal; -const shapeTetrahedralString = moleculeShapesStrings.shape.tetrahedral; -const shapeTrigonalBipyramidalString = moleculeShapesStrings.shape.trigonalBipyramidal; -const shapeTrigonalPlanarString = moleculeShapesStrings.shape.trigonalPlanar; -const shapeTrigonalPyramidalString = moleculeShapesStrings.shape.trigonalPyramidal; -const shapeTShapedString = moleculeShapesStrings.shape.tShaped; - // string list needed to compute maximum label bounds -const geometryStrings = [ - geometryEmptyString, - geometryDiatomicString, - geometryLinearString, - geometryTrigonalPlanarString, - geometryTetrahedralString, - geometryTrigonalBipyramidalString, - geometryOctahedralString +const geometryStringProperties = [ + moleculeShapesStrings.geometry.emptyProperty, + moleculeShapesStrings.geometry.diatomicProperty, + moleculeShapesStrings.geometry.linearProperty, + moleculeShapesStrings.geometry.trigonalPlanarProperty, + moleculeShapesStrings.geometry.tetrahedralProperty, + moleculeShapesStrings.geometry.trigonalBipyramidalProperty, + moleculeShapesStrings.geometry.octahedralProperty ]; // string list needed to compute maximum label bounds -const shapeStrings = [ - shapeEmptyString, - shapeDiatomicString, - shapeLinearString, - shapeBentString, - shapeTrigonalPlanarString, - shapeTrigonalPyramidalString, - shapeTShapedString, - shapeTetrahedralString, - shapeSeesawString, - shapeSquarePlanarString, - shapeTrigonalBipyramidalString, - shapeSquarePyramidalString, - shapeOctahedralString +const shapeStringProperties = [ + moleculeShapesStrings.shape.emptyProperty, + moleculeShapesStrings.shape.diatomicProperty, + moleculeShapesStrings.shape.linearProperty, + moleculeShapesStrings.shape.bentProperty, + moleculeShapesStrings.shape.trigonalPlanarProperty, + moleculeShapesStrings.shape.trigonalPyramidalProperty, + moleculeShapesStrings.shape.tShapedProperty, + moleculeShapesStrings.shape.tetrahedralProperty, + moleculeShapesStrings.shape.seesawProperty, + moleculeShapesStrings.shape.squarePlanarProperty, + moleculeShapesStrings.shape.trigonalBipyramidalProperty, + moleculeShapesStrings.shape.squarePyramidalProperty, + moleculeShapesStrings.shape.octahedralProperty ]; const geometryNameFont = new PhetFont( 16 ); -function getMaximumTextWidth( strings ) { - let maxWidth = 0; - _.each( strings, string => { - maxWidth = Math.max( maxWidth, new Text( string, { font: geometryNameFont } ).width ); +function getMaximumTextWidth( stringProperties ) { + return new DerivedProperty( stringProperties, ( ...strings ) => { + return Math.max( ...strings.map( string => { + return new Text( string, { font: geometryNameFont } ).width; + } ) ); } ); - return maxWidth; } -const maxGeometryWidth = getMaximumTextWidth( geometryStrings ); -const maxShapeWidth = getMaximumTextWidth( shapeStrings ); +const maxGeometryWidthProperty = getMaximumTextWidth( geometryStringProperties ); +const maxShapeWidthProperty = getMaximumTextWidth( shapeStringProperties ); class GeometryNamePanel extends MoleculeShapesPanel { /** @@ -102,7 +77,7 @@ class GeometryNamePanel extends MoleculeShapesPanel { ySpacing: 10 } ); - super( controlGeometryNameString, content, tandem ); + super( moleculeShapesStrings.control.geometryNameProperty, content, tandem ); // @private {MoleculeShapesModel} this.model = model; @@ -112,10 +87,11 @@ class GeometryNamePanel extends MoleculeShapesPanel { // @private {MoleculeShapesCheckbox} const moleculeGeometryCheckboxTandem = tandem.createTandem( 'moleculeGeometryCheckbox' ); - this.moleculeGeometryCheckbox = new MoleculeShapesCheckbox( model.showMoleculeGeometryProperty, new Text( controlMoleculeGeometryString, { + this.moleculeGeometryCheckbox = new MoleculeShapesCheckbox( model.showMoleculeGeometryProperty, new Text( moleculeShapesStrings.control.moleculeGeometry, { font: textLabelFont, fill: MoleculeShapesColors.moleculeGeometryNameProperty, - tandem: moleculeGeometryCheckboxTandem.createTandem( 'labelText' ) + tandem: moleculeGeometryCheckboxTandem.createTandem( 'labelText' ), + textProperty: moleculeShapesStrings.control.moleculeGeometryProperty } ), { tandem: moleculeGeometryCheckboxTandem, layoutOptions: { @@ -124,10 +100,11 @@ class GeometryNamePanel extends MoleculeShapesPanel { } } ); const electronGeometryCheckboxTandem = model.isBasicsVersion ? Tandem.OPT_OUT : tandem.createTandem( 'electronGeometryCheckbox' ); - this.electronGeometryCheckbox = new MoleculeShapesCheckbox( model.showElectronGeometryProperty, new Text( controlElectronGeometryString, { + this.electronGeometryCheckbox = new MoleculeShapesCheckbox( model.showElectronGeometryProperty, new Text( moleculeShapesStrings.control.electronGeometry, { font: textLabelFont, fill: MoleculeShapesColors.electronGeometryNameProperty, - tandem: electronGeometryCheckboxTandem.createTandem( 'labelText' ) + tandem: electronGeometryCheckboxTandem.createTandem( 'labelText' ), + textProperty: moleculeShapesStrings.control.electronGeometryProperty } ), { tandem: electronGeometryCheckboxTandem, layoutOptions: { @@ -157,10 +134,15 @@ class GeometryNamePanel extends MoleculeShapesPanel { children: [ this.moleculeText ], layoutOptions: { column: 1, - row: 1, - minContentWidth: maxGeometryWidth + row: 1 } } ); + maxGeometryWidthProperty.link( maxGeometryWidth => { + moleculeTextContainer.mutateLayoutOptions( { + minContentWidth: maxGeometryWidth + } ); + } ); + // TODO: pointer area listeners @@ -179,10 +161,14 @@ class GeometryNamePanel extends MoleculeShapesPanel { children: [ this.electronText ], layoutOptions: { column: 0, - row: 1, - minContentWidth: maxShapeWidth + row: 1 } } ); + maxShapeWidthProperty.link( maxShapeWidth => { + electronTextContainer.mutateLayoutOptions( { + minContentWidth: maxShapeWidth + } ); + } ); // basics version excludes lone-pair (electron) geometries content.addChild( this.electronGeometryCheckbox ); @@ -214,8 +200,8 @@ class GeometryNamePanel extends MoleculeShapesPanel { * @private */ updateNames() { - this.moleculeText.text = this.getMoleculeGeometryName(); - this.electronText.text = this.getElectronGeometryName(); + this.moleculeText.textProperty = this.getMoleculeGeometryName(); + this.electronText.textProperty = this.getElectronGeometryName(); // layout this.moleculeText.centerX = this.moleculeGeometryCheckbox.centerX; @@ -226,12 +212,12 @@ class GeometryNamePanel extends MoleculeShapesPanel { * @private */ getMoleculeGeometryName() { - const name = this.model.moleculeProperty.value.getCentralVSEPRConfiguration().moleculeGeometry.string; - if ( name === null ) { - return shapeEmptyString; + const nameProperty = this.model.moleculeProperty.value.getCentralVSEPRConfiguration().moleculeGeometry.stringProperty; + if ( nameProperty === null ) { + return moleculeShapesStrings.shape.emptyProperty; } else { - return name; + return nameProperty; } } @@ -239,12 +225,12 @@ class GeometryNamePanel extends MoleculeShapesPanel { * @private */ getElectronGeometryName() { - const name = this.model.moleculeProperty.value.getCentralVSEPRConfiguration().electronGeometry.string; - if ( name === null ) { - return geometryEmptyString; + const nameProperty = this.model.moleculeProperty.value.getCentralVSEPRConfiguration().electronGeometry.stringProperty; + if ( nameProperty === null ) { + return moleculeShapesStrings.geometry.emptyProperty; } else { - return name; + return nameProperty; } } } diff --git a/js/common/view/GlobalOptionsNode.js b/js/common/view/GlobalOptionsNode.js index 962756a..c955074 100644 --- a/js/common/view/GlobalOptionsNode.js +++ b/js/common/view/GlobalOptionsNode.js @@ -14,8 +14,6 @@ import moleculeShapes from '../../moleculeShapes.js'; import moleculeShapesStrings from '../../moleculeShapesStrings.js'; import MoleculeShapesGlobals from '../MoleculeShapesGlobals.js'; -const optionsShowOuterLonePairsString = moleculeShapesStrings.options.showOuterLonePairs; - class GlobalOptionsNode extends VBox { /** * @param {boolean} isBasicsVersion @@ -30,10 +28,11 @@ class GlobalOptionsNode extends VBox { if ( !isBasicsVersion ) { const showOuterLonePairsCheckboxTandem = tandem.createTandem( 'showOuterLonePairsCheckbox' ); - label = new Text( optionsShowOuterLonePairsString, { + label = new Text( moleculeShapesStrings.options.showOuterLonePairs, { font: OptionsDialog.DEFAULT_FONT, maxWidth: 350, - tandem: showOuterLonePairsCheckboxTandem.createTandem( 'labelText' ) + tandem: showOuterLonePairsCheckboxTandem.createTandem( 'labelText' ), + textProperty: moleculeShapesStrings.options.showOuterLonePairsProperty } ); checkboxes.push( new Checkbox( MoleculeShapesGlobals.showOuterLonePairsProperty, label, { diff --git a/js/common/view/MoleculeShapesPanel.js b/js/common/view/MoleculeShapesPanel.js index 4843f33..47efe86 100644 --- a/js/common/view/MoleculeShapesPanel.js +++ b/js/common/view/MoleculeShapesPanel.js @@ -15,12 +15,12 @@ import TitledPanel from './TitledPanel.js'; class MoleculeShapesPanel extends TitledPanel { /** - * @param {string} titleString + * @param {IProperty>} titleStringProperty * @param {Node} contentNode * @param {Tandem} tandem * @param {Object} [options] */ - constructor( titleString, contentNode, tandem, options ) { + constructor( titleStringProperty, contentNode, tandem, options ) { options = merge( { lineWidth: 1.5, xMargin: MoleculeShapesPanel.xMargin, @@ -35,11 +35,12 @@ class MoleculeShapesPanel extends TitledPanel { stroke: MoleculeShapesColors.controlPanelBorderProperty }, options ); - const titleNode = new Text( titleString, { + const titleNode = new Text( titleStringProperty.value, { font: new PhetFont( 18 ), fill: MoleculeShapesColors.controlPanelTitleProperty, tandem: tandem.createTandem( 'titleNode' ), - maxWidth: 280 + maxWidth: 280, + textProperty: titleStringProperty } ); super( titleNode, contentNode, options ); diff --git a/js/common/view/OptionsNode.js b/js/common/view/OptionsNode.js index e5e9c52..ab575cc 100644 --- a/js/common/view/OptionsNode.js +++ b/js/common/view/OptionsNode.js @@ -15,9 +15,6 @@ import moleculeShapesStrings from '../../moleculeShapesStrings.js'; import MoleculeShapesCheckbox from './MoleculeShapesCheckbox.js'; import MoleculeShapesColors from './MoleculeShapesColors.js'; -const controlShowBondAnglesString = moleculeShapesStrings.control.showBondAngles; -const controlShowLonePairsString = moleculeShapesStrings.control.showLonePairs; - const optionsFont = new PhetFont( 14 ); class OptionsNode extends VBox { @@ -30,18 +27,20 @@ class OptionsNode extends VBox { const showLonePairsCheckboxTandem = model.isBasicsVersion ? Tandem.OPT_OUT : tandem.createTandem( 'showLonePairsCheckbox' ); const showBondAnglesCheckboxTandem = tandem.createTandem( 'showBondAnglesCheckbox' ); - const showLonePairsLabel = new Text( controlShowLonePairsString, { + const showLonePairsLabel = new Text( moleculeShapesStrings.control.showLonePairs, { font: optionsFont, fill: MoleculeShapesColors.controlPanelTextProperty, tandem: showLonePairsCheckboxTandem.createTandem( 'labelText' ), - maxWidth: 280 + maxWidth: 280, + textProperty: moleculeShapesStrings.control.showLonePairsProperty } ); - const showBondAnglesLabel = new Text( controlShowBondAnglesString, { + const showBondAnglesLabel = new Text( moleculeShapesStrings.control.showBondAngles, { font: optionsFont, fill: MoleculeShapesColors.controlPanelTextProperty, tandem: showBondAnglesCheckboxTandem.createTandem( 'labelText' ), - maxWidth: 280 + maxWidth: 280, + textProperty: moleculeShapesStrings.control.showBondAnglesProperty } ); const showLonePairsCheckbox = new MoleculeShapesCheckbox( model.showLonePairsProperty, showLonePairsLabel, { diff --git a/js/model/BondGroupNode.js b/js/model/BondGroupNode.js index 8141c38..17eabde 100644 --- a/js/model/BondGroupNode.js +++ b/js/model/BondGroupNode.js @@ -115,7 +115,9 @@ class BondGroupNode extends HBox { */ constructor( model, bondOrder, addPairCallback, removePairCallback, tandem, options ) { super( { - tandem: tandem + tandem: tandem, + align: 'center', + widthSizable: false } ); this.model = model; // @private {MoleculeShapesModel} diff --git a/js/model/ModelMoleculesScreen.js b/js/model/ModelMoleculesScreen.js index 49bcb28..df5e1b1 100644 --- a/js/model/ModelMoleculesScreen.js +++ b/js/model/ModelMoleculesScreen.js @@ -25,7 +25,7 @@ class ModelMoleculesScreen extends Screen { */ constructor( isBasicsVersion, tandem ) { const options = { - name: moleculeShapesStrings.screen.model, + name: moleculeShapesStrings.screen.modelProperty, backgroundColorProperty: MoleculeShapesColors.backgroundProperty, homeScreenIcon: new ScreenIcon( new ScreenIconNode( true, isBasicsVersion ), { maxIconWidthProportion: 1, diff --git a/js/model/ModelMoleculesScreenView.js b/js/model/ModelMoleculesScreenView.js index 0dfc6a7..242689e 100644 --- a/js/model/ModelMoleculesScreenView.js +++ b/js/model/ModelMoleculesScreenView.js @@ -21,11 +21,6 @@ import moleculeShapes from '../moleculeShapes.js'; import moleculeShapesStrings from '../moleculeShapesStrings.js'; import BondGroupNode from './BondGroupNode.js'; -const controlBondingString = moleculeShapesStrings.control.bonding; -const controlLonePairString = moleculeShapesStrings.control.lonePair; -const controlOptionsString = moleculeShapesStrings.control.options; -const controlRemoveAllString = moleculeShapesStrings.control.removeAll; - class ModelMoleculesScreenView extends MoleculeShapesScreenView { /** @@ -58,18 +53,19 @@ class ModelMoleculesScreenView extends MoleculeShapesScreenView { new BondGroupNode( model, 3, addPairCallback, removePairCallback, bondingPanelTandem.createTandem( 'tripleBondNode' ), {} ) ], spacing: 10, - align: 'left' + align: 'center' } ); const lonePairNode = new BondGroupNode( model, 0, addPairCallback, removePairCallback, lonePairPanelTandem.createTandem( 'lonePairNode' ), {} ); - const removeAllButton = new TextPushButton( controlRemoveAllString, { + const removeAllButton = new TextPushButton( moleculeShapesStrings.control.removeAllProperty, { baseColor: MoleculeShapesColors.removeButtonBackgroundProperty, font: new PhetFont( 16 ), textFill: MoleculeShapesColors.removeButtonTextProperty.value, maxWidth: 280, + widthSizable: true, textNodeOptions: { tandem: Tandem.OPT_OUT }, - layoutOptions: { topMargin: 5, align: 'center' }, + layoutOptions: { topMargin: 5, align: 'center', stretch: false }, touchAreaXDilation: 30, touchAreaYDilation: 10, listener: () => { @@ -100,16 +96,16 @@ class ModelMoleculesScreenView extends MoleculeShapesScreenView { orientation: 'vertical', stretch: true, children: [ - new MoleculeShapesPanel( controlBondingString, bondingNode, bondingPanelTandem, { + new MoleculeShapesPanel( moleculeShapesStrings.control.bondingProperty, bondingNode, bondingPanelTandem, { tandem: bondingPanelTandem, align: 'center' } ), - ...( !model.isBasicsVersion ? [ new MoleculeShapesPanel( controlLonePairString, lonePairNode, lonePairPanelTandem, { + ...( !model.isBasicsVersion ? [ new MoleculeShapesPanel( moleculeShapesStrings.control.lonePairProperty, lonePairNode, lonePairPanelTandem, { tandem: lonePairPanelTandem, align: 'center' } ) ] : [] ), removeAllButton, - new MoleculeShapesPanel( controlOptionsString, optionsNode, optionsPanelTandem, { + new MoleculeShapesPanel( moleculeShapesStrings.control.optionsProperty, optionsNode, optionsPanelTandem, { layoutOptions: { topMargin: 10 }, tandem: optionsPanelTandem } ) diff --git a/js/molecule-shapes-main.js b/js/molecule-shapes-main.js index 1e2aa95..105ca27 100644 --- a/js/molecule-shapes-main.js +++ b/js/molecule-shapes-main.js @@ -16,8 +16,6 @@ import ModelMoleculesScreen from './model/ModelMoleculesScreen.js'; import moleculeShapesStrings from './moleculeShapesStrings.js'; import RealMoleculesScreen from './real/RealMoleculesScreen.js'; -const moleculeShapesTitleString = moleculeShapesStrings[ 'molecule-shapes' ].title; - const isBasicsVersion = false; const simOptions = { @@ -38,7 +36,7 @@ const simOptions = { // NOTE: ?webgl=false will trigger Canvas rendering with a reduced poly-count simLauncher.launch( () => { - const sim = new Sim( moleculeShapesTitleString, [ + const sim = new Sim( moleculeShapesStrings[ 'molecule-shapes' ].titleProperty, [ new ModelMoleculesScreen( isBasicsVersion, Tandem.ROOT.createTandem( 'modelScreen' ) ), new RealMoleculesScreen( isBasicsVersion, Tandem.ROOT.createTandem( 'realMoleculesScreen' ) ) ], simOptions ); diff --git a/js/moleculeShapesStrings.ts b/js/moleculeShapesStrings.ts index 7fead2c..dc4a440 100644 --- a/js/moleculeShapesStrings.ts +++ b/js/moleculeShapesStrings.ts @@ -5,55 +5,91 @@ */ /* eslint-disable */ import getStringModule from '../../chipper/js/getStringModule.js'; +import Property from '../../axon/js/Property.js'; import moleculeShapes from './moleculeShapes.js'; type StringsType = { 'molecule-shapes': { 'title': string; + 'titleProperty': Property; }; 'screen': { 'model': string; + 'modelProperty': Property; 'realMolecules': string; + 'realMoleculesProperty': Property; }; 'geometry': { 'diatomic': string; + 'diatomicProperty': Property; 'linear': string; + 'linearProperty': Property; 'trigonalPlanar': string; + 'trigonalPlanarProperty': Property; 'tetrahedral': string; + 'tetrahedralProperty': Property; 'trigonalBipyramidal': string; + 'trigonalBipyramidalProperty': Property; 'octahedral': string; + 'octahedralProperty': Property; }; 'shape': { 'diatomic': string; + 'diatomicProperty': Property; 'linear': string; + 'linearProperty': Property; 'bent': string; + 'bentProperty': Property; 'trigonalPlanar': string; + 'trigonalPlanarProperty': Property; 'trigonalPyramidal': string; + 'trigonalPyramidalProperty': Property; 'tShaped': string; + 'tShapedProperty': Property; 'tetrahedral': string; + 'tetrahedralProperty': Property; 'seesaw': string; + 'seesawProperty': Property; 'squarePlanar': string; + 'squarePlanarProperty': Property; 'trigonalBipyramidal': string; + 'trigonalBipyramidalProperty': Property; 'squarePyramidal': string; + 'squarePyramidalProperty': Property; 'octahedral': string; + 'octahedralProperty': Property; }; 'control': { 'bonding': string; + 'bondingProperty': Property; 'lonePair': string; + 'lonePairProperty': Property; 'options': string; + 'optionsProperty': Property; 'geometryName': string; + 'geometryNameProperty': Property; 'moleculeGeometry': string; + 'moleculeGeometryProperty': Property; 'electronGeometry': string; + 'electronGeometryProperty': Property; 'showLonePairs': string; + 'showLonePairsProperty': Property; 'showBondAngles': string; + 'showBondAnglesProperty': Property; 'removeAll': string; + 'removeAllProperty': Property; 'molecule': string; + 'moleculeProperty': Property; 'realView': string; + 'realViewProperty': Property; 'modelView': string; + 'modelViewProperty': Property; }; 'options': { 'showOuterLonePairs': string; + 'showOuterLonePairsProperty': Property; 'projectorColors': string; + 'projectorColorsProperty': Property; } }; diff --git a/js/real/RealMoleculesScreen.js b/js/real/RealMoleculesScreen.js index deaaf20..07622e3 100644 --- a/js/real/RealMoleculesScreen.js +++ b/js/real/RealMoleculesScreen.js @@ -25,7 +25,7 @@ class RealMoleculesScreen extends Screen { */ constructor( isBasicsVersion, tandem ) { const options = { - name: moleculeShapesStrings.screen.realMolecules, + name: moleculeShapesStrings.screen.realMoleculesProperty, backgroundColorProperty: MoleculeShapesColors.backgroundProperty, homeScreenIcon: new ScreenIcon( new ScreenIconNode( false, isBasicsVersion ), { maxIconWidthProportion: 1, diff --git a/js/real/RealMoleculesScreenView.js b/js/real/RealMoleculesScreenView.js index ed93e93..516716c 100644 --- a/js/real/RealMoleculesScreenView.js +++ b/js/real/RealMoleculesScreenView.js @@ -20,11 +20,6 @@ import OptionsNode from '../common/view/OptionsNode.js'; import moleculeShapes from '../moleculeShapes.js'; import moleculeShapesStrings from '../moleculeShapesStrings.js'; -const controlModelViewString = moleculeShapesStrings.control.modelView; -const controlMoleculeString = moleculeShapesStrings.control.molecule; -const controlOptionsString = moleculeShapesStrings.control.options; -const controlRealViewString = moleculeShapesStrings.control.realView; - class RealMoleculesScreenView extends MoleculeShapesScreenView { /** * @param {ModelMoleculesModel} model the model for the entire screen @@ -62,11 +57,11 @@ class RealMoleculesScreenView extends MoleculeShapesScreenView { orientation: 'vertical', stretch: true, children: [ - new MoleculeShapesPanel( controlMoleculeString, moleculeComboBox, moleculePanelTandem, { + new MoleculeShapesPanel( moleculeShapesStrings.control.moleculeProperty, moleculeComboBox, moleculePanelTandem, { tandem: moleculePanelTandem, align: 'center' } ), - new MoleculeShapesPanel( controlOptionsString, optionsNode, optionsPanelTandem, { + new MoleculeShapesPanel( moleculeShapesStrings.control.optionsProperty, optionsNode, optionsPanelTandem, { tandem: optionsPanelTandem } ) ] @@ -85,13 +80,15 @@ class RealMoleculesScreenView extends MoleculeShapesScreenView { const approximateVisualCenterX = this.layoutBounds.width / 2 - 100; // NOTE: these font sizes are scaled! - const realViewLabel = new Text( controlRealViewString, { + const realViewLabel = new Text( moleculeShapesStrings.control.realView, { font: new PhetFont( 28 ), - fill: MoleculeShapesColors.controlPanelTextProperty + fill: MoleculeShapesColors.controlPanelTextProperty, + textProperty: moleculeShapesStrings.control.realViewProperty } ); - const modelViewLabel = new Text( controlModelViewString, { + const modelViewLabel = new Text( moleculeShapesStrings.control.modelView, { font: new PhetFont( 28 ), - fill: MoleculeShapesColors.controlPanelTextProperty + fill: MoleculeShapesColors.controlPanelTextProperty, + textProperty: moleculeShapesStrings.control.modelViewProperty } ); const horizontalSpacing = 30; @@ -115,13 +112,15 @@ class RealMoleculesScreenView extends MoleculeShapesScreenView { scale: radioButtonScale, maxWidth: 320 }, - top: this.layoutBounds.top + 20, tandem: tandem.createTandem( 'realModelRadioButtonGroup' ), touchAreaYDilation: 10, spacing: horizontalSpacing, - centerX: approximateVisualCenterX, orientation: 'horizontal' } ); + realModelRadioButtonGroup.localBoundsProperty.link( () => { + realModelRadioButtonGroup.top = this.layoutBounds.top + 20; + realModelRadioButtonGroup.centerX = approximateVisualCenterX; + } ); this.addChild( realModelRadioButtonGroup ); }