Menu 弹出式菜单控件,支持菜单项、分隔线、子菜单、快捷键文本、勾选/禁用状态。
Menu 基于 Popup 实现弹出菜单:
• MenuItem:文本 + 图标 + 快捷键 + 子菜单 + 状态(勾选/禁用)
• Separator:分隔线
• OpenAt:在指定坐标弹出(右键菜单)
• Select 回调:点击菜单项触发
| 函数 | 说明 |
|---|---|
int xuiMenuCreate(xui_context pCtx, xui_widget* ppW, const xui_menu_desc_t* pDesc) | 创建菜单 |
int xuiMenuSetItems(xui_widget pW, const xui_menu_item_t* pItems, int iCount) | 批量设置项 |
int xuiMenuAddItem(xui_widget pW, const xui_menu_item_t* pItem) | 添加项 |
int xuiMenuAddSeparator(xui_widget pW) | 添加分隔线 |
int xuiMenuOpenAt(xui_widget pW, xui_widget pOwner, float fX, float fY) | 在坐标弹出 |
int xuiMenuClose(xui_widget pW) | 关闭 |
int xuiMenuSetSelect(xui_widget pW, xui_menu_select_proc onSelect, void* pUser) | 选中回调 |
int xuiMenuSetItemState(xui_widget pW, int iIndex, uint32_t iMask, uint32_t iState) | 项状态 |
int xuiMenuMeasure(xui_widget pW, float* pW, float* pH) | 测量尺寸 |
xui_widget xuiMenuGetPopupWidget(xui_widget pW) | 获取内部 Popup |
gcc -O2 -I. -o ch155.exe ch155_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch155.exe
xui_menu_desc_t desc = { 0 };
xui_widget pMenu;
xuiMenuCreate(pCtx, &pMenu, &desc);
// 构建菜单项
xui_menu_item_t items[] = {
{ "复制", "Ctrl+C", 100, 0 },
{ "粘贴", "Ctrl+V", 101, 0 },
{ "", "", 0, 1 }, // 分隔线
{ "删除", "Del", 102, 0 },
};
xuiMenuSetItems(pMenu, items, 4);
xuiMenuSetSelect(pMenu, OnMenuSelect, NULL);
// 右键时弹出
xuiMenuOpenAt(pMenu, pOwner, fMouseX, fMouseY);将以下代码保存为 ch155_main.c,编译后运行即可看到右键菜单效果:
#include "xge.h"
#include "xui.h"
#include <stdio.h>
static xui_context g_pCtx;
static xui_widget g_pMenu;
static void onMenuSel(xui_widget pW, int iVal, void* p) {
(void)pW; (void)p;
printf("菜单项 value=%d\n", 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_RIGHT))
xuiMenuOpenAt(g_pMenu, NULL, 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 = "ch155 - Menu";
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_menu_desc_t md = { 0 };
xuiMenuCreate(g_pCtx, &g_pMenu, &md);
xuiMenuSetSelect(g_pMenu, onMenuSel, NULL);
xui_menu_item_t items[] = {
{ "复制", "Ctrl+C", 100, 0 },
{ "粘贴", "Ctrl+V", 101, 0 },
{ "", "", 0, 1 },
{ "删除", "Del", 102, 0 },
};
xuiMenuSetItems(g_pMenu, items, 4);
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}