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.
LWXGL uses an integer ID system for all UI elements. Every element you create is assigned a unique integer ID that you choose. These IDs act as stable handles — you use them to update, query, reposition, and delete elements after creation. Elements are rendered in ascending ID order, so higher IDs are drawn on top.
All element coordinates are absolute pixels measured from the top-left corner of the window.
Element IDs
IDs are your responsibility — the library does not allocate them automatically. Rules:
- IDs must not collide between different active elements. Assigning an existing ID destroys and recreates the element at that slot.
- IDs can be any non-negative integer. The internal element vector resizes to
id + 1 on each creation, so leaving large gaps wastes memory.
/* Common element management functions */
void GDeleteElement(int id);
void GElemSetVisible(int id, int visible);
void GElemModifyBounds(int id, int x, int y, int w, int h);
int GElemInside(int id);
GDeleteElement frees all memory for the element and nulls its slot. Safe to call on an already-null slot.
GElemSetVisible hides (visible=0) or shows (visible=1) an element without freeing it. Hidden elements do not render and do not receive events.
GElemModifyBounds repositions and/or resizes an element in-place without recreating it. The element retains its type and data.
GElemInside returns 1 if the mouse cursor is currently over the element’s bounding box and the element is visible and on the active screen. Useful for hover effects outside the built-in button logic.
/* Move element 5 to (100, 200) and resize it to 120x30 */
GElemModifyBounds(5, 100, 200, 120, 30);
/* Temporarily hide element 3 */
GElemSetVisible(3, 0);
/* Check hover state in a custom draw callback */
if (GElemInside(7)) {
/* highlight something */
}
Text Labels
void GCreateText(int id, int x, int y, int color, const char* text);
| Parameter | Description |
|---|
id | Element ID. |
x, y | Position of the top-left corner. The first baseline is rendered at y + 11 (the 9x15 font’s ascent). |
color | Palette index (0–15) for the text color. |
text | The string to display. Use \n for line breaks — each line advances 15 pixels downward. |
/* Single-line label */
GCreateText(1, 20, 20, 15, "Hello, LWXGL!");
/* Multi-line label using \n */
GCreateText(2, 20, 60, 14, "Line one\nLine two\nLine three");
Text elements have no background. They draw directly over whatever is behind them. Use a GCreateRect underneath to create a labeled panel.
void GCreateButton(int id, int x, int y, int w, int h,
int u, int hvr, int p,
const char* label,
void (*onclick)(void));
| Parameter | Description |
|---|
id | Element ID. |
x, y | Top-left corner. |
w, h | Width and height in pixels. |
u | Packed color byte for the unpressed (idle) state. |
hvr | Packed color byte for the hover state. |
p | Packed color byte for the pressed state. |
label | Centered text drawn inside the button using the built-in 9x15 font. |
onclick | Callback invoked on left-click release. Pass NULL for no action. |
Packed Color Bytes
The u, hvr, and p parameters each pack two palette indices into one int:
- Lower nibble (bits 0–3): fill/background color.
- Upper nibble (bits 4–7): border/outline color.
/* Example: border = 7 (light gray), fill = 8 (dark gray) → 0x78 */
int color = (7 << 4) | 8; /* = 0x78 */
The renderer uses the fill color for XFillRectangle and the border color for XDrawRectangle and the label text.
void on_click(void) {
/* Respond to button press */
}
/* Idle: border=7 (light gray), fill=8 (dark gray)
Hover: border=15 (white), fill=7 (light gray)
Pressed: border=15 (white), fill=0 (black) */
GCreateButton(10,
/* x, y, w, h */ 50, 100, 120, 28,
/* unpressed */ 0x78,
/* hover */ 0xF7,
/* pressed */ 0xF0,
"Submit", on_click);
void GCreateInput(int id, int x, int y, int w, int h, int u, int hvr, int max);
char* GGetInput(int id);
| Parameter | Description |
|---|
id | Element ID. |
x, y | Top-left corner. |
w | Width in pixels. Pass -1 to auto-calculate: (max + 1) * 9 + 10. |
h | Height in pixels. |
u | Packed color byte for the inactive (not hovered) state. |
hvr | Packed color byte for the active (hovered) state. |
max | Maximum number of characters the user can type (up to 127). |
An input field becomes active when the mouse cursor hovers over it — keyboard events are routed to the hovered input. The internal buffer is 128 bytes (127 printable characters + null terminator). GGetInput returns a pointer directly into that buffer; copy it if you need to keep it after the element is deleted.
The renderer appends a _ cursor character to the displayed text when the field is active.
/* Simple login form */
#define ID_LABEL_USER 1
#define ID_INPUT_USER 2
#define ID_LABEL_PASS 3
#define ID_INPUT_PASS 4
#define ID_BTN_LOGIN 5
void setup_form(void) {
GCreateText(ID_LABEL_USER, 30, 30, 15, "Username:");
/* auto-width for 20 chars, height 22px */
GCreateInput(ID_INPUT_USER, 30, 50, -1, 22, 0x87, 0xF7, 20);
GCreateText(ID_LABEL_PASS, 30, 85, 15, "Password:");
GCreateInput(ID_INPUT_PASS, 30, 105, -1, 22, 0x87, 0xF7, 20);
}
void on_login(void) {
char* user = GGetInput(ID_INPUT_USER);
char* pass = GGetInput(ID_INPUT_PASS);
/* process user and pass */
(void)user; (void)pass;
}
Checkboxes
void GCreateCheckbox(int id, int x, int y, int size, int cb_col, int txt_col, const char* label);
int GGetCheckbox(int id);
| Parameter | Description |
|---|
id | Element ID. |
x, y | Top-left corner of the checkbox square. |
size | Side length of the checkbox square in pixels. |
cb_col | Packed color byte for the checkbox square (upper nibble = border, lower nibble = fill). |
txt_col | Palette index for the label text. |
label | Text rendered to the right of the checkbox square. Pass NULL for no label. |
GGetCheckbox returns 1 if the box is currently checked, 0 otherwise. Clicking the checkbox (or its label area) toggles the state.
/* 16×16 checkbox: border=7, fill=8; label in white (15) */
GCreateCheckbox(20, 40, 200, 16, 0x78, 15, "Enable notifications");
/* Later, read the state */
if (GGetCheckbox(20)) {
/* notifications enabled */
}
Rectangles
void GCreateRect(int id, int x, int y, int w, int h, int fg, int bg);
| Parameter | Description |
|---|
id | Element ID. |
x, y | Top-left corner. |
w, h | Width and height in pixels. |
fg | Palette index for the border/outline. Pass -1 to skip drawing the border. |
bg | Palette index for the fill. Pass -1 to skip filling. |
Rectangles are drawn with XFillRectangle (fill) and XDrawRectangle (outline). They are useful as visual containers or dividers behind other elements.
/* Solid dark panel at (10, 10), 300×200, dark gray fill, light gray border */
GCreateRect(0, 10, 10, 300, 200, 7, 8);
/* Place text and buttons with IDs > 0 inside the panel region */
GCreateText(1, 20, 25, 15, "Settings");
GCreateButton(2, 20, 50, 100, 24, 0x78, 0xF7, 0xF0, "Apply", NULL);
/* Horizontal divider line: 1px tall, no fill, border only */
GCreateRect(3, 10, 210, 300, 1, 7, -1);
Consoles
void GCreateConsole(int id, int x, int y, int cols, int rows, int con_clr, int txt_clr);
void GConsolePrint(int id, const char* format, ...);
void GConsoleClear(int id);
| Parameter | Description |
|---|
id | Element ID. |
x, y | Top-left corner. |
cols | Visible column count. The element width is computed automatically as cols * 9 + 17. |
rows | Visible row count. The element height is computed automatically as rows * 15 + 10. |
con_clr | Packed color byte for the console box: lower nibble = background fill, upper nibble = border and scrollbar color. |
txt_clr | Packed color byte for text: upper nibble = log text color, lower nibble = hover status overlay text color. |
A console element renders a scrollable text log. Text is appended with GConsolePrint, which accepts a printf-style format string. The internal format buffer is 1024 bytes — formatted output longer than 1023 characters is silently truncated by vsnprintf. Long lines wrap automatically at cols characters; explicit \n newlines are also supported.
Scrolling is driven by the scroll wheel when the cursor hovers over the console element (scroll up/down advances or retreats 3 lines). If the scroll position is at the bottom when new text arrives, the view automatically follows the new content. Press Space while hovering to jump to the bottom instantly.
GConsoleClear empties the text buffer and resets the scroll position to the top.
#define ID_LOG 10
void setup_console(void) {
/* 60-column, 12-row console at (10, 10) */
/* con_clr: border=7 (light gray), fill=8 (dark gray) */
/* txt_clr: text=14 (yellow), hover-status=15 (white) */
GCreateConsole(ID_LOG, 10, 10, 60, 12, 0x78, 0xEF);
}
void on_frame(int tick, float dt) {
(void)dt;
/* Print a timestamped line every 60 frames */
if (tick % 60 == 0)
GConsolePrint(ID_LOG, "Tick %d\n", tick);
}