How kojix2/uing works
Purpose and Entry Points
UIng is a Crystal-language binding to the native C library libui-ng, providing cross-platform desktop GUI controls, layout, menus, drawing, tables, and images. Consumer applications require "uing", initialize the runtime, construct controls, run the native event loop, then uninitialize. The public aggregation and runtime entry point are src/uing.cr and src/uing/lib_ui/lib_ui.cr; package installation/native-library download is driven by shard.yml and download.cr.
API Layer Boundary
The repository intentionally separates:
• Low-level FFI: UIng::LibUI exposes direct libui-ng C bindings and C-compatible structs. Paths: src/uing/lib_ui/lib_ui.cr, src/uing/lib_ui/control.cr, include/ui.h.
• High-level Crystal wrappers: object-oriented controls own native handles, expose Crystal callbacks, DSL block construction, and lifecycle methods. Paths: src/uing/control.cr, src/uing/window.cr, src/uing/block_constructor.cr.
This is the critical managed/unmanaged boundary: Crystal GC protects wrapper references and callbacks, while libui-ng resources still require explicit destroy or free.
UI Composition and Lifecycle
Control is the common abstraction for native widgets. Concrete controls and containers form parent/child ownership trees: destroying a native parent destroys its current children, while supported container deletion detaches children for reuse. Windows and menus are retained as roots to avoid premature GC. Core paths: src/uing/control.cr, src/uing/window.cr, src/uing/box.cr, src/uing/group.cr.
Application control flow is: UIng.init → construct menus/windows/control tree and install callbacks → show → UIng.main native event loop → quit/explicit resource release → UIng.uninit. Window-closing and global quit callbacks are the primary shutdown boundary.
Widget and Layout Surface
Standard controls map Crystal methods and event handlers onto libui-ng widgets. Layout containers encode the supported native composition model rather than pixel positioning: boxes, forms, tabs, groups, and grids. Key paths: src/uing/button.cr, src/uing/entry.cr, src/uing/form.cr, src/uing/grid.cr, src/uing/tab.cr.
Menus and dialog behavior are also native-backed and window-associated: src/uing/menu.cr, src/uing/menu_item.cr, src/uing/window.cr.
Advanced Data and Rendering Subsystems
Tables use a model/handler contract and selections/value types. They require explicit model and selection freeing at defined ownership boundaries; tables must be destroyed before their model. Paths: src/uing/table/table.cr, src/uing/table/table/model.cr, src/uing/table/table/model/handler.cr.
Areas provide custom drawing and input via native handler callbacks. Drawing contexts, paths, brushes, matrices, text layout, and event structures are represented as Crystal wrappers. Extended handler structures/trampolines bridge C function pointers back to boxed Crystal closures. Paths: src/uing/area/area.cr, src/uing/area/area/handler.cr, src/uing/area/area/draw/context.cr.
Native Runtime and Platform Dependencies
The binding links against downloaded patched libui-ng binaries. libui-ng uses platform-native GUI stacks: Win32 with Direct2D/DirectWrite on Windows, Cocoa/AppKit on macOS, and GTK 3/Pango on Linux/Unix. Supported CI targets cover Linux x64/ARM64, macOS Intel/ARM64, and Windows MSVC/MinGW/UCRT variants, via .github/workflows/ci-linux-x64.yml and corresponding platform workflows. Windows builds include Common Controls v6 manifest resources: comctl32.manifest, comctl32.rc.
Verification and Distribution Examples
The gallery is the primary executable compatibility surface for controls and rendering; screenshot automation runs it across OSes: examples/gallery/control_gallery.cr, .github/workflows/screenshot.yml, .github/actions/screenshot/action.yml. More complete app/distribution patterns live separately in examples/md5_checker/src/app.cr and examples/air_hockey/src/air_hockey/app.cr.
Main entry points: control.cr Control wrapper base · lib_ui.cr LibUI bindings · area.cr Areas · window.cr Windows & shutdown
Components 19
Crystal API
Public runtime, FFI, and managed wrapper boundary.
- UIng entry point · Initializes, runs, and uninitializes the native runtime.
src/uing.cr - LibUI bindings · Direct libui-ng calls and C-compatible structures.
src/uing/lib_ui/lib_ui.cr - Native control ABI
src/uing/lib_ui/control.cr - Control wrapper base · Owns native handles and provides lifecycle and callback behavior.
src/uing/control.cr - Block construction
src/uing/block_constructor.cr
UI Composition
Native-backed controls, layout, and window roots.
- Windows & shutdown · Retains window roots and supplies close and quit boundaries.
src/uing/window.cr - Standard controls · Crystal widget methods and event handlers over native controls.
src/uing/button.cr - Layout containers · Build parent-child ownership trees with native layout rules.
src/uing/box.cr - Menus & menu items · Window-associated native menu behavior.
src/uing/menu.cr
Advanced UI
Data-model and custom-rendering subsystems.
- Tables · Tables must be destroyed before their native model.
src/uing/table/table.cr - Table model handlers · Model and handler contract with explicit model and selection freeing.
src/uing/table/table/model/handler.cr - Areas · Custom drawing and input backed by native handlers.
src/uing/area/area.cr - Area callback bridge · Bridges native function pointers to boxed Crystal closures.
src/uing/area/area/handler.cr - Drawing context · Wraps drawing contexts and related rendering resources.
src/uing/area/area/draw/context.cr
Native Delivery
Downloaded runtime and platform GUI dependencies.
- libui-ng · Patched downloaded binary implementing native controls and event loop.
download.cr - Platform GUI stacks · Win32/Direct2D, Cocoa/AppKit, or GTK 3/Pango.
Examples & CI
Executable compatibility and screenshot coverage.
- Control gallery · Primary executable compatibility surface.
examples/gallery/control_gallery.cr - Screenshot automation · Runs gallery screenshots across operating systems.
.github/workflows/screenshot.yml
Other components
- Consumer application · Requires UIng and owns application shutdown.
Connections 20
- Consumer application → UIng entry point: require and lifecycle
- UIng entry point → LibUI bindings: init / main / uninit
- LibUI bindings → Native control ABI: defines ABI
- Control wrapper base → LibUI bindings: native calls
- Block construction → Control wrapper base: constructs
- Windows & shutdown → Control wrapper base: extends control lifecycle
- Standard controls → Control wrapper base: extends
- Layout containers → Control wrapper base: extends
- Layout containers → Standard controls: owns child controls
- Windows & shutdown → Layout containers: hosts control tree
- Menus & menu items → Windows & shutdown: associated with
- Tables → Table model handlers: uses model and handlers
- Tables → Control wrapper base: native control lifecycle
- Areas → Area callback bridge: installs callbacks
- Areas → Drawing context: draws through
- Areas → Control wrapper base: native control lifecycle
- LibUI bindings → libui-ng: links against
- libui-ng → Platform GUI stacks: uses
- Control gallery → UIng entry point: exercises
- Screenshot automation → Control gallery: runs