Skip to content

ui

This package is a simple IMGUI implementation. It allows plenty of customization, and currently comes with these features:

  • Window management: Basic togglable windows with scroll support,
  • Pointer-based widgets: Buttons, checkboxes, sliders that edit variables via pointers,
  • Layout system: Inline inserts to create an imitation of a simple grid layout,
  • Automated IDs: Automatic element id assignment,
  • Toggle: Configurable UI_VISIBLE_KEYCODE for the entire UI overlay (default: F1).

Command :: union {
DrawRectangleCommand,
DrawTextCommand,
SetScissorCommand,
}

Union of all possible draw operations a UI widget can request.


Container :: struct {
id: u32,
lastFrameIndex: u32,
widgetCount: u32,
// Layout State
rectangle: gmath.Rectangle,
headerHeight: f32,
scrollbarWidth: f32,
closeWidth: f32,
toggleWidth: f32,
// Cursor / Scroll State
cursor: gmath.Vector2,
scrollOffset: f32,
contentHeight: f32,
currentCursorY: f32,
// Flags
isHot: bool,
isOpen: bool,
isExpanded: bool,
isScrolling: bool,
isInitialized: bool,
// Draw List
commands: [dynamic]Command,
}

Represents a persistent window.


UI_VISIBLE_KEYCODE :: input.KeyCode.F1

Sets the key that needs to be pressed to toggle the Debug UI.


UiState :: struct {
// Interaction State
hot: u32, // The element currently hovered/ready
lastFrameHot: u32,
active: u32, // The element currently being clicked/dragged
frameIndex: u32,
// Input State
mousePosition: gmath.Vector2,
previousMousePosition: gmath.Vector2,
// Window Management
containers: map[u32]^Container,
containerOrder: [dynamic]u32, // Z-Order (Back -> Front)
currentContainer: ^Container, // The window currently being built
// ID Stack for hashing
ids: [dynamic]u32,
}

Represents the Immediate UI state.


begin :: proc ()

Starts a new UI frame. Determines which window is currently hovered to handle Z-ordering and click masking.


button :: proc (
label: string,
isInline: bool = false,
config: ButtonConfig = DEFAULT_BUTTON_CONFIG,
) -> bool

Renders a clickable button. Returns true if clicked this frame.


checkbox :: proc (
value: ^bool,
isInline: bool = false,
config: CheckboxConfig = DEFAULT_CHECKBOX_CONFIG,
) -> bool

Renders a boolean checkbox toggle. Modifies the value pointer directly. Returns true if the state has changed this frame.


end :: proc ()

Ends the UI frame and dispatches render commands. Handles clicking consumption so gameplay doesn’t react to UI clicks.


getId :: proc (title: string) -> u32

Generates a unique UI ID based on a string label and the current ID stack.


slider :: proc (
value: ^$T,
minimumValue: T,
maximumValue: T,
isInline: bool = false,
config: SliderConfig = DEFAULT_SLIDER_CONFIG,
) -> bool where intrinsics.type_is_numeric(T)

Renders a draggable slider for numeric types (i32, f32, etc.). Returns true if the value changed this frame.


text :: proc (text: string, isInline: bool = false, config: TextConfig = DEFAULT_TEXT_CONFIG)

Renders a static text label.


window :: proc (
title: string,
position: gmath.Vector2 = {0, 0},
config: WindowConfig = DEFAULT_WINDOW_CONFIG,
) -> bool

Begins a new Window container. Returns true if the window is open and expanded. Objects inside the window should be within the if-block.