brick/programs/CacheDemo.hs
Jonathan Daugherty 6f1b62ae53 AttrName: remove IsString instance
This change is motivated by the API wart that results from the
overloading of both "<>" and string literals that resulted in code like
this:

  a :: AttrName
  a = "blah" <> "things"

While this worked to create an AttrName with two segments, it is far too
easy to read this as two strings concatenated. The overloading hides
what is really going on with the segments of the attribute name. The way
to write the above example after this change is:

  a :: AttrName
  a = attrName "blah" <> attrName "things"
2022-08-04 18:44:57 -07:00

82 lines
2.5 KiB
Haskell

{-# LANGUAGE CPP #-}
module Main where
import Control.Monad (void)
import Control.Monad.State (modify)
#if !(MIN_VERSION_base(4,11,0))
import Data.Monoid ((<>))
#endif
import qualified Graphics.Vty as V
import qualified Brick.Types as T
import qualified Brick.Main as M
import qualified Brick.Widgets.Center as C
import Brick.Types
( Widget
, BrickEvent(..)
)
import Brick.Widgets.Core
( Padding(..)
, vBox
, padTopBottom
, withDefAttr
, cached
, padBottom
, str
)
import Brick (on)
import Brick.Widgets.Center
( hCenter
)
import Brick.AttrMap
( AttrName
, attrName
, attrMap
)
data Name = ExpensiveWidget
deriving (Ord, Show, Eq)
drawUi :: Int -> [Widget Name]
drawUi i = [ui]
where
ui = C.vCenter $
vBox $ hCenter <$>
[ str "This demo shows how cached widgets behave. The top widget below"
, str "is cacheable, so once it's rendered, brick re-uses the rendering"
, str "each time it is drawn. The bottom widget is not cacheable so it is"
, str "drawn on every request. Brick supports cache invalidation to force"
, str "a redraw of cached widgets; we can trigger that here with 'i'. Notice"
, str "how state changes with '+' aren't reflected in the cached widget"
, str "until the cache is invalidated with 'i'."
, padTopBottom 1 $
cached ExpensiveWidget $
withDefAttr emphAttr $ str $ "This widget is cached (state = " <> show i <> ")"
, padBottom (Pad 1) $
withDefAttr emphAttr $ str $ "This widget is not cached (state = " <> show i <> ")"
, hCenter $ str "Press 'i' to invalidate the cache,"
, str "'+' to change the state value, and"
, str "'Esc' to quit."
]
appEvent :: BrickEvent Name e -> T.EventM Name Int ()
appEvent (VtyEvent (V.EvKey (V.KChar '+') [])) = modify (+ 1)
appEvent (VtyEvent (V.EvKey (V.KChar 'i') [])) = M.invalidateCacheEntry ExpensiveWidget
appEvent (VtyEvent (V.EvKey V.KEsc [])) = M.halt
appEvent _ = return ()
emphAttr :: AttrName
emphAttr = attrName "emphasis"
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.appChooseCursor = M.neverShowCursor
}
main :: IO ()
main = void $ M.defaultMain app 0