@@ -33,16 +33,20 @@ const DetectingFace = () => {
3333 const setFaceDetectionAutoContinue = useGlobalState ( ( state ) => state . setFaceDetectionAutoContinue )
3434 // Get icon image for move to mouth
3535 let moveToMouthImage = MOVING_STATE_ICON_DICT [ MEAL_STATE . R_MovingToMouth ]
36+ let moveToRestingImage = MOVING_STATE_ICON_DICT [ MEAL_STATE . R_MovingToRestingPosition ]
37+ let moveAbovePlateImage = MOVING_STATE_ICON_DICT [ MEAL_STATE . R_MovingAbovePlate ]
3638 // Flag to check if the current orientation is portrait
3739 const isPortrait = useMediaQuery ( { query : '(orientation: portrait)' } )
3840 // Indicator of how to arrange screen elements based on orientation
3941 let dimension = isPortrait ? 'column' : 'row'
42+ let otherDimension = isPortrait ? 'row' : 'column'
4043 // Font size for text
41- let textFontSize = isPortrait ? '3vh' : '3vw'
42- let buttonWidth = isPortrait ? '30vh' : '30vw'
43- let buttonHeight = isPortrait ? '20vh' : '20vw'
44- let iconWidth = isPortrait ? '28vh' : '28vw'
45- let iconHeight = isPortrait ? '18vh' : '18vw'
44+ let textFontSize = 3
45+ let buttonWidth = 30
46+ let buttonHeight = 20
47+ let iconWidth = 28
48+ let iconHeight = 18
49+ let sizeSuffix = isPortrait ? 'vh' : 'vw'
4650 // The min and max distance from the camera to the face for the face to be
4751 // conidered valid. NOTE: This must match the values in the MoveToMouth tree.
4852 const min_face_distance = 0.4
@@ -70,6 +74,26 @@ const DetectingFace = () => {
7074 setMouthDetected ( false )
7175 } , [ setMealState , setMouthDetected ] )
7276
77+ /**
78+ * Callback function for proceeding to move to the resting position.
79+ */
80+ const moveToRestingCallback = useCallback ( ( ) => {
81+ console . log ( 'Transitioning to R_MovingToRestingPosition' )
82+ setMealState ( MEAL_STATE . R_MovingToRestingPosition )
83+ // Set mouth detected to false for the next time this screen comes up
84+ setMouthDetected ( false )
85+ } , [ setMealState , setMouthDetected ] )
86+
87+ /**
88+ * Callback function for proceeding to move above the plate.
89+ */
90+ const moveAbovePlateCallback = useCallback ( ( ) => {
91+ console . log ( 'Transitioning to R_MovingAbovePlate' )
92+ setMealState ( MEAL_STATE . R_MovingAbovePlate )
93+ // Set mouth detected to false for the next time this screen comes up
94+ setMouthDetected ( false )
95+ } , [ setMealState , setMouthDetected ] )
96+
7397 /**
7498 * Subscribe to the ROS Topic with the face detection result. This is created
7599 * in local state to avoid re-creating it upon every re-render.
@@ -157,7 +181,7 @@ const DetectingFace = () => {
157181 width : '100%'
158182 } }
159183 >
160- < p className = 'transitionMessage' style = { { marginBottom : '0px' , fontSize : textFontSize } } >
184+ < p className = 'transitionMessage' style = { { marginBottom : '0px' , fontSize : textFontSize . toString ( ) + sizeSuffix } } >
161185 < input
162186 name = 'faceDetectionAutoContinue'
163187 type = 'checkbox'
@@ -176,7 +200,7 @@ const DetectingFace = () => {
176200 width : '100%'
177201 } }
178202 >
179- < View style = { { flex : 1 , alignItems : 'center' , justifyContent : 'center' , width : '100%' , height : '100%' } } >
203+ < View style = { { flex : 5 , alignItems : 'center' , justifyContent : 'center' , width : '100%' , height : '100%' } } >
180204 < View
181205 style = { {
182206 flex : 1 ,
@@ -186,7 +210,7 @@ const DetectingFace = () => {
186210 height : '100%'
187211 } }
188212 >
189- < p className = 'transitionMessage' style = { { marginBottom : '0px' , fontSize : textFontSize } } >
213+ < p className = 'transitionMessage' style = { { marginBottom : '0px' , fontSize : textFontSize . toString ( ) + sizeSuffix } } >
190214 { mouthDetected ? 'Mouth detected!' : 'Waiting to detect mouth...' }
191215 </ p >
192216 </ View >
@@ -209,33 +233,113 @@ const DetectingFace = () => {
209233 />
210234 </ View >
211235 </ View >
212- < View style = { { flex : 1 , alignItems : 'center' , justifyContent : 'center' , width : '100%' , height : '100%' } } >
213- < p className = 'transitionMessage' style = { { marginBottom : '0px' , fontSize : textFontSize } } >
214- { mouthDetected ? 'Continue' : 'Continue without detecting mouth ' }
236+ < View style = { { flex : 3 , alignItems : 'center' , justifyContent : 'center' , width : '100%' , height : '100%' } } >
237+ < p className = 'transitionMessage' style = { { marginBottom : '0px' , fontSize : textFontSize . toString ( ) + sizeSuffix } } >
238+ { mouthDetected ? 'Continue' : 'Continue without detection ' }
215239 </ p >
216240 { /* Icon to move to mouth position */ }
217241 < Button
218242 variant = 'success'
219243 className = 'mx-2 mb-2 btn-huge'
220244 size = 'lg'
221245 onClick = { moveToMouthCallback }
222- style = { { width : buttonWidth , height : buttonHeight } }
246+ style = { {
247+ width : buttonWidth . toString ( ) + sizeSuffix ,
248+ height : buttonHeight . toString ( ) + sizeSuffix ,
249+ display : 'flex' ,
250+ justifyContent : 'center' ,
251+ alignContent : 'center'
252+ } }
223253 >
224- < img src = { moveToMouthImage } alt = 'move_to_mouth_image' className = 'center' style = { { width : iconWidth , height : iconHeight } } />
254+ < img
255+ src = { moveToMouthImage }
256+ alt = 'move_to_mouth_image'
257+ className = 'center'
258+ style = { { width : iconWidth . toString ( ) + sizeSuffix , height : iconHeight . toString ( ) + sizeSuffix } }
259+ />
225260 </ Button >
226261 </ View >
262+ < View
263+ style = { {
264+ flex : 2 ,
265+ flexDirection : otherDimension ,
266+ alignItems : 'center' ,
267+ justifyContent : 'center' ,
268+ width : '100%' ,
269+ height : '100%'
270+ } }
271+ >
272+ < View style = { { flex : 1 , alignItems : 'center' , justifyContent : 'center' , width : '100%' , height : '100%' } } >
273+ < p className = 'transitionMessage' style = { { marginBottom : '0px' , fontSize : ( textFontSize * 0.66 ) . toString ( ) + sizeSuffix } } >
274+ Move to Resting
275+ </ p >
276+ { /* Icon to move to mouth position */ }
277+ < Button
278+ variant = 'warning'
279+ className = 'mx-2 mb-2 btn-huge'
280+ size = 'lg'
281+ onClick = { moveToRestingCallback }
282+ style = { {
283+ width : ( buttonWidth / 2 ) . toString ( ) + sizeSuffix ,
284+ height : ( buttonHeight / 2 ) . toString ( ) + sizeSuffix ,
285+ display : 'flex' ,
286+ justifyContent : 'center' ,
287+ alignContent : 'center'
288+ } }
289+ >
290+ < img
291+ src = { moveToRestingImage }
292+ alt = 'move_to_resting_image'
293+ className = 'center'
294+ style = { { width : ( iconWidth / 2 ) . toString ( ) + sizeSuffix , height : ( iconHeight / 2 ) . toString ( ) + sizeSuffix } }
295+ />
296+ </ Button >
297+ </ View >
298+ < View style = { { flex : 1 , alignItems : 'center' , justifyContent : 'center' , width : '100%' , height : '100%' } } >
299+ < p className = 'transitionMessage' style = { { marginBottom : '0px' , fontSize : ( textFontSize * 0.66 ) . toString ( ) + sizeSuffix } } >
300+ Move Above Plate
301+ </ p >
302+ { /* Icon to move to mouth position */ }
303+ < Button
304+ variant = 'warning'
305+ className = 'mx-2 mb-2 btn-huge'
306+ size = 'lg'
307+ onClick = { moveAbovePlateCallback }
308+ style = { {
309+ width : ( buttonWidth / 2 ) . toString ( ) + sizeSuffix ,
310+ height : ( buttonHeight / 2 ) . toString ( ) + sizeSuffix ,
311+ display : 'flex' ,
312+ justifyContent : 'center' ,
313+ alignContent : 'center'
314+ } }
315+ >
316+ < img
317+ src = { moveAbovePlateImage }
318+ alt = 'move_above_plate_image'
319+ className = 'center'
320+ style = { { width : ( iconWidth / 2 ) . toString ( ) + sizeSuffix , height : ( iconHeight / 2 ) . toString ( ) + sizeSuffix } }
321+ />
322+ </ Button >
323+ </ View >
324+ </ View >
227325 </ View >
228326 </ >
229327 )
230328 } , [
231329 dimension ,
330+ otherDimension ,
232331 margin ,
233332 mouthDetected ,
234333 moveToMouthCallback ,
334+ moveToRestingCallback ,
335+ moveAbovePlateCallback ,
235336 moveToMouthImage ,
337+ moveToRestingImage ,
338+ moveAbovePlateImage ,
236339 textFontSize ,
237340 buttonHeight ,
238341 buttonWidth ,
342+ sizeSuffix ,
239343 iconHeight ,
240344 iconWidth ,
241345 faceDetectionAutoContinue ,
0 commit comments