boing 0.4.0

A safe, lightweight wrapper over libui-ng-sys
Documentation

boing

crates.io docs MPL 2.0 licensed

A safe, lightweight wrapper over libui-ng-sys.

Background

libui is a C library that provides a neutral interface to native GUI technologies (e.g., windows, widgets) on major OSes. libui-ng is the "next generation" of libui, developed and maintained separately. libui-ng-sys provides Rust bindings to libui-ng, and boing is a safe yet fairly unopinionated layer on top of libui-ng-sys.

Currently, boing only links with libui-ng—not the original libui. However, libui-ng-sys may be updated in the future to support a libui feature flag, in which case it should be trivial to update boing as well.

Terminology

In the context that boing uses them, the terms "widget" and "control" are not interchangeable. A widget is an interactive visual element, while controls are a specific subset of widgets that implement DerefMut<Target = boing::Control>. In particular, all widgets are controls except for Menu and MenuItem.

Design

See DESIGN.md for an explanation of how boing was designed.

Limitations

boing currently boxes callbacks passed to methods such as Window::on_closing and Button::on_clicked. This incurs a small performance and memory cost. However, this is an intentional choice for the purpose of convenience. For example, if callbacks were instead borrowed rather than owned by a transfer of ownership, the following code would fail to compile:

use boing::{Button, Error, Ui, Window};

fn main() -> Result<(), Error> {
    let ui: Ui;
    let window: Window;

    let mut button = create_button(&ui, "Hello World!".into())?;
    window.set_child(&mut button);

    window.show();
    ui.run();

    Ok(())
}

fn create_button<'cb>(ui: &Ui, text: &'cb String) -> Result<Button<'cb>, Error> {
    let button = ui.create_button("Press Me!")?;

    button.on_clicked(
        // This closure is dropped at the end of scope, so its lifetime ends before that of
        // `button`. It is not coerced to `fn()` because it captures `text`.
        &|| println!("{}", text),
    );

    button
}

In this case, the closure passed to Button::on_clicked would need to be routed through create_button as an argument. Such a hindrance was deemed untenable, hence the current callback design.

Project Progress

Feature Docs? Impl? libui-ng Type
Area uiArea
Button uiButton
Checkbox uiCheckbox
Combobox uiCombobox
FontButton uiFontButton
Form uiForm
FormEntry uiEntry
Grid uiGrid
Group uiGroup
Image uiImage
Label uiLabel
Menu uiMenu
MenuItem uiMenuItem
Path uiDrawPath
ProgressBar uiProgressBar
RadioButtons uiRadioButtons
Separator uiSeparator
Slider uiSlider
Spinbox uiSpinbox
Tab uiTab
Table uiTable
UniBox uiBox
Window uiWindow