{-# LANGUAGE CPP               #-}
{-# LANGUAGE DataKinds         #-}
{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE RankNTypes        #-}
{-# OPTIONS_GHC -Wno-unused-record-wildcards #-}
{-# OPTIONS_GHC -Wno-unused-matches #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}

{-
This module defines the brick App. The pattern is very simple:

- Pattern match on the Mode
- Dispatch drawing/events to the corresponding widget/s

In general each widget should know how to draw itself and how to handle its own events, so this
module should only contain:

- how to draw non-widget information. For example the footer
- how to change between modes (widgets aren't aware of the whole application state)

-}

module GHCup.Brick.App where

import qualified GHCup.Brick.Actions as Actions
import qualified GHCup.Brick.Attributes as Attributes
import GHCup.Brick.BrickState (BrickState (..), advanceInstallMenu, appKeys, appSettings, appState, contextMenu, mode, compileGHCMenu, compileHLSMenu)
import GHCup.Brick.Common (Mode (..), Name (..))
import qualified GHCup.Brick.Common as Common
import qualified GHCup.Brick.Widgets.KeyInfo as KeyInfo
import qualified GHCup.Brick.Widgets.Menus.Context as ContextMenu
import qualified GHCup.Brick.Widgets.Navigation as Navigation
import qualified GHCup.Brick.Widgets.Tutorial as Tutorial
import qualified GHCup.Brick.Widgets.Menu as Menu
import qualified GHCup.Brick.Widgets.Menus.AdvanceInstall as AdvanceInstall

import GHCup.List (ListResult)
import GHCup.Types (AppState (AppState, keyBindings), KeyCombination (KeyCombination), KeyBindings (..))

import qualified Brick.Focus as F
import Brick (
  App (..),
  AttrMap,
  BrickEvent (VtyEvent),
  EventM,
  Widget (..),
  (<=>),
 )
import qualified Brick
import Control.Monad.Reader (
  MonadIO (liftIO), ReaderT,
 )
import Data.IORef (readIORef)
import Data.List (find, intercalate)
import Prelude hiding (appendFile)

import qualified Graphics.Vty as Vty

import qualified Data.Text as T

import Optics (Lens')
import Optics.Getter (to)
import Optics.Operators ((^.))
import Optics.Optic ((%))
import Optics.State (use)
import Optics.State.Operators ((.=))
import qualified GHCup.Brick.Widgets.Menus.CompileGHC as CompileGHC
import qualified GHCup.Brick.Widgets.Menus.CompileHLS as CompileHLS
import Control.Monad (void, when)

app :: AttrMap -> AttrMap -> App BrickState () Name
app :: AttrMap -> AttrMap -> App BrickState () Name
app AttrMap
attrs AttrMap
dimAttrs =
  App { appDraw :: BrickState -> [Widget Name]
appDraw         = AttrMap -> BrickState -> [Widget Name]
drawUI AttrMap
dimAttrs
      , appHandleEvent :: BrickEvent Name () -> EventM Name BrickState ()
appHandleEvent  = BrickEvent Name () -> EventM Name BrickState ()
forall e. BrickEvent Name e -> EventM Name BrickState ()
eventHandler
      , appStartEvent :: EventM Name BrickState ()
appStartEvent   = EventM Name BrickState ()
setupVtyMode
      , appAttrMap :: BrickState -> AttrMap
appAttrMap      = AttrMap -> BrickState -> AttrMap
forall a b. a -> b -> a
const AttrMap
attrs
      , appChooseCursor :: BrickState -> [CursorLocation Name] -> Maybe (CursorLocation Name)
appChooseCursor = BrickState -> [CursorLocation Name] -> Maybe (CursorLocation Name)
forall s n. s -> [CursorLocation n] -> Maybe (CursorLocation n)
Brick.showFirstCursor
      }

-- | Enable mouse mode if supported by the terminal
setupVtyMode :: EventM Name BrickState ()
setupVtyMode :: EventM Name BrickState ()
setupVtyMode = do
  Vty
vty <- EventM Name BrickState Vty
forall n s. EventM n s Vty
Brick.getVtyHandle
  let output :: Output
output = Vty -> Output
Vty.outputIface Vty
vty
  Bool -> EventM Name BrickState () -> EventM Name BrickState ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Output -> Mode -> Bool
Vty.supportsMode Output
output Mode
Vty.Mouse) (EventM Name BrickState () -> EventM Name BrickState ())
-> EventM Name BrickState () -> EventM Name BrickState ()
forall a b. (a -> b) -> a -> b
$
      IO () -> EventM Name BrickState ()
forall a. IO a -> EventM Name BrickState a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> EventM Name BrickState ())
-> IO () -> EventM Name BrickState ()
forall a b. (a -> b) -> a -> b
$ Output -> Mode -> Bool -> IO ()
Vty.setMode Output
output Mode
Vty.Mouse Bool
True

drawUI :: AttrMap -> BrickState -> [Widget Name]
drawUI :: AttrMap -> BrickState -> [Widget Name]
drawUI AttrMap
dimAttrs BrickState
st =
  let
    footer :: Widget n
footer = AttrName -> Widget n -> Widget n
forall n. AttrName -> Widget n -> Widget n
Brick.withAttr AttrName
Attributes.helpAttr
      (Widget n -> Widget n)
-> ([(KeyCombination, BrickSettings -> String,
      EventM Name BrickState ())]
    -> Widget n)
-> [(KeyCombination, BrickSettings -> String,
     EventM Name BrickState ())]
-> Widget n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Widget n
forall n. Text -> Widget n
Brick.txtWrap
      (Text -> Widget n)
-> ([(KeyCombination, BrickSettings -> String,
      EventM Name BrickState ())]
    -> Text)
-> [(KeyCombination, BrickSettings -> String,
     EventM Name BrickState ())]
-> Widget n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
      (String -> Text)
-> ([(KeyCombination, BrickSettings -> String,
      EventM Name BrickState ())]
    -> String)
-> [(KeyCombination, BrickSettings -> String,
     EventM Name BrickState ())]
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> String) -> [String] -> String
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (\String
x String
y -> String
x String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"  " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
y)
      ([String] -> String)
-> ([(KeyCombination, BrickSettings -> String,
      EventM Name BrickState ())]
    -> [String])
-> [(KeyCombination, BrickSettings -> String,
     EventM Name BrickState ())]
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((KeyCombination, BrickSettings -> String,
  EventM Name BrickState ())
 -> String)
-> [(KeyCombination, BrickSettings -> String,
     EventM Name BrickState ())]
-> [String]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(KeyCombination Key
key [Modifier]
mods, BrickSettings -> String
pretty_setting, EventM Name BrickState ()
_)
                  -> String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"+" (Key -> String
Common.showKey Key
key String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (Modifier -> String
Common.showMod (Modifier -> String) -> [Modifier] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Modifier]
mods)) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
":" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> BrickSettings -> String
pretty_setting (BrickState
st BrickState
-> Optic' A_Lens NoIx BrickState BrickSettings -> BrickSettings
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx BrickState BrickSettings
appSettings)
             )
      ([(KeyCombination, BrickSettings -> String,
   EventM Name BrickState ())]
 -> Widget n)
-> [(KeyCombination, BrickSettings -> String,
     EventM Name BrickState ())]
-> Widget n
forall a b. (a -> b) -> a -> b
$ KeyBindings
-> [(KeyCombination, BrickSettings -> String,
     EventM Name BrickState ())]
Actions.keyHandlers (BrickState
st BrickState
-> Optic' A_Lens NoIx BrickState KeyBindings -> KeyBindings
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx BrickState KeyBindings
appKeys)
    navg :: Widget Name
navg = AttrMap -> BrickInternalState -> Widget Name
Navigation.draw AttrMap
dimAttrs (BrickState
st BrickState
-> Optic' A_Lens NoIx BrickState BrickInternalState
-> BrickInternalState
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx BrickState BrickInternalState
appState) Widget Name -> Widget Name -> Widget Name
forall n. Widget n -> Widget n -> Widget n
<=> Widget Name
forall {n}. Widget n
footer
  in case BrickState
st BrickState -> Optic' A_Lens NoIx BrickState Mode -> Mode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx BrickState Mode
mode of
       Mode
Navigation   -> [Widget Name
navg]
       Mode
Tutorial     -> [KeyCombination -> Widget Name
Tutorial.draw (KeyBindings -> KeyCombination
bQuit (KeyBindings -> KeyCombination) -> KeyBindings -> KeyCombination
forall a b. (a -> b) -> a -> b
$ BrickState
st BrickState
-> Optic' A_Lens NoIx BrickState KeyBindings -> KeyBindings
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx BrickState KeyBindings
appKeys), Widget Name
navg]
       Mode
KeyInfo      -> [KeyBindings -> Widget Name
KeyInfo.draw (BrickState
st BrickState
-> Optic' A_Lens NoIx BrickState KeyBindings -> KeyBindings
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx BrickState KeyBindings
appKeys), Widget Name
navg]
       Mode
ContextPanel -> [ContextMenu -> Widget Name
ContextMenu.draw (BrickState
st BrickState
-> Optic' A_Lens NoIx BrickState ContextMenu -> ContextMenu
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx BrickState ContextMenu
contextMenu), Widget Name
navg]
       Mode
AdvanceInstallPanel -> AdvanceInstallMenu -> [Widget Name]
AdvanceInstall.draw (BrickState
st BrickState
-> Optic' A_Lens NoIx BrickState AdvanceInstallMenu
-> AdvanceInstallMenu
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx BrickState AdvanceInstallMenu
advanceInstallMenu) [Widget Name] -> [Widget Name] -> [Widget Name]
forall a. [a] -> [a] -> [a]
++ [Widget Name
navg]
       Mode
CompileGHCPanel     -> CompileGHCMenu -> [Widget Name]
CompileGHC.draw (BrickState
st BrickState
-> Optic' A_Lens NoIx BrickState CompileGHCMenu -> CompileGHCMenu
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx BrickState CompileGHCMenu
compileGHCMenu) [Widget Name] -> [Widget Name] -> [Widget Name]
forall a. [a] -> [a] -> [a]
++ [Widget Name
navg]
       Mode
CompileHLSPanel     -> CompileHLSMenu -> [Widget Name]
CompileHLS.draw (BrickState
st BrickState
-> Optic' A_Lens NoIx BrickState CompileHLSMenu -> CompileHLSMenu
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx BrickState CompileHLSMenu
compileHLSMenu) [Widget Name] -> [Widget Name] -> [Widget Name]
forall a. [a] -> [a] -> [a]
++ [Widget Name
navg]

-- | On q, go back to navigation.
--   On Enter, to go to tutorial
keyInfoHandler :: BrickEvent Name e -> EventM Name BrickState ()
keyInfoHandler :: forall e. BrickEvent Name e -> EventM Name BrickState ()
keyInfoHandler BrickEvent Name e
ev = do
  AppState { keyBindings :: AppState -> KeyBindings
keyBindings = KeyBindings
kb } <- IO AppState -> EventM Name BrickState AppState
forall a. IO a -> EventM Name BrickState a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO AppState -> EventM Name BrickState AppState)
-> IO AppState -> EventM Name BrickState AppState
forall a b. (a -> b) -> a -> b
$ IORef AppState -> IO AppState
forall a. IORef a -> IO a
readIORef IORef AppState
Actions.settings'
  case BrickEvent Name e
ev of
    VtyEvent (Vty.EvKey Key
Vty.KEnter [Modifier]
_ )   -> Optic' A_Lens NoIx BrickState Mode
mode Optic' A_Lens NoIx BrickState Mode
-> Mode -> EventM Name BrickState ()
forall k s (m :: * -> *) (is :: IxList) a b.
(Is k A_Setter, MonadState s m) =>
Optic k is s s a b -> b -> m ()
.= Mode
Tutorial
    VtyEvent (Vty.EvKey Key
key [Modifier]
mods)
      | KeyBindings -> KeyCombination
bQuit KeyBindings
kb KeyCombination -> KeyCombination -> Bool
forall a. Eq a => a -> a -> Bool
== Key -> [Modifier] -> KeyCombination
KeyCombination Key
key [Modifier]
mods -> Optic' A_Lens NoIx BrickState Mode
mode Optic' A_Lens NoIx BrickState Mode
-> Mode -> EventM Name BrickState ()
forall k s (m :: * -> *) (is :: IxList) a b.
(Is k A_Setter, MonadState s m) =>
Optic k is s s a b -> b -> m ()
.= Mode
Navigation
    BrickEvent Name e
_ -> () -> EventM Name BrickState ()
forall a. a -> EventM Name BrickState a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

-- | On q, go back to navigation. Else, do nothing
tutorialHandler :: BrickEvent Name e -> EventM Name BrickState ()
tutorialHandler :: forall e. BrickEvent Name e -> EventM Name BrickState ()
tutorialHandler BrickEvent Name e
ev = do
  AppState { keyBindings :: AppState -> KeyBindings
keyBindings = KeyBindings
kb } <- IO AppState -> EventM Name BrickState AppState
forall a. IO a -> EventM Name BrickState a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO AppState -> EventM Name BrickState AppState)
-> IO AppState -> EventM Name BrickState AppState
forall a b. (a -> b) -> a -> b
$ IORef AppState -> IO AppState
forall a. IORef a -> IO a
readIORef IORef AppState
Actions.settings'
  case BrickEvent Name e
ev of
    VtyEvent (Vty.EvKey Key
key [Modifier]
mods)
      | KeyBindings -> KeyCombination
bQuit KeyBindings
kb KeyCombination -> KeyCombination -> Bool
forall a. Eq a => a -> a -> Bool
== Key -> [Modifier] -> KeyCombination
KeyCombination Key
key [Modifier]
mods -> Optic' A_Lens NoIx BrickState Mode
mode Optic' A_Lens NoIx BrickState Mode
-> Mode -> EventM Name BrickState ()
forall k s (m :: * -> *) (is :: IxList) a b.
(Is k A_Setter, MonadState s m) =>
Optic k is s s a b -> b -> m ()
.= Mode
Navigation
    BrickEvent Name e
_ -> () -> EventM Name BrickState ()
forall a. a -> EventM Name BrickState a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

-- | Tab/Arrows to navigate.
navigationHandler :: BrickEvent Name e -> EventM Name BrickState ()
navigationHandler :: forall e. BrickEvent Name e -> EventM Name BrickState ()
navigationHandler BrickEvent Name e
ev = do
  AppState { keyBindings :: AppState -> KeyBindings
keyBindings = KeyBindings
kb } <- IO AppState -> EventM Name BrickState AppState
forall a. IO a -> EventM Name BrickState a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO AppState -> EventM Name BrickState AppState)
-> IO AppState -> EventM Name BrickState AppState
forall a b. (a -> b) -> a -> b
$ IORef AppState -> IO AppState
forall a. IORef a -> IO a
readIORef IORef AppState
Actions.settings'
  case BrickEvent Name e
ev of
    inner_event :: BrickEvent Name e
inner_event@(VtyEvent (Vty.EvKey Key
key [Modifier]
mods)) ->
      case ((KeyCombination, BrickSettings -> String,
  EventM Name BrickState ())
 -> Bool)
-> [(KeyCombination, BrickSettings -> String,
     EventM Name BrickState ())]
-> Maybe
     (KeyCombination, BrickSettings -> String,
      EventM Name BrickState ())
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\(KeyCombination
key', BrickSettings -> String
_, EventM Name BrickState ()
_) -> KeyCombination
key' KeyCombination -> KeyCombination -> Bool
forall a. Eq a => a -> a -> Bool
== Key -> [Modifier] -> KeyCombination
KeyCombination Key
key [Modifier]
mods) (KeyBindings
-> [(KeyCombination, BrickSettings -> String,
     EventM Name BrickState ())]
Actions.keyHandlers KeyBindings
kb) of
        Just (KeyCombination
_, BrickSettings -> String
_, EventM Name BrickState ()
handler) -> EventM Name BrickState ()
handler
        Maybe
  (KeyCombination, BrickSettings -> String,
   EventM Name BrickState ())
Nothing -> EventM Name BrickState () -> EventM Name BrickState ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (EventM Name BrickState () -> EventM Name BrickState ())
-> EventM Name BrickState () -> EventM Name BrickState ()
forall a b. (a -> b) -> a -> b
$ Optic' A_Lens NoIx BrickState BrickInternalState
-> EventM Name BrickInternalState () -> EventM Name BrickState ()
forall {m :: * -> *} {n :: * -> *} {s} {t} {k} {c} {is :: IxList}.
(Zoom m n s t, Is k A_Lens, Functor (Zoomed m c)) =>
Optic k is t t s s -> m c -> n c
Common.zoom Optic' A_Lens NoIx BrickState BrickInternalState
appState (EventM Name BrickInternalState () -> EventM Name BrickState ())
-> EventM Name BrickInternalState () -> EventM Name BrickState ()
forall a b. (a -> b) -> a -> b
$ BrickEvent Name e -> EventM Name BrickInternalState ()
forall e. BrickEvent Name e -> EventM Name BrickInternalState ()
Navigation.handler BrickEvent Name e
inner_event
    BrickEvent Name e
inner_event -> Optic' A_Lens NoIx BrickState BrickInternalState
-> EventM Name BrickInternalState () -> EventM Name BrickState ()
forall {m :: * -> *} {n :: * -> *} {s} {t} {k} {c} {is :: IxList}.
(Zoom m n s t, Is k A_Lens, Functor (Zoomed m c)) =>
Optic k is t t s s -> m c -> n c
Common.zoom Optic' A_Lens NoIx BrickState BrickInternalState
appState (EventM Name BrickInternalState () -> EventM Name BrickState ())
-> EventM Name BrickInternalState () -> EventM Name BrickState ()
forall a b. (a -> b) -> a -> b
$ BrickEvent Name e -> EventM Name BrickInternalState ()
forall e. BrickEvent Name e -> EventM Name BrickInternalState ()
Navigation.handler BrickEvent Name e
inner_event

contextMenuHandler :: BrickEvent Name e -> EventM Name BrickState ()
contextMenuHandler :: forall e. BrickEvent Name e -> EventM Name BrickState ()
contextMenuHandler BrickEvent Name e
ev = do
  ContextMenu
ctx <- Optic' A_Lens NoIx BrickState ContextMenu
-> EventM Name BrickState ContextMenu
forall k s (m :: * -> *) (is :: IxList) a.
(Is k A_Getter, MonadState s m) =>
Optic' k is s a -> m a
use Optic' A_Lens NoIx BrickState ContextMenu
contextMenu
  let focusedElement :: Maybe Name
focusedElement = ContextMenu
ctx ContextMenu
-> Optic' A_Getter NoIx ContextMenu (Maybe Name) -> Maybe Name
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Lens' ContextMenu (FocusRing Name)
forall s n. Lens' (Menu s n) (FocusRing n)
Menu.menuFocusRingL Lens' ContextMenu (FocusRing Name)
-> Optic
     A_Getter
     NoIx
     (FocusRing Name)
     (FocusRing Name)
     (Maybe Name)
     (Maybe Name)
-> Optic' A_Getter NoIx ContextMenu (Maybe Name)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% (FocusRing Name -> Maybe Name)
-> Optic
     A_Getter
     NoIx
     (FocusRing Name)
     (FocusRing Name)
     (Maybe Name)
     (Maybe Name)
forall s a. (s -> a) -> Getter s a
to FocusRing Name -> Maybe Name
forall n. FocusRing n -> Maybe n
F.focusGetCurrent
      (KeyCombination Key
exitKey [Modifier]
mods) = ContextMenu
ctx ContextMenu
-> Optic' A_Lens NoIx ContextMenu KeyCombination -> KeyCombination
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Lens' ContextMenu MenuKeyBindings
forall s n. Lens' (Menu s n) MenuKeyBindings
Menu.menuKeyBindingsL Lens' ContextMenu MenuKeyBindings
-> Optic
     A_Lens
     NoIx
     MenuKeyBindings
     MenuKeyBindings
     KeyCombination
     KeyCombination
-> Optic' A_Lens NoIx ContextMenu KeyCombination
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Lens
  NoIx
  MenuKeyBindings
  MenuKeyBindings
  KeyCombination
  KeyCombination
Menu.mKbQuitL
  case (BrickEvent Name e
ev, Maybe Name
focusedElement) of
    (BrickEvent Name e
_ , Maybe Name
Nothing) -> () -> EventM Name BrickState ()
forall a. a -> EventM Name BrickState a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    (VtyEvent (Vty.EvKey Key
k [Modifier]
m), Just Name
n) |  Key
k Key -> Key -> Bool
forall a. Eq a => a -> a -> Bool
== Key
exitKey Bool -> Bool -> Bool
&& [Modifier]
m [Modifier] -> [Modifier] -> Bool
forall a. Eq a => a -> a -> Bool
== [Modifier]
mods -> Optic' A_Lens NoIx BrickState Mode
mode Optic' A_Lens NoIx BrickState Mode
-> Mode -> EventM Name BrickState ()
forall k s (m :: * -> *) (is :: IxList) a b.
(Is k A_Setter, MonadState s m) =>
Optic k is s s a b -> b -> m ()
.= Mode
Navigation
    (VtyEvent (Vty.EvKey Key
Vty.KEnter []),  Just (Common.MenuElement ResourceId
Common.AdvanceInstallButton) ) -> Optic' A_Lens NoIx BrickState Mode
mode Optic' A_Lens NoIx BrickState Mode
-> Mode -> EventM Name BrickState ()
forall k s (m :: * -> *) (is :: IxList) a b.
(Is k A_Setter, MonadState s m) =>
Optic k is s s a b -> b -> m ()
.= Mode
Common.AdvanceInstallPanel
    (VtyEvent (Vty.EvKey Key
Vty.KEnter []),  Just (Common.MenuElement ResourceId
Common.CompileGHCButton) ) -> Optic' A_Lens NoIx BrickState Mode
mode Optic' A_Lens NoIx BrickState Mode
-> Mode -> EventM Name BrickState ()
forall k s (m :: * -> *) (is :: IxList) a b.
(Is k A_Setter, MonadState s m) =>
Optic k is s s a b -> b -> m ()
.= Mode
Common.CompileGHCPanel
    (VtyEvent (Vty.EvKey Key
Vty.KEnter []),  Just (Common.MenuElement ResourceId
Common.CompileHLSButton) ) -> Optic' A_Lens NoIx BrickState Mode
mode Optic' A_Lens NoIx BrickState Mode
-> Mode -> EventM Name BrickState ()
forall k s (m :: * -> *) (is :: IxList) a b.
(Is k A_Setter, MonadState s m) =>
Optic k is s s a b -> b -> m ()
.= Mode
Common.CompileHLSPanel
    (BrickEvent Name e, Maybe Name)
_ -> Optic' A_Lens NoIx BrickState ContextMenu
-> EventM Name ContextMenu () -> EventM Name BrickState ()
forall {m :: * -> *} {n :: * -> *} {s} {t} {k} {c} {is :: IxList}.
(Zoom m n s t, Is k A_Lens, Functor (Zoomed m c)) =>
Optic k is t t s s -> m c -> n c
Common.zoom Optic' A_Lens NoIx BrickState ContextMenu
contextMenu (EventM Name ContextMenu () -> EventM Name BrickState ())
-> EventM Name ContextMenu () -> EventM Name BrickState ()
forall a b. (a -> b) -> a -> b
$ BrickEvent Name e -> EventM Name ContextMenu ()
forall e. BrickEvent Name e -> EventM Name ContextMenu ()
ContextMenu.handler BrickEvent Name e
ev
--
advanceInstallHandler :: BrickEvent Name e -> EventM Name BrickState ()
advanceInstallHandler :: forall e. BrickEvent Name e -> EventM Name BrickState ()
advanceInstallHandler = Optic' A_Lens NoIx BrickState AdvanceInstallMenu
-> (InstallOptions
    -> (Int, ListResult) -> ReaderT AppState IO (Either String ()))
-> (BrickEvent Name e -> EventM Name AdvanceInstallMenu ())
-> BrickEvent Name e
-> EventM Name BrickState ()
forall t a e.
Lens' BrickState (Menu t Name)
-> (t
    -> (Int, ListResult) -> ReaderT AppState IO (Either String a))
-> (BrickEvent Name e -> EventM Name (Menu t Name) ())
-> BrickEvent Name e
-> EventM Name BrickState ()
menuWithOverlayHandler Optic' A_Lens NoIx BrickState AdvanceInstallMenu
advanceInstallMenu InstallOptions
-> (Int, ListResult) -> ReaderT AppState IO (Either String ())
forall (m :: * -> *).
(MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m,
 MonadMask m, MonadUnliftIO m, Alternative m) =>
InstallOptions -> (Int, ListResult) -> m (Either String ())
Actions.installWithOptions BrickEvent Name e -> EventM Name AdvanceInstallMenu ()
forall e. BrickEvent Name e -> EventM Name AdvanceInstallMenu ()
AdvanceInstall.handler

compileGHCHandler :: BrickEvent Name e -> EventM Name BrickState ()
compileGHCHandler :: forall e. BrickEvent Name e -> EventM Name BrickState ()
compileGHCHandler = Optic' A_Lens NoIx BrickState CompileGHCMenu
-> (CompileGHCOptions
    -> (Int, ListResult) -> ReaderT AppState IO (Either String ()))
-> (BrickEvent Name e -> EventM Name CompileGHCMenu ())
-> BrickEvent Name e
-> EventM Name BrickState ()
forall t a e.
Lens' BrickState (Menu t Name)
-> (t
    -> (Int, ListResult) -> ReaderT AppState IO (Either String a))
-> (BrickEvent Name e -> EventM Name (Menu t Name) ())
-> BrickEvent Name e
-> EventM Name BrickState ()
menuWithOverlayHandler Optic' A_Lens NoIx BrickState CompileGHCMenu
compileGHCMenu CompileGHCOptions
-> (Int, ListResult) -> ReaderT AppState IO (Either String ())
forall (m :: * -> *).
(MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m,
 MonadMask m, MonadUnliftIO m, Alternative m) =>
CompileGHCOptions -> (Int, ListResult) -> m (Either String ())
Actions.compileGHC BrickEvent Name e -> EventM Name CompileGHCMenu ()
forall e. BrickEvent Name e -> EventM Name CompileGHCMenu ()
CompileGHC.handler

compileHLSHandler :: BrickEvent Name e -> EventM Name BrickState ()
compileHLSHandler :: forall e. BrickEvent Name e -> EventM Name BrickState ()
compileHLSHandler = Optic' A_Lens NoIx BrickState CompileHLSMenu
-> (CompileHLSOptions
    -> (Int, ListResult) -> ReaderT AppState IO (Either String ()))
-> (BrickEvent Name e -> EventM Name CompileHLSMenu ())
-> BrickEvent Name e
-> EventM Name BrickState ()
forall t a e.
Lens' BrickState (Menu t Name)
-> (t
    -> (Int, ListResult) -> ReaderT AppState IO (Either String a))
-> (BrickEvent Name e -> EventM Name (Menu t Name) ())
-> BrickEvent Name e
-> EventM Name BrickState ()
menuWithOverlayHandler Optic' A_Lens NoIx BrickState CompileHLSMenu
compileHLSMenu CompileHLSOptions
-> (Int, ListResult) -> ReaderT AppState IO (Either String ())
forall (m :: * -> *).
(MonadReader AppState m, MonadIO m, MonadThrow m, MonadFail m,
 MonadMask m, MonadUnliftIO m, Alternative m) =>
CompileHLSOptions -> (Int, ListResult) -> m (Either String ())
Actions.compileHLS BrickEvent Name e -> EventM Name CompileHLSMenu ()
forall e. BrickEvent Name e -> EventM Name CompileHLSMenu ()
CompileHLS.handler

-- | Passes all events to innerHandler if an overlay is opened
-- else handles the exitKey and Enter key for the Menu's "OkButton"
menuWithOverlayHandler :: Lens' BrickState (Menu.Menu t Name)
  -> (t -> ((Int, ListResult) -> ReaderT AppState IO (Either String a)))
  -> (BrickEvent Name e -> EventM Name (Menu.Menu t Name) ())
  -> BrickEvent Name e
  -> EventM Name BrickState ()
menuWithOverlayHandler :: forall t a e.
Lens' BrickState (Menu t Name)
-> (t
    -> (Int, ListResult) -> ReaderT AppState IO (Either String a))
-> (BrickEvent Name e -> EventM Name (Menu t Name) ())
-> BrickEvent Name e
-> EventM Name BrickState ()
menuWithOverlayHandler Lens' BrickState (Menu t Name)
accessor t -> (Int, ListResult) -> ReaderT AppState IO (Either String a)
action BrickEvent Name e -> EventM Name (Menu t Name) ()
innerHandler BrickEvent Name e
ev = do
  Menu t Name
ctx <- Lens' BrickState (Menu t Name)
-> EventM Name BrickState (Menu t Name)
forall k s (m :: * -> *) (is :: IxList) a.
(Is k A_Getter, MonadState s m) =>
Optic' k is s a -> m a
use Lens' BrickState (Menu t Name)
accessor
  let focusedElement :: Maybe Name
focusedElement = Menu t Name
ctx Menu t Name
-> Optic' A_Getter NoIx (Menu t Name) (Maybe Name) -> Maybe Name
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Lens' (Menu t Name) (FocusRing Name)
forall s n. Lens' (Menu s n) (FocusRing n)
Menu.menuFocusRingL Lens' (Menu t Name) (FocusRing Name)
-> Optic
     A_Getter
     NoIx
     (FocusRing Name)
     (FocusRing Name)
     (Maybe Name)
     (Maybe Name)
-> Optic' A_Getter NoIx (Menu t Name) (Maybe Name)
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% (FocusRing Name -> Maybe Name)
-> Optic
     A_Getter
     NoIx
     (FocusRing Name)
     (FocusRing Name)
     (Maybe Name)
     (Maybe Name)
forall s a. (s -> a) -> Getter s a
to FocusRing Name -> Maybe Name
forall n. FocusRing n -> Maybe n
F.focusGetCurrent
      focusedField :: Maybe (MenuField t Name)
focusedField = (\Name
n -> (MenuField t Name -> Bool)
-> [MenuField t Name] -> Maybe (MenuField t Name)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\MenuField t Name
x -> MenuField t Name -> Name
forall a n. Named a n => a -> n
Brick.getName MenuField t Name
x Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
n) ([MenuField t Name] -> Maybe (MenuField t Name))
-> [MenuField t Name] -> Maybe (MenuField t Name)
forall a b. (a -> b) -> a -> b
$ Menu t Name
ctx Menu t Name
-> Optic' A_Lens NoIx (Menu t Name) [MenuField t Name]
-> [MenuField t Name]
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx (Menu t Name) [MenuField t Name]
forall s n. Lens' (Menu s n) [MenuField s n]
Menu.menuFieldsL) (Name -> Maybe (MenuField t Name))
-> Maybe Name -> Maybe (MenuField t Name)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe Name
focusedElement
      (KeyCombination Key
exitKey [Modifier]
mods) = Menu t Name
ctx Menu t Name
-> Optic' A_Lens NoIx (Menu t Name) KeyCombination
-> KeyCombination
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Lens' (Menu t Name) MenuKeyBindings
forall s n. Lens' (Menu s n) MenuKeyBindings
Menu.menuKeyBindingsL Lens' (Menu t Name) MenuKeyBindings
-> Optic
     A_Lens
     NoIx
     MenuKeyBindings
     MenuKeyBindings
     KeyCombination
     KeyCombination
-> Optic' A_Lens NoIx (Menu t Name) KeyCombination
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Lens
  NoIx
  MenuKeyBindings
  MenuKeyBindings
  KeyCombination
  KeyCombination
Menu.mKbQuitL
  case (BrickEvent Name e
ev, Maybe Name
focusedElement, MenuField t Name -> Maybe (Widget Name)
forall s n. MenuField s n -> Maybe (Widget n)
Menu.drawFieldOverlay (MenuField t Name -> Maybe (Widget Name))
-> Maybe (MenuField t Name) -> Maybe (Widget Name)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe (MenuField t Name)
focusedField) of
    (BrickEvent Name e
_ , Maybe Name
Nothing, Maybe (Widget Name)
_) -> () -> EventM Name BrickState ()
forall a. a -> EventM Name BrickState a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    (BrickEvent Name e
_ , Maybe Name
_, Just Widget Name
_) -> Lens' BrickState (Menu t Name)
-> EventM Name (Menu t Name) () -> EventM Name BrickState ()
forall {m :: * -> *} {n :: * -> *} {s} {t} {k} {c} {is :: IxList}.
(Zoom m n s t, Is k A_Lens, Functor (Zoomed m c)) =>
Optic k is t t s s -> m c -> n c
Common.zoom Lens' BrickState (Menu t Name)
accessor (EventM Name (Menu t Name) () -> EventM Name BrickState ())
-> EventM Name (Menu t Name) () -> EventM Name BrickState ()
forall a b. (a -> b) -> a -> b
$ BrickEvent Name e -> EventM Name (Menu t Name) ()
innerHandler BrickEvent Name e
ev
    (VtyEvent (Vty.EvKey Key
k [Modifier]
m), Just Name
n, Maybe (Widget Name)
_) | Key
k Key -> Key -> Bool
forall a. Eq a => a -> a -> Bool
== Key
exitKey Bool -> Bool -> Bool
&& [Modifier]
m [Modifier] -> [Modifier] -> Bool
forall a. Eq a => a -> a -> Bool
== [Modifier]
mods -> Optic' A_Lens NoIx BrickState Mode
mode Optic' A_Lens NoIx BrickState Mode
-> Mode -> EventM Name BrickState ()
forall k s (m :: * -> *) (is :: IxList) a b.
(Is k A_Setter, MonadState s m) =>
Optic k is s s a b -> b -> m ()
.= Mode
ContextPanel
    (VtyEvent (Vty.EvKey Key
Vty.KEnter []), Just (MenuElement ResourceId
Common.OkButton), Maybe (Widget Name)
_) -> do
        let iopts :: t
iopts = Menu t Name
ctx Menu t Name -> Optic' A_Lens NoIx (Menu t Name) t -> t
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx (Menu t Name) t
forall s n. Lens' (Menu s n) s
Menu.menuStateL
        Bool -> EventM Name BrickState () -> EventM Name BrickState ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Menu t Name -> Bool
forall s n. Menu s n -> Bool
Menu.isValidMenu Menu t Name
ctx)
          (((Int, ListResult) -> ReaderT AppState IO (Either String a))
-> EventM Name BrickState ()
forall n a.
(Ord n, Eq n) =>
((Int, ListResult) -> ReaderT AppState IO (Either String a))
-> EventM n BrickState ()
Actions.withIOAction (((Int, ListResult) -> ReaderT AppState IO (Either String a))
 -> EventM Name BrickState ())
-> ((Int, ListResult) -> ReaderT AppState IO (Either String a))
-> EventM Name BrickState ()
forall a b. (a -> b) -> a -> b
$ t -> (Int, ListResult) -> ReaderT AppState IO (Either String a)
action t
iopts)
    (BrickEvent Name e, Maybe Name, Maybe (Widget Name))
_ -> Lens' BrickState (Menu t Name)
-> EventM Name (Menu t Name) () -> EventM Name BrickState ()
forall {m :: * -> *} {n :: * -> *} {s} {t} {k} {c} {is :: IxList}.
(Zoom m n s t, Is k A_Lens, Functor (Zoomed m c)) =>
Optic k is t t s s -> m c -> n c
Common.zoom Lens' BrickState (Menu t Name)
accessor (EventM Name (Menu t Name) () -> EventM Name BrickState ())
-> EventM Name (Menu t Name) () -> EventM Name BrickState ()
forall a b. (a -> b) -> a -> b
$ BrickEvent Name e -> EventM Name (Menu t Name) ()
innerHandler BrickEvent Name e
ev

eventHandler :: BrickEvent Name e -> EventM Name BrickState ()
eventHandler :: forall e. BrickEvent Name e -> EventM Name BrickState ()
eventHandler BrickEvent Name e
ev = do
  Mode
m <- Optic' A_Lens NoIx BrickState Mode -> EventM Name BrickState Mode
forall k s (m :: * -> *) (is :: IxList) a.
(Is k A_Getter, MonadState s m) =>
Optic' k is s a -> m a
use Optic' A_Lens NoIx BrickState Mode
mode
  case Mode
m of
    Mode
KeyInfo      -> BrickEvent Name e -> EventM Name BrickState ()
forall e. BrickEvent Name e -> EventM Name BrickState ()
keyInfoHandler BrickEvent Name e
ev
    Mode
Tutorial     -> BrickEvent Name e -> EventM Name BrickState ()
forall e. BrickEvent Name e -> EventM Name BrickState ()
tutorialHandler BrickEvent Name e
ev
    Mode
Navigation   -> BrickEvent Name e -> EventM Name BrickState ()
forall e. BrickEvent Name e -> EventM Name BrickState ()
navigationHandler BrickEvent Name e
ev
    Mode
ContextPanel -> BrickEvent Name e -> EventM Name BrickState ()
forall e. BrickEvent Name e -> EventM Name BrickState ()
contextMenuHandler BrickEvent Name e
ev
    Mode
AdvanceInstallPanel -> BrickEvent Name e -> EventM Name BrickState ()
forall e. BrickEvent Name e -> EventM Name BrickState ()
advanceInstallHandler BrickEvent Name e
ev
    Mode
CompileGHCPanel     -> BrickEvent Name e -> EventM Name BrickState ()
forall e. BrickEvent Name e -> EventM Name BrickState ()
compileGHCHandler BrickEvent Name e
ev
    Mode
CompileHLSPanel     -> BrickEvent Name e -> EventM Name BrickState ()
forall e. BrickEvent Name e -> EventM Name BrickState ()
compileHLSHandler BrickEvent Name e
ev