Refactor editor UI architecture
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
#include "Commands/SceneCommands.h"
|
||||
#include "EditorLayer.h"
|
||||
#include "Layout/DockLayoutController.h"
|
||||
#include "panels/MenuBar.h"
|
||||
#include "panels/HierarchyPanel.h"
|
||||
#include "panels/SceneViewPanel.h"
|
||||
@@ -9,14 +11,20 @@
|
||||
#include "Core/IEditorContext.h"
|
||||
#include "Core/EditorContext.h"
|
||||
#include "Core/IUndoManager.h"
|
||||
#include "UI/DockHostStyle.h"
|
||||
#include <filesystem>
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string BuildFallbackScenePath(const IEditorContext& context) {
|
||||
return (std::filesystem::path(context.GetProjectPath()) / "Assets" / "Scenes" / "Main.xc").string();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EditorLayer::EditorLayer() : Layer("Editor") {}
|
||||
|
||||
void EditorLayer::SetContext(std::shared_ptr<IEditorContext> context) {
|
||||
@@ -27,138 +35,49 @@ void EditorLayer::onAttach() {
|
||||
if (!m_context) {
|
||||
m_context = std::make_shared<EditorContext>();
|
||||
}
|
||||
|
||||
m_menuBar = std::make_unique<MenuBar>();
|
||||
m_hierarchyPanel = std::make_unique<HierarchyPanel>();
|
||||
m_sceneViewPanel = std::make_unique<SceneViewPanel>();
|
||||
m_gameViewPanel = std::make_unique<GameViewPanel>();
|
||||
m_inspectorPanel = std::make_unique<InspectorPanel>();
|
||||
m_consolePanel = std::make_unique<ConsolePanel>();
|
||||
m_projectPanel = std::make_unique<ProjectPanel>();
|
||||
|
||||
m_menuBar->SetContext(m_context.get());
|
||||
m_hierarchyPanel->SetContext(m_context.get());
|
||||
m_sceneViewPanel->SetContext(m_context.get());
|
||||
m_gameViewPanel->SetContext(m_context.get());
|
||||
m_inspectorPanel->SetContext(m_context.get());
|
||||
m_consolePanel->SetContext(m_context.get());
|
||||
m_projectPanel->SetContext(m_context.get());
|
||||
|
||||
m_projectPanel->Initialize(m_context->GetProjectPath());
|
||||
m_context->GetSceneManager().LoadStartupScene(m_context->GetProjectPath());
|
||||
m_context->GetProjectManager().RefreshCurrentFolder();
|
||||
m_context->GetUndoManager().ClearHistory();
|
||||
|
||||
m_menuBar->OnAttach();
|
||||
m_hierarchyPanel->OnAttach();
|
||||
m_sceneViewPanel->OnAttach();
|
||||
m_gameViewPanel->OnAttach();
|
||||
m_inspectorPanel->OnAttach();
|
||||
m_consolePanel->OnAttach();
|
||||
m_projectPanel->OnAttach();
|
||||
m_panels.Clear();
|
||||
m_panels.SetContext(m_context.get());
|
||||
m_panels.Emplace<MenuBar>();
|
||||
m_panels.Emplace<HierarchyPanel>();
|
||||
m_panels.Emplace<SceneViewPanel>();
|
||||
m_panels.Emplace<GameViewPanel>();
|
||||
m_panels.Emplace<InspectorPanel>();
|
||||
m_panels.Emplace<ConsolePanel>();
|
||||
m_projectPanel = &m_panels.Emplace<ProjectPanel>();
|
||||
m_dockLayoutController = std::make_unique<DockLayoutController>();
|
||||
|
||||
m_projectPanel->Initialize(m_context->GetProjectPath());
|
||||
Commands::LoadStartupScene(*m_context);
|
||||
m_dockLayoutController->Attach(*m_context);
|
||||
m_panels.AttachAll();
|
||||
}
|
||||
|
||||
void EditorLayer::onDetach() {
|
||||
auto& sceneManager = m_context->GetSceneManager();
|
||||
if (sceneManager.HasActiveScene() && sceneManager.IsSceneDirty()) {
|
||||
if (!sceneManager.SaveScene()) {
|
||||
const std::string fallbackPath =
|
||||
(std::filesystem::path(m_context->GetProjectPath()) / "Assets" / "Scenes" / "Main.xc").string();
|
||||
sceneManager.SaveSceneAs(fallbackPath);
|
||||
}
|
||||
if (m_context) {
|
||||
Commands::SaveDirtySceneWithFallback(*m_context, BuildFallbackScenePath(*m_context));
|
||||
}
|
||||
|
||||
m_menuBar->OnDetach();
|
||||
m_hierarchyPanel->OnDetach();
|
||||
m_sceneViewPanel->OnDetach();
|
||||
m_gameViewPanel->OnDetach();
|
||||
m_inspectorPanel->OnDetach();
|
||||
m_consolePanel->OnDetach();
|
||||
m_projectPanel->OnDetach();
|
||||
if (m_dockLayoutController) {
|
||||
m_dockLayoutController->Detach();
|
||||
}
|
||||
|
||||
m_panels.DetachAll();
|
||||
m_panels.Clear();
|
||||
m_projectPanel = nullptr;
|
||||
}
|
||||
|
||||
void EditorLayer::onUpdate(float dt) {
|
||||
m_panels.UpdateAll(dt);
|
||||
}
|
||||
|
||||
void EditorLayer::onEvent(void* event) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// TODO: These functions don't exist - need to implement them
|
||||
// if (ImGui::IsKeyPressed(ImGuiKey_F5)) {
|
||||
// TogglePlay();
|
||||
// }
|
||||
//
|
||||
// if (ImGui::IsKeyPressed(ImGuiKey_F6)) {
|
||||
// if (GetEditorMode() != EditorMode::Edit) {
|
||||
// TogglePause();
|
||||
// }
|
||||
// }
|
||||
m_panels.DispatchEvent(event);
|
||||
}
|
||||
|
||||
void EditorLayer::onImGuiRender() {
|
||||
setupDockspace();
|
||||
renderAllPanels();
|
||||
}
|
||||
|
||||
void EditorLayer::setupDockspace() {
|
||||
static ImGuiDockNodeFlags dockspaceFlags = ImGuiDockNodeFlags_NoWindowMenuButton;
|
||||
|
||||
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
||||
|
||||
ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->Pos);
|
||||
ImGui::SetNextWindowSize(viewport->Size);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
windowFlags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||
windowFlags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("MainDockspace", nullptr, windowFlags);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
ImGuiID dockspaceId = ImGui::GetID("MyDockspace");
|
||||
{
|
||||
UI::DockHostStyleScope dockHostStyle;
|
||||
ImGui::DockSpace(dockspaceId, ImVec2(0.0f, 0.0f), dockspaceFlags);
|
||||
}
|
||||
|
||||
static bool firstTime = true;
|
||||
if (firstTime) {
|
||||
firstTime = false;
|
||||
ImGui::DockBuilderRemoveNode(dockspaceId);
|
||||
ImGui::DockBuilderAddNode(dockspaceId, dockspaceFlags | ImGuiDockNodeFlags_DockSpace);
|
||||
ImGui::DockBuilderSetNodeSize(dockspaceId, viewport->Size);
|
||||
|
||||
ImGuiID dockMain = dockspaceId;
|
||||
ImGuiID dockBottom = ImGui::DockBuilderSplitNode(dockMain, ImGuiDir_Down, 0.25f, nullptr, &dockMain);
|
||||
ImGuiID dockLeft = ImGui::DockBuilderSplitNode(dockMain, ImGuiDir_Left, 0.15f, nullptr, &dockMain);
|
||||
ImGuiID dockRight = ImGui::DockBuilderSplitNode(dockMain, ImGuiDir_Right, 0.25f, nullptr, &dockMain);
|
||||
|
||||
ImGui::DockBuilderDockWindow("Hierarchy", dockLeft);
|
||||
ImGui::DockBuilderDockWindow("Scene", dockMain);
|
||||
ImGui::DockBuilderDockWindow("Game", dockMain);
|
||||
ImGui::DockBuilderDockWindow("Inspector", dockRight);
|
||||
ImGui::DockBuilderDockWindow("Console", dockBottom);
|
||||
ImGui::DockBuilderDockWindow("Project", dockBottom);
|
||||
|
||||
ImGui::DockBuilderFinish(dockspaceId);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void EditorLayer::renderAllPanels() {
|
||||
m_menuBar->Render();
|
||||
|
||||
m_hierarchyPanel->Render();
|
||||
m_sceneViewPanel->Render();
|
||||
m_gameViewPanel->Render();
|
||||
m_inspectorPanel->Render();
|
||||
m_consolePanel->Render();
|
||||
m_projectPanel->Render();
|
||||
m_dockLayoutController->RenderDockspace();
|
||||
m_panels.RenderAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user