hafen.ui builds windows and controls of your own, reads and changes the client’s widgets, and restyles both through one stylesheet.
local session = hafen.session():current()
hafen.log():write(session:ui():inventory():items():count() .. " items in the backpack")
local clock = hafen.ui():window():title("Clock"):size(160, 40):position(50, 50)
clock:on("Draw", function(draw_event)
draw_event:g():text(string.format("%d", hafen.time():clock() or 0), 6, 12)
end)
Every widget is the same Widget object. One you build, one the client put up, the one under the cursor, the container an Added subscription hands you.
| Tree | Reached through | Holds |
|---|---|---|
| The addon layer | hafen.ui():window(), :widget(), :column(), the controls, hafen.ui():root() |
What every addon builds, each widget answering :addon(). Drawn above every session and above the login screen. Stays when the player tabs between characters. |
| A character’s tree | session:ui():match(selector), :matchAll(selector), :root(), :node(id), :inventory(), :equipment() |
What the client put up for that character. Nothing you built is under it. Nothing the client built is reachable without it. |
Both trees take the same selector, which is also the key of a stylesheet rule. The pointer, hit tests and the scale are hafen.ui()’s alone: one screen, however many characters are logged in.
| Fact | Rule |
|---|---|
| Permission | Unprotected, except widget:send (widget.send) and widget:value(v) (widget.value) on a client widget. |
| Lifetime | Every window, overlay, sheet, subscription and native-widget change your addon made is given back on :reload and on disable. |
| Page | Covers |
|---|---|
| custom | Your own windows and bare canvases: setters, events, packing, resizing. |
| overlay | Painting over the screen or over one widget: the keyed collection and its draw order. |
| mirror | A surface showing another widget’s live picture, any tree, drawn or not. |
| controls | The client’s own controls, built and owned by your addon. |
| column | A column or a row that lays its children out and sizes itself to them. |
| lists | Listbox, dropdown, menu, grid and table: the row-source controls. |
| widget | The Widget object: every read, subscriptions, tooltips, focus, sending a message. |
| writes | Which writes answer on a widget you built and on one you found. Disabling one of yours. |
| selectors | The selector grammar, the roles, hit-testing, the inspector. |
| items | The items the client draws: reads and the protected item actions. |
| contents | What one item holds: nested items, a stated line, a fill meter. |
| container | ItemAdded/ItemRemoved on a container, and how deep they reach. |
| mouse | The pointer: position, hover, pick, modifiers, cursor, grab. |
| pixels | Design pixels, the unit of every coordinate, and the scale in force. |
| native | Moving, hiding and re-homing client widgets. Letting the user drag and size one. remember. |
| regions | The widgets standing for what the client paints by hand, the combat display’s elements among them. |
| edit | Changing what a client control says or does, and intercepting it. |
| replace | Watching for a widget and standing your own window in its place. |
| drawing | The g wrapper: text, shapes, images, measuring, the raster cache. |
| style | The stylesheet: rules, properties, the cascade. |
hafen.font — the handles a font property and g:text take.hafen.asset — the images and fonts your addon ships.