{-# LANGUAGE TemplateHaskell #-}
module Mensam.Client.UI.Menu where
import Mensam.Client.Application
import Mensam.Client.Application.Event.Class
import Mensam.Client.UI.Brick.Draw
import Mensam.Client.UI.Brick.Events
import Mensam.Client.UI.Brick.Names
import Brick
import Brick.Widgets.Border
import Brick.Widgets.Center
import Brick.Widgets.List
import Control.Monad.Trans.Class
import Data.Kind
import Data.Sequence qualified as Seq
import Graphics.Vty.Input.Events
import Lens.Micro.Platform
menuListInitial :: GenericList ClientName Seq.Seq MenuButton
=
ClientName
-> Seq MenuButton -> Int -> GenericList ClientName Seq MenuButton
forall (t :: * -> *) n e.
Foldable t =>
n -> t e -> Int -> GenericList n t e
list
ClientName
ClientNameMenuList
([MenuButton] -> Seq MenuButton
forall a. [a] -> Seq a
Seq.fromList [MenuButton
forall a. Bounded a => a
minBound .. MenuButton
forall a. Bounded a => a
maxBound])
Int
1
type MenuButton :: Type
data
=
|
|
deriving stock (MenuButton
MenuButton -> MenuButton -> Bounded MenuButton
forall a. a -> a -> Bounded a
$cminBound :: MenuButton
minBound :: MenuButton
$cmaxBound :: MenuButton
maxBound :: MenuButton
Bounded, Int -> MenuButton
MenuButton -> Int
MenuButton -> [MenuButton]
MenuButton -> MenuButton
MenuButton -> MenuButton -> [MenuButton]
MenuButton -> MenuButton -> MenuButton -> [MenuButton]
(MenuButton -> MenuButton)
-> (MenuButton -> MenuButton)
-> (Int -> MenuButton)
-> (MenuButton -> Int)
-> (MenuButton -> [MenuButton])
-> (MenuButton -> MenuButton -> [MenuButton])
-> (MenuButton -> MenuButton -> [MenuButton])
-> (MenuButton -> MenuButton -> MenuButton -> [MenuButton])
-> Enum MenuButton
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: MenuButton -> MenuButton
succ :: MenuButton -> MenuButton
$cpred :: MenuButton -> MenuButton
pred :: MenuButton -> MenuButton
$ctoEnum :: Int -> MenuButton
toEnum :: Int -> MenuButton
$cfromEnum :: MenuButton -> Int
fromEnum :: MenuButton -> Int
$cenumFrom :: MenuButton -> [MenuButton]
enumFrom :: MenuButton -> [MenuButton]
$cenumFromThen :: MenuButton -> MenuButton -> [MenuButton]
enumFromThen :: MenuButton -> MenuButton -> [MenuButton]
$cenumFromTo :: MenuButton -> MenuButton -> [MenuButton]
enumFromTo :: MenuButton -> MenuButton -> [MenuButton]
$cenumFromThenTo :: MenuButton -> MenuButton -> MenuButton -> [MenuButton]
enumFromThenTo :: MenuButton -> MenuButton -> MenuButton -> [MenuButton]
Enum, MenuButton -> MenuButton -> Bool
(MenuButton -> MenuButton -> Bool)
-> (MenuButton -> MenuButton -> Bool) -> Eq MenuButton
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MenuButton -> MenuButton -> Bool
== :: MenuButton -> MenuButton -> Bool
$c/= :: MenuButton -> MenuButton -> Bool
/= :: MenuButton -> MenuButton -> Bool
Eq, Eq MenuButton
Eq MenuButton =>
(MenuButton -> MenuButton -> Ordering)
-> (MenuButton -> MenuButton -> Bool)
-> (MenuButton -> MenuButton -> Bool)
-> (MenuButton -> MenuButton -> Bool)
-> (MenuButton -> MenuButton -> Bool)
-> (MenuButton -> MenuButton -> MenuButton)
-> (MenuButton -> MenuButton -> MenuButton)
-> Ord MenuButton
MenuButton -> MenuButton -> Bool
MenuButton -> MenuButton -> Ordering
MenuButton -> MenuButton -> MenuButton
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MenuButton -> MenuButton -> Ordering
compare :: MenuButton -> MenuButton -> Ordering
$c< :: MenuButton -> MenuButton -> Bool
< :: MenuButton -> MenuButton -> Bool
$c<= :: MenuButton -> MenuButton -> Bool
<= :: MenuButton -> MenuButton -> Bool
$c> :: MenuButton -> MenuButton -> Bool
> :: MenuButton -> MenuButton -> Bool
$c>= :: MenuButton -> MenuButton -> Bool
>= :: MenuButton -> MenuButton -> Bool
$cmax :: MenuButton -> MenuButton -> MenuButton
max :: MenuButton -> MenuButton -> MenuButton
$cmin :: MenuButton -> MenuButton -> MenuButton
min :: MenuButton -> MenuButton -> MenuButton
Ord, ReadPrec [MenuButton]
ReadPrec MenuButton
Int -> ReadS MenuButton
ReadS [MenuButton]
(Int -> ReadS MenuButton)
-> ReadS [MenuButton]
-> ReadPrec MenuButton
-> ReadPrec [MenuButton]
-> Read MenuButton
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS MenuButton
readsPrec :: Int -> ReadS MenuButton
$creadList :: ReadS [MenuButton]
readList :: ReadS [MenuButton]
$creadPrec :: ReadPrec MenuButton
readPrec :: ReadPrec MenuButton
$creadListPrec :: ReadPrec [MenuButton]
readListPrec :: ReadPrec [MenuButton]
Read, Int -> MenuButton -> ShowS
[MenuButton] -> ShowS
MenuButton -> [Char]
(Int -> MenuButton -> ShowS)
-> (MenuButton -> [Char])
-> ([MenuButton] -> ShowS)
-> Show MenuButton
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MenuButton -> ShowS
showsPrec :: Int -> MenuButton -> ShowS
$cshow :: MenuButton -> [Char]
show :: MenuButton -> [Char]
$cshowList :: [MenuButton] -> ShowS
showList :: [MenuButton] -> ShowS
Show)
type ScreenMenuState :: Type
newtype =
{ :: GenericList ClientName Seq.Seq MenuButton
}
menuDraw :: ScreenMenuState -> [Widget ClientName]
= \case
MkScreenMenuState {_screenStateMenuList :: ScreenMenuState -> GenericList ClientName Seq MenuButton
_screenStateMenuList = GenericList ClientName Seq MenuButton
genericList} ->
[ Widget ClientName -> Widget ClientName
forall n. Widget n -> Widget n
centerLayer (Widget ClientName -> Widget ClientName)
-> Widget ClientName -> Widget ClientName
forall a b. (a -> b) -> a -> b
$
Widget ClientName -> Widget ClientName -> Widget ClientName
forall n. Widget n -> Widget n -> Widget n
borderWithLabel (Text -> Widget ClientName
forall n. Text -> Widget n
txt Text
"Menu") (Widget ClientName -> Widget ClientName)
-> Widget ClientName -> Widget ClientName
forall a b. (a -> b) -> a -> b
$
Int -> Widget ClientName -> Widget ClientName
forall n. Int -> Widget n -> Widget n
hLimit Int
20 (Widget ClientName -> Widget ClientName)
-> Widget ClientName -> Widget ClientName
forall a b. (a -> b) -> a -> b
$
Int -> Widget ClientName -> Widget ClientName
forall n. Int -> Widget n -> Widget n
vLimit Int
10 (Widget ClientName -> Widget ClientName)
-> Widget ClientName -> Widget ClientName
forall a b. (a -> b) -> a -> b
$
(Bool -> MenuButton -> Widget ClientName)
-> Bool
-> GenericList ClientName Seq MenuButton
-> Widget ClientName
forall (t :: * -> *) n e.
(Traversable t, Splittable t, Ord n, Show n) =>
(Bool -> e -> Widget n) -> Bool -> GenericList n t e -> Widget n
renderList Bool -> MenuButton -> Widget ClientName
forall n. Bool -> MenuButton -> Widget n
buttonDraw Bool
True GenericList ClientName Seq MenuButton
genericList
, [Widget ClientName] -> Widget ClientName
forall n. [Widget n] -> Widget n
vBox
[ Text -> Widget ClientName
forall n. Text -> Widget n
txt Text
title
, Padding -> Widget ClientName -> Widget ClientName
forall n. Padding -> Widget n -> Widget n
padTop Padding
Max (Padding -> Widget ClientName -> Widget ClientName
forall n. Padding -> Widget n -> Widget n
padLeft Padding
Max (Text -> Widget ClientName
forall n. Text -> Widget n
txt Text
footerMenu))
]
]
where
buttonDraw :: Bool -> MenuButton -> Widget n
buttonDraw :: forall n. Bool -> MenuButton -> Widget n
buttonDraw Bool
_selected = \case
MenuButton
MkMenuButtonLogin -> Padding -> Widget n -> Widget n
forall n. Padding -> Widget n -> Widget n
padRight Padding
Max (Widget n -> Widget n) -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$ Text -> Widget n
forall n. Text -> Widget n
txt Text
"Login"
MenuButton
MkMenuButtonRegister -> Padding -> Widget n -> Widget n
forall n. Padding -> Widget n -> Widget n
padRight Padding
Max (Widget n -> Widget n) -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$ Text -> Widget n
forall n. Text -> Widget n
txt Text
"Register"
MenuButton
MkMenuButtonSpaces -> Padding -> Widget n -> Widget n
forall n. Padding -> Widget n -> Widget n
padRight Padding
Max (Widget n -> Widget n) -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$ Text -> Widget n
forall n. Text -> Widget n
txt Text
"Spaces"
menuHandleEvent :: BrickEvent ClientName ClientEvent -> ApplicationT (EventM ClientName ScreenMenuState) ()
menuHandleEvent :: BrickEvent ClientName ClientEvent
-> ApplicationT (EventM ClientName ScreenMenuState) ()
menuHandleEvent BrickEvent ClientName ClientEvent
event =
case BrickEvent ClientName ClientEvent
event of
VtyEvent (EvKey Key
KEsc []) -> do
ClientEvent -> ApplicationT (EventM ClientName ScreenMenuState) ()
forall (m :: * -> *). MonadEvent m => ClientEvent -> m ()
sendEvent ClientEvent
ClientEventExit
VtyEvent (EvKey Key
KEnter []) -> do
ScreenMenuState
s <- EventM ClientName ScreenMenuState ScreenMenuState
-> ApplicationT (EventM ClientName ScreenMenuState) ScreenMenuState
forall (m :: * -> *) a. Monad m => m a -> ApplicationT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift EventM ClientName ScreenMenuState ScreenMenuState
forall s (m :: * -> *). MonadState s m => m s
get
case GenericList ClientName Seq MenuButton -> Maybe (Int, MenuButton)
forall (t :: * -> *) e n.
(Splittable t, Traversable t, Semigroup (t e)) =>
GenericList n t e -> Maybe (Int, e)
listSelectedElement (GenericList ClientName Seq MenuButton -> Maybe (Int, MenuButton))
-> GenericList ClientName Seq MenuButton -> Maybe (Int, MenuButton)
forall a b. (a -> b) -> a -> b
$ ScreenMenuState -> GenericList ClientName Seq MenuButton
_screenStateMenuList ScreenMenuState
s of
Maybe (Int, MenuButton)
Nothing -> () -> ApplicationT (EventM ClientName ScreenMenuState) ()
forall a. a -> ApplicationT (EventM ClientName ScreenMenuState) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just (Int
_index, MenuButton
button) ->
case MenuButton
button of
MenuButton
MkMenuButtonLogin -> ClientEvent -> ApplicationT (EventM ClientName ScreenMenuState) ()
forall (m :: * -> *). MonadEvent m => ClientEvent -> m ()
sendEvent ClientEvent
ClientEventSwitchToScreenLogin
MenuButton
MkMenuButtonRegister -> ClientEvent -> ApplicationT (EventM ClientName ScreenMenuState) ()
forall (m :: * -> *). MonadEvent m => ClientEvent -> m ()
sendEvent ClientEvent
ClientEventSwitchToScreenRegister
MenuButton
MkMenuButtonSpaces -> ClientEvent -> ApplicationT (EventM ClientName ScreenMenuState) ()
forall (m :: * -> *). MonadEvent m => ClientEvent -> m ()
sendEvent ClientEvent
ClientEventSwitchToScreenSpaces
VtyEvent Event
e -> EventM ClientName ScreenMenuState ()
-> ApplicationT (EventM ClientName ScreenMenuState) ()
forall (m :: * -> *) a. Monad m => m a -> ApplicationT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (EventM ClientName ScreenMenuState ()
-> ApplicationT (EventM ClientName ScreenMenuState) ())
-> EventM ClientName ScreenMenuState ()
-> ApplicationT (EventM ClientName ScreenMenuState) ()
forall a b. (a -> b) -> a -> b
$ LensLike'
(Zoomed
(EventM ClientName (GenericList ClientName Seq MenuButton)) ())
ScreenMenuState
(GenericList ClientName Seq MenuButton)
-> EventM ClientName (GenericList ClientName Seq MenuButton) ()
-> EventM ClientName ScreenMenuState ()
forall c.
LensLike'
(Zoomed
(EventM ClientName (GenericList ClientName Seq MenuButton)) c)
ScreenMenuState
(GenericList ClientName Seq MenuButton)
-> EventM ClientName (GenericList ClientName Seq MenuButton) c
-> EventM ClientName ScreenMenuState c
forall (m :: * -> *) (n :: * -> *) s t c.
Zoom m n s t =>
LensLike' (Zoomed m c) t s -> m c -> n c
zoom (GenericList ClientName Seq MenuButton
-> Focusing
(StateT (EventState ClientName) IO)
()
(GenericList ClientName Seq MenuButton))
-> ScreenMenuState
-> Focusing (StateT (EventState ClientName) IO) () ScreenMenuState
LensLike'
(Zoomed
(EventM ClientName (GenericList ClientName Seq MenuButton)) ())
ScreenMenuState
(GenericList ClientName Seq MenuButton)
Lens' ScreenMenuState (GenericList ClientName Seq MenuButton)
screenStateMenuList (EventM ClientName (GenericList ClientName Seq MenuButton) ()
-> EventM ClientName ScreenMenuState ())
-> EventM ClientName (GenericList ClientName Seq MenuButton) ()
-> EventM ClientName ScreenMenuState ()
forall a b. (a -> b) -> a -> b
$ Event
-> EventM ClientName (GenericList ClientName Seq MenuButton) ()
forall (t :: * -> *) n e.
(Foldable t, Splittable t, Ord n) =>
Event -> EventM n (GenericList n t e) ()
handleListEvent Event
e
BrickEvent ClientName ClientEvent
_ -> () -> ApplicationT (EventM ClientName ScreenMenuState) ()
forall a. a -> ApplicationT (EventM ClientName ScreenMenuState) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()