uing

Crystal binding for libui

UIng

test Lines of Code Ask DeepWiki

UIng is a Crystal binding for libui-ng

Windows Mac Linux

Installation

Add the dependency to your shard.yml:

dependencies:
  uing:
    github: kojix2/uing

The required libui library is automatically downloaded via postinstall.

To download manually: crystal run download.cr

Usage

require "uing"

UIng.init

window = UIng::Window.new("Hello World", 300, 200)
window.on_closing do
  UIng.quit
  true
end

button = UIng::Button.new("Click me")
button.on_clicked do
  UIng.msg_box(window, "Info", "Button clicked!")
end

window.set_child(button)
window.show

UIng.main
UIng.uninit

DSL style

require "uing"

UIng.init do
  UIng::Window.new("Hello World", 300, 200) { |win|
    on_closing { UIng.quit; true }
    set_child {
      UIng::Button.new("Click me") {
        on_clicked {
          UIng.msg_box(win, "Info", "Button clicked!") 
        }
      }
    }
    show
  }

  UIng.main
end

For more examples, see examples. 

API Levels

Level Defined in Example Description
High-Level src/uing/*.cr button.on_clicked { }, etc. Object-oriented API
Low-Level src/uing/lib_ui/lib_ui.cr UIng::LibUI.new_button, etc. Direct bindings to libui
  • Almost all basic control functions such as Window, Label, and Button are covered.
  • APIs for advanced controls such as Table and Area are also provided. However, these are still under development and there may still be memory management issues.

Memory Safety

  • Most callbacks are stored as instance variables of their respective controls, which protects them from garbage collection (GC). Some callbacks are stored as UIng class variables, which serves the same purpose.

  • Instances of a control are passed as arguments to a parent control's append or set_child method. This establishes a reference from the parent to the child, creating a reference chain such as Window -> Box -> Button. This chain prevents the Garbage Collector (GC) from collecting the Button object (and its callbacks), thus avoiding a segmentation fault as long as the Window is present.

  • Some root components, such as Window and Menu, are stored as class variables to ensure protection from GC. This may cause memory leaks, but is acceptable for now.

  • The use of finalize is intentionally avoided in certain cases because the non-deterministic timing of memory deallocation by the GC is often incompatible with libui. Instead, RAII-style API is provided that automatically calls the free method upon exiting a block, relieving users of the need to call free manually.

Windows Setup

Hide Console Window

MinGW:

crystal build app.cr --link-flags "-mwindows"

MSVC:

crystal build app.cr --link-flags=/SUBSYSTEM:WINDOWS

MSVC Setup

Use Developer Command Prompt or add Windows Kits path:

$env:Path += ";C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64"

Closures in Low-Level Contexts

  • Many methods support Crystal closures because the underlying libui-ng functions accept a data parameter.

  • In some low-level APIs, such as function pointers assigned to struct members, no data can be passed. UIng works around this by using struct inheritance and boxed data to support closures in these cases.

  • This approach is used in controls like Table and Area.

Development

  • UIng::LibUI is the module for direct C bindings
  • Initially, crystal_lib was used to generate low-level bindings   - However, it required many manual conversions, such as changing LibC::Int to Bool. Currently, it is better to use AI.
  • When adding new UI components, follow the established callback management patterns
  • libui libraries are generated using GitHub Actions at kojix2/libui-ng in the pre-build branch.

Contributing

  • Fork this repository
  • Report bugs and submit pull requests
  • Improve documentation
  • Test memory safety improvements

License

MIT License

This project includes code generated using AI.

Repository

uing

Owner
Statistic
  • 3
  • 0
  • 2
  • 0
  • 0
  • about 3 hours ago
  • April 20, 2024
License

MIT License

Links
Synced at

Tue, 01 Jul 2025 15:22:21 GMT

Languages