Skip to content

Commit

Permalink
Factored out JoistButton from PhetButton, see #182
Browse files Browse the repository at this point in the history
  • Loading branch information
samreid committed Nov 13, 2014
1 parent b14d9b6 commit f9c0c8f
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 53 deletions.
88 changes: 88 additions & 0 deletions js/JoistButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2002-2013, University of Colorado Boulder

/**
* Base class for Joist buttons such as the "home" button and "PhET" button that show custom highlighting on mouseover.
*
* @author Sam Reid
*/
define( function( require ) {
'use strict';

// modules
var Node = require( 'SCENERY/nodes/Node' );
var inherit = require( 'PHET_CORE/inherit' );
var Shape = require( 'KITE/Shape' );
var HighlightNode = require( 'JOIST/HighlightNode' );
var ButtonListener = require( 'SUN/buttons/ButtonListener' );
var PushButtonInteractionStateProperty = require( 'SUN/buttons/PushButtonInteractionStateProperty' );
var PushButtonModel = require( 'SUN/buttons/PushButtonModel' );
var Property = require( 'AXON/Property' );

/**
* @param {Sim} sim
* @param {Node} content - the scenery node to render as the content of the button
* @param {Object} [options] Unused in client code.
* @constructor
*/
function JoistButton( sim, content, options ) {

options = _.extend( {
cursor: 'pointer', // {string}
listener: null, // {function}
ariaLabel: '' // {string}
}, options );

// Button model
this.buttonModel = new PushButtonModel( options ); // @private

// Create both highlights and only make the one visible that corresponds to the color scheme
var createHighlight = function( whiteHighlight ) {
return new HighlightNode( content.width + 6, content.height + 5, {
centerX: content.centerX,
centerY: content.centerY + 4,
whiteHighlight: whiteHighlight,
pickable: false
} );
};

// Highlight against the black background
var normalHighlight = createHighlight( true );

// Highlight against the white background
var invertedHighlight = createHighlight( false );

Node.call( this, {children: [content, normalHighlight, invertedHighlight]} );

// Button interactions
var interactionStateProperty = new PushButtonInteractionStateProperty( this.buttonModel );

this.interactionStateProperty = interactionStateProperty;//@protected

// Update the highlights based on whether the button is highlighted and whether it is against a light or dark background.
Property.multilink( [interactionStateProperty, sim.useInvertedColorsProperty], function( interactionState, useInvertedColors ) {
normalHighlight.visible = !useInvertedColors && (interactionState === 'over' || interactionState === 'pressed');
invertedHighlight.visible = useInvertedColors && (interactionState === 'over' || interactionState === 'pressed');
} );

this.addInputListener( new ButtonListener( this.buttonModel ) );

this.addPeer( '<input type="button" aria-label="' + options.ariaLabel + '">', {click: options.listener, tabIndex: 101} );

// eliminate interactivity gap between label and button
this.mouseArea = this.touchArea = Shape.bounds( this.bounds );

this.mutate( options );
}

return inherit( Node, JoistButton, {},

//statics
{

//How much space between the JoistButton and the right side of the screen.
HORIZONTAL_INSET: 5,

//How much space between the JoistButton and the bottom of the screen
VERTICAL_INSET: 0
} );
} );
63 changes: 10 additions & 53 deletions js/PhetButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,8 @@ define( function( require ) {
var FontAwesomeNode = require( 'SUN/FontAwesomeNode' );
var inherit = require( 'PHET_CORE/inherit' );
var PhetMenu = require( 'JOIST/PhetMenu' );
var Shape = require( 'KITE/Shape' );
var HighlightNode = require( 'JOIST/HighlightNode' );
var ButtonListener = require( 'SUN/buttons/ButtonListener' );
var PushButtonInteractionStateProperty = require( 'SUN/buttons/PushButtonInteractionStateProperty' );
var PushButtonModel = require( 'SUN/buttons/PushButtonModel' );
var Property = require( 'AXON/Property' );
var JoistButton = require( 'JOIST/JoistButton' );

// images
var phetLogo = require( 'image!BRAND/logo.png' );
Expand All @@ -35,15 +31,9 @@ define( function( require ) {
function PhetButton( sim, options ) {

options = _.extend( {
cursor: 'pointer', // {string}
listener: null, // {function}
phetLogoScale: 0.28, // {number}
optionsButtonVerticalMargin: 1.5 // {number}
phetLogoScale: 0.28 // {number}
}, options );

// Button model
this.buttonModel = new PushButtonModel( options ); // @private

// The PhET Label, which is the PhET logo
var phetLabel = new Image( phetLogo, {
scale: options.phetLogoScale,
Expand All @@ -53,46 +43,14 @@ define( function( require ) {
var optionsButton = new FontAwesomeNode( 'reorder', {
scale: 0.6,
left: phetLabel.width + 10,
bottom: phetLabel.bottom - options.optionsButtonVerticalMargin,
bottom: phetLabel.bottom - 1.5,
pickable: false
} );

// The icon combines the PhET label and the thre horizontal bars in the right relative positions
var icon = new Node( {children: [phetLabel, optionsButton]} );

// Create both highlights and only make the one visible that corresponds to the color scheme
var createHighlight = function( whiteHighlight ) {
return new HighlightNode( icon.width + 6, icon.height + 5, {
centerX: icon.centerX,
centerY: icon.centerY + 4,
whiteHighlight: whiteHighlight,
pickable: false
} );
};

// Highlight against the black background
var normalHighlight = createHighlight( true );

// Highlight against the white background
var invertedHighlight = createHighlight( false );

Node.call( this, {children: [icon, normalHighlight, invertedHighlight]} );

// Button interactions
var interactionStateProperty = new PushButtonInteractionStateProperty( this.buttonModel );

// Update the content of the button based on mouseover/press and whether the colors have been inverted
Property.multilink( [interactionStateProperty, sim.useInvertedColorsProperty], function( interactionState, useInvertedColors ) {
optionsButton.fill = useInvertedColors ? '#222' : 'white';
phetLabel.image = useInvertedColors ? phetLogoDarker : phetLogo;
normalHighlight.visible = !useInvertedColors && (interactionState === 'over' || interactionState === 'pressed');
invertedHighlight.visible = useInvertedColors && (interactionState === 'over' || interactionState === 'pressed');
} );

this.addInputListener( new ButtonListener( this.buttonModel ) );

//When the phet button is pressed, show the phet menu
var phetButtonPressed = function() {
JoistButton.call( this, sim, icon, {listener: function() {

var phetMenu = new PhetMenu( sim, {
showSaveAndLoad: sim.options.showSaveAndLoad,
Expand All @@ -115,18 +73,17 @@ define( function( require ) {
onResize( sim.bounds, sim.screenBounds, sim.scale );

sim.showPopup( phetMenu, true );
};
this.buttonModel.addListener( phetButtonPressed );
}} );

this.addPeer( '<input type="button" aria-label="PhET Menu">', {click: phetButtonPressed, tabIndex: 101} );

// eliminate interactivity gap between label and button
this.mouseArea = this.touchArea = Shape.bounds( this.bounds );
Property.multilink( [this.interactionStateProperty, sim.useInvertedColorsProperty], function( interactionState, useInvertedColors ) {
optionsButton.fill = useInvertedColors ? '#222' : 'white';
phetLabel.image = useInvertedColors ? phetLogoDarker : phetLogo;
} );

this.mutate( options );
}

return inherit( Node, PhetButton, {},
return inherit( JoistButton, PhetButton, {},

//statics
{
Expand Down

0 comments on commit f9c0c8f

Please sign in to comment.