module FortyTwo.Prompts.Select (select, selectWithDefault) where
import System.Console.ANSI (hideCursor, showCursor)
import FortyTwo.Renderers.Select (renderOptions)
import FortyTwo.Renderers.Question (renderQuestion)
import FortyTwo.Types(Option(..), Options)
import FortyTwo.Utils
import FortyTwo.Constants
loop :: Options -> IO (Maybe Int)
loop options = do
noEcho
renderOptions options
key <- getKey
clearLines $ length options
res <- handleEvent options key
restoreEcho
return res
handleEvent :: Options -> String -> IO (Maybe Int)
handleEvent options key
| key `elem` [upKey, leftKey] = loop $ moveUp options $ getOptionsMeta options
| key `elem` [downKey, rightKey] = loop $ moveDown options $ getOptionsMeta options
| key `elem` [enterKey, spaceKey] = return $ getFocusedOptionIndex options
| otherwise = loop options
moveUp :: Options -> (Int, Int, Maybe Int) -> Options
moveUp options (minVal, maxVal, focusedIndex) = case focusedIndex of
Just x -> if x == minVal then
focusOption x options
else
focusOption (x 1) options
Nothing -> focusOption maxVal options
moveDown :: Options -> (Int, Int, Maybe Int) -> Options
moveDown options (minVal, maxVal, focusedIndex) = case focusedIndex of
Just x -> if x == maxVal then
focusOption x options
else
focusOption (x + 1) options
Nothing -> focusOption minVal options
selectWithDefault :: String -> [String] -> String -> IO String
selectWithDefault question options defaultAnswer = do
putStrLn emptyString
renderQuestion question defaultAnswer emptyString
putStrLn emptyString
hideCursor
flush
noBuffering
res <- loop $ stringsToOptions options
restoreBuffering
showCursor
clearLines 1
case res of
Just x -> do
let answer = (!!) options x
renderQuestion question emptyString answer
return answer
Nothing -> do
renderQuestion question emptyString defaultAnswer
return defaultAnswer
select :: String -> [String] -> IO String
select question options = selectWithDefault question options emptyString