Chapter 143 · XUI 容器与导航

Panel 面板

Panel 带标题栏的容器控件,支持图标、标题对齐、头部/客户区独立背景色与边框。

143

概念

Panel 是带标题的分组容器:
• Header:标题栏(图标 + 标题文字)
• Client:内容区,子控件放置于此
• 头部和客户区可独立设置背景色
• 支持边框、圆角、裁剪

API 速查

函数说明
int xuiPanelCreate(xui_context pCtx, xui_widget* ppW, const xui_panel_desc_t* pDesc)创建面板
xui_widget xuiPanelGetClientWidget(xui_widget pW)获取客户区
int xuiPanelSetTitle(xui_widget pW, const char* sTitle)设置标题
int xuiPanelSetIcon(xui_widget pW, xui_surface pSurf, xui_rect_t tSrc)设置图标
int xuiPanelAddChild(xui_widget pW, xui_widget pChild)添加子控件
int xuiPanelSetBorder(xui_widget pW, float fWidth, uint32_t iColor)边框
int xuiPanelSetHeaderHeight(xui_widget pW, float fHeight)标题栏高度
int xuiPanelSetHeaderColor(xui_widget pW, uint32_t iColor)头部背景色
int xuiPanelSetClientColor(xui_widget pW, uint32_t iColor)客户区背景色
int xuiPanelSetClientClip(xui_widget pW, int bClip)客户区裁剪

编译本章示例

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

示例:属性面板

xui_panel_desc_t desc = { 0 };
desc.sTitle = "属性";

xui_widget pPanel;
xuiPanelCreate(pCtx, &pPanel, &desc);
xuiPanelSetHeaderHeight(pPanel, 32.0f);
xuiPanelSetBorder(pPanel, 1.0f, 0xFF374151);
xuiPanelSetHeaderColor(pPanel, 0xFF1F2937);
xuiPanelSetClientColor(pPanel, 0xFF111827);

// 向客户区添加内容
xui_widget pClient = xuiPanelGetClientWidget(pPanel);
xuiWidgetSetLayout(pClient, XUI_LAYOUT_COLUMN);
xuiPanelAddChild(pPanel, pPropGrid);

xuiWidgetAddChild(pDockRight, pPanel);

完整代码

将以下代码保存为 ch143_main.c,编译后运行即可看到面板效果:

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

static xui_context g_pCtx;

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    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 = "ch143 - Panel";
    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});
    xuiWidgetSetPadding(pRoot, 40, 40, 40, 40);
    /* 间距:用内联样式或子控件布局参数设置 */
    xuiSetRootWidget(g_pCtx, pRoot);

    /* 创建带标题的面板 */
    xui_panel_desc_t pd = { 0 };
    pd.sTitle = "属性面板";
    xui_widget pPanel;
    xuiPanelCreate(g_pCtx, &pPanel, &pd);
    xuiWidgetSetRect(pPanel, (xui_rect_t){0, 0, 400, 300});
    xuiPanelSetHeaderHeight(pPanel, 32.0f);
    xuiPanelSetBorder(pPanel, 1.0f, 0xFF374151);
    xuiPanelSetHeaderColor(pPanel, 0xFF1F2937);
    xuiPanelSetClientColor(pPanel, 0xFF111827);
    xuiPanelSetClientClip(pPanel, 1);
    xuiWidgetAddChild(pRoot, pPanel);

    /* 向客户区添加内容 */
    xui_label_desc_t lb = { 0 };
    lb.sText = "面板内容区域";
    xui_widget pLb;
    xuiLabelCreate(g_pCtx, &pLb, &lb);
    xuiPanelAddChild(pPanel, pLb);

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

代码讲解

  • Panel 结构:由 Header(标题栏)+ Client(客户区)组成,子控件添加到 Client。
  • HeaderHeight:设置标题栏高度,设为 0 可隐藏标题栏。
  • Border:设置边框宽度和颜色,实现卡片视觉效果。
  • ClientClip:启用后超出客户区的子控件被裁剪,避免溢出。

要点与陷阱

  • AddChild:子控件自动添加到 Client 区域。
  • HeaderHeight:设为 0 可隐藏标题栏。
  • ClientClip:启用后超出客户区的子控件被裁剪。
  • GetHeaderWidget:可获取标题栏控件进一步自定义。

进阶练习

  1. 可折叠面板:标题栏点击切换 Client 可见性。
  2. 多面板布局:左右各一个 Panel 实现 IDE 侧栏。
Panel 面板效果
图:Panel 面板渲染效果