Chapter 169 · XUI 数据录入控件

Slider 滑块

Slider 滑动条,支持水平/垂直方向、步进、页步进、自定义轨道与滑块样式。

169

概念

Slider 是连续值选取控件:
• Range:最小值~最大值范围
• Step:拖动步进(吸附到整数倍)
• PageStep:点击轨道跳跃步长
• Orientation:水平或垂直
• Knob:滑块手柄,可自定义尺寸和颜色

API 速查

函数说明
int xuiSliderCreate(xui_context pCtx, xui_widget* ppW, const xui_slider_desc_t* pDesc)创建滑块
int xuiSliderSetRange(xui_widget pW, float fMin, float fMax)范围
int xuiSliderSetValue(xui_widget pW, float fValue)设置值
int xuiSliderSetStep(xui_widget pW, float fStep, float fPageStep)步进
int xuiSliderSetOrientation(xui_widget pW, int iOrientation)方向
int xuiSliderSetMetrics(xui_widget pW, float fTrackSize, float fKnobSize, float fTrackRadius)尺寸
int xuiSliderSetColors(xui_widget pW, uint32_t iTrack, uint32_t iFill, uint32_t iKnob, uint32_t iFocus, uint32_t iDisabled)颜色
int xuiSliderSetKnobBorderColor(xui_widget pW, uint32_t iColor)滑块边框色
int xuiSliderSetChange(xui_widget pW, xui_slider_change_proc onChange, void* pUser)变更回调

编译本章示例

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

示例:音量控制

xui_slider_desc_t desc = { 0 };

xui_widget pSlider;
xuiSliderCreate(pCtx, &pSlider, &desc);

xuiSliderSetRange(pSlider, 0.0f, 100.0f);
xuiSliderSetValue(pSlider, 75.0f);
xuiSliderSetStep(pSlider, 1.0f, 10.0f);
xuiSliderSetOrientation(pSlider, 0);  // 水平

// 外观
xuiSliderSetMetrics(pSlider, 6.0f, 16.0f, 3.0f);
xuiSliderSetColors(pSlider,
    0x333333FF, 0x4FD8C2FF, 0xFFFFFFFF,
    0x4FD8C280, 0x666666FF);

xuiSliderSetChange(pSlider, OnVolumeChange, NULL);

static void OnVolumeChange(xui_widget pW, float fValue, void* pUser) {
    xgeAudioSetVolume(fValue / 100.0f);
}

完整代码

将以下代码保存为 ch169_main.c,编译后运行即可看到 Slider 滑块效果:

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

static xui_context g_pCtx;

static void OnVolumeChange(xui_widget pW, float fValue, void* pUser) {
    (void)pW; (void)pUser;
    xgeLogWrite("音量: %.0f%%", fValue);
}

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    xui_vec2_t pos; xgeMouseGet(&pos.x, &pos.y);
    xuiInputPointerMove(g_pCtx, pos.x, pos.y);
    if (xgeMouseDown(XGE_MOUSE_LEFT)) xuiInputPointerDown(g_pCtx, pos.x, pos.y, 0);
    else xuiInputPointerUp(g_pCtx, pos.x, pos.y, 0);
    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 = "ch169 - Slider";
    d.iFlags = XGE_INIT_VSYNC;
    xgeInit(&d);
    xuiCreate(&g_pCtx);
    /* XGE 官方代理由 xuiProxyXge() 提供 */
    xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
    xuiSetViewportSize(g_pCtx, 800, 600);

    xui_widget pRoot;
    xuiPanelCreate(g_pCtx, &pRoot, NULL);
    xuiWidgetSetRect(pRoot, (xui_rect_t){0, 0, 800, 600});

    /* 滑块 */
    xui_slider_desc_t slDesc = {0};
    xui_widget pSlider;
    xuiSliderCreate(g_pCtx, &pSlider, &slDesc);
    xuiWidgetSetRect(pSlider, (xui_rect_t){0, 0, 300, 24});
    xuiWidgetSetRect(pSlider, (xui_rect_t){250, 280, 300, 24});
    xuiSliderSetRange(pSlider, 0.0f, 100.0f);
    xuiSliderSetValue(pSlider, 75.0f);
    xuiSliderSetStep(pSlider, 1.0f, 10.0f);
    xuiSliderSetMetrics(pSlider, 6.0f, 16.0f, 3.0f);
    xuiSliderSetColors(pSlider,
        0x333333FF, 0x4FD8C2FF, 0xFFFFFFFF,
        0x4FD8C280, 0x666666FF);
    xuiSliderSetChange(pSlider, OnVolumeChange, NULL);
    xuiWidgetAddChild(pRoot, pSlider);

    xgeRun(onFrame, NULL);
    xuiDestroy(g_pCtx);
    xgeUnit();
    return 0;
}

代码讲解

  • xuiSliderCreate:创建滑块控件。
  • SetRange(0, 100):设置值域 0~100。
  • SetStep(1, 10):拖动步进 1,点击轨道跳跃 10。
  • SetMetrics:轨道宽 6px,滑块 16px,圆角 3px。
  • SetColors:自定义轨道/填充/滑块/焦点/禁用颜色。

要点与陷阱

  • Step=0:无吸附,连续滑动(浮点精度)。
  • PageStep:点击轨道(非拖动)时跳跃的步长。
  • ChangeCount:每次值变化递增,可用于脏检测。
  • 垂直:Orientation=1 时值从下到上递增。

进阶练习

  1. 亮度/对比度调节:双滑块联动实时预览图像效果。
  2. 刻度标签:在滑块旁显示当前值文本。
Slider 滑块效果
图:Slider 滑块渲染效果