brick 0.19 → 0.20
raw patch · 5 files changed
+78/−5 lines, 5 filesdep +word-wrapnew-component:exe:brick-text-wrap-demoPVP ok
version bump matches the API change (PVP)
Dependencies added: word-wrap
API changes (from Hackage documentation)
+ Brick.Widgets.Core: strWrap :: String -> Widget n
+ Brick.Widgets.Core: txtWrap :: Text -> Widget n
- Brick.Types: cursorLocationL :: forall n_aqdu. Lens' (CursorLocation n_aqdu) Location
+ Brick.Types: cursorLocationL :: forall n_aqfx. Lens' (CursorLocation n_aqfx) Location
- Brick.Types: cursorLocationNameL :: forall n_aqdu n_aqGW. Lens (CursorLocation n_aqdu) (CursorLocation n_aqGW) (Maybe n_aqdu) (Maybe n_aqGW)
+ Brick.Types: cursorLocationNameL :: forall n_aqfx n_aqIZ. Lens (CursorLocation n_aqfx) (CursorLocation n_aqIZ) (Maybe n_aqfx) (Maybe n_aqIZ)
- Brick.Types: cursorsL :: forall n_aqcp. Lens' (Result n_aqcp) [CursorLocation n_aqcp]
+ Brick.Types: cursorsL :: forall n_aqes. Lens' (Result n_aqes) [CursorLocation n_aqes]
- Brick.Types: extentsL :: forall n_aqcp. Lens' (Result n_aqcp) [Extent n_aqcp]
+ Brick.Types: extentsL :: forall n_aqes. Lens' (Result n_aqes) [Extent n_aqes]
- Brick.Types: imageL :: forall n_aqcp. Lens' (Result n_aqcp) Image
+ Brick.Types: imageL :: forall n_aqes. Lens' (Result n_aqes) Image
- Brick.Types: visibilityRequestsL :: forall n_aqcp. Lens' (Result n_aqcp) [VisibilityRequest]
+ Brick.Types: visibilityRequestsL :: forall n_aqes. Lens' (Result n_aqes) [VisibilityRequest]
- Brick.Widgets.Dialog: dialogButtonsL :: forall a_a13JU a_a13Ku. Lens (Dialog a_a13JU) (Dialog a_a13Ku) [(String, a_a13JU)] [(String, a_a13Ku)]
+ Brick.Widgets.Dialog: dialogButtonsL :: forall a_a14q0 a_a14qA. Lens (Dialog a_a14q0) (Dialog a_a14qA) [(String, a_a14q0)] [(String, a_a14qA)]
- Brick.Widgets.Dialog: dialogSelectedIndexL :: forall a_a13JU. Lens' (Dialog a_a13JU) (Maybe Int)
+ Brick.Widgets.Dialog: dialogSelectedIndexL :: forall a_a14q0. Lens' (Dialog a_a14q0) (Maybe Int)
- Brick.Widgets.Dialog: dialogTitleL :: forall a_a13JU. Lens' (Dialog a_a13JU) (Maybe String)
+ Brick.Widgets.Dialog: dialogTitleL :: forall a_a14q0. Lens' (Dialog a_a14q0) (Maybe String)
- Brick.Widgets.Dialog: dialogWidthL :: forall a_a13JU. Lens' (Dialog a_a13JU) Int
+ Brick.Widgets.Dialog: dialogWidthL :: forall a_a14q0. Lens' (Dialog a_a14q0) Int
- Brick.Widgets.Edit: editContentsL :: forall t_a15ve n_a15vf t_a15vQ. Lens (Editor t_a15ve n_a15vf) (Editor t_a15vQ n_a15vf) (TextZipper t_a15ve) (TextZipper t_a15vQ)
+ Brick.Widgets.Edit: editContentsL :: forall t_a16b8 n_a16b9 t_a16bK. Lens (Editor t_a16b8 n_a16b9) (Editor t_a16bK n_a16b9) (TextZipper t_a16b8) (TextZipper t_a16bK)
- Brick.Widgets.List: listElementsL :: forall n_a17j8 e_a17j9 e_a17t3. Lens (List n_a17j8 e_a17j9) (List n_a17j8 e_a17t3) (Vector e_a17j9) (Vector e_a17t3)
+ Brick.Widgets.List: listElementsL :: forall n_a17Z2 e_a17Z3 e_a189h. Lens (List n_a17Z2 e_a17Z3) (List n_a17Z2 e_a189h) (Vector e_a17Z3) (Vector e_a189h)
- Brick.Widgets.List: listItemHeightL :: forall n_a17j8 e_a17j9. Lens' (List n_a17j8 e_a17j9) Int
+ Brick.Widgets.List: listItemHeightL :: forall n_a17Z2 e_a17Z3. Lens' (List n_a17Z2 e_a17Z3) Int
- Brick.Widgets.List: listNameL :: forall n_a17j8 e_a17j9 n_a17t4. Lens (List n_a17j8 e_a17j9) (List n_a17t4 e_a17j9) n_a17j8 n_a17t4
+ Brick.Widgets.List: listNameL :: forall n_a17Z2 e_a17Z3 n_a189i. Lens (List n_a17Z2 e_a17Z3) (List n_a189i e_a17Z3) n_a17Z2 n_a189i
- Brick.Widgets.List: listSelectedL :: forall n_a17j8 e_a17j9. Lens' (List n_a17j8 e_a17j9) (Maybe Int)
+ Brick.Widgets.List: listSelectedL :: forall n_a17Z2 e_a17Z3. Lens' (List n_a17Z2 e_a17Z3) (Maybe Int)
Files
- CHANGELOG.md +15/−0
- brick.cabal +15/−2
- docs/guide.rst +1/−1
- programs/TextWrapDemo.hs +13/−0
- src/Brick/Widgets/Core.hs +34/−2
CHANGELOG.md view
@@ -2,6 +2,21 @@ Brick changelog --------------- +0.20+----++Package changes:+ * Added a dependency on "word-wrap" for text-wrapping.+ * Added a new TextWrapDemo demo program to illustrate text wrapping+ support++API changes:+ * Brick.Widgets.Core: added new functions txtWrap and strWrap to do+ wrapping of long lines of text.++Miscellaneous:+ * Guide: fixed event type (#126)+ 0.19 ----
brick.cabal view
@@ -1,5 +1,5 @@ name: brick-version: 0.19+version: 0.20 synopsis: A declarative terminal user interface library description: Write terminal applications painlessly with 'brick'! You write an@@ -93,7 +93,8 @@ text, text-zipper >= 0.7.1, template-haskell,- deepseq >= 1.3 && < 1.5+ deepseq >= 1.3 && < 1.5,+ word-wrap executable brick-readme-demo if !flag(demos)@@ -103,6 +104,18 @@ default-language: Haskell2010 default-extensions: CPP main-is: ReadmeDemo.hs+ build-depends: base,+ brick,+ text++executable brick-text-wrap-demo+ if !flag(demos)+ Buildable: False+ hs-source-dirs: programs+ ghc-options: -threaded -Wall -fno-warn-unused-do-bind -O3+ default-language: Haskell2010+ default-extensions: CPP+ main-is: TextWrapDemo.hs build-depends: base, brick, text
docs/guide.rst view
@@ -103,7 +103,7 @@ data App s e n = App { appDraw :: s -> [Widget n] , appChooseCursor :: s -> [CursorLocation n] -> Maybe (CursorLocation n)- , appHandleEvent :: s -> e -> EventM n (Next s)+ , appHandleEvent :: s -> BrickEvent n e -> EventM n (Next s) , appStartEvent :: s -> EventM n s , appAttrMap :: s -> AttrMap }
+ programs/TextWrapDemo.hs view
@@ -0,0 +1,13 @@+module Main where++import Data.Monoid ((<>))+import Brick++ui :: Widget ()+ui = strWrap $ "Hello, world! This line is long enough that " <>+ "it's likely to wrap on your terminal if your window " <>+ "isn't especially wide. Try narrowing and widening " <>+ "the window to see what happens to this text."++main :: IO ()+main = simpleMain ui
src/Brick/Widgets/Core.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE TupleSections #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-} -- | This module provides the core widget combinators and rendering -- routines. Everything this library does is in terms of these basic -- primitives.@@ -11,7 +12,9 @@ , emptyWidget , raw , txt+ , txtWrap , str+ , strWrap , fill -- * Padding@@ -100,6 +103,8 @@ import qualified Graphics.Vty as V import Control.DeepSeq +import Text.Wrap (wrapTextToLines)+ import Brick.Types import Brick.Types.Internal import Brick.Widgets.Border.Style@@ -195,6 +200,33 @@ then c : takeColumns (numCols - w) cs else "" +-- | Make a widget from a string, but wrap the words in the input's+-- lines at the available width.+strWrap :: String -> Widget n+strWrap = txtWrap . T.pack++safeTextWidth :: T.Text -> Int+safeTextWidth = V.safeWcswidth . T.unpack++-- | Make a widget from text, but wrap the words in the input's lines at+-- the available width.+txtWrap :: T.Text -> Widget n+txtWrap s =+ Widget Fixed Fixed $ do+ c <- getContext+ let theLines = fixEmpty <$> wrapTextToLines (c^.availWidthL) s+ fixEmpty l | T.null l = " "+ | otherwise = l+ case force theLines of+ [] -> return emptyResult+ [one] -> return $ emptyResult & imageL .~ (V.text' (c^.attrL) one)+ multiple ->+ let maxLength = maximum $ safeTextWidth <$> multiple+ lineImgs = lineImg <$> multiple+ lineImg lStr = V.text' (c^.attrL)+ (lStr <> T.replicate (maxLength - safeTextWidth lStr) " ")+ in return $ emptyResult & imageL .~ (V.vertCat lineImgs)+ -- | Build a widget from a 'String'. Breaks newlines up and space-pads -- short lines out to the length of the longest line. str :: String -> Widget n@@ -214,8 +246,8 @@ lineImg lStr = V.string (c^.attrL) (lStr ++ replicate (maxLength - V.safeWcswidth lStr) ' ') in return $ emptyResult & imageL .~ (V.vertCat lineImgs) --- | Build a widget from a one-line 'T.Text' value. Behaves the same as--- 'str'.+-- | Build a widget from a 'T.Text' value. Behaves the same as 'str'+-- when the input contains multiple lines. txt :: T.Text -> Widget n txt = str . T.unpack