Chapter 181 · XUI 专业控件

DockPanel 停靠面板

IDE 风格停靠系统:区域停靠、浮动窗口、自动隐藏、标签组合并。

181

概念

DockPanel 实现 Visual Studio 风格停靠布局:
• Region:Left/Right/Top/Bottom/Center 五个停靠区域
• Pane:面板容器,可包含多个标签页
• Float:拖出为浮动窗口
• AutoHide:自动隐藏到边缘,悬停展开
• Splitter:面板间拖拽调整比例

API 速查

函数说明
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

示例:IDE 布局

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;
}

代码讲解

  • DockPanelCreate:创建停靠容器,管理多个可拖拽面板。
  • AddWindow + DockWindow:将任意 Widget 包装为停靠窗口,Region: 0=Left 1=Right 2=Top 3=Bottom 4=Center。
  • Ratio:停靠比例 0.0-1.0,终端占底部 25%。
  • SetWindowFlags:允许关闭和拖拽停靠。

要点与陷阱

  • Region:0=Left, 1=Right, 2=Top, 3=Bottom, 4=Center。
  • Ratio:停靠比例 0.0-1.0,相对于区域总尺寸。
  • Client:AddWindow 的 pClient 是任意 Widget(CodeEdit/TreeView 等)。
  • AutoHide:自动隐藏后显示为边缘标签条,悬停时滑出。

进阶练习

  1. 布局持久化:保存/恢复 DockPanel 布局到配置文件。
  2. 多文档标签:Center 区域多个 CodeEdit 标签切换。
DockPanel 停靠面板效果
图:DockPanel 停靠面板渲染效果