LWXGL manages all on-screen widgets through a single flat array of elements, where each element is identified by an integer ID that you choose. The renderer iterates this array in ascending ID order on every frame, drawing each non-NULL element in sequence. Because the array grows on demand and IDs are entirely user-managed, you have full control over draw order and element identity throughout your application’s lifetime.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Dressedalarm184/lwxgl/llms.txt
Use this file to discover all available pages before exploring further.
Element IDs
Elements are stored in astd::vector<Element*> that is resized automatically whenever you use an ID larger than its current length. Any non-negative integer is a valid ID — you are not constrained to a small range.
The key rule is: creating an element with an ID that already exists silently replaces the previous one. The old element is freed (including any XImage data for image elements) before the new element is allocated into the same slot. This makes it straightforward to “update” an element by recreating it with the same ID.
Element IDs are entirely user-managed — LWXGL never auto-assigns an ID. Plan your ID namespace in advance to avoid accidental collisions between different parts of your application. A common convention is to allocate ID ranges per logical screen or subsystem (e.g. 0–9 for the main menu, 10–19 for the settings panel).
Element Types
LWXGL supports six built-in element types, each rendered by a dedicated function inrenderer.cc.
| Type ID | Name | Create function | Description |
|---|---|---|---|
| 0 | Text | GCreateText | Renders a string using the X11 9x15 bitmap font; supports \n newlines |
| 1 | Button | GCreateButton | Clickable rectangle with a centered label and an onclick callback; switches between three packed-color states (unpressed / hover / pressed) |
| 2 | Input | GCreateInput | Text input field; captures keyboard input while the mouse cursor is hovering over it; holds up to 127 characters |
| 3 | Rect | GCreateRect | Filled and/or outlined rectangle drawn directly with X11 primitives |
| 4 | Image | GCreateImage | Palette-indexed pixel buffer backed by an XImage; supports drawing primitives and sprites |
| 5 | Checkbox | GCreateCheckbox | Toggleable box with an optional text label drawn to its right |
Creating Elements
Text
| Parameter | Description |
|---|---|
id | Element ID — determines slot in the element array and draw order |
x, y | Top-left origin of the first line of text |
color | Palette index (0–15) for the text foreground |
text | Null-terminated string; \n advances to the next line (16 px spacing) |
Button
| Parameter | Description |
|---|---|
id | Element ID |
x, y | Top-left corner of the button rectangle |
w, h | Width and height in pixels |
u | Packed color byte for the idle (unpressed) state |
hvr | Packed color byte for the hover state |
p | Packed color byte for the pressed state |
label | Centered button label string |
onclick | Callback invoked on mouse button release inside the element bounds; may be NULL |
u, hvr, and p.
Input
-1 for w to have LWXGL calculate the width automatically based on max: (max + 1) * 9 + 10 pixels. The field displays a blinking _ cursor character while the mouse is hovering. Text is stored in a fixed 128-byte buffer; max is clamped to 127.
Rect
-1 for fg or bg to skip drawing that layer.
Image
GGetImageData, call GUpdateImage to sync changes into the underlying XImage. Only changed pixels are updated (dirty-tracked via a prev buffer) for efficiency.
Checkbox
label may be NULL if no text is needed. The checked indicator is drawn as a filled inner rectangle inset 4 px from each edge of the box.
Modifying Elements
To reposition or resize an existing element without destroying and recreating it, useGElemModifyBounds:
x, y, w, and h fields in-place. It works for all element types and takes effect on the next rendered frame.
Deleting Elements
id and sets the slot to NULL. For image elements (type 4), XDestroyImage is called and the pixel data and dirty-tracking buffers are freed before the element struct itself. Calling GDeleteElement on an ID that is already NULL or out of range is a no-op.
GTerminateWindow automatically calls GDeleteElement on every non-NULL slot before tearing down X11 resources, so manual deletion before shutdown is optional — but explicit deletion during runtime (e.g. when transitioning between screens) is good practice to avoid unbounded memory growth.