Skip to content

Commit

Permalink
Move MeanOrMedianScreenView.ts into SoccerScreenView.ts, see #152
Browse files Browse the repository at this point in the history
  • Loading branch information
samreid committed Apr 25, 2023
1 parent 0e0ca32 commit 8c193b3
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 140 deletions.
126 changes: 0 additions & 126 deletions js/common/view/MeanOrMedianScreenView.ts

This file was deleted.

99 changes: 98 additions & 1 deletion js/common/view/SoccerScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import CAVScreenView, { CAVScreenViewOptions } from './CAVScreenView.js';
import QuestionBar, { QuestionBarOptions } from '../../../../scenery-phet/js/QuestionBar.js';
import KickButtonGroup from './KickButtonGroup.js';
import BackgroundNode from './BackgroundNode.js';
import { Node } from '../../../../scenery/js/imports.js';
import { ManualConstraint, Node, Text } from '../../../../scenery/js/imports.js';
import ModelViewTransform2 from '../../../../phetcommon/js/view/ModelViewTransform2.js';
import Bounds2 from '../../../../dot/js/Bounds2.js';
import ScreenView from '../../../../joist/js/ScreenView.js';
Expand All @@ -23,9 +23,25 @@ import PhetioGroup from '../../../../tandem/js/PhetioGroup.js';
import SoccerPlayer from '../model/SoccerPlayer.js';
import NumberLineNode from './NumberLineNode.js';
import merge from '../../../../phet-core/js/merge.js';
import CAVAccordionBox from './CAVAccordionBox.js';
import CardNodeContainer from './CardNodeContainer.js';
import MedianModel from '../../median/model/MedianModel.js';
import VariabilityPlotNode from '../../variability/view/VariabilityPlotNode.js';
import VariabilityModel from '../../variability/model/VariabilityModel.js';
import CAVPlotNodeWithMedianBar from '../../mean-and-median/view/CAVPlotNodeWithMedianBar.js';
import PhetFont from '../../../../scenery-phet/js/PhetFont.js';
import CAVConstants from '../CAVConstants.js';
import VariabilityReadoutsNode from '../../variability/view/VariabilityReadoutsNode.js';
import ValueReadoutsNode from './ValueReadoutsNode.js';
import TReadOnlyProperty from '../../../../axon/js/TReadOnlyProperty.js';

type SelfOptions = {
questionBarOptions: QuestionBarOptions;

// TODO: If we are sticking with this pattern, switch to screen: 'median' | 'meanAndMedian' | 'variability' etc, see https://github.com/phetsims/center-and-variability/issues/153
isMedianScreen: boolean;
isVariabilityScreen: boolean;
accordionBoxTitleStringProperty: TReadOnlyProperty<string>;
};
export type SoccerScreenViewOptions = SelfOptions & CAVScreenViewOptions;

Expand All @@ -34,6 +50,10 @@ const GROUND_POSITION_Y = 500;
const NUMBER_LINE_MARGIN_X = 207;

export default class SoccerScreenView extends CAVScreenView {

private readonly accordionBox: CAVAccordionBox;
protected readonly accordionBoxContents: Node;

protected readonly questionBar: QuestionBar;
protected readonly chartViewWidth: number;
protected readonly playAreaNumberLineNode: NumberLineNode;
Expand Down Expand Up @@ -116,6 +136,83 @@ export default class SoccerScreenView extends CAVScreenView {

// Soccer balls go behind the accordion box after they land
this.contentLayer.addChild( this.backObjectLayer );


const accordionBoxTandem = options.tandem.createTandem( 'accordionBox' );

// TODO: Better logic for this, or better ordering
if ( options.isMedianScreen ) {
this.accordionBoxContents = new CardNodeContainer( this.model as MedianModel, {

// Expose this intermediate layer to make it so that clients can hide the number cards with one call
tandem: accordionBoxTandem.createTandem( 'cardNodeContainer' )
} );
}
else if ( options.isVariabilityScreen ) {
this.accordionBoxContents = new VariabilityPlotNode( this.model as VariabilityModel, this.chartViewWidth, {
tandem: accordionBoxTandem.createTandem( 'plotNode' )
} );
}
else {
this.accordionBoxContents = new CAVPlotNodeWithMedianBar( this.model, this.chartViewWidth, {
tandem: accordionBoxTandem.createTandem( 'plotNode' )
} );
}

const titleNode = new Text( options.accordionBoxTitleStringProperty, {
font: new PhetFont( 16 ),
maxWidth: 300
} );

this.accordionBox = new CAVAccordionBox( this.model, this.accordionBoxContents, this.accordionBoxControlNode,
titleNode,
this.layoutBounds, {
leftMargin: options.isVariabilityScreen ? 70 : 0,
tandem: accordionBoxTandem,
contentNodeOffsetY: options.isMedianScreen ? -6 : 0,
top: this.questionBar.bottom + CAVConstants.SCREEN_VIEW_Y_MARGIN,

// TODO: Better pattern for this
valueReadoutsNode: model instanceof VariabilityModel ? new VariabilityReadoutsNode( model ) :
options.isMedianScreen ? null :
new ValueReadoutsNode( model ),

...( options.isVariabilityScreen ? {
right: this.layoutBounds.right - CAVConstants.SCREEN_VIEW_X_MARGIN
} : {
centerX: this.layoutBounds.centerX
} ),
infoShowingProperty: this.model instanceof VariabilityModel ? this.model.isInfoShowingProperty : null
} );
this.contentLayer.addChild( this.accordionBox );


// TODO: What if positioning the bottomCheckboxGroup.right forces the topCheckboxGroup to the right of the accordion box bounds?
ManualConstraint.create( this, [ this.bottomCheckboxGroup, this.accordionBoxControlNode ],
( bottomCheckboxGroupWrapper, accordionBoxControlNodeWrapper ) => {
accordionBoxControlNodeWrapper.x = bottomCheckboxGroupWrapper.x;
} );

// Add in the same order as the checkboxes, so the z-order matches the checkbox order
if ( !options.isMedianScreen ) {
this.contentLayer.addChild( this.meanPredictionNode );
}

this.contentLayer.addChild( this.medianPredictionNode );
}

/**
* Floating layout that keeps the ground near the ground, and accordion box near the question bar
*/
public override layout( viewBounds: Bounds2 ): void {

// TODO: Duplicates effort with the parent implementation
this.matrix = ScreenView.getLayoutMatrix( this.layoutBounds, viewBounds, {
verticalAlign: 'bottom'
} );
this.visibleBoundsProperty.value = this.parentToLocalBounds( viewBounds );

this.accordionBox.top = this.questionBar.bottom + CAVConstants.SCREEN_VIEW_Y_MARGIN;
}
}

Expand Down
8 changes: 4 additions & 4 deletions js/mean-and-median/view/MeanAndMedianScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ import MeanAndMedianModel from '../model/MeanAndMedianModel.js';
import CAVColors from '../../common/CAVColors.js';
import CenterAndVariabilityStrings from '../../CenterAndVariabilityStrings.js';
import { ManualConstraint } from '../../../../scenery/js/imports.js';
import MeanOrMedianScreenView, { MeanOrMedianScreenViewOptions } from '../../common/view/MeanOrMedianScreenView.js';
import StrictOmit from '../../../../phet-core/js/types/StrictOmit.js';
import SoccerScreenView, { SoccerScreenViewOptions } from '../../common/view/SoccerScreenView.js';

type MeanAndMedianScreenViewOptions = StrictOmit<MeanOrMedianScreenViewOptions, 'isMedianScreen' | 'questionBarOptions'>;
type MeanAndMedianScreenViewOptions = StrictOmit<SoccerScreenViewOptions, 'isMedianScreen' | 'questionBarOptions'>;

export default class MeanAndMedianScreenView extends MeanOrMedianScreenView {
export default class MeanAndMedianScreenView extends SoccerScreenView {

public constructor( model: MeanAndMedianModel, providedOptions: MeanAndMedianScreenViewOptions ) {

const options = optionize<MeanAndMedianScreenViewOptions, EmptySelfOptions, MeanOrMedianScreenViewOptions>()( {
const options = optionize<MeanAndMedianScreenViewOptions, EmptySelfOptions, SoccerScreenViewOptions>()( {
isMedianScreen: false,
questionBarOptions: {
barFill: CAVColors.meanAndMedianQuestionBarFillColorProperty,
Expand Down
8 changes: 4 additions & 4 deletions js/median/view/MedianScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ import centerAndVariability from '../../centerAndVariability.js';
import MedianModel from '../model/MedianModel.js';
import CAVColors from '../../common/CAVColors.js';
import CenterAndVariabilityStrings from '../../CenterAndVariabilityStrings.js';
import MeanOrMedianScreenView, { MeanOrMedianScreenViewOptions } from '../../common/view/MeanOrMedianScreenView.js';
import StrictOmit from '../../../../phet-core/js/types/StrictOmit.js';
import TopRepresentationCheckboxGroup from '../../common/view/TopRepresentationCheckboxGroup.js';
import SoccerScreenView, { SoccerScreenViewOptions } from '../../common/view/SoccerScreenView.js';

type SelfOptions = EmptySelfOptions;
type MedianScreenViewOptions =
SelfOptions
& StrictOmit<MeanOrMedianScreenViewOptions, 'createAccordionBoxControlNode' | 'isMedianScreen' | 'isVariabilityScreen' | 'questionBarOptions' | 'accordionBoxTitleStringProperty'>;
& StrictOmit<SoccerScreenViewOptions, 'createAccordionBoxControlNode' | 'isMedianScreen' | 'isVariabilityScreen' | 'questionBarOptions' | 'accordionBoxTitleStringProperty'>;

export default class MedianScreenView extends MeanOrMedianScreenView {
export default class MedianScreenView extends SoccerScreenView {

public constructor( model: MedianModel, providedOptions: MedianScreenViewOptions ) {

const options = optionize<MedianScreenViewOptions, SelfOptions, MeanOrMedianScreenViewOptions>()( {
const options = optionize<MedianScreenViewOptions, SelfOptions, SoccerScreenViewOptions>()( {
isMedianScreen: true,
isVariabilityScreen: false,
questionBarOptions: {
Expand Down
9 changes: 4 additions & 5 deletions js/variability/view/VariabilityScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ import optionize, { EmptySelfOptions } from '../../../../phet-core/js/optionize.
import StrictOmit from '../../../../phet-core/js/types/StrictOmit.js';
import centerAndVariability from '../../centerAndVariability.js';
import VariabilityModel from '../model/VariabilityModel.js';
import { SoccerScreenViewOptions } from '../../common/view/SoccerScreenView.js';
import SoccerScreenView, { SoccerScreenViewOptions } from '../../common/view/SoccerScreenView.js';
import CAVColors from '../../common/CAVColors.js';
import CenterAndVariabilityStrings from '../../CenterAndVariabilityStrings.js';
import MeanOrMedianScreenView, { MeanOrMedianScreenViewOptions } from '../../common/view/MeanOrMedianScreenView.js';
import { ManualConstraint, Text } from '../../../../scenery/js/imports.js';
import DistributionRadioButtonGroup from './DistributionRadioButtonGroup.js';
import VariabilityMeasureRadioButtonGroup from './VariabilityMeasureRadioButtonGroup.js';
Expand All @@ -34,9 +33,9 @@ const TEXT_OPTIONS = {
};

type SelfOptions = EmptySelfOptions;
type VariabilityScreenViewOptions = SelfOptions & StrictOmit<SoccerScreenViewOptions, 'questionBarOptions' | 'createAccordionBoxControlNode'>;
type VariabilityScreenViewOptions = SelfOptions & StrictOmit<SoccerScreenViewOptions, 'questionBarOptions' | 'createAccordionBoxControlNode' | 'isMedianScreen' | 'isVariabilityScreen' | 'accordionBoxTitleStringProperty'>;

export default class VariabilityScreenView extends MeanOrMedianScreenView {
export default class VariabilityScreenView extends SoccerScreenView {

public constructor( model: VariabilityModel, providedOptions: VariabilityScreenViewOptions ) {

Expand All @@ -48,7 +47,7 @@ export default class VariabilityScreenView extends MeanOrMedianScreenView {

const accordionBoxTitleProperty = new DynamicProperty<string, unknown, unknown>( currentProperty );

const options = optionize<VariabilityScreenViewOptions, SelfOptions, MeanOrMedianScreenViewOptions>()( {
const options = optionize<VariabilityScreenViewOptions, SelfOptions, SoccerScreenViewOptions>()( {
isMedianScreen: false,
isVariabilityScreen: true,
questionBarOptions: {
Expand Down

0 comments on commit 8c193b3

Please sign in to comment.