192 lines
5.5 KiB
C
192 lines
5.5 KiB
C
#pragma once
|
|
// ui_core.h - Thin wrapper around Clay (https://github.com/nicbarker/clay)
|
|
// Provides Clay initialization, per-frame lifecycle, and text measurement bridging.
|
|
|
|
#include "base/base_inc.h"
|
|
#include "clay.h"
|
|
|
|
////////////////////////////////
|
|
// Text measurement callback (provided by renderer)
|
|
// This is our app-level callback; we adapt it to Clay's signature internally.
|
|
|
|
typedef Vec2F32 (*UI_MeasureTextFn)(const char *text, S32 length, F32 font_size, void *user_data);
|
|
|
|
////////////////////////////////
|
|
// UI Context
|
|
|
|
struct UI_Context {
|
|
Clay_Context *clay_ctx;
|
|
void *clay_memory;
|
|
|
|
// Text measurement
|
|
UI_MeasureTextFn measure_text_fn;
|
|
void *measure_text_user_data;
|
|
};
|
|
|
|
////////////////////////////////
|
|
// Lifecycle
|
|
|
|
UI_Context *ui_create(F32 viewport_w, F32 viewport_h);
|
|
void ui_destroy(UI_Context *ctx);
|
|
|
|
// Call each frame before declaring layout
|
|
void ui_begin_frame(UI_Context *ctx, F32 viewport_w, F32 viewport_h,
|
|
Vec2F32 mouse_pos, B32 mouse_down,
|
|
Vec2F32 scroll_delta, F32 dt);
|
|
|
|
// Call after layout is declared; returns Clay's render command array
|
|
Clay_RenderCommandArray ui_end_frame(UI_Context *ctx);
|
|
|
|
////////////////////////////////
|
|
// Text measurement
|
|
|
|
void ui_set_measure_text_fn(UI_Context *ctx, UI_MeasureTextFn fn, void *user_data);
|
|
|
|
// Measure text using the registered callback (available after ui_begin_frame)
|
|
Vec2F32 ui_measure_text(const char *text, S32 length, F32 font_size);
|
|
|
|
////////////////////////////////
|
|
// Theme colors (convenience - 0-255 Clay_Color)
|
|
|
|
struct UI_Theme {
|
|
Clay_Color bg_dark;
|
|
Clay_Color bg_medium;
|
|
Clay_Color bg_light;
|
|
Clay_Color bg_lighter;
|
|
Clay_Color border;
|
|
Clay_Color text;
|
|
Clay_Color text_dim;
|
|
Clay_Color accent;
|
|
Clay_Color accent_hover;
|
|
Clay_Color button_text;
|
|
Clay_Color disabled_bg;
|
|
Clay_Color disabled_text;
|
|
Clay_Color header_bg;
|
|
Clay_Color title_bar;
|
|
Clay_Color scrollbar_bg;
|
|
Clay_Color scrollbar_grab;
|
|
Clay_Color shadow; // Semi-transparent black for drop shadows
|
|
|
|
// Tab bar colors
|
|
Clay_Color tab_active_top;
|
|
Clay_Color tab_active_bottom;
|
|
Clay_Color tab_inactive;
|
|
Clay_Color tab_inactive_hover;
|
|
Clay_Color tab_text; // Always light — readable on colored tab gradient
|
|
|
|
// Corner radius (unscaled pixels, applied via uis())
|
|
F32 corner_radius;
|
|
};
|
|
|
|
extern UI_Theme g_theme;
|
|
extern S32 g_theme_id;
|
|
|
|
// Set theme by index: 0 = Dark, 1 = Light
|
|
void ui_set_theme(S32 theme_id);
|
|
|
|
// Accent color palette: 0=Blue, 1=Turquoise, 2=Orange, 3=Purple, 4=Pink, 5=Red, 6=Green
|
|
extern S32 g_accent_id;
|
|
void ui_set_accent(S32 accent_id);
|
|
|
|
////////////////////////////////
|
|
// UI scale (Cmd+/Cmd- zoom)
|
|
|
|
extern F32 g_ui_scale;
|
|
|
|
// Scale a F32 value (for CLAY_SIZING_FIXED, corner radii, etc.)
|
|
static inline F32 uis(F32 x) { return x * g_ui_scale; }
|
|
|
|
// Scale to U16 (for Clay_Padding, childGap, etc.)
|
|
static inline U16 uip(F32 x) { return (U16)(x * g_ui_scale + 0.5f); }
|
|
|
|
// Scale to U16 font size
|
|
static inline U16 uifs(F32 x) { return (U16)(x * g_ui_scale + 0.5f); }
|
|
|
|
////////////////////////////////
|
|
// Tab styling
|
|
|
|
#define TAB_ACTIVE_TOP g_theme.tab_active_top
|
|
#define TAB_ACTIVE_BOTTOM g_theme.tab_active_bottom
|
|
#define TAB_INACTIVE_BG g_theme.tab_inactive
|
|
#define TAB_INACTIVE_HOVER g_theme.tab_inactive_hover
|
|
#define TAB_HEIGHT uis(26)
|
|
#define TAB_CORNER_RADIUS CORNER_RADIUS
|
|
#define TAB_PADDING_H uip(10)
|
|
|
|
////////////////////////////////
|
|
// Custom render types (for gradient rects via CLAY_RENDER_COMMAND_TYPE_CUSTOM)
|
|
|
|
enum CustomRenderType {
|
|
CUSTOM_RENDER_VGRADIENT = 1,
|
|
CUSTOM_RENDER_ICON = 2,
|
|
CUSTOM_RENDER_ROTATED_ICON = 3,
|
|
};
|
|
|
|
struct CustomGradientData {
|
|
CustomRenderType type;
|
|
Clay_Color top_color;
|
|
Clay_Color bottom_color;
|
|
};
|
|
|
|
struct CustomIconData {
|
|
CustomRenderType type; // CUSTOM_RENDER_ICON
|
|
S32 icon_id;
|
|
Clay_Color color;
|
|
};
|
|
|
|
struct CustomRotatedIconData {
|
|
CustomRenderType type; // CUSTOM_RENDER_ROTATED_ICON
|
|
S32 icon_id;
|
|
Clay_Color color;
|
|
F32 angle_rad;
|
|
};
|
|
|
|
////////////////////////////////
|
|
// Font sizes
|
|
|
|
#define FONT_SIZE_NORMAL uifs(15)
|
|
#define FONT_SIZE_SMALL uifs(12)
|
|
#define FONT_SIZE_TAB uifs(13)
|
|
|
|
////////////////////////////////
|
|
// Widget sizing
|
|
|
|
#define WIDGET_BUTTON_HEIGHT uis(30)
|
|
#define WIDGET_CHECKBOX_HEIGHT uis(28)
|
|
#define WIDGET_CHECKBOX_SIZE uis(18)
|
|
#define WIDGET_RADIO_OUTER uis(16)
|
|
#define WIDGET_RADIO_INNER uis(8)
|
|
#define WIDGET_INPUT_HEIGHT uis(30)
|
|
#define WIDGET_DROPDOWN_HEIGHT uis(30)
|
|
#define WIDGET_DROPDOWN_ITEM_H uis(28)
|
|
#define WIDGET_KNOB_SIZE uis(48)
|
|
#define WIDGET_KNOB_LABEL_GAP uip(4)
|
|
|
|
#define WIDGET_SLIDER_H_WIDTH uis(160)
|
|
#define WIDGET_SLIDER_H_TRACK_H uis(6)
|
|
#define WIDGET_SLIDER_H_THUMB_W uis(14)
|
|
#define WIDGET_SLIDER_H_THUMB_H uis(20)
|
|
#define WIDGET_SLIDER_V_HEIGHT uis(100)
|
|
#define WIDGET_SLIDER_V_TRACK_W uis(6)
|
|
#define WIDGET_SLIDER_V_THUMB_W uis(20)
|
|
#define WIDGET_SLIDER_V_THUMB_H uis(14)
|
|
#define WIDGET_FADER_HEIGHT uis(160)
|
|
#define WIDGET_FADER_TRACK_W uis(4)
|
|
#define WIDGET_FADER_CAP_W uis(25)
|
|
#define WIDGET_FADER_CAP_H uis(52)
|
|
#define WIDGET_FADER_TICK_MAJOR_W uis(8)
|
|
#define WIDGET_FADER_TICK_MINOR_W uis(4)
|
|
#define WIDGET_FADER_TICK_H uis(1)
|
|
|
|
////////////////////////////////
|
|
// Corner radius (from theme)
|
|
|
|
#define CORNER_RADIUS uis(g_theme.corner_radius)
|
|
|
|
////////////////////////////////
|
|
// Panel sizing
|
|
|
|
#define PANEL_BROWSER_WIDTH uis(200)
|
|
#define PANEL_RIGHT_COL_WIDTH uis(250)
|
|
#define PANEL_LOG_HEIGHT uis(180)
|