module FortyTwo.Prompts.Multiselect (multiselect, multiselectWithDefault) where
import System.Console.ANSI (hideCursor, showCursor)
import FortyTwo.Renderers.Multiselect (renderOptions)
import FortyTwo.Renderers.Question (renderQuestion)
import FortyTwo.Types(Option(..), Options)
import FortyTwo.Utils
import FortyTwo.Constants
loop :: Options -> IO [Int]
loop options = do
noEcho
renderOptions options
key <- getKey
clearLines $ length options
res <- handleEvent options key
restoreEcho
return res
handleEvent :: Options -> String -> IO [Int]
handleEvent options key
| key `elem` [upKey, leftKey] = loop $ moveUp options $ getOptionsMeta options
| key `elem` [downKey, rightKey] = loop $ moveDown options $ getOptionsMeta options
| key == spaceKey = loop $ toggle options $ getOptionsMeta options
| key == enterKey = return $ getSelecteOptionsIndexes options
| otherwise = loop options
toggle :: Options -> (Int, Int, Maybe Int) -> Options
toggle options (minVal, maxVal, focusedIndex) = case focusedIndex of
Just x -> toggleFocusedOption x options
Nothing -> 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
multiselectWithDefault :: String -> [String] -> [String] -> IO [String]
multiselectWithDefault question options defaultAnswer = do
putStrLn emptyString
renderQuestion question (toCommaSeparatedString defaultAnswer) emptyString
putStrLn emptyString
hideCursor
flush
noBuffering
res <- loop $ stringsToOptions options
restoreBuffering
showCursor
clearLines 1
if null res then do
renderQuestion question emptyString (toCommaSeparatedString defaultAnswer)
return defaultAnswer
else do
let answer = filter' (\ i o -> elem i res) options
renderQuestion question emptyString (toCommaSeparatedString answer)
return answer
multiselect :: String -> [String] -> IO [String]
multiselect question options = multiselectWithDefault question options []