Skip to content

Commit

Permalink
Move checkbox groups into their respective accordion boxes, see: #153
Browse files Browse the repository at this point in the history
  • Loading branch information
marlitas committed Apr 28, 2023
1 parent 79181b4 commit 0b518cc
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 59 deletions.
33 changes: 13 additions & 20 deletions js/common/view/CAVAccordionBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import centerAndVariability from '../../centerAndVariability.js';
import CAVModel from '../model/CAVModel.js';
import { Shape } from '../../../../kite/js/imports.js';
import PickRequired from '../../../../phet-core/js/types/PickRequired.js';
import VerticalCheckboxGroup, { VerticalCheckboxGroupItem } from '../../../../sun/js/VerticalCheckboxGroup.js';

type SelfOptions = {
leftMargin: number;
Expand All @@ -33,11 +32,11 @@ const BUTTON_SIDE_LENGTH = 20;

export default class CAVAccordionBox extends AccordionBox {

public readonly contentNode: Node;
public readonly plotNode: Node;

// NOTE: The positions of the passed-in nodes are modified directly, so they cannot be used in the scenery DAG
public constructor( model: CAVModel, contentNode: Node, titleNode: Node,
layoutBounds: Bounds2, providedOptions: CAVAccordionBoxOptions ) {
public constructor( model: CAVModel, plotNode: Node, titleNode: Node,
layoutBounds: Bounds2, checkboxGroup: Node, providedOptions: CAVAccordionBoxOptions ) {

const options = optionize<CAVAccordionBoxOptions, SelfOptions, AccordionBoxOptions>()( {
titleAlignX: 'left',
Expand Down Expand Up @@ -76,30 +75,24 @@ export default class CAVAccordionBox extends AccordionBox {
backgroundNode.clipArea = Shape.bounds( fullBackgroundBounds );

// Vertical positioning
contentNode.centerY = fullBackgroundBounds.centerY;
if ( contentNode.bottom > fullBackgroundBounds.bottom - 5 ) {
contentNode.bottom = fullBackgroundBounds.bottom - 5;
plotNode.centerY = fullBackgroundBounds.centerY;
if ( plotNode.bottom > fullBackgroundBounds.bottom - 5 ) {
plotNode.bottom = fullBackgroundBounds.bottom - 5;
}
backgroundNode.addChild( contentNode );
backgroundNode.addChild( plotNode );

const checkboxAlignBox = new AlignBox( checkboxGroup,
{ xAlign: 'right', yAlign: 'center', rightMargin: 20, alignBounds: fullBackgroundBounds } );

backgroundNode.addChild( checkboxAlignBox );

super( backgroundNode, options );

model.resetEmitter.addListener( () => this.reset() );

this.contentNode = contentNode;
this.plotNode = plotNode;
}

protected setCheckboxGroup( items: VerticalCheckboxGroupItem[] ): void {
const accordionCheckboxGroup = new VerticalCheckboxGroup( items, {
tandem: this.tandem.createTandem( 'accordionCheckboxGroup' )
} );
this.addChild( new AlignBox( accordionCheckboxGroup, {
alignBounds: this.getVisibleBounds(),
xAlign: 'right',
xMargin: 80,
yAlign: 'top'
} ) );
}
}

centerAndVariability.register( 'CAVAccordionBox', CAVAccordionBox );
2 changes: 1 addition & 1 deletion js/common/view/CAVScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ export default class CAVScreenView extends ScreenView {
*/
protected setAccordionBoxWithAlignedContent( accordionBox: CAVAccordionBox ): void {
this.setAccordionBox( accordionBox );
ManualConstraint.create( this, [ this.playAreaNumberLineNode, accordionBox.contentNode ],
ManualConstraint.create( this, [ this.playAreaNumberLineNode, accordionBox.plotNode ],
( lowerNumberLineWrapper, contentsWrapper ) => {
contentsWrapper.x = lowerNumberLineWrapper.x;
} );
Expand Down
91 changes: 88 additions & 3 deletions js/common/view/TopRepresentationCheckboxGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ export default class TopRepresentationCheckboxGroup extends VerticalCheckboxGrou

private static createGridBox( text: Node, icon: Node, iconGroup: AlignGroup ): GridBox {
return new GridBox( {
rows: [ [ new Node( { children: [ text ], layoutOptions: { align: 'left' } } ),
spacing: 10,
stretch: true,
grow: 1,
rows: [ [ new Node( { children: [ text ], layoutOptions: { xAlign: 'left' } } ),
iconGroup.createBox( icon, { xAlign: 'center', layoutOptions: { xAlign: 'right' } } ) ]
]
} );
Expand All @@ -48,8 +51,9 @@ export default class TopRepresentationCheckboxGroup extends VerticalCheckboxGrou
return TopRepresentationCheckboxGroup.createGridBox(
new Text( CenterAndVariabilityStrings.medianStringProperty, CAVConstants.CHECKBOX_TEXT_OPTIONS ),
new MedianBarNode( {
notchDirection: 'up',
barStyle: 'continuous'
notchDirection: 'down',
barStyle: 'continuous',
arrowScale: 0.75
} )
.setMedianBarShape( 0, 0, ICON_WIDTH / 2 - LINE_WIDTH / 2, ICON_WIDTH - LINE_WIDTH, true ),
iconGroup
Expand Down Expand Up @@ -93,6 +97,87 @@ export default class TopRepresentationCheckboxGroup extends VerticalCheckboxGrou
tandemName: 'meanCheckbox'
};
}

public static getRangeCheckboxWithIconItem( iconGroup: AlignGroup, isShowingRangeProperty: Property<boolean> ): VerticalCheckboxGroupItem {
return {
createNode: ( tandem: Tandem ) => {
return TopRepresentationCheckboxGroup.createGridBox(
new Text( CenterAndVariabilityStrings.rangeStringProperty, CAVConstants.CHECKBOX_TEXT_OPTIONS ),
// TODO: Replace with range icon.
new Node( {
children: [

// Horizontal line above the triangle
new Line( -ICON_WIDTH / 2, -LINE_WIDTH / 2, ICON_WIDTH / 2, -LINE_WIDTH / 2, {
stroke: CAVColors.meanColorProperty,
lineWidth: LINE_WIDTH
} ),

// Triangle
NumberLineNode.createMeanIndicatorNode( false, true )
]
} ),
iconGroup
);
},
property: isShowingRangeProperty,
tandemName: 'rangeCheckbox'
};
}

public static getIQRCheckboxWithIconItem( iconGroup: AlignGroup, isShowingIQRProperty: Property<boolean> ): VerticalCheckboxGroupItem {
return {
createNode: ( tandem: Tandem ) => {
return TopRepresentationCheckboxGroup.createGridBox(
new Text( CenterAndVariabilityStrings.iqrStringProperty, CAVConstants.CHECKBOX_TEXT_OPTIONS ),
// TODO: Replace with IQR icon.
new Node( {
children: [

// Horizontal line above the triangle
new Line( -ICON_WIDTH / 2, -LINE_WIDTH / 2, ICON_WIDTH / 2, -LINE_WIDTH / 2, {
stroke: CAVColors.meanColorProperty,
lineWidth: LINE_WIDTH
} ),

// Triangle
NumberLineNode.createMeanIndicatorNode( false, true )
]
} ),
iconGroup
);
},
property: isShowingIQRProperty,
tandemName: 'iqrCheckbox'
};
}

public static getMADCheckboxWithIconItem( iconGroup: AlignGroup, isShowingMADProperty: Property<boolean> ): VerticalCheckboxGroupItem {
return {
createNode: ( tandem: Tandem ) => {
return TopRepresentationCheckboxGroup.createGridBox(
new Text( CenterAndVariabilityStrings.meanAbsoluteDeviationMADStringProperty, CAVConstants.CHECKBOX_TEXT_OPTIONS ),
// TODO: Replace with MAD icon.
new Node( {
children: [

// Horizontal line above the triangle
new Line( -ICON_WIDTH / 2, -LINE_WIDTH / 2, ICON_WIDTH / 2, -LINE_WIDTH / 2, {
stroke: CAVColors.meanColorProperty,
lineWidth: LINE_WIDTH
} ),

// Triangle
NumberLineNode.createMeanIndicatorNode( false, true )
]
} ),
iconGroup
);
},
property: isShowingMADProperty,
tandemName: 'madCheckbox'
};
}
}

centerAndVariability.register( 'TopRepresentationCheckboxGroup', TopRepresentationCheckboxGroup );
23 changes: 17 additions & 6 deletions js/mean-and-median/view/MeanAndMedianAccordionBox.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,45 @@
// Copyright 2023, University of Colorado Boulder

import CAVAccordionBox from '../../common/view/CAVAccordionBox.js';
import { Node, Text } from '../../../../scenery/js/imports.js';
import { AlignGroup, Node, Text } from '../../../../scenery/js/imports.js';
import CenterAndVariabilityStrings from '../../CenterAndVariabilityStrings.js';
import PhetFont from '../../../../scenery-phet/js/PhetFont.js';
import Bounds2 from '../../../../dot/js/Bounds2.js';
import Tandem from '../../../../tandem/js/Tandem.js';
import centerAndVariability from '../../centerAndVariability.js';
import MeanAndMedianModel from '../model/MeanAndMedianModel.js';
import MedianPlotNode from './MedianPlotNode.js';
import TopRepresentationCheckboxGroup from '../../common/view/TopRepresentationCheckboxGroup.js';
import VerticalCheckboxGroup from '../../../../sun/js/VerticalCheckboxGroup.js';

export default class MeanAndMedianAccordionBox extends CAVAccordionBox {

public constructor( model: MeanAndMedianModel, layoutBounds: Bounds2, tandem: Tandem, top: number, playAreaNumberLineNode: Node ) {
const iconGroup = new AlignGroup();

const accordionBoxContents = new MedianPlotNode( model, {
tandem: tandem.createTandem( 'plotNode' )
const checkboxGroup = new VerticalCheckboxGroup( [
TopRepresentationCheckboxGroup.getMedianCheckboxWithIconItem( iconGroup, model.isShowingTopMedianProperty ),
TopRepresentationCheckboxGroup.getMeanCheckboxWithIconItem( iconGroup, model.isShowingTopMeanProperty )
], {
tandem: tandem.createTandem( 'accordionCheckboxGroup' )
} );
const plotNode = new MedianPlotNode( model, { tandem: tandem.createTandem( 'plotNode' ) } );

super( model, accordionBoxContents,
super( model, plotNode,
new Text( CenterAndVariabilityStrings.distanceInMetersStringProperty, {
font: new PhetFont( 16 ),
maxWidth: 300
} ),
layoutBounds, {
layoutBounds,
checkboxGroup,
{
leftMargin: 0,
tandem: tandem,
top: top,
centerX: layoutBounds.centerX
} );
}
);

}
}

Expand Down
11 changes: 0 additions & 11 deletions js/mean-and-median/view/MedianPlotNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,6 @@ export default class MedianPlotNode extends CAVPlotNode {
...providedOptions
} );

// const checkboxGroup = new TopRepresentationCheckboxGroup( model, {
// medianBarIconOptions: {
// notchDirection: 'down',
// barStyle: 'continuous',
// arrowScale: 0.75
// },
// showMedianCheckboxIcon: true,
// tandem: providedOptions.tandem.createTandem( 'topRepresentationCheckboxGroup' )
// } );
// this.addChild( checkboxGroup );

this.addChild( this.medianBarNode );

const modelViewTransform = this.modelViewTransform;
Expand Down
19 changes: 11 additions & 8 deletions js/median/view/MedianAccordionBox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,37 @@ import Bounds2 from '../../../../dot/js/Bounds2.js';
import Tandem from '../../../../tandem/js/Tandem.js';
import centerAndVariability from '../../centerAndVariability.js';
import TopRepresentationCheckboxGroup from '../../common/view/TopRepresentationCheckboxGroup.js';
import VerticalCheckboxGroup from '../../../../sun/js/VerticalCheckboxGroup.js';

export default class MedianAccordionBox extends CAVAccordionBox {

public constructor( model: MedianModel, layoutBounds: Bounds2, tandem: Tandem, top: number ) {

const cardNodeContainer = new CardNodeContainer( model, {

// Expose this intermediate layer to make it so that clients can hide the number cards with one call
tandem: tandem.createTandem( 'cardNodeContainer' )
} );

const checkboxGroup = new VerticalCheckboxGroup( [
TopRepresentationCheckboxGroup.getSortDataCheckboxItem( model.isSortingDataProperty ),
TopRepresentationCheckboxGroup.getMedianCheckboxWithoutIconItem( model.isShowingTopMedianProperty )
], {
tandem: tandem.createTandem( 'accordionCheckboxGroup' )
} );

super( model, cardNodeContainer,
new Text( CenterAndVariabilityStrings.distanceInMetersStringProperty, {
font: new PhetFont( 16 ),
maxWidth: 300
} ),
layoutBounds, {
layoutBounds,
checkboxGroup,
{
leftMargin: 0,
tandem: tandem,
top: top,
centerX: layoutBounds.centerX
} );

this.setCheckboxGroup( [
TopRepresentationCheckboxGroup.getSortDataCheckboxItem( model.isSortingDataProperty ),
TopRepresentationCheckboxGroup.getMedianCheckboxWithoutIconItem( model.isShowingTopMedianProperty )
]
);
}


Expand Down
8 changes: 0 additions & 8 deletions js/variability/view/RangeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import StrictOmit from '../../../../phet-core/js/types/StrictOmit.js';
import CAVConstants from '../../common/CAVConstants.js';
import CAVColors from '../../common/CAVColors.js';
import VariabilityReadoutText from './VariabilityReadoutText.js';
import Checkbox from '../../../../sun/js/Checkbox.js';
import DerivedProperty from '../../../../axon/js/DerivedProperty.js';

type SelfOptions = {
Expand Down Expand Up @@ -51,13 +50,6 @@ export default class RangeNode extends CAVPlotNode {
} );

this.addChild( rangeReadoutText );

const rangeCheckbox = new Checkbox( model.isShowingRangeProperty, new Text( CenterAndVariabilityStrings.rangeStringProperty, CAVConstants.CHECKBOX_TEXT_OPTIONS ), {
tandem: options.tandem.createTandem( 'rangeCheckbox' ),
left: this.right,
y: 100
} );
this.addChild( rangeCheckbox );
}

const needAtLeastOneKickText = new Text( CenterAndVariabilityStrings.needAtLeastOneKickStringProperty, {
Expand Down
34 changes: 32 additions & 2 deletions js/variability/view/VariabilityAccordionBox.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2023, University of Colorado Boulder

import CAVAccordionBox from '../../common/view/CAVAccordionBox.js';
import { Text } from '../../../../scenery/js/imports.js';
import { AlignGroup, Text } from '../../../../scenery/js/imports.js';
import CenterAndVariabilityStrings from '../../CenterAndVariabilityStrings.js';
import PhetFont from '../../../../scenery-phet/js/PhetFont.js';
import Bounds2 from '../../../../dot/js/Bounds2.js';
Expand All @@ -14,6 +14,9 @@ import VariabilityMeasure from '../model/VariabilityMeasure.js';
import CAVConstants from '../../common/CAVConstants.js';
import DerivedProperty from '../../../../axon/js/DerivedProperty.js';
import DynamicProperty from '../../../../axon/js/DynamicProperty.js';
import ToggleNode from '../../../../sun/js/ToggleNode.js';
import VerticalCheckboxGroup from '../../../../sun/js/VerticalCheckboxGroup.js';
import TopRepresentationCheckboxGroup from '../../common/view/TopRepresentationCheckboxGroup.js';

export default class VariabilityAccordionBox extends CAVAccordionBox {

Expand Down Expand Up @@ -46,12 +49,39 @@ export default class VariabilityAccordionBox extends CAVAccordionBox {
} );
accordionBoxContents.addChild( infoButton );

const iconGroup = new AlignGroup();
const checkboxToggleNode = new ToggleNode( model.selectedVariabilityProperty, [
{
createNode: tandem => new VerticalCheckboxGroup( [
TopRepresentationCheckboxGroup.getRangeCheckboxWithIconItem( iconGroup, model.isShowingRangeProperty )
], { tandem: tandem.createTandem( 'rangeAccordionCheckboxGroup' ) } ),
tandemName: 'rangeAccordionCheckboxGroup',
value: VariabilityMeasure.RANGE
},
{
createNode: tandem => new VerticalCheckboxGroup( [
TopRepresentationCheckboxGroup.getIQRCheckboxWithIconItem( iconGroup, model.isShowingIQRProperty )
], { tandem: tandem.createTandem( 'iqrAccordionCheckboxGroup' ) } ),
tandemName: 'iqrAccordionCheckboxGroup',
value: VariabilityMeasure.IQR
},
{
createNode: tandem => new VerticalCheckboxGroup( [
TopRepresentationCheckboxGroup.getMADCheckboxWithIconItem( iconGroup, model.isShowingMADProperty )
], { tandem: tandem.createTandem( 'madAccordionCheckboxGroup' ) } ),
tandemName: 'madAccordionCheckboxGroup',
value: VariabilityMeasure.MAD
}
] );

super( model, accordionBoxContents,
new Text( accordionBoxTitleProperty, {
font: new PhetFont( 16 ),
maxWidth: 300
} ),
layoutBounds, {
layoutBounds,
checkboxToggleNode,
{
leftMargin: 70,
tandem: tandem,
top: top,
Expand Down

0 comments on commit 0b518cc

Please sign in to comment.