Skip to content

Commit

Permalink
provide the ability to permanently hide container handles, #30
Browse files Browse the repository at this point in the history
  • Loading branch information
pixelzoom committed May 1, 2024
1 parent b402e80 commit 77dc6cb
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 44 deletions.
73 changes: 52 additions & 21 deletions js/common/view/IdealGasLawContainerNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import LidNode from './LidNode.js';
import LidHandleKeyboardDragListener from './LidHandleKeyboardDragListener.js';
import ResizeHandleKeyboardDragListener from './ResizeHandleKeyboardDragListener.js';
import Multilink from '../../../../axon/js/Multilink.js';
import Tandem from '../../../../tandem/js/Tandem.js';
import DerivedProperty from '../../../../axon/js/DerivedProperty.js';
import BooleanProperty from '../../../../axon/js/BooleanProperty.js';

// constants
const LID_X_SPEED = -50; // pixels/second
Expand Down Expand Up @@ -86,15 +87,36 @@ export default class IdealGasLawContainerNode extends Node {
visible: false
} );

// Resize handle on the left wall, wrapped in a Node so that its focus highlight is not affected by scaling.
const resizeHandleNode = new ResizeHandleNode( options.resizeGripColor, options.tandem.createTandem( 'resizeHandleNode' ) );
// Resize handle on the left wall. The sim sets resizeHandleVisibleProperty, while the PhET-iO client can use
// hasResizeHandleProperty to permanently hide the handle.
const resizeHandleNodeTandem = options.tandem.createTandem( 'resizeHandleNode' );
const resizeHandleVisibleProperty = new BooleanProperty( true );
const hasResizeHandleProperty = new BooleanProperty( true, {
tandem: resizeHandleNodeTandem.createTandem( 'hasResizeHandleProperty' ),
phetioDocumentation: 'Use this Property to permanently hide the container\'s resize handle.'
} );
const resizeHandleNode = new ResizeHandleNode( {
gripColor: options.resizeGripColor,
visibleProperty: DerivedProperty.and( [ resizeHandleVisibleProperty, hasResizeHandleProperty ] ),
tandem: resizeHandleNodeTandem
} );

// Lid on the top of the container
// Lid on the top of the container. The sim sets lidHandleVisibleProperty, while the PhET-iO client can use
// hasLidHandleProperty to permanently hide the handle.
const lidHandleNodeTandem = options.tandem.createTandem( 'lidHandleNode' );
const lidHandleVisibleProperty = new BooleanProperty( true );
const hasLidHandleProperty = new BooleanProperty( true, {
tandem: lidHandleNodeTandem.createTandem( 'hasLidHandleProperty' ),
phetioDocumentation: 'Use this Property to permanently hide the container\'s lid handle.'
} );
const lidNode = new LidNode( {
baseWidth: modelViewTransform.modelToViewDeltaX( container.lidWidthProperty.value ),
baseHeight: modelViewTransform.modelToViewDeltaX( container.lidThickness ),
gripColor: options.lidGripColor,
lidHandleNodeTandem: options.tandem.createTandem( 'lidHandleNode' )
lidHandleNodeOptions: {
gripColor: options.lidGripColor,
visibleProperty: DerivedProperty.and( [ lidHandleVisibleProperty, hasLidHandleProperty ] ),
tandem: lidHandleNodeTandem
}
} );
const lidHandleNode = lidNode.handleNode;

Expand Down Expand Up @@ -158,11 +180,11 @@ export default class IdealGasLawContainerNode extends Node {
this.interruptSubtreeInput();

// Hide the resize handle when volume is held constant
resizeHandleNode.visible = ( holdConstant !== 'volume' && holdConstant !== 'pressureV' );
resizeHandleVisibleProperty.value = ( holdConstant !== 'volume' && holdConstant !== 'pressureV' );

// Hide the lid handle when holding temperature constant. We don't want to deal with counteracting evaporative
// cooling, which will occur when the lid is open. See https://github.com/phetsims/gas-properties/issues/159
lidHandleNode.visible = ( holdConstant !== 'temperature' );
lidHandleVisibleProperty.value = ( holdConstant !== 'temperature' );
} );

// Dragging the resize handle horizontally changes the container's width
Expand Down Expand Up @@ -271,26 +293,35 @@ export default class IdealGasLawContainerNode extends Node {
/**
* ResizeHandleNode is the handle used to resize the container.
*/
type ResizeHandleNodeSelfOptions = {
gripColor: TColor;
};
type ResizeHandleNodeOptions = ResizeHandleNodeSelfOptions & PickRequired<NodeOptions, 'tandem' | 'visibleProperty'>;

class ResizeHandleNode extends InteractiveHighlighting( Node ) {

public constructor( resizeGripColor: TColor, tandem: Tandem ) {
super( {
children: [
// Wrap HandleNode so that ResizeHandleNode's focus highlight is not affected by scaling.
new HandleNode( {
gripBaseColor: resizeGripColor,
attachmentLineWidth: 1,
rotation: -Math.PI / 2,
scale: 0.4
} )
],
public constructor( providedOptions: ResizeHandleNodeOptions ) {

const options = optionize<ResizeHandleNodeOptions, ResizeHandleNodeSelfOptions, NodeOptions>()( {

// NodeOptions
cursor: 'pointer',
tagName: 'div',
focusable: true,
tandem: tandem,
phetioVisiblePropertyInstrumented: false, // sim sets resizeHandle.visibleProperty
phetioInputEnabledPropertyInstrumented: true
}, providedOptions );

const handleNode = new HandleNode( {
gripBaseColor: options.gripColor,
attachmentLineWidth: 1,
rotation: -Math.PI / 2,
scale: 0.4
} );

// Wrap HandleNode so that the focus highlight is not affected by scaling.
options.children = [ handleNode ];

super( options );
}
}

Expand Down
55 changes: 32 additions & 23 deletions js/common/view/LidNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { InteractiveHighlighting, Node, NodeOptions, NodeTranslationOptions, Rec
import gasProperties from '../../gasProperties.js';
import GasPropertiesColors from '../GasPropertiesColors.js';
import PickRequired from '../../../../phet-core/js/types/PickRequired.js';
import Tandem from '../../../../tandem/js/Tandem.js';

// constants
const HANDLE_ATTACHMENT_LINE_WIDTH = 1;
Expand All @@ -22,8 +21,7 @@ const HANDLE_RIGHT_INSET = 3;
type SelfOptions = {
baseWidth: number;
baseHeight: number;
gripColor?: TColor;
lidHandleNodeTandem: Tandem;
lidHandleNodeOptions: LidHandleNodeOptions;
};

type LidNodeOptions = SelfOptions;
Expand All @@ -37,9 +35,6 @@ export default class LidNode extends Node {

const options = optionize<LidNodeOptions, SelfOptions, NodeOptions>()( {

// SelfOptions
gripColor: GasPropertiesColors.lidGripColorProperty,

// NodeOptions
isDisposable: false,
phetioVisiblePropertyInstrumented: false
Expand All @@ -51,11 +46,10 @@ export default class LidNode extends Node {
bottom: 0
} );

const lidHandleNode = new LidHandleNode( options.gripColor, {
const lidHandleNode = new LidHandleNode( combineOptions<LidHandleNodeOptions>( {
right: baseNode.right - HANDLE_RIGHT_INSET,
bottom: baseNode.top + 1,
tandem: options.lidHandleNodeTandem
} );
bottom: baseNode.top + 1
}, options.lidHandleNodeOptions ) );
assert && assert( lidHandleNode.width <= baseNode.width,
`handleNode.width ${lidHandleNode.width} is wider than baseNode.width ${baseNode.width}` );
lidHandleNode.touchArea = lidHandleNode.localBounds.dilatedXY( 25, 20 );
Expand Down Expand Up @@ -84,25 +78,40 @@ export default class LidNode extends Node {
/**
* LidHandleNode is the handle used to open and close the container's lid.
*/

type LidHandleNodeSelfOptions = {
gripColor?: TColor;
};
type LidHandleNodeOptions = LidHandleNodeSelfOptions & NodeTranslationOptions &
PickRequired<NodeOptions, 'tandem' | 'visibleProperty'>;

class LidHandleNode extends InteractiveHighlighting( Node ) {

public constructor( gripColor: TColor, providedOptions?: NodeTranslationOptions & PickRequired<NodeOptions, 'tandem'> ) {
super( combineOptions<NodeOptions>( {
children: [
// Wrap HandleNode so that LidHandleNode's focus highlight is not affected by scaling.
new HandleNode( {
hasLeftAttachment: false,
gripBaseColor: gripColor,
attachmentLineWidth: HANDLE_ATTACHMENT_LINE_WIDTH,
scale: 0.4
} )
],
public constructor( providedOptions: LidHandleNodeOptions ) {

const options = optionize<LidHandleNodeOptions, LidHandleNodeSelfOptions, NodeOptions>()( {

// LidHandleNodeSelfOptions
gripColor: GasPropertiesColors.lidGripColorProperty,

// NodeOptions
cursor: 'pointer',
tagName: 'div',
focusable: true,
phetioVisiblePropertyInstrumented: false, // sim sets lidHandleNode.visibleProperty
phetioInputEnabledPropertyInstrumented: true
}, providedOptions ) );
}, providedOptions );

const handleNode = new HandleNode( {
hasLeftAttachment: false,
gripBaseColor: options.gripColor,
attachmentLineWidth: HANDLE_ATTACHMENT_LINE_WIDTH,
scale: 0.4
} );

// Wrap HandleNode so that the focus highlight is not affected by scaling.
options.children = [ handleNode ];

super( options );
}
}

Expand Down

0 comments on commit 77dc6cb

Please sign in to comment.