Tabs 多页签容器,支持四方向放置、可关闭标签、滚动溢出、图标、脏标记指示。
Tabs 由 TabBar + Client 组成:
• TabBar:标签按钮条(可滚动、可溢出菜单)
• Client:当前选中页的内容区
• Placement:标签条位于上/下/左/右
• CloseButton:每个标签可带关闭按钮
• Dirty:未保存修改的标签显示圆点标记
| 函数 | 说明 |
|---|---|
int xuiTabsCreate(xui_context pCtx, xui_widget* ppW, const xui_tabs_desc_t* pDesc) | 创建标签页 |
int xuiTabsAddPage(xui_widget pW, const char* sTitle, xui_widget* ppPage) | 添加页 |
int xuiTabsSetSelected(xui_widget pW, int iIndex) | 切换选中 |
int xuiTabsGetSelected(xui_widget pW) | 获取选中索引 |
int xuiTabsSetPlacement(xui_widget pW, int iPlacement) | 标签位置 |
int xuiTabsSetClose(xui_widget pW, onClose, int bButtons, void* pUser) | 关闭回调 |
int xuiTabsSetScrollable(xui_widget pW, int bScrollable) | 可滚动 |
int xuiTabsSetDirtyItems(xui_widget pW, const int* arr, int iCount) | 脏标记 |
int xuiTabsSetIcons(xui_widget pW, xui_surface* arr, const xui_rect_t* arrSrc, int iCount) | 标签图标 |
int xuiTabsSetTabSize(xui_widget pW, float fWidth, float fHeight) | 标签尺寸 |
gcc -O2 -I. -o ch151.exe ch151_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch151.exe
xui_tabs_desc_t desc = { 0 };
xui_widget pTabs;
xuiTabsCreate(pCtx, &pTabs, &desc);
xuiWidgetSetRect(pTabs, (xui_rect_t){0, 0, 800.0f, 600.0f});
// 添加页面
xui_widget pPage1, pPage2;
xuiTabsAddPage(pTabs, "main.c", &pPage1);
xuiTabsAddPage(pTabs, "render.c", &pPage2);
// 可关闭 + 可滚动
xuiTabsSetClose(pTabs, OnTabClose, 1, NULL);
xuiTabsSetScrollable(pTabs, 1);
xuiTabsSetPlacement(pTabs, 0); // 顶部
// 标记 main.c 为已修改
int dirty[] = { 1, 0 };
xuiTabsSetDirtyItems(pTabs, dirty, 2);
xuiTabsSetSelect(pTabs, OnTabSelect, NULL);
xuiWidgetAddChild(pParent, pTabs);将以下代码保存为 ch151_main.c,编译后运行即可看到标签页效果:
#include "xge.h"
#include "xui.h"
#include <stdio.h>
static xui_context g_pCtx;
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 = "ch151 - Tabs";
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_tabs_desc_t td = { 0 };
xui_widget pTabs;
xuiTabsCreate(g_pCtx, &pTabs, &td);
xuiWidgetSetRect(pTabs, (xui_rect_t){0, 0, 800, 600});
xuiTabsSetPlacement(pTabs, 0); // 顶部
xuiTabsSetScrollable(pTabs, 1);
xuiWidgetAddChild(pRoot, pTabs);
/* 添加页面 */
xui_widget pPage1, pPage2, pPage3;
xuiTabsAddPage(pTabs, "main.c", &pPage1);
xuiTabsAddPage(pTabs, "render.c", &pPage2);
xuiTabsAddPage(pTabs, "ui.c", &pPage3);
/* 向页面添加内容 */
xui_label_desc_t lb = { 0 };
lb.sText = "这是 main.c 的内容";
xui_widget pLb;
xuiLabelCreate(g_pCtx, &pLb, &lb);
xuiWidgetAddChild(pPage1, pLb);
/* 标记脏页 */
int dirty[] = { 1, 0, 0 };
xuiTabsSetDirtyItems(pTabs, dirty, 3);
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}