Supporting setting panel layout
This commit is contained in:
@@ -3,9 +3,21 @@
|
||||
#include <imgui.h>
|
||||
#include <imgui_impl_glfw.h>
|
||||
#include <imgui_impl_vulkan.h>
|
||||
#include <imgui_internal.h> // DockBuilder API
|
||||
|
||||
namespace sophia {
|
||||
|
||||
namespace {
|
||||
constexpr ImGuiDockNodeFlags DOCKSPACE_FLAGS =
|
||||
ImGuiDockNodeFlags_PassthruCentralNode;
|
||||
|
||||
void dockAll(const std::vector<std::string>& windows, ImGuiID nodeId) {
|
||||
for (const std::string& name : windows) {
|
||||
ImGui::DockBuilderDockWindow(name.c_str(), nodeId);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ImGuiRenderer::ImGuiRenderer(Window& window, Device& device,
|
||||
vk::Format colorAttachmentFormat,
|
||||
u32 minImageCount) {
|
||||
@@ -65,8 +77,59 @@ void ImGuiRenderer::beginFrame() {
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport(),
|
||||
ImGuiDockNodeFlags_PassthruCentralNode);
|
||||
ImGuiID dockspaceId = ImGui::DockSpaceOverViewport(
|
||||
0, ImGui::GetMainViewport(), DOCKSPACE_FLAGS);
|
||||
applyLayoutIfNeeded(dockspaceId, DOCKSPACE_FLAGS);
|
||||
}
|
||||
|
||||
void ImGuiRenderer::setDefaultLayout(DockLayout layout) {
|
||||
defaultLayout = std::move(layout);
|
||||
seedIfUnsaved = true;
|
||||
}
|
||||
|
||||
void ImGuiRenderer::resetLayout() { forceReset = true; }
|
||||
|
||||
void ImGuiRenderer::applyLayoutIfNeeded(ImGuiID dockspaceId,
|
||||
ImGuiDockNodeFlags flags) {
|
||||
if (defaultLayout.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool apply = forceReset;
|
||||
if (seedIfUnsaved) {
|
||||
// A layout restored from imgui.ini shows up as a split root node.
|
||||
ImGuiDockNode* root = ImGui::DockBuilderGetNode(dockspaceId);
|
||||
apply = apply || root == nullptr || !root->IsSplitNode();
|
||||
seedIfUnsaved = false;
|
||||
}
|
||||
if (!apply) {
|
||||
return;
|
||||
}
|
||||
forceReset = false;
|
||||
|
||||
const ImVec2 size = ImGui::GetMainViewport()->Size;
|
||||
|
||||
ImGui::DockBuilderRemoveNode(dockspaceId);
|
||||
ImGui::DockBuilderAddNode(dockspaceId, flags | ImGuiDockNodeFlags_DockSpace);
|
||||
ImGui::DockBuilderSetNodeSize(dockspaceId, size);
|
||||
|
||||
ImGuiID center = dockspaceId;
|
||||
const ImGuiID left = ImGui::DockBuilderSplitNode(
|
||||
center, ImGuiDir_Left, defaultLayout.leftWidth, nullptr, ¢er);
|
||||
// The right split is taken from what's left after the left split.
|
||||
const float rightRatio =
|
||||
defaultLayout.rightWidth / (1.0f - defaultLayout.leftWidth);
|
||||
const ImGuiID right = ImGui::DockBuilderSplitNode(
|
||||
center, ImGuiDir_Right, rightRatio, nullptr, ¢er);
|
||||
const ImGuiID bottom = ImGui::DockBuilderSplitNode(
|
||||
center, ImGuiDir_Down, defaultLayout.bottomHeight, nullptr, ¢er);
|
||||
|
||||
dockAll(defaultLayout.left, left);
|
||||
dockAll(defaultLayout.right, right);
|
||||
dockAll(defaultLayout.bottom, bottom);
|
||||
dockAll(defaultLayout.center, center);
|
||||
|
||||
ImGui::DockBuilderFinish(dockspaceId);
|
||||
}
|
||||
|
||||
void ImGuiRenderer::endFrame(vk::CommandBuffer commandBuffer) {
|
||||
|
||||
Reference in New Issue
Block a user