Skip to main content

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);
ParameterDescription
idElement ID.
x, yPosition of the top-left corner. The first baseline is rendered at y + 11 (the 9x15 font’s ascent).
colorPalette index (0–15) for the text color.
textThe 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.

Buttons

void GCreateButton(int id, int x, int y, int w, int h,
                   int u, int hvr, int p,
                   const char* label,
                   void (*onclick)(void));
ParameterDescription
idElement ID.
x, yTop-left corner.
w, hWidth and height in pixels.
uPacked color byte for the unpressed (idle) state.
hvrPacked color byte for the hover state.
pPacked color byte for the pressed state.
labelCentered text drawn inside the button using the built-in 9x15 font.
onclickCallback 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);

Input Fields

void GCreateInput(int id, int x, int y, int w, int h, int u, int hvr, int max);
char* GGetInput(int id);
ParameterDescription
idElement ID.
x, yTop-left corner.
wWidth in pixels. Pass -1 to auto-calculate: (max + 1) * 9 + 10.
hHeight in pixels.
uPacked color byte for the inactive (not hovered) state.
hvrPacked color byte for the active (hovered) state.
maxMaximum 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);
ParameterDescription
idElement ID.
x, yTop-left corner of the checkbox square.
sizeSide length of the checkbox square in pixels.
cb_colPacked color byte for the checkbox square (upper nibble = border, lower nibble = fill).
txt_colPalette index for the label text.
labelText 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);
ParameterDescription
idElement ID.
x, yTop-left corner.
w, hWidth and height in pixels.
fgPalette index for the border/outline. Pass -1 to skip drawing the border.
bgPalette 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);
ParameterDescription
idElement ID.
x, yTop-left corner.
colsVisible column count. The element width is computed automatically as cols * 9 + 17.
rowsVisible row count. The element height is computed automatically as rows * 15 + 10.
con_clrPacked color byte for the console box: lower nibble = background fill, upper nibble = border and scrollbar color.
txt_clrPacked 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);
}

Build docs developers (and LLMs) love