packages feed

brick 0.61 → 0.62

raw patch · 8 files changed

+162/−22 lines, 8 filesdep ~basedep ~microlensdep ~vtynew-component:exe:brick-cropping-demoPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, microlens, vty

API changes (from Hackage documentation)

+ Brick.Widgets.Core: cropBottomTo :: Int -> Widget n -> Widget n
+ Brick.Widgets.Core: cropLeftTo :: Int -> Widget n -> Widget n
+ Brick.Widgets.Core: cropRightTo :: Int -> Widget n -> Widget n
+ Brick.Widgets.Core: cropTopTo :: Int -> Widget n -> Widget n
- Brick.Widgets.Dialog: dialogButtonsL :: forall a_a18Yy a_a18Zc. Lens (Dialog a_a18Yy) (Dialog a_a18Zc) [(String, a_a18Yy)] [(String, a_a18Zc)]
+ Brick.Widgets.Dialog: dialogButtonsL :: forall a_a19Cy a_a19Dc. Lens (Dialog a_a19Cy) (Dialog a_a19Dc) [(String, a_a19Cy)] [(String, a_a19Dc)]
- Brick.Widgets.Dialog: dialogSelectedIndexL :: forall a_a18Yy. Lens' (Dialog a_a18Yy) (Maybe Int)
+ Brick.Widgets.Dialog: dialogSelectedIndexL :: forall a_a19Cy. Lens' (Dialog a_a19Cy) (Maybe Int)
- Brick.Widgets.Dialog: dialogTitleL :: forall a_a18Yy. Lens' (Dialog a_a18Yy) (Maybe String)
+ Brick.Widgets.Dialog: dialogTitleL :: forall a_a19Cy. Lens' (Dialog a_a19Cy) (Maybe String)
- Brick.Widgets.Dialog: dialogWidthL :: forall a_a18Yy. Lens' (Dialog a_a18Yy) Int
+ Brick.Widgets.Dialog: dialogWidthL :: forall a_a19Cy. Lens' (Dialog a_a19Cy) Int
- Brick.Widgets.Edit: editContentsL :: forall t_a13u9 n_a13ua t_a13uO. Lens (Editor t_a13u9 n_a13ua) (Editor t_a13uO n_a13ua) (TextZipper t_a13u9) (TextZipper t_a13uO)
+ Brick.Widgets.Edit: editContentsL :: forall t_a1489 n_a148a t_a148O. Lens (Editor t_a1489 n_a148a) (Editor t_a148O n_a148a) (TextZipper t_a1489) (TextZipper t_a148O)
- Brick.Widgets.FileBrowser: fileBrowserEntryFilterL :: forall n_a1j5p. Lens' (FileBrowser n_a1j5p) (Maybe (FileInfo -> Bool))
+ Brick.Widgets.FileBrowser: fileBrowserEntryFilterL :: forall n_a1jJp. Lens' (FileBrowser n_a1jJp) (Maybe (FileInfo -> Bool))
- Brick.Widgets.FileBrowser: fileBrowserSelectableL :: forall n_a1j5p. Lens' (FileBrowser n_a1j5p) (FileInfo -> Bool)
+ Brick.Widgets.FileBrowser: fileBrowserSelectableL :: forall n_a1jJp. Lens' (FileBrowser n_a1jJp) (FileInfo -> Bool)
- Brick.Widgets.List: listElementsL :: forall n_a1dUP t_a1dUQ e_a1dUR t_a1e8W e_a1e8X. Lens (GenericList n_a1dUP t_a1dUQ e_a1dUR) (GenericList n_a1dUP t_a1e8W e_a1e8X) (t_a1dUQ e_a1dUR) (t_a1e8W e_a1e8X)
+ Brick.Widgets.List: listElementsL :: forall n_a1eyP t_a1eyQ e_a1eyR t_a1eMW e_a1eMX. Lens (GenericList n_a1eyP t_a1eyQ e_a1eyR) (GenericList n_a1eyP t_a1eMW e_a1eMX) (t_a1eyQ e_a1eyR) (t_a1eMW e_a1eMX)
- Brick.Widgets.List: listItemHeightL :: forall n_a1dUP t_a1dUQ e_a1dUR. Lens' (GenericList n_a1dUP t_a1dUQ e_a1dUR) Int
+ Brick.Widgets.List: listItemHeightL :: forall n_a1eyP t_a1eyQ e_a1eyR. Lens' (GenericList n_a1eyP t_a1eyQ e_a1eyR) Int
- Brick.Widgets.List: listNameL :: forall n_a1dUP t_a1dUQ e_a1dUR n_a1e8Y. Lens (GenericList n_a1dUP t_a1dUQ e_a1dUR) (GenericList n_a1e8Y t_a1dUQ e_a1dUR) n_a1dUP n_a1e8Y
+ Brick.Widgets.List: listNameL :: forall n_a1eyP t_a1eyQ e_a1eyR n_a1eMY. Lens (GenericList n_a1eyP t_a1eyQ e_a1eyR) (GenericList n_a1eMY t_a1eyQ e_a1eyR) n_a1eyP n_a1eMY
- Brick.Widgets.List: listSelectedL :: forall n_a1dUP t_a1dUQ e_a1dUR. Lens' (GenericList n_a1dUP t_a1dUQ e_a1dUR) (Maybe Int)
+ Brick.Widgets.List: listSelectedL :: forall n_a1eyP t_a1eyQ e_a1eyR. Lens' (GenericList n_a1eyP t_a1eyQ e_a1eyR) (Maybe Int)

Files

CHANGELOG.md view
@@ -2,6 +2,22 @@ Brick changelog --------------- +0.62+----++API changes:+ * `Brick.Widgets.Core` got new functions+   `crop{Left,Right,Bottom,Top}To`. Unlike the `crop...By` functions,+   which crop on the specified side by a particular amount, these+   `crop...To` functions crop on the specified side and take a desired+   overall width of the final result and use that to determine how much+   to crop. A widget `x` of width `w` could thus be cropped equivalently+   with `cropLeftBy a x` and `cropLeftTo (w - a) x`.++Other changes:+ * Added `programs/CroppingDemo.hs` to demonstrate the new (and+   preexisting) cropping functions.+ 0.61 ---- 
README.md view
@@ -72,6 +72,9 @@ | [`cbookview`](https://github.com/mlang/chessIO) | A TUI for exploring polyglot chess opening book files | | [`thock`](https://github.com/rmehri01/thock) | A modern TUI typing game featuring online racing against friends | | [`fifteen`](https://github.com/benjaminselfridge/fifteen) | An implementation of the [15 puzzle](https://en.wikipedia.org/wiki/15_puzzle) |+| [`maze`](https://github.com/benjaminselfridge/maze) | A Brick-based maze game |+| [`pboy`](https://github.com/2mol/pboy) | A tiny PDF organizer |+| [`hyahtzee2`](https://github.com/DamienCassou/hyahtzee2#readme) | Famous Yahtzee dice game |  These third-party packages also extend `brick`: 
brick.cabal view
@@ -1,5 +1,5 @@ name:                brick-version:             0.61+version:             0.62 synopsis:            A declarative terminal user interface library description:   Write terminal user interfaces (TUIs) painlessly with 'brick'! You@@ -318,6 +318,19 @@                        text,                        microlens >= 0.3.0.0,                        microlens-th++executable brick-cropping-demo+  if !flag(demos)+    Buildable: False+  hs-source-dirs:      programs+  ghc-options:         -threaded -Wall -Wcompat -O2+  default-language:    Haskell2010+  main-is:             CroppingDemo.hs+  build-depends:       base,+                       brick,+                       vty,+                       text,+                       microlens  executable brick-padding-demo   if !flag(demos)
+ programs/CroppingDemo.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where++import Brick.Main (App(..), neverShowCursor, resizeOrQuit, defaultMain)+import Brick.Types+  ( Widget+  , Padding(..)+  )+import Brick.Widgets.Core+  ( vBox+  , hBox+  , txt+  , (<=>)+  , padRight+  , cropLeftBy+  , cropRightBy+  , cropTopBy+  , cropBottomBy+  , cropLeftTo+  , cropRightTo+  , cropTopTo+  , cropBottomTo+  )+import Brick.Widgets.Border (border)+import Brick.AttrMap (attrMap)+import qualified Graphics.Vty as V++example :: Widget n+example =+    border $+    (txt "Example" <=> txt "Widget")++mkExample :: Widget n -> Widget n+mkExample = padRight (Pad 2)++ui :: Widget ()+ui =+    vBox [ txt "Uncropped" <=> example+         , hBox [ mkExample $ txt "cropLeftBy 2"   <=> cropLeftBy 2 example+                , mkExample $ txt "cropRightBy 2"  <=> cropRightBy 2 example+                , mkExample $ txt "cropTopBy 2"    <=> cropTopBy 2 example+                , mkExample $ txt "cropBottomBy 2" <=> cropBottomBy 2 example+                ]+         , hBox [ mkExample $ txt "cropLeftTo 4"   <=> cropLeftTo 4 example+                , mkExample $ txt "cropRightTo 4"  <=> cropRightTo 4 example+                , mkExample $ txt "cropTopTo 1"    <=> cropTopTo 1 example+                , mkExample $ txt "cropBottomTo 1" <=> cropBottomTo 1 example+                ]+         ]++app :: App () e ()+app =+    App { appDraw = const [ui]+        , appHandleEvent = resizeOrQuit+        , appStartEvent = return+        , appAttrMap = const $ attrMap V.defAttr []+        , appChooseCursor = neverShowCursor+        }++main :: IO ()+main = defaultMain app ()
programs/FileBrowserDemo.hs view
@@ -28,7 +28,7 @@   , hLimit, vLimit, txt   , withDefAttr, emptyWidget   )-import Brick.Widgets.FileBrowser as FB+import qualified Brick.Widgets.FileBrowser as FB import qualified Brick.AttrMap as A import Brick.Util (on, fg) import qualified Brick.Types as T@@ -36,7 +36,7 @@ data Name = FileBrowser1           deriving (Eq, Show, Ord) -drawUI :: FileBrowser Name -> [Widget Name]+drawUI :: FB.FileBrowser Name -> [Widget Name] drawUI b = [center $ ui <=> help]     where         ui = hCenter $@@ -45,7 +45,7 @@              borderWithLabel (txt "Choose a file") $              FB.renderFileBrowser True b         help = padTop (T.Pad 1) $-               vBox [ case fileBrowserException b of+               vBox [ case FB.fileBrowserException b of                           Nothing -> emptyWidget                           Just e -> hCenter $ withDefAttr errorAttr $                                     txt $ Text.pack $ E.displayException e@@ -58,7 +58,7 @@ appEvent :: FB.FileBrowser Name -> BrickEvent Name e -> T.EventM Name (T.Next (FB.FileBrowser Name)) appEvent b (VtyEvent ev) =     case ev of-        V.EvKey V.KEsc [] | not (fileBrowserIsSearching b) ->+        V.EvKey V.KEsc [] | not (FB.fileBrowserIsSearching b) ->             M.halt b         _ -> do             b' <- FB.handleFileBrowserEvent ev b@@ -66,7 +66,7 @@             -- event (because the user pressed Enter), shut down.             case ev of                 V.EvKey V.KEnter [] ->-                    case fileBrowserSelection b' of+                    case FB.fileBrowserSelection b' of                         [] -> M.continue b'                         _ -> M.halt b'                 _ -> M.continue b'@@ -90,7 +90,7 @@     , (errorAttr, fg V.red)     ] -theApp :: M.App (FileBrowser Name) e Name+theApp :: M.App (FB.FileBrowser Name) e Name theApp =     M.App { M.appDraw = drawUI           , M.appChooseCursor = M.showFirstCursor
programs/PaddingDemo.hs view
@@ -18,21 +18,21 @@   , padTopBottom   , padLeftRight   )-import Brick.Widgets.Border as B-import Brick.Widgets.Center as C+import qualified Brick.Widgets.Border as B+import qualified Brick.Widgets.Center as C import Brick.AttrMap (attrMap) import qualified Graphics.Vty as V  ui :: Widget () ui =-    vBox [ hBox [ padLeft Max $ vCenter $ str "Left-padded"+    vBox [ hBox [ padLeft Max $ C.vCenter $ str "Left-padded"                 , B.vBorder-                , padRight Max $ vCenter $ str "Right-padded"+                , padRight Max $ C.vCenter $ str "Right-padded"                 ]          , B.hBorder-         , hBox [ padTop Max $ hCenter $ str "Top-padded"+         , hBox [ padTop Max $ C.hCenter $ str "Top-padded"                 , B.vBorder-                , padBottom Max $ hCenter $ str "Bottom-padded"+                , padBottom Max $ C.hCenter $ str "Bottom-padded"                 ]          , B.hBorder          , hBox [ padLeftRight 2 $ str "Padded by 2 on left/right"
src/Brick/Forms.hs view
@@ -88,7 +88,6 @@ where  import Graphics.Vty hiding (showCursor)-import Control.Monad ((<=<)) #if !(MIN_VERSION_base(4,11,0)) import Data.Monoid #endif@@ -562,11 +561,7 @@                   -- ^ The initial form state.                   -> FormFieldState s e n editShowableField stLens n =-    let ini = T.pack . show-        val = readMaybe . T.unpack . T.intercalate "\n"-        limit = Just 1-        renderText = txt . T.unlines-    in editField stLens n limit ini val renderText id+    editShowableFieldWithValidate stLens n (const True)  -- | A form field using a single-line editor to edit the 'Show' representation -- of a state field value of type @a@. This automatically uses its 'Read'@@ -592,9 +587,9 @@ editShowableFieldWithValidate stLens n isValid =     let ini = T.pack . show         val ls = do-            val <- readMaybe $ T.unpack $ T.intercalate "\n" ls-            if isValid val-               then return val+            v <- readMaybe $ T.unpack $ T.intercalate "\n" ls+            if isValid v+               then return v                else Nothing         limit = Just 1         renderText = txt . T.unlines
src/Brick/Widgets/Core.hs view
@@ -71,6 +71,10 @@   , cropRightBy   , cropTopBy   , cropBottomBy+  , cropLeftTo+  , cropRightTo+  , cropTopTo+  , cropBottomTo    -- * Extent reporting   , reportExtent@@ -905,6 +909,18 @@       return $ addResultOffset (Location (-1 * cols, 0))              $ result & imageL %~ cropped +-- | Crop the specified widget to the specified size from the left.+-- Defers to the cropped widget for growth policy.+cropLeftTo :: Int -> Widget n -> Widget n+cropLeftTo cols p =+    Widget (hSize p) (vSize p) $ do+        result <- render p+        let w = V.imageWidth $ result^.imageL+            amt = w - cols+        if w <= cols+           then return result+           else render $ cropLeftBy amt $ Widget Fixed Fixed $ return result+ -- | Crop the specified widget on the right by the specified number of -- columns. Defers to the cropped widget for growth policy. cropRightBy :: Int -> Widget n -> Widget n@@ -915,6 +931,18 @@           cropped img = if amt < 0 then V.emptyImage else V.cropRight amt img       return $ result & imageL %~ cropped +-- | Crop the specified widget to the specified size from the right.+-- Defers to the cropped widget for growth policy.+cropRightTo :: Int -> Widget n -> Widget n+cropRightTo cols p =+    Widget (hSize p) (vSize p) $ do+        result <- render p+        let w = V.imageWidth $ result^.imageL+            amt = w - cols+        if w <= cols+           then return result+           else render $ cropRightBy amt $ Widget Fixed Fixed $ return result+ -- | Crop the specified widget on the top by the specified number of -- rows. Defers to the cropped widget for growth policy. cropTopBy :: Int -> Widget n -> Widget n@@ -926,6 +954,18 @@       return $ addResultOffset (Location (0, -1 * rows))              $ result & imageL %~ cropped +-- | Crop the specified widget to the specified size from the top.+-- Defers to the cropped widget for growth policy.+cropTopTo :: Int -> Widget n -> Widget n+cropTopTo rows p =+    Widget (hSize p) (vSize p) $ do+        result <- render p+        let h = V.imageHeight $ result^.imageL+            amt = h - rows+        if h <= rows+           then return result+           else render $ cropTopBy amt $ Widget Fixed Fixed $ return result+ -- | Crop the specified widget on the bottom by the specified number of -- rows. Defers to the cropped widget for growth policy. cropBottomBy :: Int -> Widget n -> Widget n@@ -935,6 +975,18 @@       let amt = V.imageHeight (result^.imageL) - rows           cropped img = if amt < 0 then V.emptyImage else V.cropBottom amt img       return $ result & imageL %~ cropped++-- | Crop the specified widget to the specified size from the bottom.+-- Defers to the cropped widget for growth policy.+cropBottomTo :: Int -> Widget n -> Widget n+cropBottomTo rows p =+    Widget (hSize p) (vSize p) $ do+        result <- render p+        let h = V.imageHeight $ result^.imageL+            amt = h - rows+        if h <= rows+           then return result+           else render $ cropBottomBy amt $ Widget Fixed Fixed $ return result  -- | When rendering the specified widget, also register a cursor -- positioning request using the specified name and location.