1
1
mirror of https://github.com/Yvee1/hascard.git synced 2024-11-25 20:33:34 +03:00

Fix menu navigation

This commit is contained in:
Steven van den Broek 2020-08-03 08:39:59 +02:00
parent f2f7b73f09
commit 388f84316e
10 changed files with 41 additions and 31 deletions

View File

@ -78,5 +78,5 @@ run opts = run' (opts ^. optFile)
start (Just result) (mkGlobalState gen) start (Just result) (mkGlobalState gen)
start :: Maybe [Card] -> GlobalState -> IO () start :: Maybe [Card] -> GlobalState -> IO ()
start Nothing gs = runBrickFlashcards (runMainMenuUI gs) start Nothing gs = runBrickFlashcards (gs `goToState` mainMenuState)
start (Just cards) gs = runBrickFlashcards =<< runCardsWithOptions gs cards start (Just cards) gs = runBrickFlashcards =<< (gs `goToState`) <$> cardsWithOptionsState gs cards

View File

@ -9,16 +9,16 @@ import qualified Brick.Widgets.List as L
import qualified Data.Vector as Vec import qualified Data.Vector as Vec
import qualified Stack as S import qualified Stack as S
runCardSelectorUI :: GlobalState -> IO GlobalState cardSelectorState :: IO State
runCardSelectorUI gs = do cardSelectorState = do
rs <- getRecents rs <- getRecents
let prettyRecents = shortenFilepaths (S.toList rs) let prettyRecents = shortenFilepaths (S.toList rs)
let options = Vec.fromList (prettyRecents ++ ["Select file from system"]) let options = Vec.fromList (prettyRecents ++ ["Select file from system"])
let initialState = CSS (L.list () options 1) Nothing rs let initialState = CSS (L.list () options 1) Nothing rs
return $ gs `goToState` CardSelectorState initialState return $ CardSelectorState initialState
runMainMenuUI :: GlobalState -> GlobalState mainMenuState :: State
runMainMenuUI gs = mainMenuState =
let options = Vec.fromList let options = Vec.fromList
[ "Select" [ "Select"
, "Info" , "Info"
@ -26,10 +26,10 @@ runMainMenuUI gs =
, "Quit" ] , "Quit" ]
initialState = MMS (L.list () options 1) in initialState = MMS (L.list () options 1) in
gs `goToState` MainMenuState initialState MainMenuState initialState
runCardsUI :: GlobalState -> [Card] -> IO GlobalState cardsState :: [Card] -> IO State
runCardsUI gs deck = do cardsState deck = do
hints <- getShowHints hints <- getShowHints
controls <- getShowControls controls <- getShowControls
@ -42,24 +42,24 @@ runCardsUI gs deck = do
, _showHints = hints , _showHints = hints
, _showControls = controls } , _showControls = controls }
return $ gs `goToState` CardsState initialState return $ CardsState initialState
runCardsWithOptions :: GlobalState -> [Card] -> IO GlobalState cardsWithOptionsState :: GlobalState -> [Card] -> IO State
runCardsWithOptions state cards = doRandomization state cards >>= runCardsUI state cardsWithOptionsState gs cards = doRandomization gs cards >>= cardsState
runSettingsUI :: GlobalState -> IO GlobalState settingsState :: IO State
runSettingsUI gs = do settingsState = do
currentSettings <- getSettings currentSettings <- getSettings
return $ gs `goToState` SettingsState (0, currentSettings) return $ SettingsState (0, currentSettings)
runInfoUI :: GlobalState -> GlobalState infoState :: State
runInfoUI = (`goToState` InfoState ()) infoState = InfoState ()
runFileBrowserUI :: GlobalState -> IO GlobalState fileBrowserState :: IO State
runFileBrowserUI gs = do fileBrowserState = do
browser <- newFileBrowser selectNonDirectories () Nothing browser <- newFileBrowser selectNonDirectories () Nothing
let filteredBrowser = setFileBrowserEntryFilter (Just (entryFilter False)) browser let filteredBrowser = setFileBrowserEntryFilter (Just (entryFilter False)) browser
return $ gs `goToState` FileBrowserState (FBS filteredBrowser Nothing [] Nothing False) return $ FileBrowserState (FBS filteredBrowser Nothing [] Nothing False)
entryFilter :: Bool -> FileInfo -> Bool entryFilter :: Bool -> FileInfo -> Bool
entryFilter acceptHidden info = fileExtensionMatch "txt" info && (acceptHidden || entryFilter acceptHidden info = fileExtensionMatch "txt" info && (acceptHidden ||

View File

@ -174,6 +174,9 @@ goToState :: GlobalState -> State -> GlobalState
goToState gs s = gs & states %~ M.insert (getMode s) s goToState gs s = gs & states %~ M.insert (getMode s) s
& stack %~ insert (getMode s) & stack %~ insert (getMode s)
moveToState :: GlobalState -> State -> GlobalState
moveToState gs = goToState (popState gs)
popState :: GlobalState -> GlobalState popState :: GlobalState -> GlobalState
popState gs = let popState gs = let
s = gs ^. stack s = gs ^. stack
@ -190,3 +193,7 @@ safeGetState gs = do
goToModeOrQuit :: GlobalState -> Mode -> EventM n (Next GlobalState) goToModeOrQuit :: GlobalState -> Mode -> EventM n (Next GlobalState)
goToModeOrQuit gs mode = goToModeOrQuit gs mode =
maybe (halt gs) (continue . goToState gs) $ M.lookup mode (gs ^. states) maybe (halt gs) (continue . goToState gs) $ M.lookup mode (gs ^. states)
moveToModeOrQuit :: GlobalState -> Mode -> EventM n (Next GlobalState)
moveToModeOrQuit gs mode =
maybe (halt gs) (continue . moveToState gs) $ M.lookup mode (gs ^. states)

View File

@ -1,4 +1,4 @@
module UI (module X, runBrickFlashcards, GlobalState(..), Card) where module UI (module X, runBrickFlashcards, GlobalState(..), Card, goToState) where
import UI.CardSelector as X (addRecent) import UI.CardSelector as X (addRecent)
import Settings as X (getUseEscapeCode) import Settings as X (getUseEscapeCode)

View File

@ -81,7 +81,8 @@ handleEvent gs s@CSS{_list=l, _exception=exc} (VtyEvent ev) =
V.EvKey V.KEnter [] -> V.EvKey V.KEnter [] ->
case L.listSelectedElement l' of case L.listSelectedElement l' of
Nothing -> continue' s' Nothing -> continue' s'
Just (_, "Select file from system") -> continue =<< liftIO (runFileBrowserUI (update s')) Just (_, "Select file from system") ->
let gs' = update s' in continue =<< (gs' `goToState`) <$> liftIO fileBrowserState
Just (i, _) -> do Just (i, _) -> do
let fp = (s' ^. recents) `S.unsafeElemAt` i let fp = (s' ^. recents) `S.unsafeElemAt` i
fileOrExc <- liftIO (try (readFile fp) :: IO (Either IOError String)) fileOrExc <- liftIO (try (readFile fp) :: IO (Either IOError String))
@ -91,7 +92,8 @@ handleEvent gs s@CSS{_list=l, _exception=exc} (VtyEvent ev) =
Left parseError -> continue' (s' & exception ?~ errorBundlePretty parseError) Left parseError -> continue' (s' & exception ?~ errorBundlePretty parseError)
Right result -> continue =<< liftIO (do Right result -> continue =<< liftIO (do
s'' <- addRecentInternal s' fp s'' <- addRecentInternal s' fp
runCardsWithOptions (update s'') result) let gs' = update s''
(gs' `goToState`) <$> cardsWithOptionsState gs' result)
_ -> continue' s' _ -> continue' s'
handleEvent gs _ _ = continue gs handleEvent gs _ _ = continue gs

View File

@ -244,7 +244,7 @@ handleEvent :: GlobalState -> CS -> BrickEvent Name Event -> EventM Name (Next G
handleEvent gs s (VtyEvent e) = handleEvent gs s (VtyEvent e) =
let update = updateCS gs let update = updateCS gs
continue' = continue . update continue' = continue . update
halt' = flip goToModeOrQuit CardSelector in halt' = flip moveToModeOrQuit CardSelector in
case e of case e of
V.EvKey V.KEsc [] -> halt' gs V.EvKey V.KEsc [] -> halt' gs
V.EvKey (V.KChar 'c') [V.MCtrl] -> halt' gs V.EvKey (V.KChar 'c') [V.MCtrl] -> halt' gs

View File

@ -79,7 +79,8 @@ handleEvent gs s@FBS{_fb=b, _exception'=excep} (VtyEvent ev) =
-- Right result -> halt' (s' & parsedCards .~ result & filePath ?~ fp) -- Right result -> halt' (s' & parsedCards .~ result & filePath ?~ fp)
Right result -> continue =<< liftIO (do Right result -> continue =<< liftIO (do
addRecent fp addRecent fp
runCardsWithOptions (update s') result) let gs' = update s'
(gs' `moveToState`) <$> cardsWithOptionsState (update s') result)
_ -> halt' gs _ -> halt' gs
_ -> continue' s' _ -> continue' s'

View File

@ -52,4 +52,4 @@ drawInfo =
info :: String info :: String
info = info =
"Hascard is a text-based user interface for reviewing notes using 'flashcards'. Cards are written in markdown-like syntax; for more info see the README file. Use the --help flag for information on the command line options.\n\nControls:\n * Use arrows or the j and k keys for menu navigation\n * Enter confirms a selection, flips a card or continues to the next card\n * Use TAB or the arrow keys for navigating gaps in open questions\n * Use the c key for confirming reorder questions or multiple choice questions with more than 1 possible answer\n * Use F1 to show the answers of a open question.\n * Use CTRL+Left and CTRL+Right to move to previous and next cards without having to answer them" "Hascard is a text-based user interface for reviewing notes using 'flashcards'. Cards are written in markdown-like syntax; for more info see the README file. Use the --help flag for information on the command line options.\n\nControls:\n * Use arrows or the j and k keys for menu navigation\n\n * Enter confirms a selection, flips a card or continues to the next card\n\n * Use TAB or the arrow keys for navigating gaps in open questions\n\n * Use the c key for confirming reorder questions or multiple choice questions with more than 1 possible answer\n\n * Use F1 to show the answers of a open question.\n\n * Use CTRL+Left and CTRL+Right to move to previous and next cards without having to answer them"

View File

@ -50,9 +50,9 @@ handleEvent gs s (VtyEvent e) =
V.EvKey V.KEsc [] -> halt gs V.EvKey V.KEsc [] -> halt gs
V.EvKey V.KEnter [] -> V.EvKey V.KEnter [] ->
case L.listSelected (s^.l) of case L.listSelected (s^.l) of
Just 0 -> continue =<< liftIO (runCardSelectorUI gs) Just 0 -> continue =<< (gs `goToState`) <$> liftIO cardSelectorState
Just 1 -> continue $ runInfoUI gs Just 1 -> continue $ gs `goToState` infoState
Just 2 -> continue =<< liftIO (runSettingsUI gs) Just 2 -> continue =<< (gs `goToState`) <$> liftIO settingsState
Just 3 -> halt gs Just 3 -> halt gs
_ -> undefined _ -> undefined

View File

@ -63,6 +63,6 @@ drawSettings s = vBox $ map (drawSetting s) (zip [0..] descriptions)
drawSetting :: SS -> (Int, String) -> Widget Name drawSetting :: SS -> (Int, String) -> Widget Name
drawSetting (selected, settings) (i, text) = drawSetting (selected, settings) (i, text) =
strWrap text <+> str " " <+> word (strWrap text <+> str " " <+> word) <=> str " "
where word = if settings ! i then underline (str "Yes") else underline (str "No") <+> str " " where word = if settings ! i then underline (str "Yes") else underline (str "No") <+> str " "
underline = if i == selected then withAttr selectedAttr else id underline = if i == selected then withAttr selectedAttr else id