MICROUI-PORT.md 3.4 KB

microui port to GNU Modula-2 - summary (2026-09-16)

An ISO Modula-2 port of microui v2.02 (immediate-mode UI by rxi, MIT), built with the existing tigr binding, plus a tigr-rendered demo.

Files

file role
microui.def public API: types, constants, widgets
microui.mod full port of microui.c (core, layout, widgets, command list)
microuiHelpers.def/.mod bit ops, memory/string helpers, %f/%g number formatting
examples/microui-demo/microui-demo.mod interactive demo (mouse/keyboard, tigr renderer)
examples/microui-demo/microui-headless.mod off-screen smoke test -> microui-demo.png
examples/microui-demo/microui-demo.png reference screenshot

The upstream C sources are vendored in microui-master/.

Build

From modula2/:

gcc -c ../tigr-master/tigr.c -o tigr.o
gm2 -fiso -c helper.mod
gm2 -fiso -I. -c microuiHelpers.mod
gm2 -fiso -I. -c microui.mod

From modula2/examples/microui-demo/:

gm2 -fiso -I ../../ ../../tigr.o ../../helper.o \
     ../../microuiHelpers.o ../../microui.o \
     microui-demo.mod -o microui-demo -lGL -lX11
gm2 -fiso -I ../../ ../../tigr.o ../../helper.o \
     ../../microuiHelpers.o ../../microui.o \
     microui-headless.mod -o microui-headless -lGL -lX11

Run

./microui-demo        # window; ESC quits
./microui-headless    # writes microui-demo.png

What works (verified)

Windows, title bars, close/resize handles, headers, tree nodes, buttons, checkboxes, sliders, number fields, text boxes, panels, popups, scroll bars, word-wrapped text, clipping, z-ordering and hover/focus tracking. The demo was run under X11 and the headless test renders an identical layout to PNG.

Design adaptations

  • The C mu_Command union is represented by a BaseCommand header and concrete command records, accessed with CAST(CommandPtr, ...).
  • Callbacks are invoked through one-argument records (TextWidthArgs, TextHeightArgs, FrameArgs).
  • drawText takes an ADDRESS + length so substrings need no copy.
  • tigr's tigrFillRect fills only the interior of a rectangle (x+1, y+1, w-2, h-2); a filled microui rectangle is therefore drawn as tigrRect (1px outline) + tigrFillRect (interior). Using tigrFillRect alone shrinks every rect by one pixel and makes all 1px borders (window and control outlines) disappear.
  • The demo window uses TIGR_AUTO: tigr resizes the bitmap to match the window (1:1), so the framebuffer is never cropped or letterboxed and resizing works like a normal resizable window. Forcing a scale with TIGR_2X crops the bitmap when it doesn't fit the screen (that cut the window title row), and TIGR_FIXED letterboxes it. The renderer uses bmp^.w/bmp^.h for its clip and clear.

GNU Modula-2 16.0.1 issues worked around

See ANALYSIS.md for the full list. Highlights:

  • Procedure types accept only a single unnamed formal parameter when the .def is parsed as part of the .mod.
  • Inline POINTER TO T is rejected in formal parameter lists and in CAST; named pointer aliases are used instead.
  • SHORTREAL(integer) is miscompiled to 0; conversions go through FLOAT (microuiHelpers.IntToReal/CardToReal).
  • TRUNC rejects values whose type is a type alias (Real = SHORTREAL); ROUND is undefined; EXIT is only allowed inside LOOP.
  • ADDRESS has no + (use ADDADR); function results cannot be dereferenced directly or discarded.