Skip to content

Commit 7c9e46d

Browse files
Fix modal toggle to unpause the game (#452)
And also enable modal view toggle using the same key. * Unpause the game after quitting a modal with Esc * Handle FKey event before `uiModal` event to enable toggle through Fkey
1 parent 7f4db06 commit 7c9e46d

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

src/Swarm/TUI/Controller.hs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ handleMainEvent s = \case
199199
continue s
200200
Key V.KEsc
201201
| isJust (s ^. uiState . uiError) -> continue $ s & uiState . uiError .~ Nothing
202-
| isJust (s ^. uiState . uiModal) -> continue $ s & uiState . uiModal .~ Nothing
202+
| isJust (s ^. uiState . uiModal) -> maybeUnpause s >>= (continue . (uiState . uiModal .~ Nothing))
203+
FKey 1 -> toggleModal s HelpModal >>= continue
203204
VtyEvent vev
204205
| isJust (s ^. uiState . uiModal) -> handleModalEvent s vev
205206
CharKey '\t' -> continue $ s & uiState . uiFocusRing %~ focusNext
@@ -213,7 +214,6 @@ handleMainEvent s = \case
213214
-- toggle creative mode if in "cheat mode"
214215
ControlKey 'k'
215216
| s ^. uiState . uiCheatMode -> continue (s & gameState . creativeMode %~ not)
216-
FKey 1 -> toggleModal s HelpModal >>= continue
217217
MouseDown n _ _ mouseLoc ->
218218
case n of
219219
WorldPanel -> do
@@ -262,28 +262,30 @@ mouseLocToWorldCoords gs (Brick.Location mouseLoc) = do
262262
setFocus :: AppState -> Name -> EventM Name (Next AppState)
263263
setFocus s name = continue $ s & uiState . uiFocusRing %~ focusSetCurrent name
264264

265-
toggleModal :: AppState -> ModalType -> EventM Name AppState
266-
toggleModal s mt = do
267-
curTime <- liftIO $ getTime Monotonic
268-
return $
269-
s & case s ^. uiState . uiModal of
270-
Nothing -> (uiState . uiModal ?~ generateModal s mt) . ensurePause
271-
Just _ -> (uiState . uiModal .~ Nothing) . maybeUnpause . resetLastFrameTime curTime
265+
-- | Set the game to Running if it was auto paused
266+
maybeUnpause :: AppState -> EventM Name AppState
267+
maybeUnpause s
268+
| s ^. gameState . runStatus == AutoPause = do
269+
curTime <- liftIO $ getTime Monotonic
270+
pure $ s & (gameState . runStatus .~ Running) . resetLastFrameTime curTime
271+
| otherwise = pure s
272272
where
273-
-- Set the game to AutoPause if needed
274-
ensurePause
275-
| s ^. gameState . paused = id
276-
| otherwise = gameState . runStatus .~ AutoPause
277-
-- Set the game to Running if it was auto paused
278-
maybeUnpause
279-
| s ^. gameState . runStatus == AutoPause = gameState . runStatus .~ Running
280-
| otherwise = id
281273
-- When unpausing, it is critical to ensure the next frame doesn't
282274
-- catch up from the time spent in pause.
283275
-- TODO: manage unpause more safely to also cover
284276
-- the world event handler for the KChar 'p'.
285277
resetLastFrameTime curTime = uiState . lastFrameTime .~ curTime
286278

279+
toggleModal :: AppState -> ModalType -> EventM Name AppState
280+
toggleModal s mt = case s ^. uiState . uiModal of
281+
Nothing -> pure $ s & (uiState . uiModal ?~ generateModal s mt) . ensurePause
282+
Just _ -> maybeUnpause s <&> uiState . uiModal .~ Nothing
283+
where
284+
-- Set the game to AutoPause if needed
285+
ensurePause
286+
| s ^. gameState . paused = id
287+
| otherwise = gameState . runStatus .~ AutoPause
288+
287289
handleModalEvent :: AppState -> V.Event -> EventM Name (Next AppState)
288290
handleModalEvent s = \case
289291
V.EvKey V.KEnter [] -> do

0 commit comments

Comments
 (0)