Chapter 128 · XUI 框架架构

布局系统:Table / Dock / Grid

Table 表格轨道布局、Dock 五区域停靠、Grid 行列网格,覆盖复杂应用布局需求。

128

概念

三种高级布局模式:
• TABLE (5):定义行/列轨道,子控件按单元格放置,支持跨行跨列
• DOCK (6):五区域停靠(Top/Bottom/Left/Right/Center),类似 WinForms DockPanel
• GRID:等分行列网格(通过 Table 实现)
适合 IDE、仪表盘、复杂表单等场景。

API 速查

宏/函数说明
XUI_LAYOUT_TABLE表格布局 (5)
XUI_LAYOUT_DOCK停靠布局 (6)
列宽由 Table 布局回调与内联样式定义(XUI_LAYOUT_TABLE)定义列宽
复杂网格用 xuiTableGrid 适配器模式定义行高
int xuiWidgetSetTableCell(xui_widget pWidget, int iRow, int iCol, int iRowSpan, int iColSpan)放置到单元格
int xuiWidgetSetDock(xui_widget pWidget, int iDock)设置停靠区域

编译本章示例

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

示例:IDE 布局

// Dock 布局:经典 IDE 五区域
xuiWidgetSetLayout(pRoot, XUI_LAYOUT_DOCK);

xuiWidgetSetDock(pMenuBar, XUI_DOCK_TOP);
xuiWidgetSetDock(pStatusBar, XUI_DOCK_BOTTOM);
xuiWidgetSetDock(pToolPanel, XUI_DOCK_LEFT);
xuiWidgetSetDock(pPropsPanel, XUI_DOCK_RIGHT);
xuiWidgetSetDock(pEditor, XUI_DOCK_FILL);

// Table 布局:表单
xuiWidgetSetLayout(pForm, XUI_LAYOUT_TABLE);
float cols[] = { 120, 0 }; // 标签列固定,输入列弹性
/* Table 列宽由布局回调/内联样式定义 */

// 第一行:用户名
xuiWidgetSetRect(pLblUser, 0, 0, 1, 1);
xuiWidgetSetRect(pInpUser, 0, 1, 1, 1);
// 第二行:密码
xuiWidgetSetRect(pLblPass, 1, 0, 1, 1);
xuiWidgetSetRect(pInpPass, 1, 1, 1, 1);
// 第三行:按钮跨两列
xuiWidgetSetRect(pBtnOk, 2, 0, 1, 2);

完整代码

将以下代码保存为 ch128_main.c,编译后运行即可看到 Dock + Table 布局效果:

#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  = "ch128 - Table/Dock";
    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);

    // Dock 布局:经典 IDE 五区域
    xui_widget pRoot;
    xuiWidgetCreate(g_pCtx, &pRoot);
    xuiWidgetSetLayout(pRoot, XUI_LAYOUT_DOCK);

    xui_widget pMenu, pStatus, pTools, pEditor;
    xuiWidgetCreate(g_pCtx, &pMenu);
    xuiWidgetCreate(g_pCtx, &pStatus);
    xuiWidgetCreate(g_pCtx, &pTools);
    xuiWidgetCreate(g_pCtx, &pEditor);

    xuiWidgetSetDock(pMenu, XUI_DOCK_TOP);
    xuiWidgetSetDock(pStatus, XUI_DOCK_BOTTOM);
    xuiWidgetSetDock(pTools, XUI_DOCK_LEFT);
    xuiWidgetSetDock(pEditor, XUI_DOCK_FILL);

    xuiWidgetAddChild(pRoot, pMenu);
    xuiWidgetAddChild(pRoot, pStatus);
    xuiWidgetAddChild(pRoot, pTools);
    xuiWidgetAddChild(pRoot, pEditor);

    xgeRun(onFrame, NULL);

    xuiDestroy(g_pCtx);
    xgeUnit();
    return 0;
}

代码讲解

  • XUI_LAYOUT_DOCK:五区域停靠布局(Top/Bottom/Left/Right/Center)。
  • xuiWidgetSetDock:指定控件停靠到哪个区域,Center 最后填充剩余空间。
  • Dock 顺序:先添加的优先占据边缘,Center 自动填充剩余。
  • Table 布局:通过 SetTableColumns/Rows 定义轨道,SetTableCell 放置子控件。

要点与陷阱

  • Dock 顺序:先添加的优先占据边缘,Center 最后填充。
  • Table 列宽:0 表示弹性(自动分配剩余空间)。
  • Span:跨行/跨列时 RowSpan/ColSpan > 1。
  • 嵌套:Dock 内可嵌套 Row/Column,实现复杂布局。

进阶练习

  1. 实现 IDE 骨架:MenuBar + ToolBar + Editor + StatusBar。
  2. Table 表单验证:标签右对齐,输入框弹性宽度。
布局系统:Table / Dock / Grid效果
图:布局系统:Table / Dock / Grid渲染效果