Chapter 129 · XUI 框架架构

样式系统

XUI 样式系统支持命名样式、类样式、类型样式、状态样式、设计令牌与主题切换,实现外观与逻辑分离。

129

概念

XUI 样式系统按优先级从低到高叠加:
• Default:全局默认属性(最低优先级)
• Type:按控件类型匹配(如所有 Button)
• Class:按类名匹配(如 "primary"、"danger")
• Named:按控件名精确匹配(最高优先级)
• StateClass:状态变化时切换类(hover/active/disabled)
• Token:设计令牌,全局变量式复用颜色/尺寸
• Theme:整套主题一键切换(亮/暗)

API 速查

函数说明
int xuiStyleSetDefault(xui_context pCtx, const xui_style_property_t* pProps, int iCount)设置全局默认属性
int xuiStyleSetType(xui_context pCtx, xui_widget_type pType, const xui_style_desc_t* pStyle)按控件类型设样式
int xuiStyleSetClass(xui_context pCtx, const char* sClass, const xui_style_desc_t* pStyle)注册类样式
int xuiStyleSetNamed(xui_context pCtx, const xui_style_desc_t* pStyle)命名样式(精确匹配)
int xuiStyleSetStateClass(xui_context pCtx, const xui_state_style_desc_t* pStyle)状态→类映射
int xuiStyleSetToken(xui_context pCtx, const char* sName, const xui_style_value_t* pValue)设置设计令牌
int xuiSetTheme(xui_context pCtx, const xui_theme_t* pTheme)切换主题
int xuiStyleRegisterProperty(xui_context pCtx, const char* sName, int iType)注册自定义属性
int xuiStyleFindProperty(xui_context pCtx, const char* sName)查找属性 ID
int xuiStyleRefresh(xui_context pCtx)刷新全部样式

编译本章示例

gcc -O2 -I. -o ch129.exe ch129_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch129.exe

示例:按钮主题

// 1. 注册设计令牌
xuiStyleSetToken(pCtx, "color.primary",
    &(xui_style_value_t){ .color = 0xFF3B82F6 });
xuiStyleSetToken(pCtx, "radius.md",
    &(xui_style_value_t){ .f = 6.0f });

// 2. 类型样式:所有按钮默认外观
xui_style_desc_t btnStyle = {
    .sName     = "button",
    .bgColor   = 0xFF2563EB,
    .fgColor   = 0xFFFFFFFF,
    .fRadius   = 6.0f,
    .fPadH     = 16.0f,
    .fPadV     = 8.0f,
};
xuiStyleSetType(pCtx, xuiButtonGetType(), &btnStyle);

// 3. 类样式:danger 变体
xui_style_desc_t dangerStyle = {
    .sName   = "danger",
    .bgColor = 0xFFDC2626,
};
xuiStyleSetClass(pCtx, "danger", &dangerStyle);

// 4. 状态样式:hover 时切换类
xui_state_style_desc_t hoverMap = {
    .pType      = xuiButtonGetType(),
    .iState     = XUI_WIDGET_STATE_HOVER,
    .sClass     = "hover",
};
xuiStyleSetStateClass(pCtx, &hoverMap);

// 5. 控件应用类
xuiWidgetAddStyleClass(pBtnDelete, "danger");

// 6. 切换暗色主题
xuiSetTheme(pCtx, &tDarkTheme);
xuiStyleRefresh(pCtx);

完整代码

将以下代码保存为 ch129_main.c,编译后运行即可看到样式系统效果:

#include "xge.h"
#include "xui.h"

static xui_context g_pCtx;

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    xuiUpdate(g_pCtx, xgeGetDelta());
    xuiLayout(g_pCtx);
    xuiRender(g_pCtx, NULL, NULL, 0);
    return XGE_OK;
}

int main(void) {
    xge_desc_t d = {0};
    d.iWidth  = 800;
    d.iHeight = 600;
    d.sTitle  = "ch129 - Style System";
    d.iFlags  = XGE_INIT_VSYNC;
    xgeInit(&d);

    xuiCreate(&g_pCtx);
    extern const xui_proxy_t tXgeProxy;
    xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
    xuiSetViewportSize(g_pCtx, 800, 600);

    // 注册设计令牌
    xuiStyleSetToken(g_pCtx, "color.primary",
        &(xui_style_value_t){ .color = 0xFF3B82F6 });

    // 类型样式:所有按钮默认外观
    xui_style_desc_t btnStyle = { 0 };
    btnStyle.bgColor = 0xFF2563EB;
    btnStyle.fgColor = 0xFFFFFFFF;
    btnStyle.fRadius = 6.0f;
    xuiStyleSetType(g_pCtx,
        xuiButtonGetType(), &btnStyle);

    // 类样式:danger 变体
    xui_style_desc_t dangerStyle = { 0 };
    dangerStyle.bgColor = 0xFFDC2626;
    xuiStyleSetClass(g_pCtx, "danger", &dangerStyle);

    // 刷新样式
    xuiStyleRefresh(g_pCtx);

    xgeRun(onFrame, NULL);

    xuiDestroy(g_pCtx);
    xgeUnit();
    return 0;
}

代码讲解

  • xuiStyleSetToken:注册全局设计令牌,样式值可引用令牌名实现统一修改。
  • xuiStyleSetType:按控件类型设置默认样式,所有 Button 自动应用。
  • xuiStyleSetClass:注册命名类样式,控件通过 AddClass 应用。
  • xuiStyleRefresh:修改样式后调用,触发全部控件重新计算外观。
  • 优先级:Named > Class > Type > Default,高优先级覆盖低优先级。

要点与陷阱

  • 优先级:Named > Class > Type > Default,高优先级覆盖低优先级。
  • 继承:字体、前景色等属性可从父控件继承;背景、圆角为私有。
  • Token 引用:样式值可引用令牌名,修改令牌即全局生效。
  • Refresh:修改样式后调用 xuiStyleRefresh 使全部控件重新计算。
  • StateClass:状态切换自动添加/移除对应类,无需手动管理。

进阶练习

  1. 实现亮/暗主题切换:定义两套 Token,按钮一键切换。
  2. 注册自定义属性 "glow-color",在绘制回调中读取使用。
样式系统效果
图:样式系统渲染效果