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:

```rust 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 createbutton<'cb>(ui: &Ui, text: &'cb String) -> Result, Error> { let button = ui.createbutton("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