-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add NumeralAccordionBoxes and CompareAccordionBoxes to the compare sc…
…reen, see #2
- Loading branch information
Showing
7 changed files
with
380 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Copyright 2019, University of Colorado Boulder | ||
|
||
/** | ||
* Model class for a ComparePlayArea, which combines a OnesPlayArea and an ObjectPlayArea. | ||
* | ||
* @author Chris Klusendorf (PhET Interactive Simulations) | ||
*/ | ||
define( require => { | ||
'use strict'; | ||
|
||
// modules | ||
const EnumerationProperty = require( 'AXON/EnumerationProperty' ); | ||
const numberPlay = require( 'NUMBER_PLAY/numberPlay' ); | ||
const ObjectsPlayArea = require( 'NUMBER_PLAY/common/model/ObjectsPlayArea' ); | ||
const OnesPlayArea = require( 'NUMBER_PLAY/common/model/OnesPlayArea' ); | ||
const ComparePlayObjectType = require( 'NUMBER_PLAY/compare/model/ComparePlayObjectType' ); | ||
|
||
class ComparePlayArea { | ||
|
||
/** | ||
* @param {NumberProperty} currentNumberProperty | ||
* @param {number} objectMaxScale - see PlayObject for doc | ||
* @param {Vector2} paperNumberOrigin - see OnesPlayArea for doc | ||
* @param {BooleanProperty} isResetting | ||
*/ | ||
constructor( currentNumberProperty, objectMaxScale, paperNumberOrigin, isResettingProperty ) { | ||
|
||
// @public {EnumerationProperty.<ComparePlayObjectType>} - the current type of playObject being displayed | ||
this.playObjectTypeProperty = new EnumerationProperty( ComparePlayObjectType, ComparePlayObjectType.DOG ); | ||
|
||
// since one value of ComparePlayObjectType is not valid in ObjectsPlayArea, this is a separate Property | ||
// to prevent that value from passing through to ObjectsPlayArea. see the link below for usage. | ||
const playObjectTypeProperty = new EnumerationProperty( ComparePlayObjectType, ComparePlayObjectType.DOG ); | ||
|
||
// @public (read-only) - the model for managing paper ones in the playArea | ||
this.onesPlayArea = new OnesPlayArea( currentNumberProperty, paperNumberOrigin, isResettingProperty ); | ||
|
||
// @public (read-only) - the model for managing objects in the playArea | ||
this.objectsPlayArea = new ObjectsPlayArea( currentNumberProperty, objectMaxScale, isResettingProperty, { | ||
playObjectTypeProperty: playObjectTypeProperty | ||
} ); | ||
|
||
// if the value of the current play object type is a paper one, don't send update the Property that was passed to | ||
// ObjectsPlayArea, as it does not handle paper ones. instead, see how this same link is used in | ||
// CompareAccordionBox to hide ObjectsPlayArea and show the OnesPlayArea for this case. | ||
this.playObjectTypeProperty.link( type => { | ||
if ( type !== ComparePlayObjectType.PAPER_ONE ) { | ||
playObjectTypeProperty.value = type; | ||
} | ||
} ); | ||
} | ||
|
||
/** | ||
* @param {number} dt - time step, in seconds | ||
* @public | ||
*/ | ||
step( dt ) { | ||
this.onesPlayArea.step( dt ); | ||
} | ||
|
||
/** | ||
* @public | ||
*/ | ||
reset() { | ||
this.onesPlayArea.reset(); | ||
this.objectsPlayArea.reset(); | ||
this.playObjectTypeProperty.reset(); | ||
} | ||
} | ||
|
||
return numberPlay.register( 'ComparePlayArea', ComparePlayArea ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright 2019, University of Colorado Boulder | ||
|
||
/** | ||
* Play object types specific to the `Compare` screen. | ||
* | ||
* @author Chris Klusendorf | ||
*/ | ||
define( require => { | ||
'use strict'; | ||
|
||
// modules | ||
const Enumeration = require( 'PHET_CORE/Enumeration' ); | ||
const numberPlay = require( 'NUMBER_PLAY/numberPlay' ); | ||
const PlayObjectType = require( 'NUMBER_PLAY/common/model/PlayObjectType' ); | ||
|
||
// @public | ||
const ComparePlayObjectType = new Enumeration( [ PlayObjectType.DOG.name, PlayObjectType.APPLE.name, 'PAPER_ONE' ] ); | ||
|
||
return numberPlay.register( 'ComparePlayObjectType', ComparePlayObjectType ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
// Copyright 2019, University of Colorado Boulder | ||
|
||
/** | ||
* Class for the `Objects` accordion box on the 'Compare' screen, which mixes the functionality of ObjectsAccordionBox | ||
* and OnesAccordionBox | ||
* | ||
* TODO: Generalize the ObjectsAccordionBox and OnesAccordionBox so that they share code, which will remove the need | ||
* to use both ObjectsPlayAreaNode and OnesPlayAreaNode. | ||
* | ||
* @author Chris Klusendorf (PhET Interactive Simulations) | ||
*/ | ||
define( require => { | ||
'use strict'; | ||
|
||
// modules | ||
const AccordionBox = require( 'SUN/AccordionBox' ); | ||
const BaseNumber = require( 'MAKE_A_TEN/make-a-ten/common/model/BaseNumber' ); | ||
const BaseNumberNode = require( 'MAKE_A_TEN/make-a-ten/common/view/BaseNumberNode' ); | ||
const Bounds2 = require( 'DOT/Bounds2' ); | ||
const ComparePlayObjectType = require( 'NUMBER_PLAY/compare/model/ComparePlayObjectType' ); | ||
const Color = require( 'SCENERY/util/Color' ); | ||
const Dimension2 = require( 'DOT/Dimension2' ); | ||
const EnumerationProperty = require( 'AXON/EnumerationProperty' ); | ||
const merge = require( 'PHET_CORE/merge' ); | ||
const ModelViewTransform2 = require( 'PHETCOMMON/view/ModelViewTransform2' ); | ||
const numberPlay = require( 'NUMBER_PLAY/numberPlay' ); | ||
const NumberPlayConstants = require( 'NUMBER_PLAY/common/NumberPlayConstants' ); | ||
const ObjectsPlayAreaNode = require( 'NUMBER_PLAY/common/view/ObjectsPlayAreaNode' ); | ||
const OnesPlayAreaNode = require( 'NUMBER_PLAY/common/view/OnesPlayAreaNode' ); | ||
const PlayObject = require( 'NUMBER_PLAY/common/model/PlayObject' ); | ||
const PlayObjectNode = require( 'NUMBER_PLAY/common/view/PlayObjectNode' ); | ||
const RadioButtonGroup = require( 'SUN/buttons/RadioButtonGroup' ); | ||
const Rectangle = require( 'SCENERY/nodes/Rectangle' ); | ||
const Text = require( 'SCENERY/nodes/Text' ); | ||
const Vector2 = require( 'DOT/Vector2' ); | ||
|
||
// constants | ||
const WIDTH = 394; // the width of this AccordionBox, in screen coordinates. from the screen's design asset. | ||
|
||
// strings | ||
const objectsString = require( 'string!NUMBER_PLAY/objects' ); | ||
|
||
class CompareAccordionBox extends AccordionBox { | ||
|
||
/** | ||
* @param {ComparePlayArea} playArea | ||
* @param {number} height - the height of this accordion box | ||
* @param {Object} [options] | ||
*/ | ||
constructor( playArea, height, options ) { | ||
|
||
options = merge( { | ||
titleNode: new Text( objectsString, { font: NumberPlayConstants.ACCORDION_BOX_TITLE_FONT } ), | ||
fill: NumberPlayConstants.BLUE_BACKGROUND, | ||
minWidth: WIDTH, | ||
maxWidth: WIDTH, | ||
|
||
contentWidth: 350, // {number} | ||
radioButtonSize: new Dimension2( 28, 28 ), // {Dimension2} | ||
radioButtonSpacing: 10 // {number} | ||
}, NumberPlayConstants.ACCORDION_BOX_OPTIONS, options ); | ||
|
||
const contentNode = new Rectangle( { | ||
rectHeight: height, | ||
rectWidth: options.contentWidth | ||
} ); | ||
|
||
// create view bounds for the ObjectsPlayAreaNode | ||
const playAreaMarginY = 15; | ||
const objectsPlayAreaViewBounds = new Bounds2( | ||
contentNode.left, | ||
contentNode.top + playAreaMarginY, | ||
contentNode.right, | ||
contentNode.bottom - playAreaMarginY | ||
); | ||
const translateMVT = ModelViewTransform2.createSinglePointScaleInvertedYMapping( | ||
Vector2.ZERO, | ||
new Vector2( objectsPlayAreaViewBounds.left + NumberPlayConstants.BUCKET_SIZE.width / 2, objectsPlayAreaViewBounds.bottom ), | ||
1 | ||
); | ||
const playAreaModelBounds = translateMVT.viewToModelBounds( objectsPlayAreaViewBounds ).dilatedX( -20 ).dilatedY( -19 ); | ||
|
||
// create and add the ObjectsPlayAreaNode | ||
const objectsPlayAreaNode = new ObjectsPlayAreaNode( | ||
playArea.objectsPlayArea, | ||
playAreaModelBounds, | ||
translateMVT | ||
); | ||
contentNode.addChild( objectsPlayAreaNode ); | ||
|
||
// create view bounds for the OnesPlayAreaNode | ||
const onesPlayAreaViewBounds = new Bounds2( | ||
contentNode.left, | ||
contentNode.top, | ||
contentNode.right, | ||
contentNode.bottom - playAreaMarginY | ||
); | ||
|
||
// create and add the OnesPlayAreaNode | ||
const onesPlayAreaNode = new OnesPlayAreaNode( | ||
playArea.onesPlayArea, | ||
onesPlayAreaViewBounds, | ||
translateMVT | ||
); | ||
contentNode.addChild( onesPlayAreaNode ); | ||
|
||
// create the icons for the RadioButtonGroup | ||
const buttons = []; | ||
ComparePlayObjectType.VALUES.forEach( playObjectType => { | ||
let iconNode = null; | ||
if ( playObjectType === ComparePlayObjectType.PAPER_ONE ) { | ||
iconNode = new BaseNumberNode( new BaseNumber( 1, 0 ), 1 ); | ||
iconNode.setScaleMagnitude( options.radioButtonSize.height / iconNode.height / 4 ); | ||
} | ||
else { | ||
iconNode = new PlayObjectNode( | ||
new PlayObject( | ||
new EnumerationProperty( ComparePlayObjectType, playObjectType ), | ||
new Vector2( 0, 0 ), | ||
options.radioButtonSize, | ||
1 | ||
), | ||
playAreaModelBounds, | ||
translateMVT | ||
); | ||
} | ||
|
||
buttons.push( { | ||
value: playObjectType, | ||
node: iconNode | ||
} ); | ||
} ); | ||
|
||
// create and add the RadioButtonGroup, which is a control for changing the ComparePlayObjectType of this play area | ||
const radioButtonGroup = new RadioButtonGroup( playArea.playObjectTypeProperty, buttons, { | ||
baseColor: Color.WHITE, | ||
orientation: 'horizontal', | ||
spacing: options.radioButtonSpacing | ||
} ); | ||
radioButtonGroup.right = objectsPlayAreaViewBounds.right - 2; // empirically determined tweak | ||
radioButtonGroup.bottom = objectsPlayAreaViewBounds.bottom; | ||
contentNode.addChild( radioButtonGroup ); | ||
|
||
// since (for now) there are two underlying play areas in place of one, hide and show whichever is appropriate | ||
// based on the value of playObjectTypeProperty | ||
playArea.playObjectTypeProperty.link( type => { | ||
if ( type === ComparePlayObjectType.PAPER_ONE ) { | ||
objectsPlayAreaNode.visible = false; | ||
onesPlayAreaNode.visible = true; | ||
} | ||
else { | ||
onesPlayAreaNode.visible = false; | ||
objectsPlayAreaNode.visible = true; | ||
} | ||
} ); | ||
|
||
super( contentNode, options ); | ||
} | ||
} | ||
|
||
return numberPlay.register( 'CompareAccordionBox', CompareAccordionBox ); | ||
} ); |
Oops, something went wrong.