Chapter 139 · XUI 基础控件

NumericInput 数字输入

NumericInput 数字输入框,支持范围限制、步进、精度、整数模式与 Spinner 按钮。

139

概念

NumericInput 专为数值输入设计:
• Range:最小/最大值限制
• Step:步进值,Spinner 按钮每次增减量
• Precision:小数位数
• Integer:整数模式,禁止小数输入
• Spinner:右侧上下箭头按钮

API 速查

函数说明
int xuiNumericInputCreate(xui_context pCtx, xui_widget* ppW, const xui_numeric_input_desc_t* pDesc)创建数字输入
int xuiNumericInputSetChange(xui_widget pW, xui_numeric_input_change_proc onChange, void* pUser)值变化回调
int xuiNumericInputSetRange(xui_widget pW, float fMin, float fMax)设置范围
int xuiNumericInputSetStep(xui_widget pW, float fStep)设置步进
int xuiNumericInputSetPrecision(xui_widget pW, int iPrecision)小数位数
int xuiNumericInputSetInteger(xui_widget pW, int bInteger)整数模式
int xuiNumericInputSetValue(xui_widget pW, float fValue)设置值
float xuiNumericInputGetValue(xui_widget pW)获取值
int xuiNumericInputStep(xui_widget pW, int iDirection)步进 (+1/-1)
int xuiNumericInputSetSpinnerVisible(xui_widget pW, int bVisible)Spinner 显隐
int xuiNumericInputSetFormatter(xui_widget pW, xui_numeric_input_format_proc onFormat, void* pUser)自定义格式化

编译本章示例

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

示例:音量与分辨率

// 音量:0-100 整数,步进 5
xui_numeric_input_desc_t volDesc = { 0 };
xui_widget pVolume;
xuiNumericInputCreate(pCtx, &pVolume, &volDesc);
xuiNumericInputSetRange(pVolume, 0, 100);
xuiNumericInputSetStep(pVolume, 5.0f);
xuiNumericInputSetInteger(pVolume, 1);
xuiNumericInputSetValue(pVolume, 80);

// 缩放比例:0.1-4.0,精度 2 位
xui_widget pZoom;
xuiNumericInputCreate(pCtx, &pZoom, NULL);
xuiNumericInputSetRange(pZoom, 0.1f, 4.0f);
xuiNumericInputSetStep(pZoom, 0.1f);
xuiNumericInputSetPrecision(pZoom, 2);
xuiNumericInputSetValue(pZoom, 1.0f);

// 自定义格式化:显示百分号
xuiNumericInputSetFormatter(pVolume,
    OnFormatPercent, NULL);

完整代码

将以下代码保存为 ch139_main.c,编译后运行即可看到数字输入框效果:

#include "xge.h"
#include "xui.h"
#include <stdio.h>

static xui_context g_pCtx;

static void OnVolChange(xui_widget pW,
    float fVal, void* pUser) {
    (void)pW; (void)pUser;
    printf("Volume: %.0f\n", fVal);
}

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    float mx, my;
    xgeMouseGet(&mx, &my);
    xuiInputPointerMove(g_pCtx, mx, my, 0);
    if (xgeMouseDown(XGE_MOUSE_LEFT))
        xuiInputPointerDown(g_pCtx, mx, my, 0, 1);
    if (!xgeMouseDown(XGE_MOUSE_LEFT) /* 释放边沿建议改用事件 */)
        xuiInputPointerUp(g_pCtx, mx, my, 0, 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  = "ch139 - NumericInput";
    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);

    // 音量:0-100 整数,步进 5
    xui_numeric_input_desc_t desc = { 0 };
    xui_widget pVol;
    xuiNumericInputCreate(g_pCtx, &pVol, &desc);
    xuiNumericInputSetRange(pVol, 0, 100);
    xuiNumericInputSetStep(pVol, 5.0f);
    xuiNumericInputSetInteger(pVol, 1);
    xuiNumericInputSetValue(pVol, 80);
    xuiNumericInputSetChange(pVol,
        OnVolChange, NULL);
    xuiWidgetSetRect(pVol,
        (xui_rect_t){ 300, 270, 200, 40 });

    xgeRun(onFrame, NULL);

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

代码讲解

  • xuiNumericInputCreate:创建数字输入框,带 Spinner 按钮。
  • xuiNumericInputSetRange:设置最小/最大值,超出自动钳制。
  • xuiNumericInputSetStep:Spinner 每次点击的增减量。
  • xuiNumericInputSetInteger:整数模式,禁止小数输入。
  • Change 回调:失焦或回车时提交,触发回调。

要点与陷阱

  • Clamp:超出范围自动钳制到边界值。
  • Spinner:到达边界时对应按钮自动禁用。
  • Formatter:自定义显示格式(如 "80%"),不影响实际值。
  • Commit:失焦或回车时提交,触发 Change 回调。

进阶练习

  1. RGB 颜色输入:三个 0-255 整数 NumericInput。
  2. 带单位后缀:Formatter 显示 "px" / "%" 后缀。
NumericInput 数字输入效果
图:NumericInput 数字输入渲染效果