brick-tabular-list 1.0.0.1 → 2.0.0.0
raw patch · 10 files changed
+313/−250 lines, 10 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Brick.Widgets.TabularList.Grid: GridContext :: FlatContext -> FlatContext -> GridContext
- Brick.Widgets.TabularList.Grid: [$sel:col:GridContext] :: GridContext -> FlatContext
- Brick.Widgets.TabularList.Grid: [$sel:drawCell:GridRenderers] :: GridRenderers n e r -> ListFocused -> WidthDeficit -> GridContext -> e -> Widget n
- Brick.Widgets.TabularList.Grid: [$sel:drawColHdrRowHdr:GridRenderers] :: GridRenderers n e r -> DrawColHdrRowHdr n
- Brick.Widgets.TabularList.Grid: [$sel:row:GridContext] :: GridContext -> FlatContext
- Brick.Widgets.TabularList.Grid: data GridContext
- Brick.Widgets.TabularList.Grid: instance GHC.Generics.Generic Brick.Widgets.TabularList.Grid.GridContext
- Brick.Widgets.TabularList.Grid: instance GHC.Show.Show Brick.Widgets.TabularList.Grid.GridContext
- Brick.Widgets.TabularList.Grid: type GridWidths = Seq Width
- Brick.Widgets.TabularList.Mixed: MixedContext :: FlatContext -> Index -> MixedContext
- Brick.Widgets.TabularList.Mixed: [$sel:calcWidthsPerRowKind:MixedTabularList] :: MixedTabularList n e w -> CalcWidthsPerRowKind e w
- Brick.Widgets.TabularList.Mixed: [$sel:col:MixedContext] :: MixedContext -> Index
- Brick.Widgets.TabularList.Mixed: [$sel:drawCell:MixedRenderers] :: MixedRenderers n e w r -> ListFocused -> MixedContext -> e -> Widget n
- Brick.Widgets.TabularList.Mixed: [$sel:drawColHdrRowHdr:MixedRenderers] :: MixedRenderers n e w r -> DrawColHdrRowHdr n
- Brick.Widgets.TabularList.Mixed: [$sel:row:MixedContext] :: MixedContext -> FlatContext
- Brick.Widgets.TabularList.Mixed: data MixedContext
- Brick.Widgets.TabularList.Mixed: type CalcWidthsPerRowKind e w = AvailWidth -> [e] -> w
- Brick.Widgets.TabularList.Mixed: type WidthsPerRow e w = w -> e -> [Width]
- Brick.Widgets.TabularList.Types: FlatContext :: Index -> Bool -> FlatContext
- Brick.Widgets.TabularList.Types: [$sel:index:FlatContext] :: FlatContext -> Index
- Brick.Widgets.TabularList.Types: [$sel:selected:FlatContext] :: FlatContext -> Bool
- Brick.Widgets.TabularList.Types: [$sel:toRowHdr:RowHdr] :: RowHdr n e r -> e -> Index -> r
- Brick.Widgets.TabularList.Types: data FlatContext
- Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.FlatContext
- Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.FlatContext
- Brick.Widgets.TabularList.Types: type AvailWidth = Int
- Brick.Widgets.TabularList.Types: type DrawColHdrRowHdr n = Maybe (ListFocused -> WidthDeficit -> Widget n)
- Brick.Widgets.TabularList.Types: type Height = Int
- Brick.Widgets.TabularList.Types: type Index = Int
- Brick.Widgets.TabularList.Types: type ListFocused = Bool
- Brick.Widgets.TabularList.Types: type ListItemHeight = Int
- Brick.Widgets.TabularList.Types: type Selected = Bool
- Brick.Widgets.TabularList.Types: type Width = Int
- Brick.Widgets.TabularList.Types: type WidthDeficit = Int
+ Brick.Widgets.TabularList.Grid: GColC :: Index -> Selected -> GridColCtxt
+ Brick.Widgets.TabularList.Grid: GRowC :: Index -> Selected -> GridRowCtxt
+ Brick.Widgets.TabularList.Grid: GrdCtxt :: GridRowCtxt -> GridColCtxt -> GridCtxt
+ Brick.Widgets.TabularList.Grid: [$sel:cell:GridRenderers] :: GridRenderers n e r -> ListFocused -> WidthDeficit -> GridCtxt -> e -> Widget n
+ Brick.Widgets.TabularList.Grid: [$sel:col:GrdCtxt] :: GridCtxt -> GridColCtxt
+ Brick.Widgets.TabularList.Grid: [$sel:colHdrRowHdr:GridRenderers] :: GridRenderers n e r -> ColHdrRowHdr n
+ Brick.Widgets.TabularList.Grid: [$sel:index:GColC] :: GridColCtxt -> Index
+ Brick.Widgets.TabularList.Grid: [$sel:index:GRowC] :: GridRowCtxt -> Index
+ Brick.Widgets.TabularList.Grid: [$sel:row:GrdCtxt] :: GridCtxt -> GridRowCtxt
+ Brick.Widgets.TabularList.Grid: [$sel:selected:GColC] :: GridColCtxt -> Selected
+ Brick.Widgets.TabularList.Grid: [$sel:selected:GRowC] :: GridRowCtxt -> Selected
+ Brick.Widgets.TabularList.Grid: data GridColCtxt
+ Brick.Widgets.TabularList.Grid: data GridCtxt
+ Brick.Widgets.TabularList.Grid: data GridRowCtxt
+ Brick.Widgets.TabularList.Grid: instance GHC.Classes.Eq Brick.Widgets.TabularList.Grid.AccWidth
+ Brick.Widgets.TabularList.Grid: instance GHC.Classes.Eq Brick.Widgets.TabularList.Grid.GridColCtxt
+ Brick.Widgets.TabularList.Grid: instance GHC.Classes.Eq Brick.Widgets.TabularList.Grid.GridCtxt
+ Brick.Widgets.TabularList.Grid: instance GHC.Classes.Eq Brick.Widgets.TabularList.Grid.GridRowCtxt
+ Brick.Widgets.TabularList.Grid: instance GHC.Classes.Eq Brick.Widgets.TabularList.Grid.Height
+ Brick.Widgets.TabularList.Grid: instance GHC.Classes.Eq Brick.Widgets.TabularList.Grid.VisibleColumns
+ Brick.Widgets.TabularList.Grid: instance GHC.Generics.Generic Brick.Widgets.TabularList.Grid.GridColCtxt
+ Brick.Widgets.TabularList.Grid: instance GHC.Generics.Generic Brick.Widgets.TabularList.Grid.GridCtxt
+ Brick.Widgets.TabularList.Grid: instance GHC.Generics.Generic Brick.Widgets.TabularList.Grid.GridRowCtxt
+ Brick.Widgets.TabularList.Grid: instance GHC.Show.Show Brick.Widgets.TabularList.Grid.AccWidth
+ Brick.Widgets.TabularList.Grid: instance GHC.Show.Show Brick.Widgets.TabularList.Grid.GridColCtxt
+ Brick.Widgets.TabularList.Grid: instance GHC.Show.Show Brick.Widgets.TabularList.Grid.GridCtxt
+ Brick.Widgets.TabularList.Grid: instance GHC.Show.Show Brick.Widgets.TabularList.Grid.GridRowCtxt
+ Brick.Widgets.TabularList.Grid: instance GHC.Show.Show Brick.Widgets.TabularList.Grid.Height
+ Brick.Widgets.TabularList.Mixed: MColC :: Index -> MixedColCtxt
+ Brick.Widgets.TabularList.Mixed: MRowC :: Index -> Selected -> MixedRowCtxt
+ Brick.Widgets.TabularList.Mixed: MxdCtxt :: MixedRowCtxt -> MixedColCtxt -> MixedCtxt
+ Brick.Widgets.TabularList.Mixed: WsPerR :: (w -> e -> [ColWidth]) -> WidthsPerRow e w
+ Brick.Widgets.TabularList.Mixed: WsPerRK :: (AvailWidth -> [e] -> w) -> WidthsPerRowKind e w
+ Brick.Widgets.TabularList.Mixed: [$sel:cell:MixedRenderers] :: MixedRenderers n e w r -> ListFocused -> MixedCtxt -> e -> Widget n
+ Brick.Widgets.TabularList.Mixed: [$sel:col:MxdCtxt] :: MixedCtxt -> MixedColCtxt
+ Brick.Widgets.TabularList.Mixed: [$sel:colHdrRowHdr:MixedRenderers] :: MixedRenderers n e w r -> ColHdrRowHdr n
+ Brick.Widgets.TabularList.Mixed: [$sel:index:MColC] :: MixedColCtxt -> Index
+ Brick.Widgets.TabularList.Mixed: [$sel:index:MRowC] :: MixedRowCtxt -> Index
+ Brick.Widgets.TabularList.Mixed: [$sel:row:MxdCtxt] :: MixedCtxt -> MixedRowCtxt
+ Brick.Widgets.TabularList.Mixed: [$sel:selected:MRowC] :: MixedRowCtxt -> Selected
+ Brick.Widgets.TabularList.Mixed: [$sel:widthsPerRowKind:MixedTabularList] :: MixedTabularList n e w -> WidthsPerRowKind e w
+ Brick.Widgets.TabularList.Mixed: data MixedCtxt
+ Brick.Widgets.TabularList.Mixed: data MixedRowCtxt
+ Brick.Widgets.TabularList.Mixed: instance GHC.Classes.Eq Brick.Widgets.TabularList.Mixed.MixedColCtxt
+ Brick.Widgets.TabularList.Mixed: instance GHC.Classes.Eq Brick.Widgets.TabularList.Mixed.MixedCtxt
+ Brick.Widgets.TabularList.Mixed: instance GHC.Classes.Eq Brick.Widgets.TabularList.Mixed.MixedRowCtxt
+ Brick.Widgets.TabularList.Mixed: instance GHC.Generics.Generic (Brick.Widgets.TabularList.Mixed.WidthsPerRow e w)
+ Brick.Widgets.TabularList.Mixed: instance GHC.Generics.Generic (Brick.Widgets.TabularList.Mixed.WidthsPerRowKind e w)
+ Brick.Widgets.TabularList.Mixed: instance GHC.Generics.Generic Brick.Widgets.TabularList.Mixed.MixedColCtxt
+ Brick.Widgets.TabularList.Mixed: instance GHC.Generics.Generic Brick.Widgets.TabularList.Mixed.MixedCtxt
+ Brick.Widgets.TabularList.Mixed: instance GHC.Generics.Generic Brick.Widgets.TabularList.Mixed.MixedRowCtxt
+ Brick.Widgets.TabularList.Mixed: instance GHC.Show.Show Brick.Widgets.TabularList.Mixed.MixedColCtxt
+ Brick.Widgets.TabularList.Mixed: instance GHC.Show.Show Brick.Widgets.TabularList.Mixed.MixedCtxt
+ Brick.Widgets.TabularList.Mixed: instance GHC.Show.Show Brick.Widgets.TabularList.Mixed.MixedRowCtxt
+ Brick.Widgets.TabularList.Mixed: newtype MixedColCtxt
+ Brick.Widgets.TabularList.Mixed: newtype WidthsPerRow e w
+ Brick.Widgets.TabularList.Mixed: newtype WidthsPerRowKind e w
+ Brick.Widgets.TabularList.Types: AvlW :: Int -> AvailWidth
+ Brick.Widgets.TabularList.Types: BlankCHRH :: ColHdrRowHdr n
+ Brick.Widgets.TabularList.Types: CHRH :: (ListFocused -> WidthDeficit -> Widget n) -> ColHdrRowHdr n
+ Brick.Widgets.TabularList.Types: ColHdrH :: Int -> ColHdrHeight
+ Brick.Widgets.TabularList.Types: ColW :: Int -> ColWidth
+ Brick.Widgets.TabularList.Types: Ix :: Int -> Index
+ Brick.Widgets.TabularList.Types: LstFcs :: Bool -> ListFocused
+ Brick.Widgets.TabularList.Types: LstItmH :: Int -> ListItemHeight
+ Brick.Widgets.TabularList.Types: RowHdrCtxt :: Selected -> RowHdrCtxt
+ Brick.Widgets.TabularList.Types: RowHdrW :: Int -> RowHdrWidth
+ Brick.Widgets.TabularList.Types: Sel :: Bool -> Selected
+ Brick.Widgets.TabularList.Types: WdthD :: Int -> WidthDeficit
+ Brick.Widgets.TabularList.Types: [$sel:toRH:RowHdr] :: RowHdr n e r -> e -> Index -> r
+ Brick.Widgets.TabularList.Types: data ColHdrRowHdr n
+ Brick.Widgets.TabularList.Types: instance GHC.Classes.Eq Brick.Widgets.TabularList.Types.AvailWidth
+ Brick.Widgets.TabularList.Types: instance GHC.Classes.Eq Brick.Widgets.TabularList.Types.ColHdrHeight
+ Brick.Widgets.TabularList.Types: instance GHC.Classes.Eq Brick.Widgets.TabularList.Types.ColWidth
+ Brick.Widgets.TabularList.Types: instance GHC.Classes.Eq Brick.Widgets.TabularList.Types.Index
+ Brick.Widgets.TabularList.Types: instance GHC.Classes.Eq Brick.Widgets.TabularList.Types.ListFocused
+ Brick.Widgets.TabularList.Types: instance GHC.Classes.Eq Brick.Widgets.TabularList.Types.ListItemHeight
+ Brick.Widgets.TabularList.Types: instance GHC.Classes.Eq Brick.Widgets.TabularList.Types.RowHdrCtxt
+ Brick.Widgets.TabularList.Types: instance GHC.Classes.Eq Brick.Widgets.TabularList.Types.RowHdrWidth
+ Brick.Widgets.TabularList.Types: instance GHC.Classes.Eq Brick.Widgets.TabularList.Types.Selected
+ Brick.Widgets.TabularList.Types: instance GHC.Classes.Eq Brick.Widgets.TabularList.Types.WidthDeficit
+ Brick.Widgets.TabularList.Types: instance GHC.Enum.Enum Brick.Widgets.TabularList.Types.Index
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic (Brick.Widgets.TabularList.Types.ColHdrRowHdr n)
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.AvailWidth
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.ColHdrHeight
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.ColWidth
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.Index
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.ListFocused
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.ListItemHeight
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.RowHdrCtxt
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.RowHdrWidth
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.Selected
+ Brick.Widgets.TabularList.Types: instance GHC.Generics.Generic Brick.Widgets.TabularList.Types.WidthDeficit
+ Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.AvailWidth
+ Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.ColHdrHeight
+ Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.ColWidth
+ Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.Index
+ Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.ListFocused
+ Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.ListItemHeight
+ Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.RowHdrCtxt
+ Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.RowHdrWidth
+ Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.Selected
+ Brick.Widgets.TabularList.Types: instance GHC.Show.Show Brick.Widgets.TabularList.Types.WidthDeficit
+ Brick.Widgets.TabularList.Types: newtype AvailWidth
+ Brick.Widgets.TabularList.Types: newtype ColHdrHeight
+ Brick.Widgets.TabularList.Types: newtype ColWidth
+ Brick.Widgets.TabularList.Types: newtype Index
+ Brick.Widgets.TabularList.Types: newtype ListFocused
+ Brick.Widgets.TabularList.Types: newtype ListItemHeight
+ Brick.Widgets.TabularList.Types: newtype RowHdrCtxt
+ Brick.Widgets.TabularList.Types: newtype RowHdrWidth
+ Brick.Widgets.TabularList.Types: newtype Selected
+ Brick.Widgets.TabularList.Types: newtype WidthDeficit
- Brick.Widgets.TabularList.Grid: GridColHdr :: (ListFocused -> WidthDeficit -> FlatContext -> Widget n) -> Height -> GridColHdr n
+ Brick.Widgets.TabularList.Grid: GridColHdr :: (ListFocused -> WidthDeficit -> GridColCtxt -> Widget n) -> ColHdrHeight -> GridColHdr n
- Brick.Widgets.TabularList.Grid: GridRenderers :: (ListFocused -> WidthDeficit -> GridContext -> e -> Widget n) -> Maybe (RowHdr n e r) -> Maybe (GridColHdr n) -> DrawColHdrRowHdr n -> GridRenderers n e r
+ Brick.Widgets.TabularList.Grid: GridRenderers :: (ListFocused -> WidthDeficit -> GridCtxt -> e -> Widget n) -> Maybe (RowHdr n e r) -> Maybe (GridColHdr n) -> ColHdrRowHdr n -> GridRenderers n e r
- Brick.Widgets.TabularList.Grid: GridTabularList :: GenericList n Seq e -> GridWidths -> Index -> GridTabularList n e
+ Brick.Widgets.TabularList.Grid: GridTabularList :: GenericList n Seq e -> Seq ColWidth -> Index -> GridTabularList n e
- Brick.Widgets.TabularList.Grid: [$sel:draw:GridColHdr] :: GridColHdr n -> ListFocused -> WidthDeficit -> FlatContext -> Widget n
+ Brick.Widgets.TabularList.Grid: [$sel:draw:GridColHdr] :: GridColHdr n -> ListFocused -> WidthDeficit -> GridColCtxt -> Widget n
- Brick.Widgets.TabularList.Grid: [$sel:height:GridColHdr] :: GridColHdr n -> Height
+ Brick.Widgets.TabularList.Grid: [$sel:height:GridColHdr] :: GridColHdr n -> ColHdrHeight
- Brick.Widgets.TabularList.Grid: [$sel:widths:GridTabularList] :: GridTabularList n e -> GridWidths
+ Brick.Widgets.TabularList.Grid: [$sel:widths:GridTabularList] :: GridTabularList n e -> Seq ColWidth
- Brick.Widgets.TabularList.Grid: gridTabularList :: n -> Seq e -> ListItemHeight -> GridWidths -> GridTabularList n e
+ Brick.Widgets.TabularList.Grid: gridTabularList :: n -> Seq e -> ListItemHeight -> Seq ColWidth -> GridTabularList n e
- Brick.Widgets.TabularList.Mixed: MixedColHdr :: (ListFocused -> Index -> Widget n) -> (w -> [Width]) -> Height -> MixedColHdr n w
+ Brick.Widgets.TabularList.Mixed: MixedColHdr :: (ListFocused -> MixedColCtxt -> Widget n) -> (w -> [ColWidth]) -> ColHdrHeight -> MixedColHdr n w
- Brick.Widgets.TabularList.Mixed: MixedRenderers :: (ListFocused -> MixedContext -> e -> Widget n) -> Maybe (RowHdr n e r) -> Maybe (MixedColHdr n w) -> DrawColHdrRowHdr n -> MixedRenderers n e w r
+ Brick.Widgets.TabularList.Mixed: MixedRenderers :: (ListFocused -> MixedCtxt -> e -> Widget n) -> Maybe (RowHdr n e r) -> Maybe (MixedColHdr n w) -> ColHdrRowHdr n -> MixedRenderers n e w r
- Brick.Widgets.TabularList.Mixed: MixedTabularList :: GenericList n Seq e -> CalcWidthsPerRowKind e w -> WidthsPerRow e w -> MixedTabularList n e w
+ Brick.Widgets.TabularList.Mixed: MixedTabularList :: GenericList n Seq e -> WidthsPerRowKind e w -> WidthsPerRow e w -> MixedTabularList n e w
- Brick.Widgets.TabularList.Mixed: [$sel:draw:MixedColHdr] :: MixedColHdr n w -> ListFocused -> Index -> Widget n
+ Brick.Widgets.TabularList.Mixed: [$sel:draw:MixedColHdr] :: MixedColHdr n w -> ListFocused -> MixedColCtxt -> Widget n
- Brick.Widgets.TabularList.Mixed: [$sel:height:MixedColHdr] :: MixedColHdr n w -> Height
+ Brick.Widgets.TabularList.Mixed: [$sel:height:MixedColHdr] :: MixedColHdr n w -> ColHdrHeight
- Brick.Widgets.TabularList.Mixed: [$sel:widths:MixedColHdr] :: MixedColHdr n w -> w -> [Width]
+ Brick.Widgets.TabularList.Mixed: [$sel:widths:MixedColHdr] :: MixedColHdr n w -> w -> [ColWidth]
- Brick.Widgets.TabularList.Mixed: mixedTabularList :: n -> Seq e -> ListItemHeight -> CalcWidthsPerRowKind e w -> WidthsPerRow e w -> MixedTabularList n e w
+ Brick.Widgets.TabularList.Mixed: mixedTabularList :: n -> Seq e -> ListItemHeight -> WidthsPerRowKind e w -> WidthsPerRow e w -> MixedTabularList n e w
- Brick.Widgets.TabularList.Types: RowHdr :: (ListFocused -> WidthDeficit -> Selected -> r -> Widget n) -> (AvailWidth -> [r] -> Width) -> (e -> Index -> r) -> RowHdr n e r
+ Brick.Widgets.TabularList.Types: RowHdr :: (ListFocused -> WidthDeficit -> RowHdrCtxt -> r -> Widget n) -> (AvailWidth -> [r] -> RowHdrWidth) -> (e -> Index -> r) -> RowHdr n e r
- Brick.Widgets.TabularList.Types: [$sel:draw:RowHdr] :: RowHdr n e r -> ListFocused -> WidthDeficit -> Selected -> r -> Widget n
+ Brick.Widgets.TabularList.Types: [$sel:draw:RowHdr] :: RowHdr n e r -> ListFocused -> WidthDeficit -> RowHdrCtxt -> r -> Widget n
- Brick.Widgets.TabularList.Types: [$sel:width:RowHdr] :: RowHdr n e r -> AvailWidth -> [r] -> Width
+ Brick.Widgets.TabularList.Types: [$sel:width:RowHdr] :: RowHdr n e r -> AvailWidth -> [r] -> RowHdrWidth
Files
- CHANGELOG.md +5/−0
- brick-tabular-list.cabal +1/−1
- demo/GridTabularList.hs +15/−15
- demo/MixedTabularList.hs +21/−21
- src/Brick/Widgets/TabularList.hs +25/−14
- src/Brick/Widgets/TabularList/Grid.hs +120/−101
- src/Brick/Widgets/TabularList/Internal/Common.hs +18/−18
- src/Brick/Widgets/TabularList/Internal/Lens.hs +1/−1
- src/Brick/Widgets/TabularList/Mixed.hs +54/−43
- src/Brick/Widgets/TabularList/Types.hs +53/−36
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for brick-tabular-list +## 2.0.0.0 -- 2023-03-13++* Made it much easier to understand API and implementation+* Improved documentation+ ## 1.0.0.1 -- 2023-03-10 * Decreased lower version bound for base to allow hackage to build haddock documentation with ghc-9.2.4
brick-tabular-list.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: brick-tabular-list-version: 1.0.0.1+version: 2.0.0.0 synopsis: Tabular list widgets for brick.
demo/GridTabularList.hs view
@@ -96,7 +96,7 @@ , "Press Ctrl+End or L to go to the last column" , "Press Ctrl+PageUp or Alt+h or Backspace to go left by one page of columns" , "Press Ctrl+PageDown or Alt+l to go right by one page of columns" ]- theList = renderGridTabularList (s ^. #libRenderers) True (s ^. #libList)+ theList = renderGridTabularList (s ^. #libRenderers) (LstFcs True) (s ^. #libList) in [vCenter $ vBox $ hCenter (padLeftRight 2 $ joinBorders $ border $ hLimit (s ^. #listWidth) $ vLimit 15 theList) : hCenter (str "Press Esc or q to exit" ) : hCenter (str "Press c to toggle column headers")@@ -112,33 +112,33 @@ colSelectedAttr :: AttrName colSelectedAttr = attrName "selectedColumn" -colHdrs :: Vector String-colHdrs = V.fromList ["Artist", "Title", "Album", "Composer", "Genre", "Time"]- rowHdr :: RowHdr Name Song Int rowHdr = RowHdr {- draw = \_ wd f rh -> let- attrFn = if f+ draw = \_ (WdthD wd) (RowHdrCtxt (Sel s)) r -> let+ attrFn = if s then id else withAttr rowHdrAttr- in attrFn $ padRight (Pad $ if wd > 0 then 0 else 1) $ padLeft Max (str $ show rh)-, width = \_ rh -> (+2) $ maximum $ map (length . show) rh-, toRowHdr = \_ i -> i+1+ in attrFn $ padRight (Pad $ if wd > 0 then 0 else 1) $ padLeft Max (str $ show r)+, width = \_ rs -> RowHdrW $ (+2) $ maximum $ map (length . show) rs+, toRH = \_ (Ix i) -> i+1 } +colHdrs :: Vector String+colHdrs = V.fromList ["Artist", "Title", "Album", "Composer", "Genre", "Time"]+ colHdr :: GridColHdr Name colHdr = GridColHdr {- draw = \_ wd (FlatContext i _) -> let+ draw = \_ (WdthD wd) (GColC (Ix ci) _) -> let renderColH = withAttr columnHdrAttr . padRight (Pad $ if wd > 0 then 0 else 1) . padRight Max . str- in case colHdrs V.!? i of+ in case colHdrs V.!? ci of Just ch -> renderColH ch <=> hBorder Nothing -> emptyWidget-, height = 2+, height = ColHdrH 2 } renderers :: LibraryRenderers renderers = GridRenderers {- drawCell = \_ wd (GridContext (FlatContext _ rs) (FlatContext ci cs)) s -> let+ cell = \_ (WdthD wd) (GrdCtxt (GRowC _ (Sel rs)) (GColC (Ix ci) (Sel cs))) s -> let attrFn = if rs && cs then withAttr colSelectedAttr else id@@ -157,11 +157,11 @@ _ -> fill ' ' , rowHdr = Just rowHdr , colHdr = Just colHdr-, drawColHdrRowHdr = Just $ \_ _ -> vLimit 1 (fill ' ') <=> hBorder+, colHdrRowHdr = CHRH $ \_ _ -> vLimit 1 (fill ' ') <=> hBorder } theList :: LibraryList-theList = gridTabularList TheList songs 1 $ S.fromList [12, 11, 11, 14, 11, 7]+theList = gridTabularList TheList songs (LstItmH 1) $ S.fromList $ fmap ColW [12, 11, 11, 14, 11, 7] main :: IO () main = do
demo/MixedTabularList.hs view
@@ -11,7 +11,7 @@ import GHC.Generics (Generic) import Control.Monad (void) -- Third party libraries-import Optics.Core+import Optics.Core ( (^.) ) import Data.Sequence (Seq) import qualified Data.Sequence as S import Data.Vector (Vector)@@ -26,7 +26,7 @@ import Brick.Util import Brick.Widgets.List import Brick.Widgets.Border.Style-import Graphics.Vty (defAttr, Event(..), Key(..), Modifier(..), black, white, blue, red)+import Graphics.Vty data Song = Song { artist :: String@@ -40,8 +40,8 @@ data Name = TheList deriving (Eq, Ord, Show) data Widths = Widths {- song :: [Width]-, folder :: [Width]+ song :: [ColWidth]+, folder :: [ColWidth] } deriving Generic data AppState = AppState {@@ -84,7 +84,7 @@ drawUi :: AppState -> [Widget Name] drawUi s = let- theList = renderMixedTabularList (s ^. #libRenderers) True (s ^. #libList)+ theList = renderMixedTabularList (s ^. #libRenderers) (LstFcs True) (s ^. #libList) msgs = [ "Press Up arrow or k to go up one item" , "Press Down arrow or j to go down one item" , "Press PageUp or Ctrl+b to go up one page"@@ -106,8 +106,8 @@ rowHdrAttr :: AttrName rowHdrAttr = attrName "rowHeader" -dc :: ListFocused -> MixedContext -> LibraryEntry -> Widget n-dc lf (MixedContext (FlatContext _ f) ci) e = let+dc :: ListFocused -> MixedCtxt -> LibraryEntry -> Widget n+dc _ (MxdCtxt _ (MColC (Ix ci))) e = let renderPlainCell s = padRight Max (str s) <+> str " " in case e of LibFolder f -> case ci of@@ -127,48 +127,48 @@ colHdrs :: Vector String colHdrs = V.fromList ["Artist", "Title", "Album", "Time"] -cWprk :: AvailWidth -> [LibraryEntry] -> Widths-cWprk aW _ = let+wprk :: WidthsPerRowKind LibraryEntry Widths+wprk = WsPerRK $ \(AvlW aW) _ -> let artist = max 7 $ (aW * 30) `div` 100 title = max 6 $ (aW * 30) `div` 100 time = 7 album = aW - artist - title - time- in Widths { song = [artist, title, album, time], folder = [aW] }+ in Widths { song = fmap ColW [artist, title, album, time], folder = [ColW aW] } -wpr :: Widths -> LibraryEntry -> [Width]-wpr (Widths {song, folder}) = \case+wpr :: WidthsPerRow LibraryEntry Widths+wpr = WsPerR $ \(Widths {song, folder}) e -> case e of LibSong _ -> song LibFolder _ -> folder rowHdr :: RowHdr Name LibraryEntry Int rowHdr = RowHdr {- draw = \lf wd f rh -> let- attrFn = if f+ draw = \_ (WdthD wd) (RowHdrCtxt (Sel s)) rh -> let+ attrFn = if s then id else withAttr rowHdrAttr in attrFn $ padRight (Pad $ if wd > 0 then 0 else 1) $ padLeft Max (str $ show rh)-, width = \_ rh -> (+2) $ maximum $ map (length . show) rh-, toRowHdr = \_ i -> i+1+, width = \_ rh -> RowHdrW $ (+2) $ maximum $ map (length . show) rh+, toRH = \_ (Ix i) -> i + 1 } colHdr :: MixedColHdr Name Widths colHdr = MixedColHdr {- draw = \_ ci -> case colHdrs V.!? ci of+ draw = \_ (MColC (Ix ci)) -> case colHdrs V.!? ci of Just ch -> withAttr columnHdrAttr (padRight Max (str ch) <+> str " ") <=> hBorder Nothing -> emptyWidget , widths = \Widths {song} -> song-, height = 2+, height = ColHdrH 2 } main :: IO () main = do let appState = AppState {- libList = mixedTabularList TheList libraryEntries 1 cWprk wpr+ libList = mixedTabularList TheList libraryEntries (LstItmH 1) wprk wpr , libRenderers = MixedRenderers {- drawCell = dc+ cell = dc , rowHdr = Just rowHdr , colHdr = Just colHdr- , drawColHdrRowHdr = Just $ \_ _ -> vLimit 1 (fill ' ') <=> hBorder+ , colHdrRowHdr = CHRH $ \_ _ -> vLimit 1 (fill ' ') <=> hBorder } , listWidth = 80 }
src/Brick/Widgets/TabularList.hs view
@@ -1,4 +1,4 @@--- | This module contains only conceptual documentation.+-- | Conceptual documentation module Brick.Widgets.TabularList where import Brick.Widgets.TabularList.Types@@ -23,29 +23,38 @@ -- Because tabular list widgets build on top of 'GenericList', attributes for 'GenericList' apply to tabular list -- widgets if the attributes are defined in your brick application. ----- A rendering function for row columns or row headers is given a space with+-- A rendering function for row headers is given a space with -- -- @--- 'setAvailableSize' (width, listItemHeight)+-- 'setAvailableSize' (rowHeaderWidth, listItemHeight) -- @ ----- A rendering function for column headers or column header row header is given a space with+-- A rendering function for row columns is given a space with -- -- @--- 'setAvailableSize' (width, columnHeaderHeight)+-- 'setAvailableSize' (columnWidth, listItemHeight) -- @ ----- If the given height for rendering functions is not claimed, the list will look broken.+-- A rendering function for column headers is given a space with ----- The given width for rendering functions must be claimed by the returned widget with brick's padding functions or--- 'hCenter'. Otherwise, the list will look broken.+-- @+-- 'setAvailableSize' (columnWidth, columnHeaderHeight)+-- @ ----- 'WidthDeficit' is calculated for renderers of tabular list components that are shrunk to the available width.+-- A rendering function for column header row header is given a space with --+-- @+-- 'setAvailableSize' (rowHeaderWidth, columnHeaderHeight)+-- @+--+-- If the given height and the given width for rendering functions are not claimed, the list will look broken.+--+-- The given width for rendering functions should be claimed with brick's padding functions or 'hCenter'.+-- -- The following examples show how a rendering function can claim the available width. -- -- @--- 'padRight' ('Pad' $ if widthDeficit > 0 then 0 else 1) $ 'padLeft' 'Max' content+-- 'padRight' ('Pad' 1) $ 'padLeft' 'Max' content -- @ -- -- @@@ -53,9 +62,11 @@ -- @ -- -- @--- 'padLeft' ('Pad' $ if widthDeficit > 0 then 0 else 1) $ 'hCenter' content+-- 'padLeft' ('Pad' 1) $ 'hCenter' content -- @ ----- In the examples above, I used padding with one space character at the left or the right to introduce gaps between--- columns. If 'WidthDeficit' is positive, you may want to remove padding because a column is not followed or preceded--- by other columns.+-- In the examples above, I used fixed padding with one space character at the left or the right to introduce gaps+-- between columns.+--+-- If there are fixed paddings used as gaps between columns, then 'WidthDeficit' should be used to remove gaps when the+-- available width is narrower than the desired column width.
src/Brick/Widgets/TabularList/Grid.hs view
@@ -1,10 +1,11 @@+{-# OPTIONS_HADDOCK show-extensions #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NoFieldSelectors #-} {-# LANGUAGE NamedFieldPuns #-}-{-# OPTIONS_HADDOCK show-extensions #-}+{-# LANGUAGE TypeApplications #-} -- | Grid tabular list is a uniform grid that supports cell-by-cell navigation. -- --   @@ -18,10 +19,11 @@ -- It should be fast enough to handle a large spreadsheet. It is also suitable for an interface to a database table. module Brick.Widgets.TabularList.Grid ( -- * Data types- GridContext(..)+ GridRowCtxt(..)+, GridColCtxt(..)+, GridCtxt(..) , GridColHdr(..) , GridRenderers(..)-, GridWidths , GridTabularList(..) -- * List construction , gridTabularList@@ -50,7 +52,7 @@ import Data.Foldable (toList) import Control.Monad (unless) -- Third party libraries-import Optics.Core ( (&), (%), (%~), (.~), (^.) )+import Optics.Core ( (&), (%), (%~), (.~), (^.), coercedTo ) import qualified Data.Sequence as S import Data.Sequence (Seq(..)) import Data.Generics.Labels@@ -61,19 +63,31 @@ import Graphics.Vty (Event(..), Key(..), Modifier(..)) import Brick.Main (lookupViewport) +-- | Grid row context+data GridRowCtxt = GRowC {+ index :: Index+, selected :: Selected+} deriving (Eq, Generic, Show)++-- | Grid column context+data GridColCtxt = GColC {+ index :: Index+, selected :: Selected+} deriving (Eq, Generic, Show)+ -- | Context for grid cells-data GridContext = GridContext {- row :: FlatContext -- ^ Row context-, col :: FlatContext -- ^ Column context-} deriving (Show, Generic)+data GridCtxt = GrdCtxt {+ row :: GridRowCtxt+, col :: GridColCtxt+} deriving (Eq, Generic, Show) -- | Grid column header -- -- * [Type Variables]("Brick.Widgets.TabularList#g:TypeVariables") -- * [Rendering]("Brick.Widgets.TabularList#g:Rendering") data GridColHdr n = GridColHdr {- draw :: ListFocused -> WidthDeficit -> FlatContext -> Widget n-, height :: Height -- ^ Height for column headers and column header row header+ draw :: ListFocused -> WidthDeficit -> GridColCtxt -> Widget n+, height :: ColHdrHeight } deriving Generic -- | Rendering functions for components of grid tabular list@@ -81,20 +95,17 @@ -- * [Type Variables]("Brick.Widgets.TabularList#g:TypeVariables") -- * [Rendering]("Brick.Widgets.TabularList#g:Rendering") data GridRenderers n e r = GridRenderers {- drawCell :: ListFocused -> WidthDeficit -> GridContext -> e -> Widget n+ cell :: ListFocused -> WidthDeficit -> GridCtxt -> e -> Widget n , rowHdr :: Maybe (RowHdr n e r) , colHdr :: Maybe (GridColHdr n)-, drawColHdrRowHdr :: DrawColHdrRowHdr n+, colHdrRowHdr :: ColHdrRowHdr n } deriving Generic --- | Widths for column headers and row columns.-type GridWidths = Seq Width- -- | * [Type Variables]("Brick.Widgets.TabularList#g:TypeVariables") data GridTabularList n e = GridTabularList { -- | The underlying primitive list that comes from brick list :: L.GenericList n Seq e-, widths :: GridWidths+, widths :: Seq ColWidth -- | Manipulating this field directly is unsafe. Use -- [column navigation]("Brick.Widgets.TabularList.Grid#g:ColumnNavigation") functions to manipulate this. If you still -- want to manipulate this directly, create a function that manipulates it, and test the function properly.@@ -106,125 +117,132 @@ :: n -- ^ The list name (must be unique) -> Seq e -- ^ The initial list elements -> ListItemHeight- -> GridWidths+ -> Seq ColWidth -> GridTabularList n e-gridTabularList n rows h widths = GridTabularList {+gridTabularList n rows (LstItmH h) widths = GridTabularList { list = L.list n rows h , widths = widths-, currentColumn = 0+, currentColumn = Ix 0 } +-- | Width accumulated in the process of traversing columns+newtype AccWidth = AccW Int deriving (Eq, Show)+ data VisibleColumns = -- | No column is visible- NoColumn+ NoColumn | -- | Only current column is visible- | CurrentColumn+ CurrentColumn | -- | The first column is shown at the left corner.- | AnchoredLeft {- right :: Int -- ^ The rightmost column that is visible- }+ AnchoredLeft {+ right :: Index -- ^ The rightmost column that is visible+ } | -- | The current column is shown in the center- | MiddleColumns {+ MiddleColumns { -- | The leftmost visible column- left :: Int,+ left :: Index, -- | The rightmost visible column- right :: Int,+ right :: Index, -- | Slide the columns to the left by this offset to show the current column in the center offset :: Int, -- | Total widths of all visible columns.- totalWidth :: Int- }+ tW :: AccWidth+ } | -- | The last column is shown at the right corner.- | AnchoredRight {+ AnchoredRight { -- | The leftmost visible column- left :: Int,+ left :: Index, -- | Slide the columns to the left by this offset to show the last column at the right corner. offset :: Int, -- | Total widths of all visible columns.- totalWidth :: Int+ tW :: AccWidth }- deriving Show+ deriving (Eq, Show) -- | Calculate visible columns with the width available for columns. It tries to show the current column in the center. -- If it can't show the current column in the center, the first column is shown at the left corner, or the last column -- is shown at the right corner. visibleColumns :: GridTabularList n e -> AvailWidth -> VisibleColumns-visibleColumns l aW = let curCol = l ^. #currentColumn in- case S.splitAt curCol (l ^. #widths) of+visibleColumns l (AvlW aW) = let+ (Ix curCol) = l ^. #currentColumn+ ws = l ^. #widths+ in case S.splitAt curCol ws of -- If current column is outside the boundary of row columns, return `NoColumn`. (_, Empty) -> NoColumn- (left, cW :<| right) -> if aW <= 0+ (left, ColW cW :<| right) -> if aW <= 0 -- If the available width is 0 or less than 0, then NoColumn- -- If the available width is less than the current column's width,- else if cW >= aW+ -- If the available width is equal to or less than the current column's width,+ else if aW <= cW then CurrentColumn- -- Otherwise,+ -- Otherwise else let -- The amount of space to the left of the current column shown in the center. lW = (aW - cW) `div` 2 -- The amount of space to the right of the current column shown in the center. rW = aW - lW - cW -- Calculate the leftmost visible column for the current column shown in the center.- leftForMiddle (l :|> w) idx accW = if accW+w < lW+ leftForMiddle (l :|> ColW w) (Ix idx) (AccW accW) = if accW+w < lW -- If the leftmost visible column hasn't been reached, go to the left by one column.- then leftForMiddle l (idx-1) (accW+w)+ then leftForMiddle l (Ix $ idx-1) (AccW $ accW+w) -- If the leftmost visible column has been reached, calculate the rightmost visible column.- else rightForMiddle idx (accW+w) right (curCol+1) 0+ else rightForMiddle (Ix idx) (AccW $ accW+w) right (Ix $ curCol + 1) (AccW 0) -- If there aren't enough columns to the left of the current column shown in the center, calculate the rightmost -- visible column for the first column shown at the left corner.- leftForMiddle Empty _ accW = rightForLeft right (curCol+1) (accW+cW)+ leftForMiddle Empty _ (AccW accW) = rightForLeft right (Ix $ curCol+1) (AccW $ accW+cW) -- Calculate the rightmost visible column for the current column shown in the center.- rightForMiddle li lAccW (w :<| r) ri accW = if accW+w < rW+ rightForMiddle (Ix li) (AccW lAccW) (ColW w :<| r) (Ix ri) (AccW accW) = if accW+w < rW -- If the rightmost visible column hasn't been reached, go to the right by one column.- then rightForMiddle li lAccW r (ri+1) (accW+w)+ then rightForMiddle (Ix li) (AccW lAccW) r (Ix $ ri+1) (AccW $ accW+w) -- If the rightmost visible column has been reached, return 'MiddleColumns'.- else MiddleColumns { left = li, right = ri, offset = lAccW-lW, totalWidth = lAccW+cW+accW+w }+ else MiddleColumns { left = Ix li, right = Ix ri, offset = lAccW-lW, tW = AccW $ lAccW+cW+accW+w } -- If there aren't enough columns to the right of the current column shown in the center, calculate the leftmost -- visible column for the last column shown at the right corner.- rightForMiddle _ _ Empty _ accW = leftForRight left (curCol-1) (accW+cW)+ rightForMiddle _ _ Empty _ (AccW accW) = leftForRight left (Ix $ curCol-1) (AccW $ accW+cW) -- Calculate the rightmost visible column for the first column shown at the left corner.- rightForLeft (w :<| r) idx accW = if accW+w < aW+ rightForLeft (ColW w :<| r) (Ix idx) (AccW accW) = if accW+w < aW -- If the rightmost visible column hasn't been reached, go to the right by one column.- then rightForLeft r (idx+1) (accW+w)+ then rightForLeft r (Ix $ idx+1) (AccW $ accW+w) -- If the rightmost visible column has been reached, return 'AnchoredLeft'.- else AnchoredLeft idx+ else AnchoredLeft $ Ix idx -- If there aren't enough columns to fill the available width with the first column at the left corner, return -- 'AnchoredLeft' with the last column as the rightmost visible column.- rightForLeft Empty idx _ = AnchoredLeft (idx-1)+ rightForLeft Empty (Ix idx) _ = AnchoredLeft (Ix $ idx-1) -- Calculate the leftmost visible column for the last column shown at the right corner.- leftForRight (l :|> w) idx accW = if accW+w < aW+ leftForRight (l :|> ColW w) (Ix idx) (AccW accW) = if accW+w < aW -- If the leftmost visible column hasn't been reached, go to the left by one column.- then leftForRight l (idx-1) (accW+w)+ then leftForRight l (Ix $ idx-1) (AccW $ accW+w) -- If the leftmost visible column has been reached, return 'AnchoredRight'.- else AnchoredRight { left = idx, offset = accW+w-aW, totalWidth = accW+w }+ else AnchoredRight { left = Ix idx, offset = accW+w-aW, tW = AccW $ accW+w } -- If there aren't enough columns to fill the available width with the last column at the right corner, return -- 'AnchoredLeft' with the last column as the rightmost visible column.- leftForRight Empty _ _ = AnchoredLeft $ length (l ^. #widths) - 1- -- Calculate the leftmost visible column for the current column shown in the center.- in leftForMiddle left (curCol-1) 0+ leftForRight Empty _ _ = AnchoredLeft $ Ix $ length ws - 1+ in leftForMiddle left (Ix $ curCol-1) (AccW 0) +-- | Height for tabular list components+newtype Height = H Int deriving (Eq, Show)+ renderColumns :: GridTabularList n e -> VisibleColumns- -> (WidthDeficit -> Index -> Width -> Widget n)+ -> (WidthDeficit -> Index -> ColWidth -> Widget n) -> Height -> Widget n-renderColumns l vCs dC h = Widget Greedy Fixed $ do+renderColumns l vCs dC (H h) = Widget Greedy Fixed $ do c <- getContext let cWs = l ^. #widths- curCol = l ^. #currentColumn+ Ix curCol = l ^. #currentColumn aW = c^^.availWidthL render $ case vCs of NoColumn -> emptyWidget CurrentColumn -> case S.lookup curCol cWs of Nothing -> error $ "Current column, " <> show curCol <> " is outside the boundary of column widths."- Just cW -> dC (max 0 $ cW - aW) curCol aW- AnchoredLeft right -> hBox $ zipWith (dC 0) [0..] $ toList $ S.take (right+1) cWs- MiddleColumns {left, right, offset, totalWidth} -> cropLeftBy offset $ setAvailableSize (totalWidth, h) $- hBox $ zipWith (dC 0) [left..] $ toList $ S.take (right-left+1) $ S.drop left cWs- AnchoredRight {left, offset, totalWidth} -> cropLeftBy offset $ setAvailableSize (totalWidth, h) $- hBox $ zipWith (dC 0) [left..] $ toList $ S.drop left cWs+ Just (ColW cW) -> dC (WdthD $ max 0 $ cW - aW) (Ix curCol) (ColW aW)+ AnchoredLeft {right=Ix r} -> hBox $ zipWith (dC $ WdthD 0) [Ix 0..] $ toList $ S.take (r+1) cWs+ MiddleColumns {left=Ix l, right=Ix r, offset, tW=AccW tw} -> cropLeftBy offset $ sz (tw, h) $+ hBox $ zipWith (dC $ WdthD 0) [Ix l..] $ toList $ S.take (r-l+1) $ S.drop l cWs+ AnchoredRight {left=Ix l, offset, tW=AccW tw} -> cropLeftBy offset $ sz (tw, h) $+ hBox $ zipWith (dC $ WdthD 0) [Ix l..] $ toList $ S.drop l cWs -- | Render grid tabular list renderGridTabularList :: (Ord n, Show n)@@ -232,35 +250,35 @@ -> ListFocused -> GridTabularList n e -- ^ The list -> Widget n-renderGridTabularList r lf l = Widget Greedy Greedy $ do+renderGridTabularList r (LstFcs f) l = Widget Greedy Greedy $ do c <- getContext let aW = c^^.availWidthL aH = c^^.availHeightL- GridRenderers {drawCell} = r+ cell = r ^. #cell GridTabularList {list=l', currentColumn=curCol} = l iH = l' ^. #listItemHeight- colHdrRow vCs rhw' rhwd = case r ^. #colHdr of+ colHdrRow vCs (RowHdrW rhw) (WdthD rhwd) = case r ^. #colHdr of Nothing -> emptyWidget- Just (GridColHdr {draw, height}) -> let- drawCol wd c w = setAvailableSize (w, height) $ draw lf wd (FlatContext c (c == curCol))- chrw = case r ^. #drawColHdrRowHdr of- Nothing -> fill ' '- Just dchrw -> dchrw lf rhwd- in setAvailableSize (rhw', height) chrw <+> renderColumns l vCs drawCol height- renderRow vCs i f r = let- drawCol wd c w = let gc = GridContext (FlatContext i f) (FlatContext c $ c == curCol)- in setAvailableSize (w, iH) $ drawCell lf wd gc r- in renderColumns l vCs drawCol iH- renderList = let vCs = visibleColumns l aW in- render $ colHdrRow vCs 0 0 <=> L.renderListWithIndex (renderRow vCs) lf l'- renderHdrList (RowHdr {draw, width, toRowHdr}) = let- rhw = width aW $ zipWithVisibleRowsAndIndexes l' aH toRowHdr- rhw' = min rhw aW- rhwd = max 0 $ rhw - aW- vCs = visibleColumns l $ aW - rhw'- renderHdrRow i f r = setAvailableSize (rhw', iH) (draw lf rhwd f $ toRowHdr r i) <+> renderRow vCs i f r- in render $ colHdrRow vCs rhw' rhwd <=> L.renderListWithIndex renderHdrRow lf l'- maybe renderList renderHdrList $ r ^. #rowHdr+ Just (GridColHdr {draw, height=ColHdrH chh}) -> let+ drawCol wd c (ColW w) = sz (w, chh) $ draw (LstFcs f) wd $ GColC c $ Sel (c == curCol)+ chrw = case r ^. #colHdrRowHdr of+ BlankCHRH -> fill ' '+ CHRH dchrw -> dchrw (LstFcs f) (WdthD rhwd)+ in sz (rhw, chh) chrw <+> renderColumns l vCs drawCol (H chh)+ row vCs i f r = let+ col wd c (ColW w) = let gc = GrdCtxt (GRowC (Ix i) (Sel f)) $ GColC c $ Sel (c == curCol)+ in sz (w, iH) $ cell (LstFcs f) wd gc r+ in renderColumns l vCs col (H iH)+ drawList = let vCs = visibleColumns l (AvlW aW) in+ render $ colHdrRow vCs (RowHdrW 0) (WdthD 0) <=> L.renderListWithIndex (row vCs) f l'+ drawHdrList (RowHdr {draw, width, toRH}) = let+ RowHdrW rhw' = width (AvlW aW) $ uncurry (zipWith toRH) $ visibleRowIdx l' (AvlH aH)+ rhw = min rhw' aW+ rhwd = WdthD $ max 0 $ rhw' - aW+ vCs = visibleColumns l $ AvlW $ aW - rhw+ hdrRow i f r = sz (rhw, iH) (draw (LstFcs f) rhwd (RowHdrCtxt $ Sel f) $ toRH r (Ix i)) <+> row vCs i f r+ in render $ colHdrRow vCs (RowHdrW rhw) rhwd <=> L.renderListWithIndex hdrRow f l'+ maybe drawList drawHdrList $ r ^. #rowHdr -- | Move to the left by one column. gridMoveLeft@@ -268,7 +286,7 @@ -> GridTabularList n e gridMoveLeft gl = if null $ gl ^. #list % #listSelected then gl- else gl & #currentColumn %~ max 0 . subtract 1+ else gl & #currentColumn % coercedTo @Int %~ max 0 . subtract 1 -- | Move to the right by one column. gridMoveRight@@ -276,16 +294,16 @@ -> GridTabularList n e gridMoveRight gl = if null $ gl ^. #list % #listSelected then gl- else gl & #currentColumn %~ min (length (gl ^. #widths) - 1) . (+1)+ else gl & #currentColumn % coercedTo @Int %~ min (length (gl ^. #widths) - 1) . (+1) -- | Move to the given column index gridMoveTo :: Index -> GridTabularList n e -- ^ The list -> GridTabularList n e-gridMoveTo n gl = if null $ gl ^. #list % #listSelected+gridMoveTo (Ix n) gl = if null $ gl ^. #list % #listSelected then gl- else gl & #currentColumn .~ (max 0 . min (length (gl ^. #widths) - 1)) n+ else gl & #currentColumn % coercedTo @Int .~ max 0 (min (length (gl ^. #widths) - 1) n) -- | Move to the first column. gridMoveToBeginning@@ -293,7 +311,7 @@ -> GridTabularList n e gridMoveToBeginning gl = if null $ gl ^. #list % #listSelected then gl- else gl & #currentColumn .~ 0+ else gl & #currentColumn % coercedTo @Int .~ 0 -- | Move to the last column. gridMoveToEnd@@ -301,7 +319,7 @@ -> GridTabularList n e gridMoveToEnd gl = if null $ gl ^. #list % #listSelected then gl- else gl & #currentColumn .~ length (gl ^. #widths) - 1+ else gl & #currentColumn % coercedTo @Int .~ length (gl ^. #widths) - 1 -- | 'GridRenderers' are needed because if row header renderer doesn't exist, width calculation is affected. gridMovePage :: Ord n@@ -310,16 +328,17 @@ -> EventM n (GridTabularList n e) () gridMovePage r f = do l <- get- unless (null $ l ^. #list % #listSelected) $ do- v <- lookupViewport $ l ^. #list % #listName+ let l' = l ^. #list+ unless (null $ l' ^^. L.listSelectedL) $ do+ v <- lookupViewport $ l' ^^. L.listNameL case v of Nothing -> return () Just vp -> let (aW, aH) = vp ^. #_vpSize- rhw = case r ^. #rowHdr of- Nothing -> 0- Just (RowHdr {width, toRowHdr}) -> width aW $ zipWithVisibleRowsAndIndexes (l ^. #list) aH toRowHdr- in f $ visibleColumns l $ aW - rhw+ RowHdrW rhw = case r ^. #rowHdr of+ Nothing -> RowHdrW 0+ Just (RowHdr {width, toRH}) -> width (AvlW aW) $ uncurry (zipWith toRH) $ visibleRowIdx l' (AvlH aH)+ in f $ visibleColumns l $ AvlW $ aW - rhw -- | Move to the previous page of columns. --
src/Brick/Widgets/TabularList/Internal/Common.hs view
@@ -1,8 +1,7 @@ module Brick.Widgets.TabularList.Internal.Common (- AvailHeight-, visibleRowsWithStart-, visibleRows-, zipWithVisibleRowsAndIndexes+ AvailHeight(..)+, visibleRowIdx+, sz ) where import Brick.Widgets.TabularList.Types@@ -14,27 +13,28 @@ import Data.Sequence (Seq) -- Brick import Brick.Widgets.List+import Brick.Types+import Brick.Widgets.Core -- | Height available for 'GenericList'-type AvailHeight = Int+newtype AvailHeight = AvlH Int deriving (Show, Eq) --- | Return visible rows and the index of the first visible row, given 'GenericList' and height available for list.-visibleRowsWithStart :: GenericList n Seq row -> AvailHeight -> ([row], Index)-visibleRowsWithStart l aH = let+-- | Return visible rows and their row indexes.+--+-- The visible rows are rows that are visible when the current row is either at the top or the bottom.+visibleRowIdx :: GenericList n Seq e -> AvailHeight -> ([e], [Index])+visibleRowIdx l (AvlH h) = let idx = fromMaybe 0 (l^.listSelectedL)- numPerHeight = case aH `divMod` (l^.listItemHeightL) of+ numPerHeight = case h `divMod` (l^.listItemHeightL) of (nph, 0) -> nph (nph, _) -> nph + 1+ -- If the current row is at the bottom, the start should be visible. start = max 0 $ idx - numPerHeight + 1+ -- If the current row is at the top, the row at start + length - 1 should be visible. length = numPerHeight * 2 rows = toList $ slice start length $ l^.listElementsL- in (rows, start)---- | Return visible rows, given 'GenericList' and height available for list.-visibleRows :: GenericList n Seq e -> AvailHeight -> [e]-visibleRows l aH = fst $ visibleRowsWithStart l aH+ in (rows, [Ix start..]) --- | Zip visible rows and their row indexes with a function.-zipWithVisibleRowsAndIndexes :: GenericList n Seq e -> AvailHeight -> (e -> Index -> c) -> [c]-zipWithVisibleRowsAndIndexes l aH f = let (es, s) = visibleRowsWithStart l aH- in zipWith f es [s..]+-- | It is a shortened version of 'setAvailableSize'.+sz :: (Int, Int) -> Widget n -> Widget n+sz (w, h) = if w <= 0 then const emptyWidget else setAvailableSize (w, h)
src/Brick/Widgets/TabularList/Internal/Lens.hs view
@@ -1,6 +1,6 @@ -- | Alternate operators for microlens. ----- Since optic operators take precedence, microlens operators need to be given alternate names.+-- Since optic operators take precedence in this library, microlens operators need to be given alternate names. module Brick.Widgets.TabularList.Internal.Lens ( (^^.) ) where
src/Brick/Widgets/TabularList/Mixed.hs view
@@ -1,9 +1,9 @@+{-# OPTIONS_HADDOCK show-extensions #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE NoFieldSelectors #-}-{-# OPTIONS_HADDOCK show-extensions #-} -- | Mixed tabular list is a list with different kinds of rows. -- -- @@ -17,11 +17,13 @@ -- Because this list is designed to show every column in the available space, horizontal scrolling is not supported. module Brick.Widgets.TabularList.Mixed ( -- * Data types- MixedContext(..)+ MixedRowCtxt(..)+, MixedColCtxt(..)+, MixedCtxt(..) , MixedColHdr(..) , MixedRenderers(..)-, CalcWidthsPerRowKind-, WidthsPerRow+, WidthsPerRowKind(..)+, WidthsPerRow(..) , MixedTabularList(..) -- * List construction , mixedTabularList@@ -52,21 +54,30 @@ import Brick.Widgets.Core import Graphics.Vty.Input.Events (Event) +-- | Mixed row context+data MixedRowCtxt = MRowC {+ index :: Index+, selected :: Selected+} deriving (Eq, Generic, Show)++-- | Mixed column context+newtype MixedColCtxt = MColC { index :: Index } deriving (Eq, Generic, Show)+ -- | Context for mixed columns-data MixedContext = MixedContext {- row :: FlatContext -- ^ Row context-, col :: Index -- ^ Index of column-}+data MixedCtxt = MxdCtxt {+ row :: MixedRowCtxt+, col :: MixedColCtxt+} deriving (Eq, Generic, Show) -- | Mixed column header -- -- * [Type Variables]("Brick.Widgets.TabularList#g:TypeVariables") -- * [Rendering]("Brick.Widgets.TabularList#g:Rendering") data MixedColHdr n w = MixedColHdr {- draw :: ListFocused -> Index -> Widget n+ draw :: ListFocused -> MixedColCtxt -> Widget n -- | A function for getting widths for column headers from the type that contains widths per row kind-, widths :: w -> [Width]-, height:: Height -- ^ Height for column headers and column header row header+, widths :: w -> [ColWidth]+, height :: ColHdrHeight } deriving Generic -- | Rendering functions for components of mixed tabular list@@ -74,27 +85,27 @@ -- * [Type Variables]("Brick.Widgets.TabularList#g:TypeVariables") -- * [Rendering]("Brick.Widgets.TabularList#g:Rendering") data MixedRenderers n e w r = MixedRenderers {- drawCell :: ListFocused -> MixedContext -> e -> Widget n+ cell :: ListFocused -> MixedCtxt -> e -> Widget n , rowHdr :: Maybe (RowHdr n e r) , colHdr :: Maybe (MixedColHdr n w)-, drawColHdrRowHdr :: DrawColHdrRowHdr n+, colHdrRowHdr :: ColHdrRowHdr n } deriving Generic -- | Calculate widths per row kind from visible list rows and the width available after row header. -- -- * [Type Variables]("Brick.Widgets.TabularList#g:TypeVariables")-type CalcWidthsPerRowKind e w = AvailWidth -> [e] -> w+newtype WidthsPerRowKind e w = WsPerRK (AvailWidth -> [e] -> w) deriving Generic -- | It is a function to get widths for each row. Use pattern matching to detect the kind of each row. Usually, a row -- kind is a data constructor of row data type. -- -- * [Type Variables]("Brick.Widgets.TabularList#g:TypeVariables")-type WidthsPerRow e w = w -> e -> [Width]+newtype WidthsPerRow e w = WsPerR (w -> e -> [ColWidth]) deriving Generic -- | * [Type Variables]("Brick.Widgets.TabularList#g:TypeVariables") data MixedTabularList n e w = MixedTabularList { list :: L.GenericList n Seq e -- ^ The underlying list that comes from brick-, calcWidthsPerRowKind :: CalcWidthsPerRowKind e w+, widthsPerRowKind :: WidthsPerRowKind e w , widthsPerRow :: WidthsPerRow e w } deriving Generic @@ -102,12 +113,12 @@ mixedTabularList :: n -- ^ The name of the list. It must be unique. -> Seq e -- ^ The initial list elements -> ListItemHeight- -> CalcWidthsPerRowKind e w+ -> WidthsPerRowKind e w -> WidthsPerRow e w -> MixedTabularList n e w-mixedTabularList n rows h cWprk wpr = MixedTabularList {+mixedTabularList n rows (LstItmH h) wprk wpr = MixedTabularList { list = L.list n rows h-, calcWidthsPerRowKind = cWprk+, widthsPerRowKind = wprk , widthsPerRow = wpr } @@ -117,35 +128,35 @@ -> ListFocused -> MixedTabularList n e w -- ^ The list -> Widget n-renderMixedTabularList r lf l = Widget Greedy Greedy $ do+renderMixedTabularList r (LstFcs f) l = Widget Greedy Greedy $ do c <- getContext let aW = c^^.availWidthL aH = c^^.availHeightL- MixedRenderers {drawCell} = r- MixedTabularList {list=l', calcWidthsPerRowKind=cWprk, widthsPerRow=wpr} = l+ cell = r ^. #cell+ MixedTabularList {list=l', widthsPerRowKind=WsPerRK wprk', widthsPerRow=WsPerR wpr} = l iH = l' ^^. L.listItemHeightL- colHdrRow wprk rhw' rhwd = case r ^. #colHdr of+ colHdrRow wprk (RowHdrW rhw) (WdthD rhwd) = case r ^. #colHdr of Nothing -> emptyWidget- Just (MixedColHdr {draw, widths, height}) -> let- drawCol ci w = setAvailableSize (w, height) $ draw lf ci- chrw = case r ^. #drawColHdrRowHdr of- Nothing -> fill ' '- Just dchrw -> dchrw lf rhwd- in setAvailableSize (rhw', height) chrw <+> hBox (zipWith drawCol [0..] $ widths wprk)- renderRow wprk i f row = let- drawColumn ci w = setAvailableSize (w, iH) $ drawCell lf (MixedContext (FlatContext i f) ci) row- in hBox $ zipWith drawColumn [0..] $ wpr wprk row- renderList = let wprk = cWprk aW $ visibleRows l' aH- in render $ colHdrRow wprk 0 0 <=> L.renderListWithIndex (renderRow wprk) lf l'- renderHdrList (RowHdr {draw, width, toRowHdr}) = let- (es, s) = visibleRowsWithStart l' aH- rhw = width aW $ zipWith toRowHdr es [s..]- rhw' = min rhw aW- rhwd = max 0 $ rhw - aW- wprk = cWprk (aW - rhw') es- renderHdrRow i f r = setAvailableSize (rhw', iH) (draw lf rhwd f $ toRowHdr r i) <+> renderRow wprk i f r- in render $ colHdrRow wprk rhw' rhwd <=> L.renderListWithIndex renderHdrRow lf l'- maybe renderList renderHdrList $ r ^. #rowHdr+ Just (MixedColHdr {draw, widths, height=ColHdrH chh}) -> let+ drawCol ci (ColW w) = sz (w, chh) $ draw (LstFcs f) (MColC ci)+ chrw = case r ^. #colHdrRowHdr of+ BlankCHRH -> fill ' '+ CHRH chrw -> chrw (LstFcs f) (WdthD rhwd)+ in sz (rhw, chh) chrw <+> hBox (zipWith drawCol [Ix 0..] $ widths wprk)+ row wprk i f r = let+ col ci (ColW w) = sz (w, iH) $ cell (LstFcs f) (MxdCtxt (MRowC (Ix i) (Sel f)) $ MColC ci) r+ in hBox $ zipWith col [Ix 0..] $ wpr wprk r+ drawList = let wprk = wprk' (AvlW aW) $ fst $ visibleRowIdx l' (AvlH aH)+ in render $ colHdrRow wprk (RowHdrW 0) (WdthD 0) <=> L.renderListWithIndex (row wprk) f l'+ drawHdrList (RowHdr {draw, width, toRH}) = let+ (es, is) = visibleRowIdx l' (AvlH aH)+ RowHdrW rhw' = width (AvlW aW) $ zipWith toRH es is+ rhw = min rhw' aW+ rhwd = WdthD $ max 0 $ rhw' - aW+ wprk = wprk' (AvlW $ aW - rhw) es+ hdrRow i f r = sz (rhw, iH) (draw (LstFcs f) rhwd (RowHdrCtxt $ Sel f) $ toRH r (Ix i)) <+> row wprk i f r+ in render $ colHdrRow wprk (RowHdrW rhw) rhwd <=> L.renderListWithIndex hdrRow f l'+ maybe drawList drawHdrList $ r ^. #rowHdr -- | Handle events for mixed tabular list with navigation keys. This just calls 'L.handleListEvent'. handleMixedListEvent :: Ord n
src/Brick/Widgets/TabularList/Types.hs view
@@ -1,79 +1,96 @@+{-# OPTIONS_HADDOCK show-extensions #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE NoFieldSelectors #-}-{-# OPTIONS_HADDOCK show-extensions #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Types shared by tabular list widgets. -- -- You don't have to import this module because modules for tabular list widgets re-export this module. module Brick.Widgets.TabularList.Types (- Index-, Width-, Height-, AvailWidth-, ListItemHeight-, FlatContext(..)-, WidthDeficit-, ListFocused-, Selected+-- * Tabular dimensions+ RowHdrWidth(..)+, ColWidth(..)+, ColHdrHeight(..)+, ListItemHeight(..)+-- * Shared rendering context+, Index(..)+, AvailWidth(..)+, WidthDeficit(..)+, ListFocused(..)+, Selected(..)+-- * Row header+, RowHdrCtxt(..) , RowHdr(..)-, DrawColHdrRowHdr+, ColHdrRowHdr(..) ) where -- base import GHC.Generics (Generic) -- brick import Brick.Types+import Brick.Widgets.Center+import Brick.Widgets.Core -- | Index of a tabular list component among the same kind of components-type Index = Int+newtype Index = Ix Int deriving (Enum, Eq, Generic, Show) --- | Width of a tabular list component-type Width = Int+-- | Width for row header+newtype RowHdrWidth = RowHdrW Int deriving (Eq, Generic, Show) --- | Height of a tabular list component-type Height = Int+-- | Width of a column header or a row column+newtype ColWidth = ColW Int deriving (Eq, Generic, Show) --- | Available width-type AvailWidth = Int+-- | Height for column headers and column header row header+newtype ColHdrHeight = ColHdrH Int deriving (Eq, Generic, Show) -- | The fixed height for row headers and row columns. -- -- If the height of row headers or row columns is not this height, then the list will look broken.-type ListItemHeight = Int+newtype ListItemHeight = LstItmH Int deriving (Eq, Generic, Show) --- | Context for one dimensional tabular list components-data FlatContext = FlatContext {- index :: Index -- ^ Index of a component-, selected :: Bool -- ^ Whether a component is selected-} deriving (Show, Generic)+-- | Available width+newtype AvailWidth = AvlW Int deriving (Eq, Generic, Show) --- | > widthDeficit = max 0 $ desiredWidth - availableWidth+-- | > widthDeficit = max 0 $ desiredColumnWidth - availableWidth -- -- It is positive when a column is shrunk to the available width. ----- If it is positive, you may want to remove paddings in your content because it is not followed or preceded by--- other columns.-type WidthDeficit = Int+-- If you use fixed paddings to introduce gaps between columns, you may want to remove fixed paddings when width deficit+-- is positive because a column is not preceded or followed by other columns and its width is shrunk.+--+-- The following examples show how to remove gaps between columns when width deficit is positive.+--+-- @+-- 'padRight' ('Pad' $ if widthDeficit > 0 then 0 else 1) $ 'padLeft' 'Max' content+-- @+--+-- @+-- 'padLeft' ('Pad' $ if widthDeficit > 0 then 0 else 1) $ 'hCenter' content+-- @+newtype WidthDeficit = WdthD Int deriving (Eq, Generic, Show) -- | Whether the list is focused in an application-type ListFocused = Bool+newtype ListFocused = LstFcs Bool deriving (Eq, Generic, Show) -- | Whether a tabular list component is selected-type Selected = Bool+newtype Selected = Sel Bool deriving (Eq, Generic, Show) +-- | Row header context+newtype RowHdrCtxt = RowHdrCtxt Selected deriving (Eq, Generic, Show)+ -- | Row header -- -- * [Type Variables]("Brick.Widgets.TabularList#g:TypeVariables") -- * [Rendering]("Brick.Widgets.TabularList#g:Rendering") data RowHdr n e r = RowHdr {- draw :: ListFocused -> WidthDeficit -> Selected -> r -> Widget n+ draw :: ListFocused -> WidthDeficit -> RowHdrCtxt -> r -> Widget n -- | Calculate row header width from visible row headers and the width available for a list row.-, width :: AvailWidth -> [r] -> Width+, width :: AvailWidth -> [r] -> RowHdrWidth -- | Get a row header from a list row and row index.-, toRowHdr :: e -> Index -> r+, toRH :: e -> Index -> r } deriving Generic -- | The renderer for column header row header. ----- If row headers and column headers exist and 'DrawColHdrRowHdr' is 'Nothing', then column header row header is--- filled with empty space. 'DrawColHdrRowHdr' merely allows you to customize column header row header.-type DrawColHdrRowHdr n = Maybe (ListFocused -> WidthDeficit -> Widget n)+-- If row headers and column headers exist and 'ColHdrRowHdr' is 'BlankCHRH', then column header row header is+-- filled with empty space. 'ColHdrRowHdr' merely allows you to customize column header row header.+data ColHdrRowHdr n = BlankCHRH | CHRH (ListFocused -> WidthDeficit -> Widget n) deriving Generic