/****************************************************************************** * File - panel_manager.cpp * Author - Joey Pollack * Date - 2022/02/07 (y/m/d) * Mod Date - 2022/02/07 (y/m/d) * Description - Manage the editor panels ******************************************************************************/ #include "panel_manager.h" #include "gui.h" #include #include #include // To use the DockWindowXXX methods #include // Panels namespace lunarium { PanelManager::PanelManager() : mResetDockSpace(false), mDockSpaceID(0), mSplitBottom(false) { } OpRes PanelManager::Initialize(std::string name, bool split_bottom) { mName = name; mSplitBottom = split_bottom; memset(&mWindowClass, 0, sizeof(ImGuiWindowClass)); mWindowClass.ClassId = GUI::GetInstance().GetNextWindowID(); if (!std::filesystem::exists("imgui.ini")) { mResetDockSpace = true; } return OpRes::OK(); } void PanelManager::Shutdown() { DestoryPanels(); } OpRes PanelManager::AddPanel(Panel* panel, uint32_t& id) { if (mPanelsByName.find(panel->GetName()) != mPanelsByName.end()) { return OpRes::Fail("Cannot add panel - panel already exists. Panel Name: %s", panel->GetName()); } mPanelsByName[panel->GetName()] = panel; mPanels.push_back(panel); id = mPanels.size() - 1; return OpRes::OK(); } void PanelManager::OpenPanel(uint32_t id) { if (id >= mPanels.size() || id < 0) return; mPanels[id]->SetOpen(true); } void PanelManager::ClosePanel(uint32_t id) { if (mPanels.size() >= id || id < 0) return; mPanels[id]->SetOpen(false); } bool PanelManager::IsOpen(uint32_t id) { if (mPanels.size() >= id || id < 0) return false; return mPanels[id]->IsOpen(); } Panel* PanelManager::GetPanel(uint32_t id) { if (id >= 0 && id < mPanels.size()) { return mPanels[id]; } Logger::Warn(GUI::LogCat, "Requested panel not found: %d", id); return nullptr; } const ImGuiWindowClass* PanelManager::GetWindowClass() const { return &mWindowClass; } bool PanelManager::IsBottomSplit() const { return mSplitBottom; } void PanelManager::SetSplitBottom(bool split_bottom) { mSplitBottom = split_bottom; } void PanelManager::ResetDocking() { mResetDockSpace = true; } void PanelManager::OnTick(double delta) { for (auto iter = mPanels.begin(); iter != mPanels.end(); iter++) { if ((*iter)->IsOpen()) { (*iter)->Update(delta); } } } void PanelManager::RenderPanels() { for (auto iter = mPanels.begin(); iter != mPanels.end(); iter++) { if ((*iter)->IsOpen()) { ImGui::SetNextWindowClass(&mWindowClass); (*iter)->OnUIRender(); } } } //////////////////////////////////////////////////////////// // HELPER METHODS //////////////////////////////////////////////////////////// void PanelManager::DestoryPanels() { for (auto iter = mPanels.begin(); iter != mPanels.end(); iter++) { delete (*iter); } mPanels.clear(); } void PanelManager::MakeDockSpaces() { //ImGuiViewport* Viewport = ImGui::GetMainViewport(); ImGuiViewport* Viewport = ImGui::GetWindowViewport(); ImGuiID windowID = GUI::GetInstance().GetNextWindowID(); std::string dock_name = mName; dock_name += " DockSpace"; mDockSpaceID = ImGui::DockSpace(ImGui::GetID(dock_name.c_str()), ImVec2(0, 0), 0, &mWindowClass); if (!ImGui::DockBuilderGetNode(mDockSpaceID) || mResetDockSpace) { Logger::Trace(GUI::LogCat, "Resetting Dockspace: %s", dock_name.c_str()); mResetDockSpace = false; ImGui::DockBuilderRemoveNode(mDockSpaceID); ImGui::DockBuilderAddNode(mDockSpaceID, ImGuiDockNodeFlags_DockSpace); ImGui::DockBuilderSetNodeSize(mDockSpaceID, Viewport->Size); //ImGui::DockBuilderSetNodePos(mDockSpaces.Main, Viewport->WorkPos); ImGui::DockBuilderSplitNode(mDockSpaceID, ImGuiDir_Down, 0.25f, &mDockZoneIDs[PanelDockZone::DDZ_BOTTOM], &mDockZoneIDs[PanelDockZone::DDZ_CENTER]); if (mSplitBottom) { ImGui::DockBuilderSplitNode(mDockZoneIDs[PanelDockZone::DDZ_BOTTOM], ImGuiDir_Left, 0.2f, &mDockZoneIDs[PanelDockZone::DDZ_BOT_LEFT], &mDockZoneIDs[PanelDockZone::DDZ_BOT_RIGHT]); } ImGui::DockBuilderSplitNode(mDockZoneIDs[PanelDockZone::DDZ_CENTER], ImGuiDir_Right, 0.2f, &mDockZoneIDs[PanelDockZone::DDZ_RIGHT], &mDockZoneIDs[PanelDockZone::DDZ_CENTER]); ImGui::DockBuilderSplitNode(mDockZoneIDs[PanelDockZone::DDZ_CENTER], ImGuiDir_Left, 0.2f, &mDockZoneIDs[PanelDockZone::DDZ_LEFT], &mDockZoneIDs[PanelDockZone::DDZ_CENTER]); ImGui::DockBuilderFinish(mDockSpaceID); // Dock Panels for (auto iter = mPanels.begin(); iter != mPanels.end(); iter++) { PanelDockZone dz = (*iter)->GetDockZone(); if (dz != PanelDockZone::DDZ_NONE) { // If the panel expects the bottom node to be split but it isn't // we need to change it to just dock to the bottom if ((dz == PanelDockZone::DDZ_BOT_LEFT || dz == PanelDockZone::DDZ_BOT_RIGHT) && !mSplitBottom) { dz = PanelDockZone::DDZ_BOTTOM; } // Also need to account for the opposite situation // Default it to the bottom left if (dz == PanelDockZone::DDZ_BOTTOM && mSplitBottom) { dz = PanelDockZone::DDZ_BOT_LEFT; } ImGui::DockBuilderDockWindow((*iter)->GetName(), mDockZoneIDs[dz]); } } } } }