如何让ImGui的BeginChild控件像Begin创建的窗口一样支持拖拽调整大小
实现ImGui子窗口拖拽调整大小的方案
方案1:原生标志实现(适用于ImGui 1.87及以上版本)
ImGui新版本已经为BeginChild内置了拖拽调整大小的能力,只需要传入对应的子窗口标志即可,修改你的代码如下:
// 注意child_size需要是持久存储的变量,比如类成员、全局变量,不能是函数内临时变量 ImVec2 child_size = ImVec2(300, 200); // 初始大小 ui::Begin("title"); { // 传入ResizeY标志允许垂直拖拽调整高度,如需横向调整加 ImGuiChildFlags_ResizeX即可 ui::BeginChild("child title", child_size, ImGuiChildFlags_None | ImGuiChildFlags_ResizeY); { ui::Text("example"); } ui::EndChild(); } ui::End();
拖拽手柄会自动显示在子窗口的底部(垂直调整)/右侧(横向调整),调整后的数值会自动同步到你传入的child_size变量中。
方案2:自定义拖拽手柄(兼容所有ImGui版本)
如果你的项目用的是旧版本ImGui,可以自己在子窗口底部加一个拖拽区域,手动处理拖拽逻辑:
ImVec2 child_size = ImVec2(300, 200); const float resize_grabber_height = 4.0f; // 拖拽条高度 ui::Begin("title"); { ui::BeginChild("child title", ImVec2(child_size.x, child_size.y - resize_grabber_height)); { ui::Text("example"); } ui::EndChild(); // 拖拽区域逻辑 ui::InvisibleButton("child_resize_grabber", ImVec2(child_size.x, resize_grabber_height)); if (ui::IsItemActive() && ui::IsMouseDragging(ImGuiMouseButton_Left)) { child_size.y += ui::GetIO().MouseDelta.y; // 可以加最小高度限制,避免拖得太小 child_size.y = ImMax(child_size.y, 50.0f); } // 鼠标悬停时显示调整光标 if (ui::IsItemHovered()) { ui::SetMouseCursor(ImGuiMouseCursor_ResizeNS); } } ui::End();
注意事项
- 存储
child_size的变量必须是持久化的,不能在每帧渲染时重新初始化,否则拖拽后的数值会被重置 - 如果需要同时支持横向调整大小,只需要在方案1中额外添加
ImGuiChildFlags_ResizeX标志,或者在方案2中仿照纵向逻辑添加横向拖拽的处理即可
内容的提问来源于stack exchange,提问作者ZeroCool
相关产品推荐
相关产品推荐

