MacUi (mac_ui v0.1.0)

Copy Markdown View Source

A declarative macOS UI toolkit built on Elixir, GLFW, and Apple Metal.

UI is described as XML, parsed into an AST, and re-rendered every frame by a C++ engine process (mac_ui_engine) that talks to the Elixir runtime over stdio. The engine draws rects, lines, text, PNG images, and 3D wireframes with Metal, and reports mouse/keyboard input back as JSON events.

Opt-in startup

mac_ui does not start automatically. Add MacUi.Application to your supervision tree to launch the engine (a GLFW window) and the event controller:

children = [
  MacUi.Application
]

Supervisor.start_link(children, strategy: :one_for_one)

Usage

Load a UI XML file and subscribe the calling process to events:

MacUi.load_file(Application.app_dir(:mac_ui, "priv/sample_ui.xml"))
MacUi.subscribe()

UI events arrive as {:mac_ui_event, event} messages (see the README for the event shapes). Interactive widgets such as Checkbox, Toggle, Slider, Dropdown, Tabs, List, and Table are controller-driven: they emit :change events and the controller echoes the new value back so the rendered UI stays in sync.

Platform

macOS only. Requires a macOS 15+ SDK (Metal shader toolchain) and GLFW (brew install glfw). One window per VM.

Summary

Functions

Loads a UI XML file from disk and renders it.

Parses an XML string, calculates layouts, and renders to the screen.

Sets an attribute on an element by ID (controller-driven state push-back).

Sets multiple attributes on an element by ID.

Subscribes the calling process to receive UI events.

Updates the text content of an element by its ID/UUID.

Functions

load_file(path)

@spec load_file(String.t()) :: {:ok, String.t()} | {:error, term()}

Loads a UI XML file from disk and renders it.

render_xml(xml_string)

@spec render_xml(String.t()) :: :ok

Parses an XML string, calculates layouts, and renders to the screen.

set_attr(id, key, value)

@spec set_attr(String.t(), String.t(), String.t()) :: :ok

Sets an attribute on an element by ID (controller-driven state push-back).

set_attrs(id, attrs)

@spec set_attrs(String.t(), map() | list()) :: :ok

Sets multiple attributes on an element by ID.

subscribe()

@spec subscribe() :: :ok

Subscribes the calling process to receive UI events.

update_element_text(id, new_text)

@spec update_element_text(String.t(), String.t()) :: :ok

Updates the text content of an element by its ID/UUID.