raygui controls in Jolt

24 raygui examples written in Jolt, native Clojure on Chez Scheme, no JVM. They call raygui directly over its C ABI through jolt.ffi: no wrapper library, no codegen, no C shim. Unlike its sibling, raygui is header-only: there is no library to install, so this repo vendors the header and builds lib/libraygui.dylib itself.

A few of them

basics 4 · inputs 5 · collections 5 · containers 4 · dialogs 2 · color 2 · styling 2. See every one of them.

Why this is interesting

raygui's API is 61 functions that nearly all share one shape: a bounding Rectangle passed by value, application state through a pointer, an int result. Exactly one struct crosses that ABI by value anywhere in the control surface, which is rare enough to be worth explaining outright:

How it fits together

flowchart LR
  subgraph ex["24 example namespaces"]
    e["basic-controls · sliders · tab-bar
style-selector · scroll-panel · …"] end subgraph shared["net.b12n.raygui-jlt.raygui: one shared layer"] kw["keyword-argument control API
button! · slider! · panel! · …"] fb["jolt.ffi/defcfn binds
positional, mirroring C"] kw --> fb end lib["lib/libraygui.dylib
built from the vendored header"] rl["system libraylib
already loaded by the jolt process"] e --> kw fb -->|"Rectangle by value, one scratch buffer"| lib lib -->|"GetMousePosition, DrawRectangle, …"| rl

Every example is a small namespace over that one shared layer. Adding one touches exactly five places: the source namespace, a deps.edn alias, a check.clj require, a registry row in scripts/examples_registry.clj, and a bb.edn task.

What's here

Header-only, so this repo builds its own library

raygui ships one header, not a compiled library: no brew install, no package to find. bb lib:build compiles the vendored raygui.h into lib/libraygui.dylib, linked dynamically against the same raylib the process loads.

One binding layer

All the FFI binds, the keyword-argument control API, and cell handling for all eight cell types live in a single namespace. Examples stay small enough to read in one sitting.

Reads like Clojure, not like C

(rg/button! :x 24 :y 24 :w 120 :h 30 :text "Save"): positional binds at the boundary, keyword wrappers on top.

Provable without a display

RAYGUI_APP_AUTO_QUIT_MS closes the window on a timer and RAYGUI_APP_SHOT dumps a frame to PNG, so a windowed example can prove itself unattended.

A compile gate over all 24

bb check requires every example namespace headlessly. No window, no JVM, and it catches a broken binding across the whole suite at once.

A screenshot gate, not just a compile gate

A control drawn at the wrong bounds, or a style that never loaded, compiles perfectly and passes bb check. Looking at the actual PNG is the gate that catches it.

Quickstart

bb lib:check       # is raylib installed, and is libraygui already built?
bb lib:build       # …compile the vendored header into lib/libraygui.dylib

bb info            # grouped cheat-sheet of every example
bb style-selector  # run one (opens a window)
bb check           # headless compile-check of all 24, no window

Needs jolt and a system libraylib (raygui links against it dynamically at build time). babashka is optional but gives every example a friendly task; without it each one is a jolt -M:<alias> away. raygui.h is vendored at 5.0-9-gfbf5d95, zlib licensed, the same license this repo ships under.