XUI 滚动条内嵌于 ScrollView / TreeView / TableView 等可滚动控件,通过策略、模式、度量、颜色进行定制。
XUI 没有独立的 Scrollbar 控件——滚动条作为可滚动控件的内部组件存在。核心配置项:
• Policy:显示策略(始终显示 / 自动 / 隐藏)
• Mode:渲染模式(经典带按钮 / 简约覆盖式)
• Metrics:滚动条宽度、最小滑块尺寸、按钮尺寸
• Colors:轨道色、滑块色、悬停/按下/焦点/禁用色
| 函数 | 说明 |
|---|---|
int xuiScrollViewSetScrollbarPolicy(xui_widget pW, int iPX, int iPY) | X/Y 轴策略 |
int xuiScrollViewGetScrollbarPolicy(xui_widget pW, int* pPX, int* pPY) | 查询策略 |
int xuiScrollViewSetScrollbarMode(xui_widget pW, int iMode) | 滚动条模式 |
int xuiScrollViewSetMetrics(xui_widget pW, float fSize, float fMinThumb, float fBtn) | 度量参数 |
int xuiScrollViewSetColors(xui_widget pW, ...) | 滚动条颜色 |
int xuiScrollViewSetButtonColors(xui_widget pW, uint32_t iBtn, uint32_t iIcon) | 按钮颜色 |
int xuiScrollViewSetCornerMode(xui_widget pW, int iMode) | 角落模式 |
int xuiScrollViewSetCornerColors(xui_widget pW, uint32_t iCorner, uint32_t iGrip) | 角落颜色 |
gcc -O2 -I. -o ch145.exe ch145_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch145.exe
// 策略:X 轴隐藏,Y 轴自动
xuiScrollViewSetScrollbarPolicy(pScroll, 0, 1);
// 简约模式(覆盖式,无按钮)
xuiScrollViewSetScrollbarMode(pScroll, 1);
// 度量:宽 8px,最小滑块 30px,按钮 0
xuiScrollViewSetMetrics(pScroll, 8.0f, 30.0f, 0.0f);
// 颜色:Track / Thumb / Hover / Active / Focus / Disabled
xuiScrollViewSetColors(pScroll,
0x00000000, // 透明轨道
0x80FFFFFF, // 半透明白色滑块
0xC0FFFFFF, // 悬停
0xFFFFFFFF, // 按下
0x804FD8C2, // 焦点
0x40FFFFFF); // 禁用将以下代码保存为 ch145_main.c,编译后运行即可看到自定义滚动条效果:
#include "xge.h"
#include "xui.h"
#include <stdio.h>
static xui_context g_pCtx;
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x081114FF);
float mx, my;
xgeMouseGet(&mx, &my);
xuiInputPointerMove(g_pCtx, mx, my);
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 = "ch145 - Scrollbar";
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);
/* 根容器 */
xui_widget pRoot;
xuiWidgetCreate(g_pCtx, &pRoot);
xuiWidgetSetLayoutType(pRoot, XUI_LAYOUT_COLUMN);
xuiWidgetSetRect(pRoot, (xui_rect_t){0, 0, 800, 600});
xuiWidgetSetPadding(pRoot, 40, 40, 40, 40);
xuiSetRootWidget(g_pCtx, pRoot);
/* 滚动视图 + 自定义滚动条 */
xui_scroll_view_desc_t svd = { 0 };
xui_widget pScroll;
xuiScrollViewCreate(g_pCtx, &pScroll, &svd);
xuiWidgetSetRect(pScroll, (xui_rect_t){0, 0, 400, 500});
xuiScrollViewSetContentSize(pScroll, 400, 3000);
xuiScrollViewSetWheelStep(pScroll, 40.0f);
xuiWidgetAddChild(pRoot, pScroll);
/* 滚动条外观配置 */
xuiScrollViewSetScrollbarPolicy(pScroll, 0, 2); // Y轴始终显示
xuiScrollViewSetScrollbarMode(pScroll, 1); // 覆盖式
xuiScrollViewSetMetrics(pScroll, 8.0f, 30.0f, 0.0f);
xuiScrollViewSetColors(pScroll,
0x00000000, 0x80FFFFFF, 0xC0FFFFFF,
0xFFFFFFFF, 0x804FD8C2, 0x40FFFFFF);
/* 填充内容 */
xui_widget pContent = xuiScrollViewGetContentWidget(pScroll);
xuiWidgetSetLayout(pContent, XUI_LAYOUT_COLUMN);
static char buf[80][32];
for (int i = 0; i < 80; i++) {
sprintf(buf[i], "Row %d", i + 1);
xui_label_desc_t lb = { 0 };
lb.sText = buf[i];
xui_widget pLb;
xuiLabelCreate(g_pCtx, &pLb, &lb);
xuiWidgetSetRect(pLb, (xui_rect_t){0, 0, 380, 34});
xuiWidgetAddChild(pContent, pLb);
}
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}