{-# LANGUAGE NamedFieldPuns #-}
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(Options)
import FortyTwo.Utils
import FortyTwo.Constants
loop :: Options -> IO (Maybe Int)
loop :: Options -> IO (Maybe Int)
loop Options
options = do
IO ()
noEcho
Options -> IO ()
renderOptions Options
options
String
key <- IO String
getKey
Int -> IO ()
clearLines (Int -> IO ()) -> Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Options -> Int
getOptionsLines Options
options
Maybe Int
res <- Options -> String -> IO (Maybe Int)
handleEvent Options
options String
key
IO ()
restoreEcho
Maybe Int -> IO (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Int
res
handleEvent :: Options -> String -> IO (Maybe Int)
handleEvent :: Options -> String -> IO (Maybe Int)
handleEvent Options
options String
key
| String
key String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
upKey, String
leftKey] = Options -> IO (Maybe Int)
loop (Options -> IO (Maybe Int)) -> Options -> IO (Maybe Int)
forall a b. (a -> b) -> a -> b
$ Options -> (Int, Int, Maybe Int) -> Options
moveUp Options
options ((Int, Int, Maybe Int) -> Options)
-> (Int, Int, Maybe Int) -> Options
forall a b. (a -> b) -> a -> b
$ Options -> (Int, Int, Maybe Int)
getOptionsMeta Options
options
| String
key String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
downKey, String
rightKey] = Options -> IO (Maybe Int)
loop (Options -> IO (Maybe Int)) -> Options -> IO (Maybe Int)
forall a b. (a -> b) -> a -> b
$ Options -> (Int, Int, Maybe Int) -> Options
moveDown Options
options ((Int, Int, Maybe Int) -> Options)
-> (Int, Int, Maybe Int) -> Options
forall a b. (a -> b) -> a -> b
$ Options -> (Int, Int, Maybe Int)
getOptionsMeta Options
options
| String
key String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
enterKey, String
spaceKey] = Maybe Int -> IO (Maybe Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> IO (Maybe Int)) -> Maybe Int -> IO (Maybe Int)
forall a b. (a -> b) -> a -> b
$ Options -> Maybe Int
getFocusedOptionIndex Options
options
| Bool
otherwise = Options -> IO (Maybe Int)
loop Options
options
moveUp :: Options -> (Int, Int, Maybe Int) -> Options
moveUp :: Options -> (Int, Int, Maybe Int) -> Options
moveUp Options
options (Int
minVal, Int
maxVal, Maybe Int
focusedIndex) = case Maybe Int
focusedIndex of
Just Int
x -> if Int
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
minVal then
Int -> Options -> Options
focusOption Int
x Options
options
else
Int -> Options -> Options
focusOption (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Options
options
Maybe Int
Nothing -> Int -> Options -> Options
focusOption Int
maxVal Options
options
moveDown :: Options -> (Int, Int, Maybe Int) -> Options
moveDown :: Options -> (Int, Int, Maybe Int) -> Options
moveDown Options
options (Int
minVal, Int
maxVal, Maybe Int
focusedIndex) = case Maybe Int
focusedIndex of
Just Int
x -> if Int
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
maxVal then
Int -> Options -> Options
focusOption Int
x Options
options
else
Int -> Options -> Options
focusOption (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Options
options
Maybe Int
Nothing -> Int -> Options -> Options
focusOption Int
minVal Options
options
selectWithDefault :: String -> [String] -> String -> IO String
selectWithDefault :: String -> [String] -> String -> IO String
selectWithDefault String
question [String]
options String
defaultAnswer = do
String -> IO ()
putStrLn String
emptyString
String -> String -> String -> IO ()
renderQuestion String
question String
defaultAnswer String
emptyString
String -> IO ()
putStrLn String
emptyString
IO ()
hideCursor
IO ()
flush
IO ()
noBuffering
Maybe Int
res <- Options -> IO (Maybe Int)
loop (Options -> IO (Maybe Int)) -> Options -> IO (Maybe Int)
forall a b. (a -> b) -> a -> b
$ [String] -> Options
stringsToOptions [String]
options
IO ()
restoreBuffering
IO ()
showCursor
Int -> IO ()
clearLines Int
1
case Maybe Int
res of
Just Int
x -> do
let answer :: String
answer = [String] -> Int -> String
forall a. [a] -> Int -> a
(!!) [String]
options Int
x
String -> String -> String -> IO ()
renderQuestion String
question String
emptyString String
answer
String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
answer
Maybe Int
Nothing -> do
String -> String -> String -> IO ()
renderQuestion String
question String
emptyString String
defaultAnswer
String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
defaultAnswer
select :: String -> [String] -> IO String
select :: String -> [String] -> IO String
select String
question [String]
options = String -> [String] -> String -> IO String
selectWithDefault String
question [String]
options String
emptyString