add themes and colors :D

This commit is contained in:
2026-03-03 12:12:41 -05:00
parent bae74d7a96
commit 3173fabfc1
9 changed files with 308 additions and 116 deletions

View File

@@ -10,7 +10,6 @@
#include "midi/midi.h"
#include "audio/audio.h"
#include "ui/ui_core.h"
#include "ui/ui_theme.h"
#include "ui/ui_widgets.h"
// [cpp]
@@ -94,9 +93,14 @@ struct AppState {
B32 show_about_window;
B32 show_confirm_dialog;
S32 settings_theme_sel;
S32 settings_theme_prev;
B32 settings_vsync;
B32 settings_autosave;
// Accent color selection
S32 accent_sel;
S32 accent_prev;
// Audio device selection
S32 audio_device_sel; // dropdown index: 0 = None, 1+ = device
S32 audio_device_prev; // previous selection for change detection
@@ -507,11 +511,19 @@ static void settings_window_content(void *user_data) {
AppState *app = (AppState *)user_data;
ui_label("SettingsLblTheme", "Theme");
static const char *theme_options[] = { "Dark", "Light", "Solarized" };
static const char *theme_options[] = { "Dark", "Light" };
CLAY(CLAY_ID("SettingsThemeWrap"),
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(180)), .height = CLAY_SIZING_FIT() } }
) {
ui_dropdown("SettingsTheme", theme_options, 3, &app->settings_theme_sel);
ui_dropdown("SettingsTheme", theme_options, 2, &app->settings_theme_sel);
}
ui_label("SettingsLblAccent", "Accent Color");
static const char *accent_options[] = { "Blue", "Turquoise", "Orange", "Purple", "Pink", "Red", "Green" };
CLAY(CLAY_ID("SettingsAccentWrap"),
.layout = { .sizing = { .width = CLAY_SIZING_FIXED(uis(180)), .height = CLAY_SIZING_FIT() } }
) {
ui_dropdown("SettingsAccent", accent_options, 7, &app->accent_sel);
}
ui_checkbox("SettingsVsync", "V-Sync", &app->settings_vsync);
@@ -575,11 +587,11 @@ static void settings_window_content(void *user_data) {
.padding = { uip(12), uip(12), 0, 0 },
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER },
},
.backgroundColor = Clay_Color{50, 50, 50, 255},
.backgroundColor = g_theme.disabled_bg,
.cornerRadius = CLAY_CORNER_RADIUS(uis(3))
) {
static Clay_TextElementConfig disabled_text = {};
disabled_text.textColor = Clay_Color{100, 100, 100, 255};
disabled_text.textColor = g_theme.disabled_text;
disabled_text.fontSize = FONT_SIZE_NORMAL;
disabled_text.wrapMode = CLAY_TEXT_WRAP_NONE;
CLAY_TEXT(CLAY_STRING("Play Test Tone"), &disabled_text);
@@ -705,6 +717,34 @@ static void do_frame(AppState *app) {
g_ui_scale = app->ui_scale;
renderer_set_font_scale(app->renderer, app->ui_scale);
// Handle theme change
if (app->settings_theme_sel != app->settings_theme_prev) {
ui_set_theme(app->settings_theme_sel);
ui_set_accent(app->accent_sel); // reapply accent on new base theme
app->settings_theme_prev = app->settings_theme_sel;
// Refresh all text configs with new theme colors
g_text_config_normal.textColor = g_theme.text;
g_text_config_title.textColor = g_theme.text;
g_text_config_dim.textColor = g_theme.text_dim;
ui_widgets_theme_changed();
// Update renderer clear color to match theme
renderer_set_clear_color(app->renderer,
g_theme.bg_dark.r / 255.f, g_theme.bg_dark.g / 255.f, g_theme.bg_dark.b / 255.f);
}
// Handle accent change
if (app->accent_sel != app->accent_prev) {
ui_set_accent(app->accent_sel);
app->accent_prev = app->accent_sel;
g_text_config_normal.textColor = g_theme.text;
g_text_config_title.textColor = g_theme.text;
g_text_config_dim.textColor = g_theme.text_dim;
ui_widgets_theme_changed();
}
// Update text configs when scale changes
if (g_text_config_normal.fontSize != FONT_SIZE_NORMAL) {
g_text_config_normal.fontSize = FONT_SIZE_NORMAL;
@@ -760,7 +800,7 @@ int main(int argc, char **argv) {
AudioEngine *audio = audio_create(platform_get_native_handle(window));
// Initialize UI (Clay)
ui_init_theme();
ui_set_theme(0);
UI_Context *ui = ui_create((F32)w, (F32)h);
ui_set_measure_text_fn(ui, renderer_measure_text, renderer);
init_text_configs();

View File

@@ -19,6 +19,7 @@ bool renderer_begin_frame(Renderer *renderer);
void renderer_end_frame(Renderer *renderer, Clay_RenderCommandArray render_commands);
void renderer_resize(Renderer *renderer, int32_t width, int32_t height);
void renderer_set_font_scale(Renderer *renderer, float scale);
void renderer_set_clear_color(Renderer *renderer, float r, float g, float b);
// Text measurement callback compatible with UI_MeasureTextFn
// Measures text of given length (NOT necessarily null-terminated) at font_size pixels.

View File

@@ -1,6 +1,5 @@
#include "renderer/renderer.h"
#include "ui/ui_core.h"
#include "ui/ui_theme.h"
#include <d3d12.h>
#include <dxgi1_5.h>

View File

@@ -1,6 +1,5 @@
#include "renderer/renderer.h"
#include "ui/ui_core.h"
#include "ui/ui_theme.h"
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
@@ -166,6 +165,9 @@ struct Renderer {
// Text measurement (Core Text)
CTFontRef measure_font;
F32 measure_font_size;
// Clear color
F32 clear_r, clear_g, clear_b;
};
////////////////////////////////
@@ -617,6 +619,11 @@ Renderer *renderer_create(RendererDesc *desc) {
r->measure_font = nullptr;
r->measure_font_size = 0;
// Default clear color (dark theme bg_dark)
r->clear_r = 0.12f;
r->clear_g = 0.12f;
r->clear_b = 0.13f;
return r;
}
@@ -647,7 +654,7 @@ void renderer_end_frame(Renderer *r, Clay_RenderCommandArray render_commands) {
pass.colorAttachments[0].texture = drawable.texture;
pass.colorAttachments[0].loadAction = MTLLoadActionClear;
pass.colorAttachments[0].storeAction = MTLStoreActionStore;
pass.colorAttachments[0].clearColor = MTLClearColorMake(0.12, 0.12, 0.13, 1.0);
pass.colorAttachments[0].clearColor = MTLClearColorMake(r->clear_r, r->clear_g, r->clear_b, 1.0);
id<MTLCommandBuffer> cmd_buf = [r->command_queue commandBuffer];
id<MTLRenderCommandEncoder> encoder = [cmd_buf renderCommandEncoderWithDescriptor:pass];
@@ -801,6 +808,12 @@ void renderer_end_frame(Renderer *r, Clay_RenderCommandArray render_commands) {
r->frame_index++;
}
void renderer_set_clear_color(Renderer *r, float cr, float cg, float cb) {
r->clear_r = cr;
r->clear_g = cg;
r->clear_b = cb;
}
void renderer_set_font_scale(Renderer *r, float scale) {
float target_size = 15.0f * scale;
if (fabsf(target_size - r->font_atlas_size) < 0.1f) return;

View File

@@ -19,20 +19,122 @@ F32 g_ui_scale = 1.0f;
// Theme global
UI_Theme g_theme = {};
S32 g_theme_id = 0;
void ui_init_theme() {
g_theme.bg_dark = Clay_Color{ 30, 30, 33, 255};
g_theme.bg_medium = Clay_Color{ 41, 41, 43, 255};
g_theme.bg_light = Clay_Color{ 51, 51, 56, 255};
g_theme.bg_lighter = Clay_Color{ 56, 56, 61, 255};
g_theme.border = Clay_Color{ 56, 56, 61, 255};
g_theme.text = Clay_Color{224, 224, 224, 255};
g_theme.text_dim = Clay_Color{112, 112, 112, 255};
g_theme.accent = Clay_Color{ 87, 138, 176, 255};
g_theme.accent_hover = Clay_Color{102, 153, 191, 255};
g_theme.title_bar = Clay_Color{ 26, 26, 28, 255};
g_theme.scrollbar_bg = Clay_Color{ 26, 26, 28, 255};
g_theme.scrollbar_grab= Clay_Color{ 61, 61, 66, 255};
void ui_set_theme(S32 theme_id) {
g_theme_id = theme_id;
switch (theme_id) {
default:
case 0: // Dark
g_theme.bg_dark = Clay_Color{ 30, 30, 33, 255};
g_theme.bg_medium = Clay_Color{ 41, 41, 43, 255};
g_theme.bg_light = Clay_Color{ 51, 51, 56, 255};
g_theme.bg_lighter = Clay_Color{ 56, 56, 61, 255};
g_theme.border = Clay_Color{ 56, 56, 61, 255};
g_theme.text = Clay_Color{224, 224, 224, 255};
g_theme.text_dim = Clay_Color{112, 112, 112, 255};
g_theme.accent = Clay_Color{ 87, 138, 176, 255};
g_theme.accent_hover = Clay_Color{102, 153, 191, 255};
g_theme.button_text = Clay_Color{224, 224, 224, 255};
g_theme.disabled_bg = Clay_Color{ 50, 50, 50, 255};
g_theme.disabled_text = Clay_Color{100, 100, 100, 255};
g_theme.title_bar = Clay_Color{ 26, 26, 28, 255};
g_theme.scrollbar_bg = Clay_Color{ 26, 26, 28, 255};
g_theme.scrollbar_grab = Clay_Color{ 61, 61, 66, 255};
g_theme.tab_active_top = Clay_Color{ 70, 120, 160, 255};
g_theme.tab_active_bottom= Clay_Color{ 30, 55, 80, 255};
g_theme.tab_inactive = Clay_Color{ 45, 45, 48, 255};
g_theme.tab_inactive_hover= Clay_Color{ 55, 55, 60, 255};
g_theme.tab_text = Clay_Color{240, 240, 240, 255};
break;
case 1: // Light
g_theme.bg_dark = Clay_Color{210, 210, 215, 255};
g_theme.bg_medium = Clay_Color{230, 230, 233, 255};
g_theme.bg_light = Clay_Color{242, 242, 245, 255};
g_theme.bg_lighter = Clay_Color{248, 248, 250, 255};
g_theme.border = Clay_Color{190, 190, 195, 255};
g_theme.text = Clay_Color{ 30, 30, 35, 255};
g_theme.text_dim = Clay_Color{120, 120, 130, 255};
g_theme.accent = Clay_Color{ 50, 110, 170, 255};
g_theme.accent_hover = Clay_Color{ 65, 125, 185, 255};
g_theme.button_text = Clay_Color{255, 255, 255, 255};
g_theme.disabled_bg = Clay_Color{195, 195, 200, 255};
g_theme.disabled_text = Clay_Color{150, 150, 155, 255};
g_theme.title_bar = Clay_Color{220, 220, 225, 255};
g_theme.scrollbar_bg = Clay_Color{220, 220, 225, 255};
g_theme.scrollbar_grab = Clay_Color{180, 180, 185, 255};
g_theme.tab_active_top = Clay_Color{ 70, 130, 180, 255};
g_theme.tab_active_bottom= Clay_Color{ 50, 100, 150, 255};
g_theme.tab_inactive = Clay_Color{218, 218, 222, 255};
g_theme.tab_inactive_hover= Clay_Color{205, 205, 210, 255};
g_theme.tab_text = Clay_Color{255, 255, 255, 255};
break;
}
}
////////////////////////////////
// Accent palette
S32 g_accent_id = 0;
void ui_set_accent(S32 accent_id) {
g_accent_id = accent_id;
B32 dark = (g_theme_id == 0);
// Each palette: accent, accent_hover, tab_top, tab_bottom, button_text, tab_text
struct AccentColors {
Clay_Color accent, accent_hover, tab_top, tab_bottom, button_text, tab_text;
};
// Dark-mode palettes
static const AccentColors dark_palettes[] = {
// 0: Blue
{ {87,138,176,255}, {102,153,191,255}, {70,120,160,255}, {30,55,80,255}, {224,224,224,255}, {240,240,240,255} },
// 1: Turquoise
{ {60,160,155,255}, {75,175,170,255}, {50,140,135,255}, {25,70,68,255}, {224,224,224,255}, {240,240,240,255} },
// 2: Orange
{ {200,130,50,255}, {215,145,65,255}, {190,120,40,255}, {100,60,20,255}, {240,240,240,255}, {240,240,240,255} },
// 3: Purple
{ {130,100,180,255}, {145,115,195,255}, {120,90,170,255}, {60,45,85,255}, {224,224,224,255}, {240,240,240,255} },
// 4: Pink
{ {185,95,140,255}, {200,110,155,255}, {175,85,130,255}, {88,42,65,255}, {240,240,240,255}, {240,240,240,255} },
// 5: Red
{ {190,75,75,255}, {205,90,90,255}, {180,65,65,255}, {90,32,32,255}, {240,240,240,255}, {240,240,240,255} },
// 6: Green
{ {80,155,80,255}, {95,170,95,255}, {70,140,70,255}, {35,70,35,255}, {240,240,240,255}, {240,240,240,255} },
};
// Light-mode palettes (slightly more saturated for contrast on light bg)
static const AccentColors light_palettes[] = {
// 0: Blue
{ {50,110,170,255}, {65,125,185,255}, {70,130,180,255}, {50,100,150,255}, {255,255,255,255}, {255,255,255,255} },
// 1: Turquoise
{ {30,140,135,255}, {45,155,150,255}, {40,150,145,255}, {25,115,110,255}, {255,255,255,255}, {255,255,255,255} },
// 2: Orange
{ {190,115,25,255}, {205,130,40,255}, {195,120,30,255}, {155,90,15,255}, {255,255,255,255}, {255,255,255,255} },
// 3: Purple
{ {110,75,170,255}, {125,90,185,255}, {115,80,175,255}, {85,55,140,255}, {255,255,255,255}, {255,255,255,255} },
// 4: Pink
{ {175,70,125,255}, {190,85,140,255}, {180,75,130,255}, {140,50,100,255}, {255,255,255,255}, {255,255,255,255} },
// 5: Red
{ {185,55,55,255}, {200,70,70,255}, {190,60,60,255}, {150,40,40,255}, {255,255,255,255}, {255,255,255,255} },
// 6: Green
{ {55,140,55,255}, {70,155,70,255}, {60,145,60,255}, {40,110,40,255}, {255,255,255,255}, {255,255,255,255} },
};
S32 idx = accent_id;
if (idx < 0) idx = 0;
if (idx > 6) idx = 6;
const AccentColors &c = dark ? dark_palettes[idx] : light_palettes[idx];
g_theme.accent = c.accent;
g_theme.accent_hover = c.accent_hover;
g_theme.tab_active_top = c.tab_top;
g_theme.tab_active_bottom = c.tab_bottom;
g_theme.button_text = c.button_text;
g_theme.tab_text = c.tab_text;
}
////////////////////////////////

View File

@@ -58,11 +58,107 @@ struct UI_Theme {
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 title_bar;
Clay_Color scrollbar_bg;
Clay_Color scrollbar_grab;
// 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
};
extern UI_Theme g_theme;
extern S32 g_theme_id;
void ui_init_theme();
// 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 float value (for CLAY_SIZING_FIXED, corner radii, etc.)
static inline float uis(float x) { return x * g_ui_scale; }
// Scale to uint16_t (for Clay_Padding, childGap, etc.)
static inline uint16_t uip(float x) { return (uint16_t)(x * g_ui_scale + 0.5f); }
// Scale to uint16_t font size
static inline uint16_t uifs(float x) { return (uint16_t)(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 uis(5)
#define TAB_PADDING_H uip(10)
////////////////////////////////
// Custom render types (for gradient rects via CLAY_RENDER_COMMAND_TYPE_CUSTOM)
enum CustomRenderType {
CUSTOM_RENDER_VGRADIENT = 1,
};
struct CustomGradientData {
CustomRenderType type;
Clay_Color top_color;
Clay_Color bottom_color;
};
////////////////////////////////
// Font sizes
#define FONT_SIZE_NORMAL uifs(15)
#define FONT_SIZE_SMALL uifs(12)
////////////////////////////////
// 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)
////////////////////////////////
// Corner radii
#define CORNER_RADIUS_SM uis(3)
#define CORNER_RADIUS_MD uis(6)
#define CORNER_RADIUS_ROUND uis(8)
////////////////////////////////
// Modal / window styling
#define MODAL_OVERLAY_COLOR Clay_Color{ 0, 0, 0, 120}
#define MODAL_WIDTH uis(400)
#define MODAL_CORNER_RADIUS CORNER_RADIUS_MD
#define WINDOW_CORNER_RADIUS CORNER_RADIUS_MD
#define WINDOW_TITLE_HEIGHT uis(32)
////////////////////////////////
// Panel sizing
#define PANEL_BROWSER_WIDTH uis(200)
#define PANEL_RIGHT_COL_WIDTH uis(250)
#define PANEL_LOG_HEIGHT uis(180)

View File

@@ -1,85 +0,0 @@
#pragma once
// ui_theme.h - Theme constants and defines for the UI layer.
// Centralizes colors, sizing, padding, and radius values used across the app.
#include "clay.h"
////////////////////////////////
// UI scale (Cmd+/Cmd- zoom)
extern F32 g_ui_scale;
// Scale a float value (for CLAY_SIZING_FIXED, corner radii, etc.)
static inline float uis(float x) { return x * g_ui_scale; }
// Scale to uint16_t (for Clay_Padding, childGap, etc.)
static inline uint16_t uip(float x) { return (uint16_t)(x * g_ui_scale + 0.5f); }
// Scale to uint16_t font size
static inline uint16_t uifs(float x) { return (uint16_t)(x * g_ui_scale + 0.5f); }
////////////////////////////////
// Tab styling
#define TAB_ACTIVE_TOP Clay_Color{ 70, 120, 160, 255}
#define TAB_ACTIVE_BOTTOM Clay_Color{ 30, 55, 80, 255}
#define TAB_INACTIVE_BG Clay_Color{ 45, 45, 48, 255}
#define TAB_INACTIVE_HOVER Clay_Color{ 55, 55, 60, 255}
#define TAB_HEIGHT uis(26)
#define TAB_CORNER_RADIUS uis(5)
#define TAB_PADDING_H uip(10)
////////////////////////////////
// Custom render types (for gradient rects via CLAY_RENDER_COMMAND_TYPE_CUSTOM)
enum CustomRenderType {
CUSTOM_RENDER_VGRADIENT = 1,
};
struct CustomGradientData {
CustomRenderType type;
Clay_Color top_color;
Clay_Color bottom_color;
};
////////////////////////////////
// Font sizes
#define FONT_SIZE_NORMAL uifs(15)
#define FONT_SIZE_SMALL uifs(12)
////////////////////////////////
// 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)
////////////////////////////////
// Corner radii
#define CORNER_RADIUS_SM uis(3)
#define CORNER_RADIUS_MD uis(6)
#define CORNER_RADIUS_ROUND uis(8)
////////////////////////////////
// Modal / window styling
#define MODAL_OVERLAY_COLOR Clay_Color{ 0, 0, 0, 120}
#define MODAL_WIDTH uis(400)
#define MODAL_CORNER_RADIUS CORNER_RADIUS_MD
#define WINDOW_CORNER_RADIUS CORNER_RADIUS_MD
#define WINDOW_TITLE_HEIGHT uis(32)
////////////////////////////////
// Panel sizing
#define PANEL_BROWSER_WIDTH uis(200)
#define PANEL_RIGHT_COL_WIDTH uis(250)
#define PANEL_LOG_HEIGHT uis(180)

View File

@@ -43,8 +43,14 @@ void ui_widgets_begin_frame(PlatformInput input) {
static Clay_TextElementConfig g_widget_text_config;
static Clay_TextElementConfig g_widget_text_config_dim;
static Clay_TextElementConfig g_widget_text_config_sel;
static Clay_TextElementConfig g_widget_text_config_btn;
static Clay_TextElementConfig g_widget_text_config_tab;
static F32 g_widget_text_configs_scale = 0;
void ui_widgets_theme_changed() {
g_widget_text_configs_scale = 0;
}
static void ensure_widget_text_configs() {
if (g_widget_text_configs_scale == g_ui_scale) return;
g_widget_text_configs_scale = g_ui_scale;
@@ -64,6 +70,18 @@ static void ensure_widget_text_configs() {
g_widget_text_config_sel.textColor = Clay_Color{255, 255, 255, 255};
g_widget_text_config_sel.fontSize = FONT_SIZE_NORMAL;
g_widget_text_config_sel.wrapMode = CLAY_TEXT_WRAP_NONE;
// Button text (always readable on accent background)
g_widget_text_config_btn = {};
g_widget_text_config_btn.textColor = g_theme.button_text;
g_widget_text_config_btn.fontSize = FONT_SIZE_NORMAL;
g_widget_text_config_btn.wrapMode = CLAY_TEXT_WRAP_NONE;
// Tab text (always light — readable on colored tab gradient)
g_widget_text_config_tab = {};
g_widget_text_config_tab.textColor = g_theme.tab_text;
g_widget_text_config_tab.fontSize = FONT_SIZE_NORMAL;
g_widget_text_config_tab.wrapMode = CLAY_TEXT_WRAP_NONE;
}
static Clay_String clay_str(const char *s) {
@@ -111,7 +129,7 @@ B32 ui_button(const char *id, const char *text) {
.backgroundColor = hovered ? g_theme.accent_hover : g_theme.accent,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS_SM)
) {
CLAY_TEXT(clay_str(text), &g_widget_text_config);
CLAY_TEXT(clay_str(text), &g_widget_text_config_btn);
}
return (hovered && g_wstate.mouse_clicked) ? 1 : 0;
@@ -737,6 +755,9 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
Clay_Color item_bg = is_item_selected ? g_theme.accent : g_theme.bg_dark;
if (item_hovered) item_bg = g_theme.bg_lighter;
Clay_TextElementConfig *item_text = (is_item_selected && !item_hovered)
? &g_widget_text_config_btn : &g_widget_text_config;
CLAY(item_id,
.layout = {
.sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_FIXED(WIDGET_DROPDOWN_ITEM_H) },
@@ -745,7 +766,7 @@ B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected)
},
.backgroundColor = item_bg
) {
CLAY_TEXT(clay_str(options[i]), &g_widget_text_config);
CLAY_TEXT(clay_str(options[i]), item_text);
}
if (item_hovered && g_wstate.mouse_clicked) {
@@ -892,7 +913,7 @@ S32 ui_modal(const char *id, const char *title, const char *message,
.backgroundColor = btn_hovered ? g_theme.accent_hover : g_theme.accent,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS_SM)
) {
CLAY_TEXT(clay_str(buttons[i]), &g_widget_text_config);
CLAY_TEXT(clay_str(buttons[i]), &g_widget_text_config_btn);
}
if (btn_hovered && g_wstate.mouse_clicked) {
@@ -1057,7 +1078,7 @@ B32 ui_window(const char *id, const char *title, B32 *open,
.backgroundColor = close_bg,
.cornerRadius = CLAY_CORNER_RADIUS(CORNER_RADIUS_SM)
) {
CLAY_TEXT(CLAY_STRING("x"), &g_widget_text_config);
CLAY_TEXT(CLAY_STRING("x"), &g_widget_text_config_btn);
}
}
@@ -1088,11 +1109,13 @@ B32 ui_window(const char *id, const char *title, B32 *open,
////////////////////////////////
// Tab bar
static CustomGradientData g_tab_gradient = {
CUSTOM_RENDER_VGRADIENT, TAB_ACTIVE_TOP, TAB_ACTIVE_BOTTOM
};
static CustomGradientData g_tab_gradient;
S32 ui_tab_bar(const char *id, const char **labels, S32 count, S32 *selected) {
g_tab_gradient.type = CUSTOM_RENDER_VGRADIENT;
g_tab_gradient.top_color = TAB_ACTIVE_TOP;
g_tab_gradient.bottom_color = TAB_ACTIVE_BOTTOM;
Clay_String id_str = clay_str(id);
Clay_ElementId row_eid = Clay__HashString(id_str, 0);
@@ -1122,7 +1145,7 @@ S32 ui_tab_bar(const char *id, const char **labels, S32 count, S32 *selected) {
.cornerRadius = { .topLeft = TAB_CORNER_RADIUS, .topRight = TAB_CORNER_RADIUS, .bottomLeft = 0, .bottomRight = 0 },
.custom = { .customData = &g_tab_gradient },
) {
CLAY_TEXT(lbl_str, &g_widget_text_config);
CLAY_TEXT(lbl_str, &g_widget_text_config_tab);
}
} else {
Clay_Color bg = hovered ? (Clay_Color)TAB_INACTIVE_HOVER : (Clay_Color)TAB_INACTIVE_BG;

View File

@@ -78,6 +78,9 @@ 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();