Chapter 164 · XUI 数据录入控件

ComboBox 组合框

ComboBox 下拉组合框,支持只选模式与可编辑模式、弹出列表、占位文本、右键菜单。

164

概念

ComboBox 是下拉选择/输入复合控件:
• Mode:0=只选(DropDownList),1=可编辑(DropDown)
• Items:字符串列表或带 Value 的结构体列表
• Popup:下拉弹出列表,支持高度/最大高度/方向
• Placeholder:未选择时的灰色提示文本
• InputMenu:可编辑模式下右键上下文菜单

API 速查

函数说明
int xuiComboBoxCreate(xui_context pCtx, xui_widget* ppW, const xui_combobox_desc_t* pDesc)创建组合框
int xuiComboBoxSetItems(xui_widget pW, const char** arrItems, int iCount)设置项列表
int xuiComboBoxSetItemData(xui_widget pW, const xui_combobox_item_t* pItems, int iCount)带值项列表
int xuiComboBoxSetSelected(xui_widget pW, int iIndex)选中索引
int xuiComboBoxSetSelectedValue(xui_widget pW, int iValue)按值选中
int xuiComboBoxSetMode(xui_widget pW, int iMode)模式
int xuiComboBoxSetText(xui_widget pW, const char* sText)编辑文本
int xuiComboBoxSetPlaceholder(xui_widget pW, const char* sText)占位文本
int xuiComboBoxOpen(xui_widget pW)打开下拉
int xuiComboBoxSetSelect(xui_widget pW, xui_combobox_select_proc onSelect, void* pUser)选中回调
int xuiComboBoxSetPopupMaxHeight(xui_widget pW, float fMaxHeight)弹出最大高度

编译本章示例

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

示例:字体选择器

xui_combobox_desc_t desc = { 0 };

xui_widget pCombo;
xuiComboBoxCreate(pCtx, &pCombo, &desc);

// 设置选项
const char* fonts[] = { "Arial", "Consolas", "微软雅黑" };
xuiComboBoxSetItems(pCombo, fonts, 3);

xuiComboBoxSetMode(pCombo, 0);  // 只选
xuiComboBoxSetPlaceholder(pCombo, "选择字体...");
xuiComboBoxSetSelected(pCombo, 1);
xuiComboBoxSetPopupMaxHeight(pCombo, 200.0f);

xuiComboBoxSetSelect(pCombo, OnFontSelect, NULL);

static void OnFontSelect(xui_widget pW, int iIndex, void* pUser) {
    ApplyFont(iIndex);
}

完整代码

将以下代码保存为 ch164_main.c,编译后运行即可看到 ComboBox 组合框效果:

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

static xui_context g_pCtx;

static void OnFontSelect(xui_widget pW, int iIndex, void* pUser) {
    (void)pW; (void)pUser;
    xgeLogWrite("选中字体索引: %d", iIndex);
}

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 = "ch164 - ComboBox";
    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_combobox_desc_t cbDesc = {0};
    xui_widget pCombo;
    xuiComboBoxCreate(g_pCtx, &pCombo, &cbDesc);
    xuiWidgetSetRect(pCombo, (xui_rect_t){0, 0, 200, 32});
    xuiWidgetSetRect(pCombo, (xui_rect_t){300, 200, 200, 32});

    const char* fonts[] = { "Arial", "Consolas", "微软雅黑", "JetBrains Mono" };
    xuiComboBoxSetItems(pCombo, fonts, 4);
    xuiComboBoxSetMode(pCombo, 0);
    xuiComboBoxSetPlaceholder(pCombo, "选择字体...");
    xuiComboBoxSetSelected(pCombo, 1);
    xuiComboBoxSetPopupMaxHeight(pCombo, 200.0f);
    xuiComboBoxSetSelect(pCombo, OnFontSelect, NULL);
    xuiWidgetAddChild(pRoot, pCombo);

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

代码讲解

  • xuiComboBoxCreate:创建组合框控件。
  • SetItems:传入字符串数组作为下拉选项。
  • SetMode(0):只选模式,用户不可输入自定义文本。
  • SetSelected(1):默认选中第二项 Consolas。
  • SetPopupMaxHeight:限制下拉列表最大高度,超出时滚动。

要点与陷阱

  • Mode 0 vs 1:只选模式不可输入;可编辑模式支持自由文本 + 下拉建议。
  • Value:ItemData 模式每项携带 int 值,Select 回调返回索引而非值。
  • Popup Placement:默认向下弹出,空间不足自动翻转向上。
  • ChangeCount:每次用户操作递增,可用于脏检测。

进阶练习

  1. 可搜索组合框:可编辑模式 + TextChange 回调过滤列表项。
  2. 分组下拉:使用 Separator 项分隔不同类别。
ComboBox 组合框效果
图:ComboBox 组合框渲染效果