{-# LANGUAGE RecursiveDo #-}
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad
import Data.Maybe
import Graphics.UI.Threepenny.Core
import Graphics.UI.Threepenny.Editors
import Graphics.UI.Threepenny.Elements
main :: IO ()
main = startGUI defaultConfig setup
data LegalStatus
= Single
| Married
| Divorced
| Widowed
deriving (Bounded, Enum, Eq, Ord, Show)
data Education
= Basic_
| Intermediate_
| Other_ String
deriving (Eq, Ord, Read, Show)
getOther :: Education -> Maybe String
getOther (Other_ s) = Just s
getOther _ = Nothing
data EducationTag = Basic | Intermediate | Other deriving (Eq,Ord,Show)
data Person = Person
{ education :: Education
, firstName, lastName :: String
, age :: Int
, brexiteer :: Bool
, status :: Maybe LegalStatus
}
deriving Show
instance Editable Education where
editor b = do
basicEditor <- fmap (const Basic_) <$> editor (pure ())
intermediateEditor <- fmap (const Intermediate_) <$> editor (pure ())
otherEditor <- fmap Other_ <$> editor (fromMaybe "" . getOther <$> b)
let selector x =
case x of
Basic_ -> Basic
Intermediate_ -> Intermediate
Other_ _ -> Other
editorSum
[ (Basic, basicEditor)
, (Intermediate, intermediateEditor)
, (Other, otherEditor)
]
selector
b
instance Editable Person where
editor b =
fmap (\fn ln a e ls b -> Person e fn ln a b ls)
<$> string "First:" *| editor (firstName <$> b)
-*- string "Last:" *| editor (lastName <$> b)
-*- string "Age:" *| editor (age <$> b)
-*- string "Education:" *| editor (education <$> b)
-*- string "Status" *| editorEnumBounded(pure(string.show)) (status <$> b)
-*- string "Brexiter" *| editor (brexiteer <$> b)
setup :: Window -> UI ()
setup w = void $ mdo
_ <- return w # set title "Threepenny editors example"
person1 :: Editor Person <- editor person1B
person1B <- stepper (Person Basic_ "" "" 0 False Nothing) (edited person1)
getBody w #+ [grid
[ [return $ editorElement person1]
, [sink text (show <$> contents person1) p]
]]