mirror of
https://github.com/jtdaugherty/brick.git
synced 2024-12-12 12:23:21 +03:00
Add documentation to Brick.Main
This commit is contained in:
parent
618f6f4e4e
commit
c4c80492f4
@ -5,12 +5,14 @@ module Brick.Main
|
||||
, simpleMain
|
||||
, resizeOrQuit
|
||||
|
||||
-- * Event handler functions
|
||||
, EventM
|
||||
, Next
|
||||
, continue
|
||||
, halt
|
||||
, suspendAndResume
|
||||
|
||||
-- ** Viewport scrolling
|
||||
, viewportScroll
|
||||
, ViewportScroll
|
||||
, scrollBy
|
||||
@ -18,6 +20,7 @@ module Brick.Main
|
||||
, scrollToBeginning
|
||||
, scrollToEnd
|
||||
|
||||
-- * Cursor management functions
|
||||
, neverShowCursor
|
||||
, showFirstCursor
|
||||
)
|
||||
@ -49,29 +52,69 @@ import Brick.Widgets.Internal (renderFinal, RenderState(..), ScrollRequest(..),
|
||||
import Brick.Core (row, column, CursorLocation(..), Name(..))
|
||||
import Brick.AttrMap
|
||||
|
||||
-- | The type of actions to take in an event handler.
|
||||
data Next a = Continue a
|
||||
| SuspendAndResume (IO a)
|
||||
| Halt a
|
||||
|
||||
-- | The library application abstraction. Your application's operations
|
||||
-- are represented here and passed to one of the various main functions
|
||||
-- in this module. An application is in terms of an application state
|
||||
-- type 'a' and an application event type 'e'. In the simplest case 'e' is
|
||||
-- vty's 'Event' type, but you may define your own event type, permitted
|
||||
-- that it has a constructor for wrapping Vty events, so that Vty events
|
||||
-- can be handled by your event loop.
|
||||
data App a e =
|
||||
App { appDraw :: a -> [Widget]
|
||||
-- ^ This function turns your application state into a list of
|
||||
-- widget layers. The layers are listed topmost first.
|
||||
, appChooseCursor :: a -> [CursorLocation] -> Maybe CursorLocation
|
||||
-- ^ This function chooses which of the zero or more cursor
|
||||
-- locations reported by the rendering process should be
|
||||
-- selected as the one to use to place the cursor. If this
|
||||
-- returns 'Nothing', no cursor is placed. The rationale here
|
||||
-- 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 :: e -> a -> EventM (Next a)
|
||||
-- ^ This function takes an event and your application state
|
||||
-- and returns an action to be taken. Possible options are
|
||||
-- 'continue', 'suspendAndResume', and 'halt'.
|
||||
, appStartEvent :: a -> EventM a
|
||||
-- ^ This function gets called once just prior to the first
|
||||
-- drawing of your application. Here is where you can make
|
||||
-- initial scrolling requests, for example.
|
||||
, appAttrMap :: a -> AttrMap
|
||||
-- ^ The attribute map that should be used during rendering.
|
||||
, appMakeVtyEvent :: 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 monad in which event handlers run.
|
||||
type EventM a = StateT EventState IO a
|
||||
|
||||
type EventState = [(Name, ScrollRequest)]
|
||||
|
||||
defaultMain :: App a Event -> a -> IO a
|
||||
-- | The default main entry point which takes an application and an
|
||||
-- initial state and returns the final state returned by a 'halt'
|
||||
-- operation.
|
||||
defaultMain :: App a Event
|
||||
-- ^ The application.
|
||||
-> a
|
||||
-- ^ The initial application state.
|
||||
-> IO a
|
||||
defaultMain app st = do
|
||||
chan <- newChan
|
||||
customMain (mkVty def) chan app st
|
||||
|
||||
simpleMain :: Widget -> IO ()
|
||||
-- | A simple main entry point which takes a widget and renders it. This
|
||||
-- event loop terminates when the user presses any key, but terminal
|
||||
-- resize events cause redraws.
|
||||
simpleMain :: Widget
|
||||
-- ^ The widget to draw.
|
||||
-> IO ()
|
||||
simpleMain w =
|
||||
let app = App { appDraw = const [w]
|
||||
, appHandleEvent = resizeOrQuit
|
||||
@ -82,6 +125,11 @@ simpleMain w =
|
||||
}
|
||||
in defaultMain app ()
|
||||
|
||||
-- | An event-handling function which continues execution of the event
|
||||
-- loop only when resize events occur; all other types of events trigger
|
||||
-- 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 :: Event -> a -> EventM (Next a)
|
||||
resizeOrQuit e a =
|
||||
case e of
|
||||
@ -107,7 +155,21 @@ runWithNewVty buildVty chan app initialRS initialSt = do
|
||||
Continue s -> runInner newRS s
|
||||
runInner initialRS initialSt
|
||||
|
||||
customMain :: IO Vty -> Chan e -> App a e -> a -> IO a
|
||||
-- | The custom event loop entry point to use when the simpler ones
|
||||
-- don't permit enough control.
|
||||
customMain :: IO Vty
|
||||
-- ^ An IO action to build a Vty handle. This is used to
|
||||
-- build a Vty handle whenever the event loop begins or is
|
||||
-- resumed after suspension.
|
||||
-> Chan e
|
||||
-- ^ An event channel for sending custom events to the event
|
||||
-- loop (you write to this channel, the event loop reads from
|
||||
-- it).
|
||||
-> App a e
|
||||
-- ^ The application.
|
||||
-> a
|
||||
-- ^ The initial application state.
|
||||
-> IO a
|
||||
customMain buildVty chan app initialAppState = do
|
||||
let run rs st = do
|
||||
result <- runWithNewVty buildVty chan app rs st
|
||||
@ -155,12 +217,22 @@ renderApp vty app appState rs = do
|
||||
|
||||
return newRS
|
||||
|
||||
-- | Ignore all requested cursor positions returned by the rendering
|
||||
-- process. This is a convenience function useful as an
|
||||
-- 'appChooseCursor' value when a simple application has no need to
|
||||
-- position the cursor.
|
||||
neverShowCursor :: a -> [CursorLocation] -> Maybe CursorLocation
|
||||
neverShowCursor = const $ const Nothing
|
||||
|
||||
-- | Always show the first cursor, if any, returned by the rendering
|
||||
-- process. This is a convenience function useful as an
|
||||
-- 'appChooseCursor' value when a simple program has zero or more
|
||||
-- widgets that advertise a cursor position.
|
||||
showFirstCursor :: a -> [CursorLocation] -> Maybe CursorLocation
|
||||
showFirstCursor = const $ listToMaybe
|
||||
|
||||
-- | A viewport scrolling handle for managing the scroll state of
|
||||
-- viewports.
|
||||
data ViewportScroll =
|
||||
ViewportScroll { viewportName :: Name
|
||||
, scrollPage :: Direction -> EventM ()
|
||||
@ -169,6 +241,7 @@ data ViewportScroll =
|
||||
, scrollToEnd :: EventM ()
|
||||
}
|
||||
|
||||
-- | Build a viewport scroller for the viewport with the specified name.
|
||||
viewportScroll :: Name -> ViewportScroll
|
||||
viewportScroll n =
|
||||
ViewportScroll { viewportName = n
|
||||
@ -178,11 +251,19 @@ viewportScroll n =
|
||||
, scrollToEnd = modify ((n, ScrollToEnd) :)
|
||||
}
|
||||
|
||||
-- | Continue running the event loop with the specified application
|
||||
-- state.
|
||||
continue :: a -> EventM (Next a)
|
||||
continue = return . Continue
|
||||
|
||||
-- | Halt the event loop and return the specified application state as
|
||||
-- the final state value.
|
||||
halt :: a -> EventM (Next a)
|
||||
halt = return . Halt
|
||||
|
||||
-- | Suspend the event loop, save the terminal state, and run the
|
||||
-- specified action. When it returns an application state value, restore
|
||||
-- the terminal state, and resume the event loop with the returned
|
||||
-- application state.
|
||||
suspendAndResume :: IO a -> EventM (Next a)
|
||||
suspendAndResume = return . SuspendAndResume
|
||||
|
Loading…
Reference in New Issue
Block a user