-
Notifications
You must be signed in to change notification settings - Fork 1
/
PaperLandControls.js
147 lines (134 loc) · 5 KB
/
PaperLandControls.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/**
* Controls that impact the behavior of the board in paper-land.
*/
import React, { useEffect, useState } from 'react';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import styles from './BoardMain.css';
// Program positions are normalized from 0-1 in both dimensions. So a value of 0.05 means that the program
// must move 5% of the distance in X or Y to be considered a change and trigger events.
const MIN_POSITION_INTERVAL = 0;
const MAX_POSITION_INTERVAL = 0.5;
const POSITION_INTERVAL_STEP = 0.01;
// A delay in seconds that controls how long a program must be out of detection before calling
// any removal callbacks (onProgramRemoved, onProgramMarkersRemoved).
const MIN_REMOVAL_DELAY = 0;
const MAX_REMOVAL_DELAY = 5;
const REMOVAL_INTERVAL_STEP = 0.5;
export default function PaperLandControls( props ) {
const [ positionInterval, setPositionInterval ] = useState( props.initialPositionInterval );
const [ removalDelay, setRemovalDelay ] = useState( props.initialRemovalDelay );
const [ consoleVisible, setConsoleVisible ] = useState( true );
const [ printSpeechSynthesis, setPrintSpeechSynthesis ] = useState( false );
useEffect( () => {
const fullScreenListener = fullScreen => {
if ( props.sceneryDisplay ) {
if ( fullScreen ) {
// remove the styling that positions the board for development
props.sceneryDisplay.domElement.classList.remove( styles.simDisplayPanel );
props.sceneryDisplay.domElement.classList.remove( styles.boardPanel );
// take up the full window
props.sceneryDisplay.setWidthHeight( window.innerWidth, window.innerHeight );
phet.paperLand.displaySizeProperty.value = new phet.dot.Dimension2( window.innerWidth, window.innerHeight );
}
else {
const smallWidth = 640;
const smallHeight = 480;
// re-apply styling for development
props.sceneryDisplay.domElement.classList.add( styles.simDisplayPanel );
props.sceneryDisplay.domElement.classList.add( styles.boardPanel );
props.sceneryDisplay.setWidthHeight( smallWidth, smallHeight );
phet.paperLand.displaySizeProperty.value = new phet.dot.Dimension2( smallWidth, smallHeight );
}
}
};
phet.scenery.FullScreen.isFullScreenProperty.link( fullScreenListener );
// cleanup, removing the listener before re-render
return () => {
phet.scenery.FullScreen.isFullScreenProperty.unlink( fullScreenListener );
};
}, [ props.sceneryDisplay ] );
// Print speech synthesis to the console
useEffect( () => {
const printListener = response => {
if ( printSpeechSynthesis ) {
phet.paperLand.console.log( 'Speech', `"${response}"` );
}
};
phet.scenery.voicingManager.startSpeakingEmitter.addListener( printListener );
return () => {
phet.scenery.voicingManager.startSpeakingEmitter.removeListener( printListener );
};
}, [ printSpeechSynthesis ] );
return (
<div className={`${styles.boardPanel}`}>
<>
<>
<div>
<Form.Label>Position Interval (%):</Form.Label>
<p className={styles.inlineValue}>{positionInterval}</p>
<Form.Range
min={MIN_POSITION_INTERVAL}
max={MAX_POSITION_INTERVAL}
step={POSITION_INTERVAL_STEP}
value={positionInterval}
onChange={event => {
const newValue = event.target.value;
setPositionInterval( newValue );
props.updatePositionInterval( newValue );
}}
/>
</div>
</>
</>
<>
<div>
<Form.Label>Removal Delay (seconds):</Form.Label>
<p className={styles.inlineValue}>{removalDelay}</p>
<Form.Range
min={MIN_REMOVAL_DELAY}
max={MAX_REMOVAL_DELAY}
step={REMOVAL_INTERVAL_STEP}
value={removalDelay}
onChange={event => {
const newValue = event.target.value;
setRemovalDelay( newValue );
props.updateRemovalDelay( newValue );
}}
/>
</div>
</>
<>
<Form.Check
type='checkbox'
label='Show Console'
checked={consoleVisible}
onChange={event => {
const newValue = event.target.checked;
setConsoleVisible( newValue );
props.updateConsoleVisibility( newValue );
}}
/>
</>
<>
<Form.Check
type='checkbox'
label='Print Speech'
checked={printSpeechSynthesis}
onChange={event => {
setPrintSpeechSynthesis( event.target.checked );
}}
></Form.Check>
</>
<>
<Button
onClick={() => {
if ( props.sceneryDisplay ) {
phet.scenery.FullScreen.enterFullScreen( props.sceneryDisplay );
}
}}
>Projector Mode</Button>
</>
</div>
);
}