The Barium Toolkit

An X Window System toolkit for Common Lisp

Home | Gallery | Source

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]

bmi-calculator.png

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]

tonegen.png

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]

molview.png

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]

chatroom.png

Features:

  • event loop with user-defined file descriptor event sources

Test programs (bundled with Barium)

windows

[source]

Top-level window with basic widgets

window.png

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

popup.png

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

multiple-windows.png

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]

grid-2.png

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:

grid-3.png

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]

container.png

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.png

cairo image

The class image holds image data read from a PNG on to a Cairo surface.

image.png

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]

combobox.png

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]

listbox.png

listbox-2.png

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]

fonts.png

textview and textedit

The textview and its derivative textedit deal with multi-line text. They support wrapping modes (none, char and word), and are scrollable in potentially both directions. They also feature settable alignments in both directions. [source: textedit textview]

textedit.png

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]

range.png

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]

scrollbox.png

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]

slider.png

slider-2.png

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]

pane.png

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]

notebook.png

Barium provides menu bars (to be used at the top of windows as a main application menu) to open up potentially hierarchically embedded (cascading) menus. The same kind of menu can be popped up on demand (via right-click or whatever mechanism preferred by the application). Menus are built from a simple recursive descriptor (list structure) supplied by the application. [source]

Menus provide support for:

  • hotkeys (auto-registered as window-global hotkeys; displayed in Emacs notation)
  • shortcut keys (underscored with red; flashed on menubar while pressing and holding Alt)
  • icons
  • tick-boxes
  • radio selectors
  • separators

menu.png

menu-2.png

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]

event-loop.png

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]

shell.png

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

dialog-msg.png

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

dialog-fc.png

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]:

gl-array.png

Gears [source]:

gl-gears.png

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]:

gl-shader-vao.png

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.