dlxjj/imradv3
0262
1#pragma once2#include "imgui.h"3#include "imgui_internal.h"4#include <functional>5 6class SimpleLayout {7public:8 // 使用函数对象代替函数指针,更现代的C++风格9 using WindowCallback = std::function<void()>;10 11 SimpleLayout(float splitRatio = 0.5f)12 : m_splitRatio(splitRatio)13 , m_splitBarWidth(4.0f)14 , m_isDragging(false)15 , m_splitBarHeld(false)16 , m_splitBarDelta(0.0f)17 {}18 19 void SetLeftWindow(WindowCallback callback) { m_leftWindow = callback; }20 void SetRightWindow(WindowCallback callback) { m_rightWindow = callback; }21 22 void Draw() {23 ImGuiViewport* viewport = ImGui::GetMainViewport();24 ImVec2 pos = viewport->WorkPos;25 ImVec2 size = viewport->WorkSize;26 27 // 计算左右窗口的位置和大小28 float splitX = pos.x + size.x * m_splitRatio;29 30 // 绘制左窗口31 if (m_leftWindow) {32 ImGui::SetNextWindowPos(ImVec2(pos.x, pos.y));33 ImGui::SetNextWindowSize(ImVec2(splitX - pos.x - m_splitBarWidth/2, size.y));34 ImGui::Begin("Left Window", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);35 m_leftWindow();36 ImGui::End();37 }38 39 // 绘制右窗口40 if (m_rightWindow) {41 ImGui::SetNextWindowPos(ImVec2(splitX + m_splitBarWidth/2, pos.y));42 ImGui::SetNextWindowSize(ImVec2(size.x - (splitX - pos.x) - m_splitBarWidth/2, size.y));43 ImGui::Begin("Right Window", nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);44 m_rightWindow();45 ImGui::End();46 }47 48 // 处理分隔条49 ImGui::SetNextWindowPos(ImVec2(splitX - m_splitBarWidth/2, pos.y));50 ImGui::SetNextWindowSize(ImVec2(m_splitBarWidth, size.y));51 ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.3f, 0.3f, 0.3f, 1.0f));52 ImGui::Begin("##Splitter", nullptr, 53 ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | 54 ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus);55 56 // 处理拖拽57 if (!m_splitBarHeld) {58 // 检测鼠标是否悬停在分隔条上59 ImVec2 splitBarMin = ImGui::GetWindowPos();60 ImVec2 splitBarMax = ImVec2(splitBarMin.x + ImGui::GetWindowSize().x,61 splitBarMin.y + ImGui::GetWindowSize().y);62 63 if (ImGui::IsMouseHoveringRect(splitBarMin, splitBarMax, false)) {64 ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);65 66 if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {67 m_splitBarHeld = true;68 m_splitBarDelta = splitX - ImGui::GetMousePos().x;69 }70 }71 } else {72 if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) {73 ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);74 75 // 计算新的分隔比例76 float newSplitX = ImGui::GetMousePos().x + m_splitBarDelta;77 float newRatio = (newSplitX - pos.x) / size.x;78 79 // 限制分隔条的移动范围80 m_splitRatio = ImClamp(newRatio, 0.1f, 0.9f);81 } else {82 m_splitBarHeld = false;83 }84 }85 86 ImGui::End();87 ImGui::PopStyleColor();88 }89 90private:91 float m_splitRatio; // 分割比例(0-1)92 float m_splitBarWidth; // 分隔条宽度93 bool m_isDragging; // 是否正在拖拽(已废弃)94 bool m_splitBarHeld; // 分隔条是否被按住95 float m_splitBarDelta; // 鼠标按下时与分隔条的位置差96 WindowCallback m_leftWindow; // 左窗口回调97 WindowCallback m_rightWindow; // 右窗口回调98};