IDE 风格停靠系统:区域停靠、浮动窗口、自动隐藏、标签组合并。
DockPanel 实现 Visual Studio 风格停靠布局:
• Region:Left/Right/Top/Bottom/Center 五个停靠区域
• Pane:面板容器,可包含多个标签页
• Float:拖出为浮动窗口
• AutoHide:自动隐藏到边缘,悬停展开
• Splitter:面板间拖拽调整比例
| 函数 | 说明 |
|---|---|
int xuiDockPanelCreate(xui_context pCtx, xui_widget* ppW, const xui_dock_panel_desc_t* pDesc) | 创建停靠面板 |
int xuiDockPanelAddWindow(pW, sTitle, pClient, pWindow) | 添加窗口 |
int xuiDockPanelSetWindowTitle(pW, iWin, sTitle) | 设置标题 |
int xuiDockPanelSetWindowFlags(pW, iWin, bClosable, bDockable) | 窗口标志 |
int xuiDockPanelDockWindow(pW, iWin, iRegion, iSide, fRatio, pPane) | 停靠到区域 |
int xuiDockPanelFloatWindow(pW, iWin, tRect) | 浮动窗口 |
int xuiDockPanelHideWindow(pW, iWin) | 隐藏窗口 |
int xuiDockPanelAutoHideWindow(pW, iWin) | 自动隐藏 |
gcc -O2 -I. -o ch181.exe ch181_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch181.exe
xui_dock_panel_desc_t desc = { 0 };
xui_widget pDock;
xuiDockPanelCreate(pCtx, &pDock, &desc);
// 添加编辑器窗口到 Center
int iEditor;
xuiDockPanelAddWindow(pDock, "main.c", pCodeEdit, &iEditor);
xuiDockPanelDockWindow(pDock, iEditor, 4, 0, 1.0f, NULL);
// 属性面板停靠右侧 30%
int iProps;
xuiDockPanelAddWindow(pDock, "Properties", pPropGrid, &iProps);
xuiDockPanelDockWindow(pDock, iProps, 1, 0, 0.3f, NULL);
// 终端停靠底部 25%
int iTerm;
xuiDockPanelAddWindow(pDock, "Terminal", pTerminal, &iTerm);
xuiDockPanelDockWindow(pDock, iTerm, 3, 0, 0.25f, NULL);
// 允许关闭和停靠
xuiDockPanelSetWindowFlags(pDock, iTerm, 1, 1);将以下代码保存为 ch181_main.c,编译后运行即可看到 VS 风格停靠布局:
#include "xge.h"
#include "xui.h"
static xui_context g_pCtx;
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x252526FF);
xui_vec2_t pos;
xgeMouseGet(&pos.x, &pos.y);
xuiInputPointerMove(g_pCtx, pos.x, pos.y);
if (xgeMouseDown(XGE_MOUSE_LEFT))
xuiInputPointerDown(g_pCtx, pos.x, pos.y, 0);
else
xuiInputPointerUp(g_pCtx, pos.x, pos.y, 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 = 1024; d.iHeight = 700;
d.sTitle = "ch181 - DockPanel";
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, 1024, 700);
// 创建停靠面板
xui_dock_panel_desc_t ddesc = { 0 };
xui_widget pDock;
xuiDockPanelCreate(g_pCtx, &pDock, &ddesc);
// 创建编辑器控件作为 Center
xui_code_edit_desc_t edesc = { 0 };
xui_widget pEditor;
xuiCodeEditCreate(g_pCtx, &pEditor, &edesc);
xuiCodeEditSetLanguage(pEditor, "c");
xuiCodeEditSetText(pEditor, "int main(void) {\n return 0;\n}\n");
int iEditor;
xuiDockPanelAddWindow(pDock, "main.c", pEditor, &iEditor);
xuiDockPanelDockWindow(pDock, iEditor, 4, 0, 1.0f, NULL);
// 终端停靠底部 25%
xui_terminal_desc_t tdesc = { 0 };
xui_widget pTerm;
xuiTerminalCreate(g_pCtx, &pTerm, &tdesc);
xuiTerminalWriteText(pTerm, "Build Output\r\n");
xuiTerminalFlush(pTerm);
int iTerm;
xuiDockPanelAddWindow(pDock, "Terminal", pTerm, &iTerm);
xuiDockPanelDockWindow(pDock, iTerm, 3, 0, 0.25f, NULL);
xuiDockPanelSetWindowFlags(pDock, iTerm, 1, 1);
xui_widget pRoot = xuiGetRootWidget(g_pCtx);
xuiWidgetAddChild(pRoot, pDock);
xuiWidgetSetRect(pDock, (xui_rect_t){0, 0, 1024, 700});
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}