Files
autosample/src/ui/ui_widgets.h

133 lines
4.9 KiB
C

#pragma once
// ui_widgets.h - Immediate-mode widgets built on top of Clay.
//
// Each widget function takes a unique string ID, the value to display/edit,
// and returns whether the value was changed (or the widget was activated).
// The caller owns all data — the widget layer only stores transient UI state
// like which text field is focused or which dropdown is open.
#include "ui/ui_core.h"
#include "ui/ui_icons.h"
#include "platform/platform.h"
////////////////////////////////
// Widget state (global, managed by widget layer)
#define UI_WIDGET_MAX_DROPDOWN_ITEMS 32
#define UI_WIDGET_MAX_TEXT_INPUTS 16
#define UI_WIDGET_MAX_WINDOWS 16
struct UI_ModalState {
B32 active;
uint32_t id; // Hash of the modal's string ID
S32 result; // Button index pressed, -1 = pending
};
struct UI_WindowSlot {
uint32_t id; // Hash of the window's string ID (0 = unused)
Vec2F32 position;
Vec2F32 size;
B32 open;
int16_t z_order;
};
struct UI_DragState {
uint32_t dragging_id; // Window ID currently being dragged (0 = none)
Vec2F32 drag_anchor; // Mouse position when drag started
Vec2F32 pos_anchor; // Window position when drag started
};
struct UI_WidgetState {
// Text input focus
uint32_t focused_id; // Clay element ID hash of the focused text input (0 = none)
int32_t cursor_pos; // Cursor position in focused text input
F32 cursor_blink; // Blink timer (seconds)
// Text selection (sel_start == sel_end means no selection)
int32_t sel_start; // Selection anchor (where selection began)
int32_t sel_end; // Selection extent (moves with cursor)
// Tab cycling: registered text input IDs in order of declaration
uint32_t text_input_ids[UI_WIDGET_MAX_TEXT_INPUTS];
int32_t text_input_count;
B32 tab_pressed; // True on the frame Tab was pressed
// Dropdown
uint32_t open_dropdown_id; // Clay element ID hash of the open dropdown (0 = none)
// Input for this frame
PlatformInput input;
// Click detection
B32 mouse_clicked; // true on the frame mouse transitions from up->down
// Modal state
UI_ModalState modal;
// Window state
UI_WindowSlot windows[UI_WIDGET_MAX_WINDOWS];
S32 window_count;
int16_t next_z;
UI_DragState drag;
};
extern UI_WidgetState g_wstate;
// Call once at startup
void ui_widgets_init();
// Call each frame before building widgets. Pass in the frame's input.
void ui_widgets_begin_frame(PlatformInput input);
// Call after changing theme to force text config refresh
void ui_widgets_theme_changed();
// Reset per-frame text input display buffer allocator (called by begin_frame, but
// can also be called manually if needed)
void ui_text_input_reset_display_bufs();
////////////////////////////////
// Widgets
// All IDs must be unique string literals (passed to CLAY_ID internally).
// Icon element (rendered via icon atlas)
void ui_icon(UI_IconID icon, F32 size, Clay_Color color);
// Simple label
void ui_label(const char *id, const char *text);
// Clickable button. Returns true on the frame it was clicked.
B32 ui_button(const char *id, const char *text);
// Checkbox. Toggles *value on click. Returns true if value changed.
B32 ui_checkbox(const char *id, const char *label, B32 *value);
// Radio button group. Sets *selected to the clicked index. Returns true if changed.
// options is an array of label strings, count is the number of options.
B32 ui_radio_group(const char *id, const char **options, S32 count, S32 *selected);
// Single-line text input. Edits buf in-place (null-terminated, max buf_size-1 chars).
// Returns true if the text changed this frame.
B32 ui_text_input(const char *id, char *buf, S32 buf_size);
// Dropdown / combo box. Sets *selected to chosen index. Returns true if changed.
// options is an array of label strings, count is the number of options.
B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected);
// Modal dialog. Returns button index pressed (0-based), -1 if pending, -2 if Escape dismissed.
// Call every frame while active — it draws the overlay and dialog box.
S32 ui_modal(const char *id, const char *title, const char *message,
const char **buttons, S32 button_count);
B32 ui_modal_is_active();
// Tab bar. Renders a row of tabs with active/inactive states.
// Returns the currently selected index. Clicking an inactive tab updates *selected.
S32 ui_tab_bar(const char *id, const char **labels, S32 count, S32 *selected);
// Draggable floating window. content_fn is called inside the window body each frame.
// *open is set to 0 when the close button is clicked. Returns true while window is open.
typedef void (*UI_WindowContentFn)(void *user_data);
B32 ui_window(const char *id, const char *title, B32 *open,
Vec2F32 initial_pos, Vec2F32 initial_size,
UI_WindowContentFn content_fn, void *user_data);