-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathToolboxPanel.js
120 lines (101 loc) · 5.26 KB
/
ToolboxPanel.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright 2018-2020, University of Colorado Boulder
/**
* Shows the toolbox from whence tools (measuring tape, timer, probe) can be dragged.
*
* @author Sam Reid (PhET Interactive Simulations)
*/
import Vector2 from '../../../../dot/js/Vector2.js';
import DragListener from '../../../../scenery/js/listeners/DragListener.js';
import HBox from '../../../../scenery/js/nodes/HBox.js';
import waveInterference from '../../waveInterference.js';
import WaveInterferenceConstants from '../WaveInterferenceConstants.js';
import WaveInterferencePanel from './WaveInterferencePanel.js';
class ToolboxPanel extends WaveInterferencePanel {
/**
* @param {MeasuringTapeNode} measuringTapeNode
* @param {WaveInterferenceStopwatchNode} stopwatchNode
* @param {WaveMeterNode} waveMeterNode
* @param {AlignGroup} alignGroup - to align with neighbors
* @param {Property.<Boolean>} isMeasuringTapeInPlayAreaProperty
* @param {Property.<Vector2>} measuringTapeTipPositionProperty
* @param {Property.<Boolean>} isStopwatchVisibleProperty
* @param {Property.<Boolean>} isWaveMeterInPlayAreaProperty
*/
constructor( measuringTapeNode, stopwatchNode, waveMeterNode, alignGroup, isMeasuringTapeInPlayAreaProperty,
measuringTapeTipPositionProperty, isStopwatchVisibleProperty, isWaveMeterInPlayAreaProperty ) {
// Capture image for icon
isMeasuringTapeInPlayAreaProperty.value = true;
measuringTapeNode.setTextVisible( false );
measuringTapeTipPositionProperty.value = new Vector2( 220, 200 ); // Shorter tape for icon
const measuringTapeIcon = measuringTapeNode.rasterized( { wrap: true } ).mutate( { scale: 0.65 } );
measuringTapeTipPositionProperty.reset();
isMeasuringTapeInPlayAreaProperty.value = false;
measuringTapeNode.setTextVisible( true );
initializeIcon( measuringTapeIcon, isMeasuringTapeInPlayAreaProperty, event => {
// When clicking on the measuring tape icon, pop it out into the play area
const targetPosition = this.globalToParentPoint( event.pointer.point );
const currentPosition = measuringTapeNode.basePositionProperty.value;
const delta = targetPosition.minus( currentPosition );
measuringTapeNode.basePositionProperty.set( measuringTapeNode.basePositionProperty.value.plus( delta ) );
measuringTapeNode.tipPositionProperty.set( measuringTapeNode.tipPositionProperty.value.plus( delta ) );
measuringTapeNode.startBaseDrag( event );
isMeasuringTapeInPlayAreaProperty.value = true;
} );
// Node used to create the icon
isStopwatchVisibleProperty.value = true;
const stopwatchNodeIcon = stopwatchNode.rasterized().mutate( { scale: 0.45 } );
isStopwatchVisibleProperty.value = false;
// The draggable icon, which has an overlay to make the buttons draggable instead of pressable
initializeIcon( stopwatchNodeIcon, isStopwatchVisibleProperty, event => {
stopwatchNode.center = this.globalToParentPoint( event.pointer.point );
// stopwatchNode provided as targetNode in the DragListener constructor, so this press will target it
stopwatchNode.dragListener.press( event );
isStopwatchVisibleProperty.value = true;
} );
// Make sure the probes have enough breathing room so they don't get shoved into the WaveMeterNode icon. Anything
// above 60 seems to work equally well, closer than that causes the probes to overlap each other or the meter
// body. The true translation is set when dragged out of the toolbox.
waveMeterNode.backgroundNode.translate( 60, 0 );
// The draggable icon, which has an overlay to make the buttons draggable instead of pressable
// Temporarily show the node so it can be rasterized for an icon
isWaveMeterInPlayAreaProperty.value = true;
const waveMeterIcon = waveMeterNode.rasterized().mutate( { scale: 0.25 } );
isWaveMeterInPlayAreaProperty.value = false;
initializeIcon( waveMeterIcon, isWaveMeterInPlayAreaProperty, event => {
// Fine-tuned empirically to set the drag point to be the center of the chart.
waveMeterNode.backgroundNode.setTranslation( this.globalToParentPoint( event.pointer.point ).plusXY( -60, -66 ) );
// Set the internal flag that indicates the probes should remain in alignment during the drag
waveMeterNode.synchronizeProbePositions = true;
waveMeterNode.startDrag( event );
isWaveMeterInPlayAreaProperty.value = true;
} );
// Layout for the toolbox
super( alignGroup.createBox( new HBox( {
spacing: 10,
children: [
measuringTapeIcon,
stopwatchNodeIcon,
waveMeterIcon
],
excludeInvisibleChildrenFromBounds: false
} ) ), {
// Panel options
yMargin: 9.55,
maxWidth: WaveInterferenceConstants.PANEL_MAX_WIDTH
}
);
}
}
/**
* Initialize the icon for use in the toolbox.
* @param {Node} node
* @param {Property.<boolean>} inPlayAreaProperty
* @param {Object} forwardingListener
*/
const initializeIcon = ( node, inPlayAreaProperty, forwardingListener ) => {
node.cursor = 'pointer';
inPlayAreaProperty.link( inPlayArea => { node.visible = !inPlayArea; } );
node.addInputListener( DragListener.createForwardingListener( forwardingListener ) );
};
waveInterference.register( 'ToolboxPanel', ToolboxPanel );
export default ToolboxPanel;