Row 水平排列、Column 垂直排列、Flow 自动换行,支持 grow/shrink 弹性分配。
弹性布局是 UI 开发最常用的模式:
• ROW (2):子控件从左到右水平排列
• COLUMN (3):子控件从上到下垂直排列
• FLOW (4):水平排列,空间不足时自动换行
每个子控件可设置 grow(伸展因子)和 shrink(收缩因子),
实现类似 CSS Flexbox 的弹性分配。
| 宏/函数 | 说明 |
|---|---|
XUI_LAYOUT_ROW | 水平排列 (2) |
XUI_LAYOUT_COLUMN | 垂直排列 (3) |
XUI_LAYOUT_FLOW | 流式换行 (4) |
int xuiWidgetSetFlex(xui_widget pWidget, float fGrow, float fShrink) | 设置伸展因子 |
int xuiWidgetGetFlex(xui_widget pWidget, float* pGrow, float* pShrink) | 设置收缩因子 |
int xuiWidgetSetPadding(xui_widget pWidget, xui_thickness_t tPadding) | 设置内边距 |
gcc -O2 -I. -o ch127.exe ch127_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch127.exe
// 水平工具栏(Row)
xuiWidgetSetLayoutType(pToolbar, XUI_LAYOUT_ROW);
xuiWidgetSetGap(pToolbar, 4);
xuiWidgetSetPadding(pToolbar,
(xui_thickness_t){ 8, 4, 8, 4 });
// 按钮固定宽度,搜索框弹性伸展
xuiWidgetSetFlex(pSearchInput, 1.0f, 1.0f);
// 按钮 grow=0(默认),保持固有宽度
// 垂直侧边栏(Column)
xuiWidgetSetLayoutType(pSidebar, XUI_LAYOUT_COLUMN);
xuiWidgetSetGap(pSidebar, 8);
// 列表区域弹性填满剩余空间
xuiWidgetSetFlex(pListView, 1.0f, 1.0f);
// 流式标签(Flow)
xuiWidgetSetLayoutType(pTagContainer, XUI_LAYOUT_FLOW);
xuiWidgetSetGap(pTagContainer, 6);
// 标签自动换行排列将以下代码保存为 ch127_main.c,编译后运行即可看到 Row/Column/Flow 弹性布局:
#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 = "ch127 - Row/Column/Flow";
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);
// 根控件:Column 布局
xui_widget pRoot;
xuiWidgetCreate(g_pCtx, &pRoot);
xuiWidgetSetLayoutType(pRoot, XUI_LAYOUT_COLUMN);
xuiWidgetSetGap(pRoot, 8);
xuiWidgetSetPadding(pRoot,
(xui_thickness_t){ 10, 10, 10, 10 });
// 工具栏:Row 布局
xui_widget pToolbar;
xuiWidgetCreate(g_pCtx, &pToolbar);
xuiWidgetSetLayoutType(pToolbar, XUI_LAYOUT_ROW);
xuiWidgetSetGap(pToolbar, 4);
// 按钮固定宽 + 搜索框弹性伸展
xui_widget pBtn1, pBtn2, pSearch;
xuiWidgetCreate(g_pCtx, &pBtn1);
xuiWidgetCreate(g_pCtx, &pBtn2);
xuiWidgetCreate(g_pCtx, &pSearch);
xuiWidgetSetFlex(pSearch, 1.0f, 1.0f);
xuiWidgetAddChild(pToolbar, pBtn1);
xuiWidgetAddChild(pToolbar, pBtn2);
xuiWidgetAddChild(pToolbar, pSearch);
xuiWidgetAddChild(pRoot, pToolbar);
// 标签容器:Flow 布局(自动换行)
xui_widget pTags;
xuiWidgetCreate(g_pCtx, &pTags);
xuiWidgetSetLayoutType(pTags, XUI_LAYOUT_FLOW);
xuiWidgetSetGap(pTags, 6);
xuiWidgetSetFlex(pTags, 1.0f, 1.0f);
xuiWidgetAddChild(pRoot, pTags);
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}