The Barium Toolkit
The below screenshots might not always be up to date and are certainly not exhaustive. They are meant to convey a quick idea of what is achievable with Barium. In all cases, a direct link to the respective source code is provided.
Demos (bundled with Barium)
bmi-calculator
This is a basic example utilizing a fixed layout. [source]
Features:
- fixed layout
- entries with input validation
tonegen
This demo is meant to be a close reproduction of the GTK via CFFI example (and other similar applications of Matthew D. Miller's excellent Survey of the State of GUI Programming in Lisp). [source]
Features:
- grid layout
- logarithmic slider for frequency adjustment
- widgets wired together via conventional event bindings
molview
This demo is derived from Doug Hoyte's Molecule Viewer distributed as
the molview example program of cl-opengl (under examples/misc):
original source. The original OpenGL code is preserved as much as
possible; the demo adds UI elements allowing easy adjustment and
visual parameter feedback, while keeping all the original key
bindings.
[source]
Features:
- grid layout
- using OpenGL (including GLUT functions)
- setup variable-like UI state accessors to simplify code
- user-defined periodic timer source plugged into event loop (Random walk)
- window-global registered key bindings
- auxiliary window opened as a singleton on '?'-button (will be raised if already open)
Tip: click and drag left mouse button (for X and Y axis) and/or use scrollwheel (for Z axis) on GL area to adjust rotation (in addition to sliders and key bindings).
chatroom
The chatroom demonstrates Barium's support for writing fully async (event driven) applications. This demo multiplexes I/O from several event sources (in this case: network sockets) together with X Window System events in the same Barium event loop. Running all code in a single thread avoids the many traps and complexities of coordination and communication between threads and makes the program much easier to reason about. It is also the best design for high performance applications! [source]
Features:
- event loop with user-defined file descriptor event sources
Test programs (bundled with Barium)
windows
[source]
Top-level window with basic widgets
This demonstrates a fixed layout with some widgets such as a label, a regular button, a button displaying an image and another one displaying a figure, some checkbuttons, a text entry and an editable combobox. It also has various handlers bound to several events, demonstrating basic use of event bindings.
Transient & pop-up windows
This example demonstrates window placement (initial alignment); transient vs. regular top-level windows; pop-up dialogs and popup windows containing any desired widgets (in this case, a clickable button).
Multiple top-level windows
Customizing and programmatically changing text and background colors; various x/y label alignments; keeping track of top-level windows.
grid
Most example programs use the grid layout manager; this is a dedicated example. [source]
Fixed aspect ratio
The grid is able to accommodate aspect ratio constraints (width per height) as specified on its children, as the below example demonstrates:
container
The container is a base class (also usable as a widget on its own)
that provides a grid layout manager. Toplevel windows are containers,
but containers can be hierarchically embedded. This example
demonstrates two containers placed in the toplevel window's grid
layout, each with 3 buttons, one horizontally and one vertically
packed. The container is scrollable; see fonts example. [source]
cairo
All widgets other than OpenGL areas are descendants of canvas, which
provides (optionally double-buffered) Cairo drawing. This is a
dedicated example demonstrating some non-trivial Cairo functionality.
[source]
cairo image
The class image holds image data read from a PNG on to a Cairo
surface.
N.B.: Buttons have support for displaying such an image instead of text.
combobox
The combobox is a composite widget: it is built out of an actual
entry and button widget, which triggers a popup containing a listbox.
As it is just an ordinary listbox, it can contain a list of complex
data (with its car containing the string to be displayed), or just
plain strings. [source]
The entry contents can be manually editable or only changeable via list selection. A non-editable combobox (not allowing manual editing of the entry field, only selection of a list item) reacts to mouse wheel events in the entry field, making it convenient to scroll the selected item up/down the list without popping it up. Other "obvious" key bindings are implemented as well.
listbox
The listbox holds a list of user-provided items: either just strings
or complex data which has a string (to be displayed) as its car.
Three select modes are available: none, single and multiple. The
key bindings and other behaviour of the widget depends on this mode.
The listbox is scrollable, as demonstrated by the second test
program below. [source]
fonts
Barium draws text via Cairo functions; the list of available fonts can be queried (at this time) via an Xft binding. This example also demonstrates how multiple (potentially many) widgets can be arranged into a grid that is itself made (efficiently) scrollable. [source]
textview and textedit
range
The range class is not a widget by itself. Rather, it is an
auxiliary object representing a range of values. It supports
scrollbars as well as sliders, and potentially other use cases. This
example demonstrates a range shared between four scrollbars, with all
combinations of horizontal/vertical and normal/reversed. [source]
scrollbox
Barium has a generic way of making widgets scrollable. Using a
scrollable widget is possible via manually connecting it to a
scrollbar; an even simpler way is embedding it into a scrollbox that
may provide scrollbars in one or both directions. The scrollbars can
also be hidden and shown dynamically as required. [source]
slider
Sliders can be horizontal or vertical, with potentially reversed scale, and can have a linear or logarithmic taper. They can be bound to an external range object (potentially sharing it with other widgets) or have their own internal range instance. Sliders receive keyboard focus and respond to arrows and Page Up/Down keys. [source]
pane
Panes are helpful when arranging complex user interfaces. They help the user feel in control as they allow seamless resizing of their subdivisions.
A pane can be split horizontally or vertically, and can contain one, two, or even more child widgets. This demo presents multiple horizontal panes stacked in a vertical pane. [source]
notebook
Similar to a pane, a notebook can be helpful when arranging complex user interfaces with many elements. Contrary to a pane, a notebook shows only one of its children at any moment. The notebook allows runtime management (inserting and removing) of its children that make up the pages, and also supports custom widgets placed into the selector tabs. The example demonstrates this with tabs that contain a label and an image. [source]
event loop
The main event loop (tasked with processing and dispatching X Window System events) is a first-class object in Barium. It is made available for applications to manage (add or remove) their own handlers to various events on demand. This capability supports event-driven (async) programming, allowing for the creation of highly efficient yet comprehensible programs without the need to run concurrent activities in separate threads (and the added complexity associated with synchronizing and communicating between them).
Handlers can be registered for:
- file descriptor read and error events
- periodic (recurring) timer events
- deferred (run-once) timer events
- idle events (to be run as frequently as possible)
This example demonstrates timed events (both periodic and
deferred). For events on file descriptors, take a look at the shell
example. [source]
shell
With Barium's ba-ext:shell facility, it is possible to create an
inferior process to run an external program concurrently with Common
Lisp. The standard input, output and error of this process is
connected to file descriptors accessible from Lisp. These descriptors
can be used to plug user-defined handlers into the Barium event loop,
allowing you to build a fully event-driven (async) application where
GUI events and I/O are handled by the same thread. To perform actual
I/O from Lisp, use make-fd-stream (hopefully supplied by your Common
Lisp implementation) to obtain a stream.
This example program runs /bin/sh and allows you to interact with
it. Note that this is not meant to be a functional terminal
application, just a small demo! [source]
dialogs
Barium provides a small but growing set of dialogs ready to be invoked by the application. There is nothing magical here that you could not write yourself using already existing widgets. [source]
Message dialog
The message dialog contains a textview and a button to close the window. It can be invoked by providing the text (and optionally any other arguments) of the textview as well as (optionally) the title, the caption of the close button, and text area dimensions (width and height). If any of the latter are provided, the text will be scrollable in the respective direction; if omitted, the window will assume the size required by the textview.
File chooser dialog
The file chooser dialog lets the user browse the filesystem (starting from an arbitrary directory) going up to the parent or down into any subdirectory; to apply filters specified by the application; to toggle the visibility of hidden files; and to select a file (unless hidden by the chosen filter).
Double-clicking on list entries (or pressing Enter while they are selected) invokes Select, which concludes the dialog or enters the selected subdirectory.
When invoking the dialog with :freeform-entry t an additional entry
for entering an arbitrary filename is included. A variant of an
existing file can quickly be specified by clicking on it in the list
(populating its name into the entry), then editing it. A new
subdirectory named after the entry text can also be created by
pressing + Folder. This is suitable for using the dialog for picking
the destination of "Save As…" operations.
OpenGL area
Part of Barium's raison d'être is easy integration of OpenGL-drawn
widgets with regular (Cairo-drawn) ones. OpenGL code (via cl-opengl)
can be used to render into the gl-area widget. These examples
demonstrate various OpenGL features, but they all build on a plain
gl-area with user-bound event handlers. (In a typical "real"
program, the gl-area would be subclassed and the derived class would
be endowed with methods instead of binding ad-hoc handlers to it.) The
GL code of these programs is derived from corresponding "bare"
examples distributed with cl-opengl.
GL Arrays [source]:
Gears [source]:
Tip: as an alternative to the six adjustment buttons, click and drag left mouse button (for X and Y axis) and/or use scrollwheel (for Z axis) on GL area to adjust rotation.
Shader VAO [source]:
This last example demonstrates loading, compiling and linking the GL program (vertex and fragment shaders from GLSL source in a string), creating and binding a VAO (vertex array object), updating and refreshing the view at the framerate.