brick
A declarative terminal user interface library
https://github.com/jtdaugherty/brick/
Version on this page: | 0.4.1 |
LTS Haskell 21.23: | 1.9@rev:1 |
Stackage Nightly 2023-12-08: | 2.1.1 |
Latest on Hackage: | 2.1.1 |
brick-0.4.1@sha256:7892a48be9966912481891cba9329792a10fbef15b585c70828f0ca1f3a639d1,8248
Module documentation for 0.4.1
brick
brick
is a terminal user interface programming
library written in Haskell, in the style of
gloss. This means you write
a function that describes how your user interface should look, but the
library takes care of a lot of the book-keeping that so commonly goes
into writing such programs.
brick
exposes a declarative API. Unlike most GUI toolkits which
require you to write a long and tedious sequence of “create a widget,
now bind an event handler”, brick
just requires you to describe
your interface – even the bits that are stateful – using a set of
declarative combinators. Then you provide a function to transform your
own application state when input (or other kinds of) events arrive.
Under the hood, this library builds upon vty.
This library deprecates vty-ui.
Feature Overview
brick
comes with a bunch of widget types to get you started:
- Vertical and horizontal box layout widgets
- Basic single- and multi-line text editor widgets
- List widget
- Progress bar widget
- Simple dialog box widget
- Border-drawing widgets (put borders around or in between things)
- Generic scrollable viewports
- Extensible widget-building API
- (And many more general-purpose layout control combinators)
In addition, some of brick
’s more powerful features may not be obvious
right away:
- All widgets can be arranged in predictable layouts so you don’t have to worry about terminal resizes.
- Most widgets can be made scrollable for free.
- Attribute management is flexible and can be customized at runtime on a per-widget basis.
brick
exports lens and non-lens
interfaces for most things, so you can get the full power of lens
if
you want it or use plain Haskell if you don’t. If a brick
library
function named thing
has a lens
version, the lens
version is named
thingL
.
Getting Started
TLDR:
$ cabal sandbox init
$ cabal install -j -f demos
$ .cabal-sandbox/bin/brick-???-demo
To get started, see the first few sections of the brick user guide.
Documentation
Your documentation options, in recommended order, are:
- FAQ
- The brick user guide
- Haddock (all modules)
- Demo programs
Status
brick
is young and may be missing some essential features. There are
some places were I have deliberately chosen to worry about performance
later for the sake of spending more time on the design (and to wait on
performance issues to arise first). brick
exports an extension API
that makes it possible to make your own packages and widgets. If you
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
Please file bug reports as GitHub issues. For best results:
-
Include the versions of relevant software packages: your terminal emulator,
brick
,ghc
, andvty
will be the most important ones. Even better, the output ofcabal freeze
would probably be helpful in making the problem reproducible. -
Clearly describe the behavior you expected …
-
… and include a minimal demonstration program that exhibits the behavior you actually observed.
Contributing
If you decide to contribute, that’s great! Here are some guidelines you should consider to make submitting patches easier for all concerned:
- If you want to take on big things, talk to me first; let’s have a design/vision discussion before you start coding. Create a GitHub issue and we can use that as the place to hash things out.
- If you make changes, try to make them consistent with the syntactic conventions I’ve used in the codebase.
- Please provide Haddock and/or user guide documentation for any changes you make.
Changes
Brick changelog
0.4.1
Bug fixes:
- Fixed a bug in the ‘visible’ combinator: If the size of the visibility request was larger than the available space, then the rendering of a viewport was toggling between two states, one with aligning on the end of the visibility request, and another one aligning on the start. This commit fixes it so that a visibility request is always aligned on the start if not enough space is available. (thanks Thomas Strobel ts468@cam.ac.uk)
Behavior changes:
- Honor multiple ‘visible’ markers in a single viewport with preference on the innermost request (thanks Thomas Strobel ts468@cam.ac.uk)
0.4
API changes:
- Added Brick.Widgets.Core.unsafeLookupViewport to make certain kinds of custom widget implementations easier when viewport states are needed (thanks Markus Hauck markus1189@gmail.com)
- List: added listClear and listReverse functions (thanks Markus Hauck)
- List: Derive instances for Functor, Foldable, Traversable (thanks Markus Hauck)
Documentation changes:
- Hyperlink “Data.Text.Markup” inside Brick.Markup haddock (thanks Markus Hauck)
- Fix typo in ‘Attribute Management’ section of user guide (thanks Markus Hauck)
0.3.1
Bug fixes:
- EventM newtype again instances MonadIO (thanks Andrew Rademacher)
0.3
API changes:
- Made EventM a newtype instead of a type alias
- List: listReplace now takes the new selected index and no longer does element diffing
Package changes:
- Removed the dependency on the Diff package
Misc:
- Applied some hlint hints (thanks Markus Hauck markus1189@gmail.com)
- Fixed a typo in the README (thanks Markus Hauck markus1189@gmail.com)
- Improved the renderList documentation (thanks Profpatsch mail@profpatsch.de)
- Types: added an explicit import of Applicative for older GHCs
0.2.3
Bug fixes:
- Fixed viewport behavior when the image in a viewport reduces its size enough to render the viewport offsets invalid. Before, this behavior caused a crash during image croppin in vty; now the behavior is handled sanely (fixes #22; reported by Hans-Peter Deifel)
0.2.2
Demo changes:
- Improved the list demo by using characters instead of integers in the demo list and cleaned up item-adding code (thanks Jøhannes Lippmann code@schauderbasis.de)
0.2.1
Bug fixes:
- List:
- Fixed size policy of lists so that rather than being Fixed/Fixed, they are Greedy/Greedy. This resolves issues that arise when the box layout widget renders a list widget alongside a Fixed/Fixed one. (Closes issue #17, thanks Karl Voelker)
- Scrolling:
- vScrollPage actually scrolls vertically now rather than horizontally (Thanks Hans-Peter Deifel hpd@hpdeifel.de)
0.2
API changes:
- Added top-level
Brick
module that re-exports the most important modules in the library. - List:
- Now instead of passing the item-drawing function to the
list
state constructor, it is passed torenderList
renderList
now takes the row height of the list’s item widgets. The list item-drawing function must respect this in order for scrolling to work properly. This change made it possible to optimize the list so that it only draws widgets visible in the viewport rather than rendering all of the list’s items (even the ones off-screen). But to do this we must be able to tell in advance how high each one is, so we require this parameter. In addition this change means that lists no longer support items of different heights.- The list now uses Data.Vector instead of [a] to store items; this permits efficient slicing so we can do the optimized rendering described above.
- Now instead of passing the item-drawing function to the
- The
HandleEvent
type classhandleEvent
method now runs inEventM
. This permits event-handling code implemented in terms ofHandleEvent
to do get access to viewport state and to run IO code, making it just as powerful as code in the top-levelEventM
handler. - Many types were moved from
Brick.Widgets.Core
andBrick.Main
toBrick.Types
, making the former module merely a home forWidget
constructors and combinators. - The
IsString
instance forWidget
was removed; this might be reinstated later, but this package provides enoughIsString
instances that things can get confusing. EventM
is now reader monad over the most recent rendering pass’s viewport state, in addition to being a state monad over viewport requests for the renderer. Added thelookupViewport
function to provide access to the most recent viewport state. Exported theViewport
type and lenses.- Now that
handleEvent
is now anEventM
action, composition withcontinue
et al got a little messier when using lenses to update the application state. To help with this, there is nowhandleEventLensed
.
Bugfixes:
- Lists now perform well with 10 items or a million (see above; fixes #7, thanks Simon Michael)
- Added more haddock notes to
Brick.Widgets.Core
about growth policies. - Forced evaluation of render states to address a space leak in the renderer (fixes #14, thanks Sebastian Reuße seb@wirrsal.net)
- str: only reference string content that can be shown (eliminates a space leak, fixes #14, thanks Sebastian Reuße seb@wirrsal.net)
Misc:
- Added a makefile for the user guide.
- List: added support for Home and End keys (thanks Simon Michael)
- Viewports: when rendering viewports, scroll requests from
EventM
are processed before visibility requests from the rendering process; this reverses this previous order of operations but permits user-supplied event handlers to reset viewports when desired.
Package changes:
- Added
deepseq
dependency
0.1
Initial release