# `MacUi`
[🔗](https://github.com/thenatespack/mac_ui/blob/main/lib/mac_ui.ex#L1)

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.

# `load_file`

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

Loads a UI XML file from disk and renders it.

# `render_xml`

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

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

# `set_attr`

```elixir
@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`

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

Sets multiple attributes on an element by ID.

# `subscribe`

```elixir
@spec subscribe() :: :ok
```

Subscribes the calling process to receive UI events.

# `update_element_text`

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

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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
