diff --git a/js/common/view/FELDeveloperAccordionBox.ts b/js/common/view/FELDeveloperAccordionBox.ts index a833d4f..f234472 100644 --- a/js/common/view/FELDeveloperAccordionBox.ts +++ b/js/common/view/FELDeveloperAccordionBox.ts @@ -14,7 +14,7 @@ import AccordionBox from '../../../../sun/js/AccordionBox.js'; import faradaysElectromagneticLab from '../../faradaysElectromagneticLab.js'; -import { Node, Text, VBox } from '../../../../scenery/js/imports.js'; +import { HBox, Node, Text, VBox } from '../../../../scenery/js/imports.js'; import FELConstants from '../../common/FELConstants.js'; import BooleanProperty from '../../../../axon/js/BooleanProperty.js'; import Tandem from '../../../../tandem/js/Tandem.js'; @@ -26,28 +26,20 @@ import NumberControl from '../../../../scenery-phet/js/NumberControl.js'; import PickupCoil from '../model/PickupCoil.js'; import Electromagnet from '../model/Electromagnet.js'; import { FELDeveloperNumberControl } from './FELDeveloperNumberControl.js'; - -// Developer controls are styled independently of controls in the UI, so that we can cram more of them in. -const CONTROL_FONT_SIZE = 12; -const CONTROL_FONT = new PhetFont( CONTROL_FONT_SIZE ); -const TEXT_OPTIONS = { - font: CONTROL_FONT -}; -const SUBTITLE_OPTIONS = { - font: new PhetFont( { - size: CONTROL_FONT_SIZE + 2, - weight: 'bold' - } ) -}; -const CHECKBOX_OPTIONS = { - boxWidth: new Text( 'X', { font: CONTROL_FONT } ).height, - tandem: Tandem.OPT_OUT -}; +import NumberDisplay from '../../../../scenery-phet/js/NumberDisplay.js'; +import TReadOnlyProperty from '../../../../axon/js/TReadOnlyProperty.js'; +import Range from '../../../../dot/js/Range.js'; const VBOX_SPACING = 15; export default class FELDeveloperAccordionBox extends AccordionBox { + public static readonly CONTROL_FONT = new PhetFont( 12 ); + public static readonly SUBTITLE_FONT = new PhetFont( { + size: 12, + weight: 'bold' + } ); + protected constructor( content: Node ) { const titleText = new Text( 'Developer', { @@ -81,11 +73,15 @@ export default class FELDeveloperAccordionBox extends AccordionBox { * Creates the set of controls related to the pickup coil. */ protected static createPickupCoilControls( pickupCoil: PickupCoil ): VBox { + return new VBox( { align: 'left', spacing: VBOX_SPACING, children: [ - new Text( 'Pickup Coil', SUBTITLE_OPTIONS ), + new Text( 'Pickup Coil', { + font: FELDeveloperAccordionBox.SUBTITLE_FONT + } ), + new MaxEMFDisplay( pickupCoil.emfProperty, pickupCoil.maxEMFProperty.range ), new FELDeveloperNumberControl( 'Max EMF:', pickupCoil.maxEMFProperty, { useCommaSeparator: true } ), @@ -109,7 +105,9 @@ export default class FELDeveloperAccordionBox extends AccordionBox { align: 'left', spacing: VBOX_SPACING, children: [ - new Text( 'Electromagnet', SUBTITLE_OPTIONS ), + new Text( 'Electromagnet', { + font: FELDeveloperAccordionBox.SUBTITLE_FONT + } ), new FELDeveloperNumberControl( 'Current Speed Scale:', electromagnet.coil.currentSpeedScaleProperty, { decimalPlaces: 1 } ), @@ -121,7 +119,40 @@ export default class FELDeveloperAccordionBox extends AccordionBox { class FELDeveloperCheckbox extends Checkbox { public constructor( labelString: string, property: Property ) { - super( property, new Text( labelString, TEXT_OPTIONS ), CHECKBOX_OPTIONS ); + const text = new Text( labelString, { + font: FELDeveloperAccordionBox.CONTROL_FONT + } ); + super( property, text, { + boxWidth: new Text( 'X', { font: FELDeveloperAccordionBox.CONTROL_FONT } ).height, + tandem: Tandem.OPT_OUT + } ); + } +} + +class MaxEMFDisplay extends HBox { + public constructor( emfProperty: TReadOnlyProperty, emfRange: Range, decimalPlaces = 0 ) { + + const maxEMFProperty = new NumberProperty( emfProperty.value ); + emfProperty.link( emf => { + if ( emf > maxEMFProperty.value ) { + maxEMFProperty.value = emf; + } + } ); + + const maxEMFText = new Text( 'Max EMF:', { + font: FELDeveloperAccordionBox.CONTROL_FONT + } ); + const maxEMFNumberDisplay = new NumberDisplay( maxEMFProperty, emfRange, { + numberFormatter: value => FELDeveloperNumberControl.formatValue( value, decimalPlaces, true ), + textOptions: { + font: FELDeveloperAccordionBox.CONTROL_FONT + } + } ); + + super( { + children: [ maxEMFText, maxEMFNumberDisplay ], + spacing: 5 + } ); } } diff --git a/js/common/view/FELDeveloperNumberControl.ts b/js/common/view/FELDeveloperNumberControl.ts index 0f54a99..c1792b4 100644 --- a/js/common/view/FELDeveloperNumberControl.ts +++ b/js/common/view/FELDeveloperNumberControl.ts @@ -1,7 +1,7 @@ // Copyright 2024, University of Colorado Boulder /** - * FELDeveloperNumberControl is the number control used in FELDeveloperAccordionBox. + * FELDeveloperNumberControl is a NumberControl that is specialized for use in FELDeveloperAccordionBox. * * @author Chris Malley (PixelZoom, Inc.) */ @@ -17,8 +17,8 @@ import Dimension2 from '../../../../dot/js/Dimension2.js'; import faradaysElectromagneticLab from '../../faradaysElectromagneticLab.js'; import StrictOmit from '../../../../phet-core/js/types/StrictOmit.js'; import optionize from '../../../../phet-core/js/optionize.js'; +import FELDeveloperAccordionBox from './FELDeveloperAccordionBox.js'; -const CONTROL_FONT = new PhetFont( 12 ); const TICK_TEXT_OPTIONS = { font: new PhetFont( 10 ) }; @@ -45,8 +45,8 @@ export class FELDeveloperNumberControl extends NumberControl { const range = numberProperty.range; - const min = formatValue( range.min, options.decimalPlaces, options.useCommaSeparator ); - const max = formatValue( range.max, options.decimalPlaces, options.useCommaSeparator ); + const min = FELDeveloperNumberControl.formatValue( range.min, options.decimalPlaces, options.useCommaSeparator ); + const max = FELDeveloperNumberControl.formatValue( range.max, options.decimalPlaces, options.useCommaSeparator ); // Tick marks at the extremes of the range const majorTicks = [ @@ -73,7 +73,7 @@ export class FELDeveloperNumberControl extends NumberControl { delta: sliderStep, layoutFunction: createLayoutFunction( resetButton ), titleNodeOptions: { - font: CONTROL_FONT + font: FELDeveloperAccordionBox.CONTROL_FONT }, sliderOptions: { soundGenerator: null, @@ -91,15 +91,25 @@ export class FELDeveloperNumberControl extends NumberControl { } }, numberDisplayOptions: { - numberFormatter: value => formatValue( value, options.decimalPlaces, options.useCommaSeparator ), + numberFormatter: value => FELDeveloperNumberControl.formatValue( value, options.decimalPlaces, options.useCommaSeparator ), maxWidth: 100, textOptions: { - font: CONTROL_FONT + font: FELDeveloperAccordionBox.CONTROL_FONT } }, tandem: Tandem.OPT_OUT } ); } + + /** + * Formats a numeric value, with the option to use a comma separator to make large values more readable. + * For example, '6023145' vs '6,023,145'. + */ + public static formatValue( value: number, decimalPlaces: number, useCommaSeparator: boolean ): string { + return useCommaSeparator ? + Utils.toFixedNumber( value, decimalPlaces ).toLocaleString() : + Utils.toFixed( value, decimalPlaces ); + } } /** @@ -131,14 +141,4 @@ function createLayoutFunction( resetButton: Node ): LayoutFunction { }; } -/** - * Formats a numeric value, with the option to use a comma separator to make large values more readable. - * For example, '6023145' vs '6,023,145'. - */ -function formatValue( value: number, decimalPlaces: number, useCommaSeparator: boolean ): string { - return useCommaSeparator ? - Utils.toFixedNumber( value, decimalPlaces ).toLocaleString() : - Utils.toFixed( value, decimalPlaces ); -} - faradaysElectromagneticLab.register( 'FELDeveloperNumberControl', FELDeveloperNumberControl ); \ No newline at end of file