brick 0.4.1 → 0.5
raw patch · 9 files changed
+91/−33 lines, 9 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Brick.Widgets.Dialog: dialogButtonsL :: Lens (Dialog a_aI7t) (Dialog a_aI7Y) [(String, a_aI7t)] [(String, a_aI7Y)]
+ Brick.Widgets.Dialog: dialogButtonsL :: Lens (Dialog a_aUvO) (Dialog a_aUwj) [(String, a_aUvO)] [(String, a_aUwj)]
- Brick.Widgets.Dialog: dialogNameL :: Lens' (Dialog a_aI7t) Name
+ Brick.Widgets.Dialog: dialogNameL :: Lens' (Dialog a_aUvO) Name
- Brick.Widgets.Dialog: dialogSelectedIndexL :: Lens' (Dialog a_aI7t) (Maybe Int)
+ Brick.Widgets.Dialog: dialogSelectedIndexL :: Lens' (Dialog a_aUvO) (Maybe Int)
- Brick.Widgets.Dialog: dialogTitleL :: Lens' (Dialog a_aI7t) (Maybe String)
+ Brick.Widgets.Dialog: dialogTitleL :: Lens' (Dialog a_aUvO) (Maybe String)
- Brick.Widgets.Dialog: dialogWidthL :: Lens' (Dialog a_aI7t) Int
+ Brick.Widgets.Dialog: dialogWidthL :: Lens' (Dialog a_aUvO) Int
- Brick.Widgets.List: listElementsL :: Lens (List e_aMyc) (List e_aMEV) (Vector e_aMyc) (Vector e_aMEV)
+ Brick.Widgets.List: listElementsL :: Lens (List e_a118d) (List e_a11eW) (Vector e_a118d) (Vector e_a11eW)
- Brick.Widgets.List: listItemHeightL :: Lens' (List e_aMyc) Int
+ Brick.Widgets.List: listItemHeightL :: Lens' (List e_a118d) Int
- Brick.Widgets.List: listNameL :: Lens' (List e_aMyc) Name
+ Brick.Widgets.List: listNameL :: Lens' (List e_a118d) Name
- Brick.Widgets.List: listSelectedL :: Lens' (List e_aMyc) (Maybe Int)
+ Brick.Widgets.List: listSelectedL :: Lens' (List e_a118d) (Maybe Int)
- Data.Text.Markup: markupToList :: (Eq a) => Markup a -> [(Text, a)]
+ Data.Text.Markup: markupToList :: (Eq a) => Markup a -> [[(Text, a)]]
Files
- CHANGELOG.md +25/−0
- README.md +0/−4
- brick.cabal +1/−1
- programs/EditDemo.hs +1/−0
- programs/MarkupDemo.hs +5/−1
- src/Brick/Markup.hs +9/−6
- src/Brick/Widgets/Core.hs +31/−5
- src/Brick/Widgets/List.hs +8/−11
- src/Data/Text/Markup.hs +11/−5
CHANGELOG.md view
@@ -2,6 +2,31 @@ Brick changelog --------------- +0.5+---++Functionality changes:+ * Markup: make markup support multi-line strings (fixes #41)+ * brick-edit-demo: support shift-tab to switch editors+ * Core: improve box layout algorithm (when rendering boxes, track+ remaining space while rendering high-priority children to use+ successively more constrained primary dimensions)+ * Core: make fixed padding take precedence over padded widgets (fixes #42)+ Prior to this commit, padding a widget meant that if there was room+ after rendering the widget, the specified amount of padding would be+ added. This meant that under tight layout constraints padding would+ disappear before a padded widget would. This is often a desirable+ outcome but it also led to unexpected behavior when adding padding+ to a widget that grows greedily: fixed padding would never show up+ because it was placed in a box adjacent to the widget in question,+ and boxes always render greedy children before fixed ones. As a+ result fixed padding would disappear under these conditions. Instead,+ in the case of fixed padding, since we often intend to *guarantee*+ that padding is present, all of the padding combinators have been+ modified so that when the padded widget is rendered with fixed+ padding in the amount V, the widget is given V fewer rows/columns+ when it is rendered so that the padding always has room.+ 0.4.1 -----
README.md view
@@ -86,10 +86,6 @@ use that, you'll also be helping to test whether the exported interface is usable and complete! -The development of this library has revealed some bugs in `vty`, and-I've tried to report those as I go. If they haven't been resolved,-you'll see them arise when using `brick`.- Reporting bugs --------------
brick.cabal view
@@ -1,5 +1,5 @@ name: brick-version: 0.4.1+version: 0.5 synopsis: A declarative terminal user interface library description: Write terminal applications painlessly with 'brick'! You write an
programs/EditDemo.hs view
@@ -60,6 +60,7 @@ case ev of V.EvKey V.KEsc [] -> M.halt st V.EvKey (V.KChar '\t') [] -> M.continue $ switchEditors st+ V.EvKey V.KBackTab [] -> M.continue $ switchEditors st _ -> M.continue =<< T.handleEventLensed st (currentEditorL st) ev initialState :: St
programs/MarkupDemo.hs view
@@ -7,9 +7,12 @@ import Brick.Main (App(..), defaultMain, resizeOrQuit, neverShowCursor) import Brick.Types ( Widget+ , Padding(..) ) import Brick.Widgets.Core ( (<=>)+ , (<+>)+ , padLeft ) import Brick.Util (on, fg) import Brick.Markup (markup, (@?))@@ -17,10 +20,11 @@ import Data.Text.Markup ((@@)) ui :: Widget-ui = m1 <=> m2+ui = (m1 <=> m2) <+> (padLeft (Pad 1) m3) where m1 = markup $ ("Hello" @@ fg V.blue) <> ", " <> ("world!" @@ fg V.red) m2 = markup $ ("Hello" @? "keyword1") <> ", " <> ("world!" @? "keyword2")+ m3 = markup $ ("Hello," @? "keyword1") <> "\n" <> ("world!" @? "keyword2") theMap :: AttrMap theMap = attrMap V.defAttr
src/Brick/Markup.hs view
@@ -17,7 +17,7 @@ import Data.Text.Markup import Data.Default (def) -import Graphics.Vty (Attr, horizCat, string)+import Graphics.Vty (Attr, vertCat, horizCat, string) import Brick.AttrMap import Brick.Types@@ -47,8 +47,11 @@ markup :: (Eq a, GetAttr a) => Markup a -> Widget markup m = Widget Fixed Fixed $ do- let pairs = markupToList m- imgs <- forM pairs $ \(t, aSrc) -> do- a <- getAttr aSrc- return $ string a $ T.unpack t- return $ def & imageL .~ horizCat imgs+ let markupLines = markupToList m+ mkLine pairs = do+ is <- forM pairs $ \(t, aSrc) -> do+ a <- getAttr aSrc+ return $ string a $ T.unpack t+ return $ horizCat is+ lineImgs <- mapM mkLine markupLines+ return $ def & imageL .~ vertCat lineImgs
src/Brick/Widgets/Core.hs view
@@ -153,7 +153,11 @@ Max -> (id, Greedy) Pad i -> (hLimit i, hSize p) in Widget sz (vSize p) $ do- result <- render p+ c <- getContext+ let lim = case padding of+ Max -> c^.availWidthL+ Pad i -> c^.availWidthL - i+ result <- render $ hLimit lim p render $ (f $ vLimit (result^.imageL.to V.imageHeight) $ fill ' ') <+> (Widget Fixed Fixed $ return result) @@ -166,7 +170,11 @@ Max -> (id, Greedy) Pad i -> (hLimit i, hSize p) in Widget sz (vSize p) $ do- result <- render p+ c <- getContext+ let lim = case padding of+ Max -> c^.availWidthL+ Pad i -> c^.availWidthL - i+ result <- render $ hLimit lim p render $ (Widget Fixed Fixed $ return result) <+> (f $ vLimit (result^.imageL.to V.imageHeight) $ fill ' ') @@ -178,7 +186,11 @@ Max -> (id, Greedy) Pad i -> (vLimit i, vSize p) in Widget (hSize p) sz $ do- result <- render p+ c <- getContext+ let lim = case padding of+ Max -> c^.availHeightL+ Pad i -> c^.availHeightL - i+ result <- render $ vLimit lim p render $ (f $ hLimit (result^.imageL.to V.imageWidth) $ fill ' ') <=> (Widget Fixed Fixed $ return result) @@ -191,7 +203,11 @@ Max -> (id, Greedy) Pad i -> (vLimit i, vSize p) in Widget (hSize p) sz $ do- result <- render p+ c <- getContext+ let lim = case padding of+ Max -> c^.availHeightL+ Pad i -> c^.availHeightL - i+ result <- render $ vLimit lim p render $ (Widget Fixed Fixed $ return result) <=> (f $ hLimit (result^.imageL.to V.imageWidth) $ fill ' ') @@ -344,7 +360,17 @@ let pairsIndexed = zip [(0::Int)..] ws (his, lows) = partition (\p -> (primaryWidgetSize br $ snd p) == Fixed) pairsIndexed - renderedHis <- mapM (\(i, prim) -> (i,) <$> render prim) his+ let availPrimary = c^.(contextPrimary br)+ availSecondary = c^.(contextSecondary br)++ renderHis _ prev [] = return prev+ renderHis remainingPrimary prev ((i, prim):rest) = do+ result <- render $ limitPrimary br remainingPrimary+ $ limitSecondary br availSecondary+ $ cropToContext prim+ renderHis (remainingPrimary - (result^.imageL.(to $ imagePrimary br))) (prev ++ [(i, result)]) rest++ renderedHis <- renderHis availPrimary [] his renderedLows <- case lows of [] -> return []
src/Brick/Widgets/List.hs view
@@ -9,7 +9,7 @@ module Brick.Widgets.List ( List(listElements, listSelected, listName, listItemHeight) - -- * Consructing a list+ -- * Constructing a list , list -- * Rendering a list@@ -139,11 +139,11 @@ off = start * (l^.listItemHeightL) - drawnElements = (flip V.imap) es $ \i e ->+ drawnElements = flip V.imap es $ \i e -> let isSelected = Just (i + start) == l^.listSelectedL elemWidget = drawElem isSelected e makeVisible = if isSelected- then (visible . withDefAttr listSelectedAttr)+ then visible . withDefAttr listSelectedAttr else id in makeVisible elemWidget @@ -180,13 +180,10 @@ | otherwise = let newSel = case l^.listSelectedL of Nothing -> 0- Just s -> if pos == 0- then 0- else if pos == s- then pos - 1- else if pos < s- then s - 1- else s+ Just s | pos == 0 -> 0+ | pos == s -> pos - 1+ | pos < s -> s - 1+ | otherwise -> s (front, back) = V.splitAt pos es es' = front V.++ V.tail back es = l^.listElementsL@@ -224,7 +221,7 @@ listMoveTo :: Int -> List e -> List e listMoveTo pos l = let len = V.length (l^.listElementsL)- newSel = clamp 0 (len - 1) $ if pos < 0 then (len - pos) else pos+ newSel = clamp 0 (len - 1) $ if pos < 0 then len - pos else pos in l & listSelectedL .~ if len > 0 then Just newSel else Nothing
src/Data/Text/Markup.hs view
@@ -45,7 +45,7 @@ -- | Extract the text from markup, discarding the markup metadata. toText :: (Eq a) => Markup a -> T.Text-toText = T.concat . (fst <$>) . markupToList+toText = T.concat . (fst <$>) . concat . markupToList -- | Set the metadata for a range of character positions in a piece of -- markup. This is useful for, e.g., syntax highlighting.@@ -59,11 +59,17 @@ (theOldEntries, theTail) = splitAt len theLongTail theNewEntries = zip (fst <$> theOldEntries) (repeat val) --- | Convert markup to a list of pairs in which each pair contains the--- longest subsequence of characters having the same metadata.-markupToList :: (Eq a) => Markup a -> [(T.Text, a)]-markupToList (Markup thePairs) = toList thePairs+-- | Convert markup to a list of lines. Each line is represented by a+-- list of pairs in which each pair contains the longest subsequence of+-- characters having the same metadata.+markupToList :: (Eq a) => Markup a -> [[(T.Text, a)]]+markupToList (Markup thePairs) = toList <$> toLines [] [] thePairs where+ toLines ls cur [] = ls ++ [cur]+ toLines ls cur ((ch, val):rest)+ | ch == '\n' = toLines (ls ++ [cur]) [] rest+ | otherwise = toLines ls (cur ++ [(ch, val)]) rest+ toList [] = [] toList ((ch, val):rest) = (T.pack $ ch : (fst <$> matching), val) : toList remaining where