mirror of
https://github.com/jtdaugherty/brick.git
synced 2024-11-26 09:06:56 +03:00
Merge branch 'master' into feature/mouse-support
This commit is contained in:
commit
3d50122d5b
15
brick.cabal
15
brick.cabal
@ -312,3 +312,18 @@ executable brick-border-demo
|
|||||||
data-default,
|
data-default,
|
||||||
text,
|
text,
|
||||||
microlens
|
microlens
|
||||||
|
|
||||||
|
executable brick-progressbar-demo
|
||||||
|
if !flag(demos)
|
||||||
|
Buildable: False
|
||||||
|
hs-source-dirs: programs
|
||||||
|
ghc-options: -threaded -Wall -fno-warn-unused-do-bind -O3
|
||||||
|
default-extensions: CPP
|
||||||
|
default-language: Haskell2010
|
||||||
|
main-is: ProgressBarDemo.hs
|
||||||
|
build-depends: base <= 5,
|
||||||
|
brick,
|
||||||
|
vty >= 5.5.0,
|
||||||
|
data-default,
|
||||||
|
text,
|
||||||
|
microlens
|
||||||
|
@ -670,6 +670,7 @@ map combinators:
|
|||||||
* ``Brick.Widgets.Core.updateAttrMap``
|
* ``Brick.Widgets.Core.updateAttrMap``
|
||||||
* ``Brick.Widgets.Core.forceAttr``
|
* ``Brick.Widgets.Core.forceAttr``
|
||||||
* ``Brick.Widgets.Core.withDefAttr``
|
* ``Brick.Widgets.Core.withDefAttr``
|
||||||
|
* ``Brick.Widgets.Core.overrideAttr``
|
||||||
|
|
||||||
Viewports
|
Viewports
|
||||||
=========
|
=========
|
||||||
@ -938,6 +939,12 @@ widgets. If you don't want to crop in this way, you can use any of
|
|||||||
``vty``'s cropping functions to operate on the ``Result`` image as
|
``vty``'s cropping functions to operate on the ``Result`` image as
|
||||||
desired.
|
desired.
|
||||||
|
|
||||||
|
Sub-widgets may specify specific attribute name values influencing
|
||||||
|
that sub-widget. If the custom widget utilizes its own attribute
|
||||||
|
names but needs to render the sub-widget, it can use ``overrideAttr``
|
||||||
|
or ``mapAttrNames`` to convert its custom names to the names that the
|
||||||
|
sub-widget uses for rendering its output.
|
||||||
|
|
||||||
.. _vty: https://github.com/coreyoconnor/vty
|
.. _vty: https://github.com/coreyoconnor/vty
|
||||||
.. _Hackage: http://hackage.haskell.org/
|
.. _Hackage: http://hackage.haskell.org/
|
||||||
.. _microlens: http://hackage.haskell.org/package/microlens
|
.. _microlens: http://hackage.haskell.org/package/microlens
|
||||||
|
104
programs/ProgressBarDemo.hs
Normal file
104
programs/ProgressBarDemo.hs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
module Main where
|
||||||
|
|
||||||
|
-- import Lens.Micro ((^.))
|
||||||
|
import Control.Monad (void)
|
||||||
|
import Data.Monoid
|
||||||
|
-- import Data.Maybe (fromMaybe)
|
||||||
|
import qualified Graphics.Vty as V
|
||||||
|
|
||||||
|
import qualified Brick.AttrMap as A
|
||||||
|
import qualified Brick.Main as M
|
||||||
|
import qualified Brick.Types as T
|
||||||
|
import qualified Brick.Widgets.ProgressBar as P
|
||||||
|
import Brick.Types
|
||||||
|
( Widget
|
||||||
|
)
|
||||||
|
import Brick.Widgets.Core
|
||||||
|
( (<+>), (<=>)
|
||||||
|
, str
|
||||||
|
, updateAttrMap
|
||||||
|
, overrideAttr
|
||||||
|
)
|
||||||
|
import Brick.Util (fg, bg, on, clamp)
|
||||||
|
|
||||||
|
data MyAppState n = MyAppState { x, y, z :: Float }
|
||||||
|
|
||||||
|
drawUI :: MyAppState () -> [Widget ()]
|
||||||
|
drawUI p = [ui]
|
||||||
|
where
|
||||||
|
-- use mapAttrNames
|
||||||
|
xBar = updateAttrMap
|
||||||
|
(A.mapAttrNames [ (xDoneAttr, P.progressCompleteAttr)
|
||||||
|
, (xToDoAttr, P.progressIncompleteAttr)
|
||||||
|
]
|
||||||
|
) $ bar $ x p
|
||||||
|
-- or use individual mapAttrName calls
|
||||||
|
yBar = updateAttrMap
|
||||||
|
(A.mapAttrName yDoneAttr P.progressCompleteAttr .
|
||||||
|
A.mapAttrName yToDoAttr P.progressIncompleteAttr) $
|
||||||
|
bar $ y p
|
||||||
|
-- or use overrideAttr calls
|
||||||
|
zBar = overrideAttr P.progressCompleteAttr zDoneAttr $
|
||||||
|
overrideAttr P.progressIncompleteAttr zToDoAttr $
|
||||||
|
bar $ z p
|
||||||
|
lbl c = Just $ show $ fromEnum $ c * 100
|
||||||
|
bar v = P.progressBar (lbl v) v
|
||||||
|
ui = (str "X: " <+> xBar) <=>
|
||||||
|
(str "Y: " <+> yBar) <=>
|
||||||
|
(str "Z: " <+> zBar) <=>
|
||||||
|
str "" <=>
|
||||||
|
str "Hit 'x', 'y', or 'z' to advance progress, or 'q' to quit"
|
||||||
|
|
||||||
|
|
||||||
|
appEvent :: MyAppState () -> V.Event -> T.EventM () (T.Next (MyAppState ()))
|
||||||
|
appEvent p e =
|
||||||
|
let valid = clamp (0.0 :: Float) 1.0
|
||||||
|
in case e of
|
||||||
|
V.EvKey (V.KChar 'x') [] -> M.continue $ p { x = valid $ x p + 0.05 }
|
||||||
|
V.EvKey (V.KChar 'y') [] -> M.continue $ p { y = valid $ y p + 0.03 }
|
||||||
|
V.EvKey (V.KChar 'z') [] -> M.continue $ p { z = valid $ z p + 0.02 }
|
||||||
|
V.EvKey (V.KChar 'q') [] -> M.halt p
|
||||||
|
_ -> M.continue p
|
||||||
|
|
||||||
|
initialState :: MyAppState ()
|
||||||
|
initialState = MyAppState 0.25 0.18 0.63
|
||||||
|
|
||||||
|
theBaseAttr :: A.AttrName
|
||||||
|
theBaseAttr = A.attrName "theBase"
|
||||||
|
|
||||||
|
xDoneAttr, xToDoAttr :: A.AttrName
|
||||||
|
xDoneAttr = theBaseAttr <> A.attrName "X:done"
|
||||||
|
xToDoAttr = theBaseAttr <> A.attrName "X:remaining"
|
||||||
|
|
||||||
|
yDoneAttr, yToDoAttr :: A.AttrName
|
||||||
|
yDoneAttr = theBaseAttr <> A.attrName "Y:done"
|
||||||
|
yToDoAttr = theBaseAttr <> A.attrName "Y:remaining"
|
||||||
|
|
||||||
|
zDoneAttr, zToDoAttr :: A.AttrName
|
||||||
|
zDoneAttr = theBaseAttr <> A.attrName "Z:done"
|
||||||
|
zToDoAttr = theBaseAttr <> A.attrName "Z:remaining"
|
||||||
|
|
||||||
|
theMap :: A.AttrMap
|
||||||
|
theMap = A.attrMap V.defAttr
|
||||||
|
[ (theBaseAttr, bg V.brightBlack)
|
||||||
|
, (xDoneAttr, V.black `on` V.white)
|
||||||
|
, (xToDoAttr, V.white `on` V.black)
|
||||||
|
, (yDoneAttr, V.magenta `on` V.yellow)
|
||||||
|
, (zDoneAttr, V.blue `on` V.green)
|
||||||
|
, (zToDoAttr, V.blue `on` V.red)
|
||||||
|
, (P.progressIncompleteAttr, fg V.yellow)
|
||||||
|
]
|
||||||
|
|
||||||
|
theApp :: M.App (MyAppState ()) V.Event ()
|
||||||
|
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 ()
|
||||||
|
main = void $ M.defaultMain theApp initialState
|
@ -35,6 +35,8 @@ module Brick.AttrMap
|
|||||||
, setDefault
|
, setDefault
|
||||||
, applyAttrMappings
|
, applyAttrMappings
|
||||||
, mergeWithDefault
|
, mergeWithDefault
|
||||||
|
, mapAttrName
|
||||||
|
, mapAttrNames
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
@ -169,3 +171,18 @@ combineMDs _ v = v
|
|||||||
applyAttrMappings :: [(AttrName, Attr)] -> AttrMap -> AttrMap
|
applyAttrMappings :: [(AttrName, Attr)] -> AttrMap -> AttrMap
|
||||||
applyAttrMappings _ (ForceAttr a) = ForceAttr a
|
applyAttrMappings _ (ForceAttr a) = ForceAttr a
|
||||||
applyAttrMappings ms (AttrMap d m) = AttrMap d ((M.fromList ms) `M.union` m)
|
applyAttrMappings ms (AttrMap d m) = AttrMap d ((M.fromList ms) `M.union` m)
|
||||||
|
|
||||||
|
-- | Update an attribute map such that a lookup of 'ontoName' returns
|
||||||
|
-- the attribute value specified by 'fromName'. This is useful for
|
||||||
|
-- composite widgets with specific attribute names mapping those names
|
||||||
|
-- to the sub-widget's expected name when calling that sub-widget's
|
||||||
|
-- rendering function. See the ProgressBarDemo for an example usage,
|
||||||
|
-- and 'overrideAttr' for an alternate syntax.
|
||||||
|
mapAttrName :: AttrName -> AttrName -> AttrMap -> AttrMap
|
||||||
|
mapAttrName fromName ontoName inMap =
|
||||||
|
applyAttrMappings [(ontoName, attrMapLookup fromName inMap)] inMap
|
||||||
|
|
||||||
|
-- | Map several attributes to return the value associated with an
|
||||||
|
-- alternate name. Applies 'mapAttrName' across a list of mappings.
|
||||||
|
mapAttrNames :: [(AttrName, AttrName)] -> AttrMap -> AttrMap
|
||||||
|
mapAttrNames names inMap = foldr (uncurry mapAttrName) inMap names
|
||||||
|
@ -35,6 +35,7 @@ module Brick.Widgets.Core
|
|||||||
, withDefAttr
|
, withDefAttr
|
||||||
, withAttr
|
, withAttr
|
||||||
, forceAttr
|
, forceAttr
|
||||||
|
, overrideAttr
|
||||||
, updateAttrMap
|
, updateAttrMap
|
||||||
|
|
||||||
-- * Border style management
|
-- * Border style management
|
||||||
@ -508,6 +509,13 @@ forceAttr an p =
|
|||||||
c <- getContext
|
c <- getContext
|
||||||
withReaderT (& ctxAttrMapL .~ (forceAttrMap (attrMapLookup an (c^.ctxAttrMapL)))) (render p)
|
withReaderT (& ctxAttrMapL .~ (forceAttrMap (attrMapLookup an (c^.ctxAttrMapL)))) (render p)
|
||||||
|
|
||||||
|
-- | Override the lookup of 'targetName' to return the attribute value
|
||||||
|
-- associated with 'fromName' when rendering the specified widget.
|
||||||
|
-- See also 'mapAttrName'.
|
||||||
|
overrideAttr :: AttrName -> AttrName -> Widget n -> Widget n
|
||||||
|
overrideAttr targetName fromName =
|
||||||
|
updateAttrMap (mapAttrName fromName targetName)
|
||||||
|
|
||||||
-- | Build a widget directly from a raw Vty image.
|
-- | Build a widget directly from a raw Vty image.
|
||||||
raw :: V.Image -> Widget n
|
raw :: V.Image -> Widget n
|
||||||
raw img = Widget Fixed Fixed $ return $ def & imageL .~ img
|
raw img = Widget Fixed Fixed $ return $ def & imageL .~ img
|
||||||
|
Loading…
Reference in New Issue
Block a user