131 lines
5.3 KiB
C
131 lines
5.3 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 "platform/platform.h"
|
|
#include "ui/ui_core.h"
|
|
#include "ui/ui_icons.h"
|
|
|
|
////////////////////////////////
|
|
// Widget state (global, managed by widget layer)
|
|
|
|
#define UI_WIDGET_MAX_DROPDOWN_ITEMS 32
|
|
#define UI_WIDGET_MAX_TEXT_INPUTS 16
|
|
|
|
struct UI_KnobDragState {
|
|
U32 dragging_id; // Hash of the knob being dragged (0 = none)
|
|
F32 drag_start_y; // Mouse Y when drag started
|
|
F32 drag_start_x; // Mouse X when drag started (for h-slider)
|
|
F32 value_at_start; // Value when drag started
|
|
B32 was_shift; // Shift state last frame (to re-anchor on change)
|
|
U32 last_click_id; // Knob hash of last click (for F64-click detection)
|
|
S32 last_click_frame; // Frame number of last click
|
|
};
|
|
|
|
struct UI_WidgetState {
|
|
// Text input focus
|
|
U32 focused_id; // Clay element ID hash of the focused text input (0 = none)
|
|
S32 cursor_pos; // Cursor position in focused text input
|
|
F32 cursor_blink; // Blink timer (seconds)
|
|
|
|
// Text selection (sel_start == sel_end means no selection)
|
|
S32 sel_start; // Selection anchor (where selection began)
|
|
S32 sel_end; // Selection extent (moves with cursor)
|
|
|
|
// Tab cycling: registered text input IDs in order of declaration
|
|
U32 text_input_ids[UI_WIDGET_MAX_TEXT_INPUTS];
|
|
S32 text_input_count;
|
|
B32 tab_pressed; // True on the frame Tab was pressed
|
|
|
|
// Dropdown
|
|
U32 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
|
|
|
|
// Knob drag state
|
|
UI_KnobDragState knob_drag;
|
|
|
|
// Knob text edit state
|
|
U32 knob_edit_id; // Hash of knob in text edit mode (0 = none)
|
|
char knob_edit_buf[32]; // Text buffer for numeric entry
|
|
S32 knob_edit_cursor; // Cursor position in edit buffer
|
|
S32 knob_edit_sel_start; // Selection anchor
|
|
S32 knob_edit_sel_end; // Selection extent
|
|
};
|
|
|
|
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);
|
|
|
|
// 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);
|
|
|
|
// Content function type (used by popup windows)
|
|
typedef void (*UI_WindowContentFn)(void *user_data);
|
|
|
|
// Knob / potentiometer. Vertical drag to change value.
|
|
// unsigned (is_signed=0): value in [0, max_val]
|
|
// signed (is_signed=1): value in [-max_val, +max_val]
|
|
// default_val: value restored on F64-click.
|
|
// editable: if true, clicking the value text opens a text input for direct entry.
|
|
// Hold Shift while dragging for fine control.
|
|
// Returns true if value changed this frame.
|
|
B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_signed, F32 default_val, B32 editable = 0);
|
|
|
|
// Horizontal slider. Drag left/right to change value.
|
|
B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32 is_signed, F32 default_val, B32 editable = 0);
|
|
|
|
// Vertical slider. Drag up/down to change value.
|
|
B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32 is_signed, F32 default_val, B32 editable = 0);
|
|
|
|
// DAW-style fader (vertical slider with fader cap icon).
|
|
B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_signed, F32 default_val, B32 editable = 0);
|