Chapter 157 · XUI 弹出层与反馈

Toolbar 工具栏

Toolbar 图标按钮条,支持水平/垂直方向、分隔线、勾选态、溢出菜单、Tooltip。

157

概念

Toolbar 是快捷操作按钮条:
• Item:按钮(图标/文本)、分隔线、弹性间隔
• Orientation:水平或垂直排列
• Checked:切换按钮(如加粗/斜体)
• Overflow:空间不足时溢出按钮弹出菜单
• Group:分组互斥(类似 Radio)

API 速查

函数说明
int xuiToolbarCreate(xui_context pCtx, xui_widget* ppW, const xui_toolbar_desc_t* pDesc)创建工具栏
int xuiToolbarAddItem(xui_widget pW, const char* sText, int iType, int iValue)添加按钮
int xuiToolbarAddSeparator(xui_widget pW)添加分隔线
int xuiToolbarSetOrientation(xui_widget pW, int iOrientation)方向
int xuiToolbarSetItemChecked(xui_widget pW, int iIndex, int bChecked)勾选态
int xuiToolbarSetItemIcon(xui_widget pW, int iIndex, xui_surface pIcon, xui_rect_t tSrc)图标
int xuiToolbarSetItemTooltip(xui_widget pW, int iIndex, const char* sText)提示文本
int xuiToolbarSetOverflow(xui_widget pW, int bEnabled, float fBtnSize, onOverflow, void* pUser)溢出
int xuiToolbarSetItemGroup(xui_widget pW, int iIndex, int iGroup)分组互斥
int xuiToolbarSetSelect(xui_widget pW, xui_toolbar_select_proc onSelect, void* pUser)点击回调

编译本章示例

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

示例:编辑工具栏

xui_toolbar_desc_t desc = { 0 };

xui_widget pToolbar;
xuiToolbarCreate(pCtx, &pToolbar, &desc);

// 添加按钮(文本, 类型, 值)
xuiToolbarAddItem(pToolbar, "撤销", 0, 200);
xuiToolbarAddItem(pToolbar, "重做", 0, 201);
xuiToolbarAddSeparator(pToolbar);
xuiToolbarAddItem(pToolbar, "加粗", 1, 202); // 切换类型
xuiToolbarAddItem(pToolbar, "斜体", 1, 203);

// Tooltip
xuiToolbarSetItemTooltip(pToolbar, 0, "撤销 (Ctrl+Z)");
xuiToolbarSetItemTooltip(pToolbar, 1, "重做 (Ctrl+Y)");

xuiToolbarSetSelect(pToolbar, OnToolSelect, NULL);
xuiWidgetAddChild(pTopDock, pToolbar);

完整代码

将以下代码保存为 ch157_main.c,编译后运行即可看到工具栏效果:

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

static xui_context g_pCtx;

static void onTool(xui_widget pW, int iIdx, int iVal, void* p) {
    (void)pW; (void)p;
    printf("工具栏 idx=%d val=%d\n", iIdx, iVal);
}

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    float mx, my;
    xgeMouseGet(&mx, &my);
    xuiInputPointerMove(g_pCtx, mx, my);
    if (xgeMouseDown(XGE_MOUSE_LEFT))
        xuiInputPointerDown(g_pCtx, 0);
    else
        xuiInputPointerUp(g_pCtx, 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 = "ch157 - Toolbar";
    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});
    xuiSetRootWidget(g_pCtx, pRoot);

    /* 创建工具栏 */
    xui_toolbar_desc_t td = { 0 };
    xui_widget pTb;
    xuiToolbarCreate(g_pCtx, &pTb, &td);
    xuiToolbarSetSelect(pTb, onTool, NULL);
    xuiWidgetAddChild(pRoot, pTb);

    xuiToolbarAddItem(pTb, "撤销", 0, 200);
    xuiToolbarAddItem(pTb, "重做", 0, 201);
    xuiToolbarAddSeparator(pTb);
    xuiToolbarAddItem(pTb, "加粗", 1, 202);
    xuiToolbarAddItem(pTb, "斜体", 1, 203);
    xuiToolbarSetItemTooltip(pTb, 0, "撤销 (Ctrl+Z)");
    xuiToolbarSetItemTooltip(pTb, 1, "重做 (Ctrl+Y)");

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

代码讲解

  • AddItem(text, type, value):type=0 普通按钮,type=1 切换按钮。
  • AddSeparator:插入垂直分隔线分组按钮。
  • Tooltip:悬停显示快捷键提示。
  • Select 回调:点击按钮时触发,通过 value 识别操作。

要点与陷阱

  • Type:0 = 普通按钮,1 = 切换按钮(Checked 状态)。
  • Group:同组切换按钮互斥(如对齐方式)。
  • Overflow:窗口缩小时自动将溢出按钮收入下拉菜单。
  • ItemSize:统一设置按钮宽高和分隔线尺寸。

进阶练习

  1. 绘图工具栏:垂直方向 + 图标按钮 + 分组互斥。
  2. 动态启用/禁用:根据编辑状态更新按钮可用性。
Toolbar 工具栏效果
图:Toolbar 工具栏渲染效果