mirror of
https://github.com/jtdaugherty/brick.git
synced 2024-11-22 23:15:59 +03:00
Remove appLiftVtyEvent in favor of library event type BrickEvent
This change makes it possible for brick to extent the event space using its own event notions in addition those provided by Vty and the application itself. This means we no longer need the user to provide the type and appLiftVtyEvent went away. This makes pattern-matching in event handlers a little noisier with the benefit that we can now add events like mouse clicks or drags to the event type.
This commit is contained in:
parent
831092e1bd
commit
fc8cfe3b4a
@ -3,7 +3,7 @@ module Main where
|
||||
|
||||
import Data.Monoid
|
||||
import Graphics.Vty
|
||||
( Event, Attr, white, blue, cyan, green, red, yellow
|
||||
( Attr, white, blue, cyan, green, red, yellow
|
||||
, black
|
||||
)
|
||||
|
||||
@ -20,7 +20,7 @@ import Brick.Widgets.Core
|
||||
import Brick.Util (on, fg)
|
||||
import Brick.AttrMap (attrMap, AttrMap)
|
||||
|
||||
ui :: Widget ()
|
||||
ui :: Widget n
|
||||
ui =
|
||||
vBox [ str "This text uses the global default attribute."
|
||||
, withAttr "foundFull" $
|
||||
@ -51,14 +51,13 @@ theMap = attrMap globalDefault
|
||||
, ("general" <> "specific", fg cyan)
|
||||
]
|
||||
|
||||
app :: App () Event ()
|
||||
app :: App () e ()
|
||||
app =
|
||||
App { appDraw = const [ui]
|
||||
, appHandleEvent = resizeOrQuit
|
||||
, appStartEvent = return
|
||||
, appAttrMap = const theMap
|
||||
, appChooseCursor = neverShowCursor
|
||||
, appLiftVtyEvent = id
|
||||
}
|
||||
|
||||
main :: IO ()
|
||||
|
@ -14,6 +14,7 @@ import qualified Brick.Main as M
|
||||
import qualified Brick.Widgets.Center as C
|
||||
import Brick.Types
|
||||
( Widget
|
||||
, BrickEvent(..)
|
||||
)
|
||||
import Brick.Widgets.Core
|
||||
( vBox
|
||||
@ -57,22 +58,21 @@ drawUi i = [ui]
|
||||
, str "'Esc' to quit."
|
||||
]
|
||||
|
||||
appEvent :: Int -> V.Event -> T.EventM Name (T.Next Int)
|
||||
appEvent i (V.EvKey (V.KChar '+') []) = M.continue $ i + 1
|
||||
appEvent i (V.EvKey (V.KChar 'i') []) = M.invalidateCacheEntry ExpensiveWidget >> M.continue i
|
||||
appEvent i (V.EvKey V.KEsc []) = M.halt i
|
||||
appEvent :: Int -> BrickEvent Name e -> T.EventM Name (T.Next Int)
|
||||
appEvent i (VtyEvent (V.EvKey (V.KChar '+') [])) = M.continue $ i + 1
|
||||
appEvent i (VtyEvent (V.EvKey (V.KChar 'i') [])) = M.invalidateCacheEntry ExpensiveWidget >> M.continue i
|
||||
appEvent i (VtyEvent (V.EvKey V.KEsc [])) = M.halt i
|
||||
appEvent i _ = M.continue i
|
||||
|
||||
emphAttr :: AttrName
|
||||
emphAttr = "emphasis"
|
||||
|
||||
app :: M.App Int V.Event Name
|
||||
app :: M.App Int e Name
|
||||
app =
|
||||
M.App { M.appDraw = drawUi
|
||||
, M.appStartEvent = return
|
||||
, M.appHandleEvent = appEvent
|
||||
, M.appAttrMap = const $ attrMap V.defAttr [(emphAttr, V.white `on` V.blue)]
|
||||
, M.appLiftVtyEvent = id
|
||||
, M.appChooseCursor = M.neverShowCursor
|
||||
}
|
||||
|
||||
|
@ -21,39 +21,40 @@ import Brick.Types
|
||||
( Widget
|
||||
, Next
|
||||
, EventM
|
||||
, BrickEvent(..)
|
||||
)
|
||||
import Brick.Widgets.Core
|
||||
( (<=>)
|
||||
, str
|
||||
)
|
||||
|
||||
data CustomEvent = Counter deriving Show
|
||||
|
||||
data St =
|
||||
St { _stLastVtyEvent :: Maybe V.Event
|
||||
St { _stLastBrickEvent :: Maybe (BrickEvent () CustomEvent)
|
||||
, _stCounter :: Int
|
||||
}
|
||||
|
||||
makeLenses ''St
|
||||
|
||||
data CustomEvent = VtyEvent V.Event
|
||||
| Counter
|
||||
|
||||
drawUI :: St -> [Widget ()]
|
||||
drawUI st = [a]
|
||||
where
|
||||
a = (str $ "Last Vty event: " <> (show $ st^.stLastVtyEvent))
|
||||
a = (str $ "Last event: " <> (show $ st^.stLastBrickEvent))
|
||||
<=>
|
||||
(str $ "Counter value is: " <> (show $ st^.stCounter))
|
||||
|
||||
appEvent :: St -> CustomEvent -> EventM () (Next St)
|
||||
appEvent :: St -> BrickEvent () CustomEvent -> EventM () (Next St)
|
||||
appEvent st e =
|
||||
case e of
|
||||
VtyEvent (V.EvKey V.KEsc []) -> halt st
|
||||
VtyEvent ev -> continue $ st & stLastVtyEvent .~ (Just ev)
|
||||
Counter -> continue $ st & stCounter %~ (+1)
|
||||
VtyEvent _ -> continue $ st & stLastBrickEvent .~ (Just e)
|
||||
AppEvent Counter -> continue $ st & stCounter %~ (+1)
|
||||
& stLastBrickEvent .~ (Just e)
|
||||
|
||||
initialState :: St
|
||||
initialState =
|
||||
St { _stLastVtyEvent = Nothing
|
||||
St { _stLastBrickEvent = Nothing
|
||||
, _stCounter = 0
|
||||
}
|
||||
|
||||
@ -64,7 +65,6 @@ theApp =
|
||||
, appHandleEvent = appEvent
|
||||
, appStartEvent = return
|
||||
, appAttrMap = def
|
||||
, appLiftVtyEvent = VtyEvent
|
||||
}
|
||||
|
||||
main :: IO ()
|
||||
|
@ -7,6 +7,7 @@ import qualified Graphics.Vty as V
|
||||
import qualified Brick.Main as M
|
||||
import Brick.Types
|
||||
( Widget
|
||||
, BrickEvent(..)
|
||||
)
|
||||
import Brick.Widgets.Core
|
||||
( padAll
|
||||
@ -26,12 +27,13 @@ drawUI d = [ui]
|
||||
where
|
||||
ui = D.renderDialog d $ C.hCenter $ padAll 1 $ str "This is the dialog body."
|
||||
|
||||
appEvent :: D.Dialog Choice -> V.Event -> T.EventM () (T.Next (D.Dialog Choice))
|
||||
appEvent d ev =
|
||||
appEvent :: D.Dialog Choice -> BrickEvent () e -> T.EventM () (T.Next (D.Dialog Choice))
|
||||
appEvent d (VtyEvent ev) =
|
||||
case ev of
|
||||
V.EvKey V.KEsc [] -> M.halt d
|
||||
V.EvKey V.KEnter [] -> M.halt d
|
||||
_ -> M.continue =<< D.handleDialogEvent ev d
|
||||
appEvent d _ = M.continue d
|
||||
|
||||
initialState :: D.Dialog Choice
|
||||
initialState = D.dialog (Just "Title") (Just (0, choices)) 50
|
||||
@ -48,14 +50,13 @@ theMap = A.attrMap V.defAttr
|
||||
, (D.buttonSelectedAttr, bg V.yellow)
|
||||
]
|
||||
|
||||
theApp :: M.App (D.Dialog Choice) V.Event ()
|
||||
theApp :: M.App (D.Dialog Choice) e ()
|
||||
theApp =
|
||||
M.App { M.appDraw = drawUI
|
||||
, M.appChooseCursor = M.showFirstCursor
|
||||
, M.appHandleEvent = appEvent
|
||||
, M.appStartEvent = return
|
||||
, M.appAttrMap = const theMap
|
||||
, M.appLiftVtyEvent = id
|
||||
}
|
||||
|
||||
main :: IO ()
|
||||
|
@ -47,8 +47,8 @@ drawUI st = [ui]
|
||||
str " " <=>
|
||||
str "Press Tab to switch between editors, Esc to quit."
|
||||
|
||||
appEvent :: St -> V.Event -> T.EventM Name (T.Next St)
|
||||
appEvent st ev =
|
||||
appEvent :: St -> T.BrickEvent Name e -> T.EventM Name (T.Next St)
|
||||
appEvent st (T.VtyEvent ev) =
|
||||
case ev of
|
||||
V.EvKey V.KEsc [] -> M.halt st
|
||||
V.EvKey (V.KChar '\t') [] -> M.continue $ st & focusRing %~ F.focusNext
|
||||
@ -58,6 +58,7 @@ appEvent st ev =
|
||||
Just Edit1 -> T.handleEventLensed st edit1 E.handleEditorEvent ev
|
||||
Just Edit2 -> T.handleEventLensed st edit2 E.handleEditorEvent ev
|
||||
Nothing -> return st
|
||||
appEvent st _ = M.continue st
|
||||
|
||||
initialState :: St
|
||||
initialState =
|
||||
@ -74,14 +75,13 @@ theMap = A.attrMap V.defAttr
|
||||
appCursor :: St -> [T.CursorLocation Name] -> Maybe (T.CursorLocation Name)
|
||||
appCursor = F.focusRingCursor (^.focusRing)
|
||||
|
||||
theApp :: M.App St V.Event Name
|
||||
theApp :: M.App St e Name
|
||||
theApp =
|
||||
M.App { M.appDraw = drawUI
|
||||
, M.appChooseCursor = appCursor
|
||||
, M.appHandleEvent = appEvent
|
||||
, M.appStartEvent = return
|
||||
, M.appAttrMap = const theMap
|
||||
, M.appLiftVtyEvent = id
|
||||
}
|
||||
|
||||
main :: IO ()
|
||||
|
@ -43,27 +43,26 @@ bottomLayer st =
|
||||
translateBy (st^.bottomLayerLocation) $
|
||||
B.border $ str "Bottom layer\n(Ctrl-arrow keys move)"
|
||||
|
||||
appEvent :: St -> V.Event -> T.EventM () (T.Next St)
|
||||
appEvent st (V.EvKey V.KDown []) = M.continue $ st & topLayerLocation.rowL %~ (+ 1)
|
||||
appEvent st (V.EvKey V.KUp []) = M.continue $ st & topLayerLocation.rowL %~ (subtract 1)
|
||||
appEvent st (V.EvKey V.KRight []) = M.continue $ st & topLayerLocation.columnL %~ (+ 1)
|
||||
appEvent st (V.EvKey V.KLeft []) = M.continue $ st & topLayerLocation.columnL %~ (subtract 1)
|
||||
appEvent :: St -> T.BrickEvent () e -> T.EventM () (T.Next St)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KDown [])) = M.continue $ st & topLayerLocation.rowL %~ (+ 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KUp [])) = M.continue $ st & topLayerLocation.rowL %~ (subtract 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KRight [])) = M.continue $ st & topLayerLocation.columnL %~ (+ 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KLeft [])) = M.continue $ st & topLayerLocation.columnL %~ (subtract 1)
|
||||
|
||||
appEvent st (V.EvKey V.KDown [V.MCtrl]) = M.continue $ st & bottomLayerLocation.rowL %~ (+ 1)
|
||||
appEvent st (V.EvKey V.KUp [V.MCtrl]) = M.continue $ st & bottomLayerLocation.rowL %~ (subtract 1)
|
||||
appEvent st (V.EvKey V.KRight [V.MCtrl]) = M.continue $ st & bottomLayerLocation.columnL %~ (+ 1)
|
||||
appEvent st (V.EvKey V.KLeft [V.MCtrl]) = M.continue $ st & bottomLayerLocation.columnL %~ (subtract 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KDown [V.MCtrl])) = M.continue $ st & bottomLayerLocation.rowL %~ (+ 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KUp [V.MCtrl])) = M.continue $ st & bottomLayerLocation.rowL %~ (subtract 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KRight [V.MCtrl])) = M.continue $ st & bottomLayerLocation.columnL %~ (+ 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KLeft [V.MCtrl])) = M.continue $ st & bottomLayerLocation.columnL %~ (subtract 1)
|
||||
|
||||
appEvent st (V.EvKey V.KEsc []) = M.halt st
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KEsc [])) = M.halt st
|
||||
appEvent st _ = M.continue st
|
||||
|
||||
app :: M.App St V.Event ()
|
||||
app :: M.App St e ()
|
||||
app =
|
||||
M.App { M.appDraw = drawUi
|
||||
, M.appStartEvent = return
|
||||
, M.appHandleEvent = appEvent
|
||||
, M.appAttrMap = const def
|
||||
, M.appLiftVtyEvent = id
|
||||
, M.appChooseCursor = M.neverShowCursor
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,8 @@ drawUI l = [ui]
|
||||
, C.hCenter $ str "Press Esc to exit."
|
||||
]
|
||||
|
||||
appEvent :: L.List () Char -> V.Event -> T.EventM () (T.Next (L.List () Char))
|
||||
appEvent l e =
|
||||
appEvent :: L.List () Char -> T.BrickEvent () e -> T.EventM () (T.Next (L.List () Char))
|
||||
appEvent l (T.VtyEvent e) =
|
||||
case e of
|
||||
V.EvKey (V.KChar '+') [] ->
|
||||
let el = nextElement (L.listElements l)
|
||||
@ -64,6 +64,7 @@ appEvent l e =
|
||||
where
|
||||
nextElement :: Vec.Vector Char -> Char
|
||||
nextElement v = fromMaybe '?' $ Vec.find (flip Vec.notElem v) (Vec.fromList ['a' .. 'z'])
|
||||
appEvent l _ = M.continue l
|
||||
|
||||
listDrawElement :: (Show a) => Bool -> a -> Widget ()
|
||||
listDrawElement sel a =
|
||||
@ -85,14 +86,13 @@ theMap = A.attrMap V.defAttr
|
||||
, (customAttr, fg V.cyan)
|
||||
]
|
||||
|
||||
theApp :: M.App (L.List () Char) V.Event ()
|
||||
theApp :: M.App (L.List () Char) e ()
|
||||
theApp =
|
||||
M.App { M.appDraw = drawUI
|
||||
, M.appChooseCursor = M.showFirstCursor
|
||||
, M.appHandleEvent = appEvent
|
||||
, M.appStartEvent = return
|
||||
, M.appAttrMap = const theMap
|
||||
, M.appLiftVtyEvent = id
|
||||
}
|
||||
|
||||
main :: IO ()
|
||||
|
@ -32,14 +32,13 @@ theMap = attrMap V.defAttr
|
||||
, ("keyword2", V.white `on` V.blue)
|
||||
]
|
||||
|
||||
app :: App () V.Event ()
|
||||
app :: App () e ()
|
||||
app =
|
||||
App { appDraw = const [ui]
|
||||
, appHandleEvent = resizeOrQuit
|
||||
, appAttrMap = const theMap
|
||||
, appStartEvent = return
|
||||
, appChooseCursor = neverShowCursor
|
||||
, appLiftVtyEvent = id
|
||||
}
|
||||
|
||||
main :: IO ()
|
||||
|
@ -68,9 +68,9 @@ draggableLayer st =
|
||||
"clicking and dragging anywhere\n" <>
|
||||
"on or within its border.") <+> fill ' '
|
||||
|
||||
appEvent :: St -> V.Event -> T.EventM Name (T.Next St)
|
||||
appEvent st (V.EvKey V.KEsc []) = M.halt st
|
||||
appEvent st ev = do
|
||||
appEvent :: St -> T.BrickEvent Name e -> T.EventM Name (T.Next St)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KEsc [])) = M.halt st
|
||||
appEvent st (T.VtyEvent ev) = do
|
||||
Just e <- M.lookupExtent Layer
|
||||
M.continue =<< case ev of
|
||||
-- If the mouse button was released, stop dragging.
|
||||
@ -99,6 +99,7 @@ appEvent st ev = do
|
||||
es <- M.findClickedExtents (c, r)
|
||||
return $ st' & clicked .~ es
|
||||
_ -> return st
|
||||
appEvent st _ = M.continue st
|
||||
|
||||
aMap :: AttrMap
|
||||
aMap = attrMap V.defAttr
|
||||
@ -106,13 +107,12 @@ aMap = attrMap V.defAttr
|
||||
, ("dragging", V.black `on` V.yellow)
|
||||
]
|
||||
|
||||
app :: M.App St V.Event Name
|
||||
app :: M.App St e Name
|
||||
app =
|
||||
M.App { M.appDraw = drawUi
|
||||
, M.appStartEvent = return
|
||||
, M.appHandleEvent = appEvent
|
||||
, M.appAttrMap = const aMap
|
||||
, M.appLiftVtyEvent = id
|
||||
, M.appChooseCursor = M.neverShowCursor
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
module Main where
|
||||
|
||||
import Data.Default
|
||||
import qualified Graphics.Vty as V
|
||||
|
||||
import Brick.Main (App(..), neverShowCursor, resizeOrQuit, defaultMain)
|
||||
import Brick.Types
|
||||
@ -46,14 +45,13 @@ ui =
|
||||
, padAll 2 $ str "Padded by 2 on all sides"
|
||||
]
|
||||
|
||||
app :: App () V.Event ()
|
||||
app :: App () e ()
|
||||
app =
|
||||
App { appDraw = const [ui]
|
||||
, appHandleEvent = resizeOrQuit
|
||||
, appStartEvent = return
|
||||
, appAttrMap = const def
|
||||
, appChooseCursor = neverShowCursor
|
||||
, appLiftVtyEvent = id
|
||||
}
|
||||
|
||||
main :: IO ()
|
||||
|
@ -17,6 +17,7 @@ import Brick.Types
|
||||
( Widget
|
||||
, EventM
|
||||
, Next
|
||||
, BrickEvent(..)
|
||||
)
|
||||
import Brick.Widgets.Core
|
||||
( vBox
|
||||
@ -36,8 +37,8 @@ drawUI st = [ui]
|
||||
, str "(Press Esc to quit or Space to ask for input)"
|
||||
]
|
||||
|
||||
appEvent :: St -> V.Event -> EventM () (Next St)
|
||||
appEvent st e =
|
||||
appEvent :: St -> BrickEvent () e -> EventM () (Next St)
|
||||
appEvent st (VtyEvent e) =
|
||||
case e of
|
||||
V.EvKey V.KEsc [] -> halt st
|
||||
V.EvKey (V.KChar ' ') [] -> suspendAndResume $ do
|
||||
@ -45,20 +46,20 @@ appEvent st e =
|
||||
s <- getLine
|
||||
return $ st & stExternalInput .~ s
|
||||
_ -> continue st
|
||||
appEvent st _ = continue st
|
||||
|
||||
initialState :: St
|
||||
initialState =
|
||||
St { _stExternalInput = ""
|
||||
}
|
||||
|
||||
theApp :: App St V.Event ()
|
||||
theApp :: App St e ()
|
||||
theApp =
|
||||
App { appDraw = drawUI
|
||||
, appChooseCursor = neverShowCursor
|
||||
, appHandleEvent = appEvent
|
||||
, appStartEvent = return
|
||||
, appAttrMap = const def
|
||||
, appLiftVtyEvent = id
|
||||
}
|
||||
|
||||
main :: IO ()
|
||||
|
@ -58,25 +58,24 @@ vp2Scroll = M.viewportScroll VP2
|
||||
vp3Scroll :: M.ViewportScroll Name
|
||||
vp3Scroll = M.viewportScroll VP3
|
||||
|
||||
appEvent :: () -> V.Event -> T.EventM Name (T.Next ())
|
||||
appEvent _ (V.EvKey V.KDown [V.MCtrl]) = M.vScrollBy vp3Scroll 1 >> M.continue ()
|
||||
appEvent _ (V.EvKey V.KUp [V.MCtrl]) = M.vScrollBy vp3Scroll (-1) >> M.continue ()
|
||||
appEvent _ (V.EvKey V.KRight [V.MCtrl]) = M.hScrollBy vp3Scroll 1 >> M.continue ()
|
||||
appEvent _ (V.EvKey V.KLeft [V.MCtrl]) = M.hScrollBy vp3Scroll (-1) >> M.continue ()
|
||||
appEvent _ (V.EvKey V.KDown []) = M.vScrollBy vp1Scroll 1 >> M.continue ()
|
||||
appEvent _ (V.EvKey V.KUp []) = M.vScrollBy vp1Scroll (-1) >> M.continue ()
|
||||
appEvent _ (V.EvKey V.KRight []) = M.hScrollBy vp2Scroll 1 >> M.continue ()
|
||||
appEvent _ (V.EvKey V.KLeft []) = M.hScrollBy vp2Scroll (-1) >> M.continue ()
|
||||
appEvent _ (V.EvKey V.KEsc []) = M.halt ()
|
||||
appEvent :: () -> T.BrickEvent Name e -> T.EventM Name (T.Next ())
|
||||
appEvent _ (T.VtyEvent (V.EvKey V.KDown [V.MCtrl])) = M.vScrollBy vp3Scroll 1 >> M.continue ()
|
||||
appEvent _ (T.VtyEvent (V.EvKey V.KUp [V.MCtrl])) = M.vScrollBy vp3Scroll (-1) >> M.continue ()
|
||||
appEvent _ (T.VtyEvent (V.EvKey V.KRight [V.MCtrl])) = M.hScrollBy vp3Scroll 1 >> M.continue ()
|
||||
appEvent _ (T.VtyEvent (V.EvKey V.KLeft [V.MCtrl])) = M.hScrollBy vp3Scroll (-1) >> M.continue ()
|
||||
appEvent _ (T.VtyEvent (V.EvKey V.KDown [])) = M.vScrollBy vp1Scroll 1 >> M.continue ()
|
||||
appEvent _ (T.VtyEvent (V.EvKey V.KUp [])) = M.vScrollBy vp1Scroll (-1) >> M.continue ()
|
||||
appEvent _ (T.VtyEvent (V.EvKey V.KRight [])) = M.hScrollBy vp2Scroll 1 >> M.continue ()
|
||||
appEvent _ (T.VtyEvent (V.EvKey V.KLeft [])) = M.hScrollBy vp2Scroll (-1) >> M.continue ()
|
||||
appEvent _ (T.VtyEvent (V.EvKey V.KEsc [])) = M.halt ()
|
||||
appEvent _ _ = M.continue ()
|
||||
|
||||
app :: M.App () V.Event Name
|
||||
app :: M.App () e Name
|
||||
app =
|
||||
M.App { M.appDraw = drawUi
|
||||
, M.appStartEvent = return
|
||||
, M.appHandleEvent = appEvent
|
||||
, M.appAttrMap = const def
|
||||
, M.appLiftVtyEvent = id
|
||||
, M.appChooseCursor = M.neverShowCursor
|
||||
}
|
||||
|
||||
|
@ -99,16 +99,16 @@ vp2Scroll = M.viewportScroll VP2
|
||||
vp3Scroll :: M.ViewportScroll Name
|
||||
vp3Scroll = M.viewportScroll VP3
|
||||
|
||||
appEvent :: St -> V.Event -> T.EventM Name (T.Next St)
|
||||
appEvent st (V.EvKey V.KDown [V.MCtrl]) = M.continue $ st & vp3Index._1 %~ min (vp3Size^._1) . (+ 1)
|
||||
appEvent st (V.EvKey V.KUp [V.MCtrl]) = M.continue $ st & vp3Index._1 %~ max 1 . subtract 1
|
||||
appEvent st (V.EvKey V.KRight [V.MCtrl]) = M.continue $ st & vp3Index._2 %~ min (vp3Size^._1) . (+ 1)
|
||||
appEvent st (V.EvKey V.KLeft [V.MCtrl]) = M.continue $ st & vp3Index._2 %~ max 1 . subtract 1
|
||||
appEvent st (V.EvKey V.KDown []) = M.continue $ st & vp1Index %~ min vp1Size . (+ 1)
|
||||
appEvent st (V.EvKey V.KUp []) = M.continue $ st & vp1Index %~ max 1 . subtract 1
|
||||
appEvent st (V.EvKey V.KRight []) = M.continue $ st & vp2Index %~ min vp2Size . (+ 1)
|
||||
appEvent st (V.EvKey V.KLeft []) = M.continue $ st & vp2Index %~ max 1 . subtract 1
|
||||
appEvent st (V.EvKey V.KEsc []) = M.halt st
|
||||
appEvent :: St -> T.BrickEvent Name e -> T.EventM Name (T.Next St)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KDown [V.MCtrl])) = M.continue $ st & vp3Index._1 %~ min (vp3Size^._1) . (+ 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KUp [V.MCtrl])) = M.continue $ st & vp3Index._1 %~ max 1 . subtract 1
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KRight [V.MCtrl])) = M.continue $ st & vp3Index._2 %~ min (vp3Size^._1) . (+ 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KLeft [V.MCtrl])) = M.continue $ st & vp3Index._2 %~ max 1 . subtract 1
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KDown [])) = M.continue $ st & vp1Index %~ min vp1Size . (+ 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KUp [])) = M.continue $ st & vp1Index %~ max 1 . subtract 1
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KRight [])) = M.continue $ st & vp2Index %~ min vp2Size . (+ 1)
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KLeft [])) = M.continue $ st & vp2Index %~ max 1 . subtract 1
|
||||
appEvent st (T.VtyEvent (V.EvKey V.KEsc [])) = M.halt st
|
||||
appEvent st _ = M.continue st
|
||||
|
||||
theMap :: AttrMap
|
||||
@ -116,13 +116,12 @@ theMap = attrMap V.defAttr
|
||||
[ (selectedAttr, V.black `on` V.yellow)
|
||||
]
|
||||
|
||||
app :: M.App St V.Event Name
|
||||
app :: M.App St e Name
|
||||
app =
|
||||
M.App { M.appDraw = drawUi
|
||||
, M.appStartEvent = return
|
||||
, M.appHandleEvent = appEvent
|
||||
, M.appAttrMap = const theMap
|
||||
, M.appLiftVtyEvent = id
|
||||
, M.appChooseCursor = M.neverShowCursor
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ data App s e n =
|
||||
-- is that many widgets may request a cursor placement but your
|
||||
-- application state is what you probably want to use to decide
|
||||
-- which one wins.
|
||||
, appHandleEvent :: s -> e -> EventM n (Next s)
|
||||
, appHandleEvent :: s -> BrickEvent n e -> EventM n (Next s)
|
||||
-- ^ This function takes the current application state and an
|
||||
-- event and returns an action to be taken and a corresponding
|
||||
-- transformed application state. Possible options are
|
||||
@ -118,17 +118,13 @@ data App s e n =
|
||||
-- initial scrolling requests, for example.
|
||||
, appAttrMap :: s -> AttrMap
|
||||
-- ^ The attribute map that should be used during rendering.
|
||||
, appLiftVtyEvent :: Event -> e
|
||||
-- ^ The event constructor to use to wrap Vty events in your own
|
||||
-- event type. For example, if the application's event type is
|
||||
-- 'Event', this is just 'id'.
|
||||
}
|
||||
|
||||
-- | The default main entry point which takes an application and an
|
||||
-- initial state and returns the final state returned by a 'halt'
|
||||
-- operation.
|
||||
defaultMain :: (Ord n)
|
||||
=> App s Event n
|
||||
=> App s e n
|
||||
-- ^ The application.
|
||||
-> s
|
||||
-- ^ The initial application state.
|
||||
@ -149,7 +145,6 @@ simpleMain w =
|
||||
, appHandleEvent = resizeOrQuit
|
||||
, appStartEvent = return
|
||||
, appAttrMap = def
|
||||
, appLiftVtyEvent = id
|
||||
, appChooseCursor = neverShowCursor
|
||||
}
|
||||
in defaultMain app ()
|
||||
@ -159,8 +154,8 @@ simpleMain w =
|
||||
-- a halt. This is a convenience function useful as an 'appHandleEvent'
|
||||
-- value for simple applications using the 'Event' type that do not need
|
||||
-- to get more sophisticated user input.
|
||||
resizeOrQuit :: s -> Event -> EventM n (Next s)
|
||||
resizeOrQuit s (EvResize _ _) = continue s
|
||||
resizeOrQuit :: s -> BrickEvent n e -> EventM n (Next s)
|
||||
resizeOrQuit s (VtyEvent (EvResize _ _)) = continue s
|
||||
resizeOrQuit s _ = halt s
|
||||
|
||||
data InternalNext n a = InternalSuspendAndResume (RenderState n) (IO a)
|
||||
@ -168,7 +163,7 @@ data InternalNext n a = InternalSuspendAndResume (RenderState n) (IO a)
|
||||
|
||||
runWithNewVty :: (Ord n)
|
||||
=> IO Vty
|
||||
-> Chan (Either Event e)
|
||||
-> Chan (BrickEvent n e)
|
||||
-> App s e n
|
||||
-> RenderState n
|
||||
-> s
|
||||
@ -219,18 +214,18 @@ customMain buildVty userChan app initialAppState = do
|
||||
(st, eState) <- runStateT (runReaderT (runEventM (appStartEvent app initialAppState)) eventRO) emptyES
|
||||
let initialRS = RS M.empty (esScrollRequests eState) S.empty mempty
|
||||
chan <- newChan
|
||||
forkIO $ forever $ readChan userChan >>= (\userEvent -> writeChan chan (Right userEvent))
|
||||
forkIO $ forever $ readChan userChan >>= (\userEvent -> writeChan chan $ AppEvent userEvent)
|
||||
run initialRS st chan
|
||||
|
||||
supplyVtyEvents :: Vty -> Chan (Either Event e) -> IO ()
|
||||
supplyVtyEvents :: Vty -> Chan (BrickEvent n e) -> IO ()
|
||||
supplyVtyEvents vty chan =
|
||||
forever $ do
|
||||
e <- nextEvent vty
|
||||
writeChan chan $ Left e
|
||||
writeChan chan $ VtyEvent e
|
||||
|
||||
runVty :: (Ord n)
|
||||
=> Vty
|
||||
-> Chan (Either Event e)
|
||||
-> Chan (BrickEvent n e)
|
||||
-> App s e n
|
||||
-> s
|
||||
-> RenderState n
|
||||
@ -243,17 +238,14 @@ runVty vty chan app appState rs = do
|
||||
-- states before we invoke the event handler since we want the event
|
||||
-- handler to have access to accurate viewport information.
|
||||
(nextRS, nextExts) <- case e of
|
||||
Left (EvResize _ _) ->
|
||||
(VtyEvent (EvResize _ _)) ->
|
||||
renderApp vty app appState $ firstRS & observedNamesL .~ S.empty
|
||||
_ -> return (firstRS, exts)
|
||||
|
||||
let emptyES = ES [] []
|
||||
userEvent = case e of
|
||||
Left e' -> appLiftVtyEvent app e'
|
||||
Right e' -> e'
|
||||
eventRO = EventRO (viewportMap nextRS) (Just vty) nextExts
|
||||
|
||||
let eventRO = EventRO (viewportMap nextRS) (Just vty) nextExts
|
||||
(next, eState) <- runStateT (runReaderT (runEventM (appHandleEvent app appState userEvent))
|
||||
(next, eState) <- runStateT (runReaderT (runEventM (appHandleEvent app appState e))
|
||||
eventRO) emptyES
|
||||
return (next, nextRS { rsScrollRequests = esScrollRequests eState
|
||||
, renderCache = applyInvalidations (cacheInvalidateRequests eState) $
|
||||
|
@ -25,6 +25,7 @@ module Brick.Types
|
||||
-- * Event-handling types
|
||||
, EventM(..)
|
||||
, Next
|
||||
, BrickEvent(..)
|
||||
, handleEventLensed
|
||||
|
||||
-- * Rendering infrastructure
|
||||
@ -76,7 +77,7 @@ import Lens.Micro (_1, _2, to, (^.), (&), (.~), Lens')
|
||||
import Lens.Micro.Type (Getting)
|
||||
import Control.Monad.Trans.State.Lazy
|
||||
import Control.Monad.Trans.Reader
|
||||
import Graphics.Vty (Event, Attr)
|
||||
import Graphics.Vty (Attr)
|
||||
import Control.Monad.IO.Class
|
||||
|
||||
import Brick.Types.TH
|
||||
|
@ -24,6 +24,7 @@ module Brick.Types.Internal
|
||||
, Result(..)
|
||||
, Extent(..)
|
||||
, CacheInvalidateRequest(..)
|
||||
, BrickEvent(..)
|
||||
|
||||
, rsScrollRequestsL
|
||||
, viewportMapL
|
||||
@ -48,7 +49,7 @@ import Lens.Micro.TH (makeLenses)
|
||||
import Lens.Micro.Internal (Field1, Field2)
|
||||
import qualified Data.Set as S
|
||||
import qualified Data.Map as M
|
||||
import Graphics.Vty (Vty, DisplayRegion, Image, emptyImage)
|
||||
import Graphics.Vty (Vty, Event, DisplayRegion, Image, emptyImage)
|
||||
import Data.Default (Default(..))
|
||||
|
||||
import Brick.Types.TH
|
||||
@ -191,6 +192,13 @@ suffixLenses ''Result
|
||||
instance Default (Result n) where
|
||||
def = Result emptyImage [] [] []
|
||||
|
||||
-- | The type of events.
|
||||
data BrickEvent n e = VtyEvent Event
|
||||
-- ^ The event was a Vty event.
|
||||
| AppEvent e
|
||||
-- ^ The event was an application event.
|
||||
deriving (Show, Eq)
|
||||
|
||||
data RenderState n =
|
||||
RS { viewportMap :: M.Map n Viewport
|
||||
, rsScrollRequests :: [(n, ScrollRequest)]
|
||||
|
Loading…
Reference in New Issue
Block a user