From 9fae910854491ca8adcf7261bb45c76518923724 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Tue, 24 Mar 2026 20:02:38 +0800 Subject: [PATCH] =?UTF-8?q?Editor:=20=E6=9B=B4=E6=96=B0=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E9=9D=A2=E6=9D=BF=E5=92=8CUI=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加新的UI控件系统(Core.h, ScalarControls.h, VectorControls.h, UI.h) - 更新SceneManager支持场景层级管理 - 优化SelectionManager选择管理 - 改进InspectorPanel/GameViewPanel/HierarchyPanel等面板 - 更新RHI文档说明Vulkan实现计划 --- .../plan/end/RHI模块设计与实现/RHI模块总览.md | 2 +- editor/CMakeLists.txt | 6 +- editor/src/Application.cpp | 4 +- editor/src/Application.h | 4 +- editor/src/Core/AssetItem.h | 4 +- editor/src/Core/LogEntry.h | 6 +- editor/src/Managers/LogSystem.cpp | 6 +- editor/src/Managers/LogSystem.h | 6 +- editor/src/Managers/ProjectManager.cpp | 4 +- editor/src/Managers/ProjectManager.h | 4 +- editor/src/Managers/SceneManager.cpp | 64 ++-- editor/src/Managers/SceneManager.h | 42 +-- editor/src/Managers/SelectionManager.h | 14 +- editor/src/Theme.cpp | 4 +- editor/src/Theme.h | 4 +- editor/src/UI/Core.h | 61 ++++ editor/src/UI/ScalarControls.h | 322 ++++++++++++++++++ editor/src/UI/UI.h | 13 + editor/src/UI/VectorControls.h | 150 ++++++++ editor/src/main.cpp | 8 +- editor/src/panels/ConsolePanel.cpp | 26 +- editor/src/panels/ConsolePanel.h | 4 +- editor/src/panels/GameViewPanel.cpp | 4 +- editor/src/panels/GameViewPanel.h | 4 +- editor/src/panels/HierarchyPanel.cpp | 50 +-- editor/src/panels/HierarchyPanel.h | 18 +- editor/src/panels/InspectorPanel.cpp | 31 +- editor/src/panels/InspectorPanel.h | 8 +- editor/src/panels/MenuBar.cpp | 4 +- editor/src/panels/MenuBar.h | 4 +- editor/src/panels/Panel.cpp | 4 +- editor/src/panels/Panel.h | 4 +- editor/src/panels/ProjectPanel.cpp | 4 +- editor/src/panels/ProjectPanel.h | 4 +- editor/src/panels/SceneViewPanel.cpp | 4 +- editor/src/panels/SceneViewPanel.h | 4 +- 36 files changed, 757 insertions(+), 148 deletions(-) create mode 100644 editor/src/UI/Core.h create mode 100644 editor/src/UI/ScalarControls.h create mode 100644 editor/src/UI/UI.h create mode 100644 editor/src/UI/VectorControls.h diff --git a/docs/plan/end/RHI模块设计与实现/RHI模块总览.md b/docs/plan/end/RHI模块设计与实现/RHI模块总览.md index c2212399..eda6f8d0 100644 --- a/docs/plan/end/RHI模块设计与实现/RHI模块总览.md +++ b/docs/plan/end/RHI模块设计与实现/RHI模块总览.md @@ -1,6 +1,6 @@ # RHI 渲染模块设计文档 ## 1. 项目背景 -本项目旨在参考 Unity 渲染架构,为已有的 **OpenGL** 、**Direct3D 12** 和 **Vulkan** 图形 API 后端设计统一的**渲染硬件抽象层(RHI)**,屏蔽 API 差异,实现引擎上层逻辑与底层图形 API 的解耦。 +本项目旨在参考 Unity 渲染架构,为已有的 **OpenGL** 、**Direct3D 12** 和 **Vulkan** 图形 API 后端设计统一的**渲染硬件抽象层(RHI)**,屏蔽 API 差异,实现引擎上层逻辑与底层图形 API 的解耦。(暂时只实现D3D12和OpenGL,后面会加上Vulkan) ## 2. 核心设计理念 **求同存异,分层抽象,特性降级,底层逃逸** diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index b7fff6eb..9dbb5c59 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -51,18 +51,20 @@ target_include_directories(${PROJECT_NAME} PRIVATE ${imgui_SOURCE_DIR} ${imgui_SOURCE_DIR}/backends ${CMAKE_CURRENT_SOURCE_DIR}/../engine/include + ${CMAKE_CURRENT_SOURCE_DIR}/../tests/OpenGL/package/glm ) target_compile_definitions(${PROJECT_NAME} PRIVATE UNICODE _UNICODE) -target_compile_options(${PROJECT_NAME} PRIVATE /utf-8 /MT) +target_compile_options(${PROJECT_NAME} PRIVATE /utf-8 /MD) target_link_libraries(${PROJECT_NAME} PRIVATE d3d12.lib dxgi.lib d3dcompiler.lib - XCEngine + ${CMAKE_SOURCE_DIR}/engine/build/Release/XCEngine.lib ) set_target_properties(${PROJECT_NAME} PROPERTIES + OUTPUT_NAME "XCEngine" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin" ) \ No newline at end of file diff --git a/editor/src/Application.cpp b/editor/src/Application.cpp index 47074823..9dcfef22 100644 --- a/editor/src/Application.cpp +++ b/editor/src/Application.cpp @@ -6,7 +6,8 @@ extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -namespace UI { +namespace XCEngine { +namespace Editor { Application& Application::Get() { static Application instance; @@ -300,4 +301,5 @@ void Application::RenderUI() { m_projectPanel->Render(); } +} } \ No newline at end of file diff --git a/editor/src/Application.h b/editor/src/Application.h index 8e1d92dd..bb3c3972 100644 --- a/editor/src/Application.h +++ b/editor/src/Application.h @@ -15,7 +15,8 @@ #include "panels/ConsolePanel.h" #include "panels/ProjectPanel.h" -namespace UI { +namespace XCEngine { +namespace Editor { class Application { public: @@ -62,4 +63,5 @@ private: std::unique_ptr m_projectPanel; }; +} } \ No newline at end of file diff --git a/editor/src/Core/AssetItem.h b/editor/src/Core/AssetItem.h index 8875bcd3..bbd0526d 100644 --- a/editor/src/Core/AssetItem.h +++ b/editor/src/Core/AssetItem.h @@ -4,7 +4,8 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { struct AssetItem { std::string name; @@ -16,4 +17,5 @@ struct AssetItem { using AssetItemPtr = std::shared_ptr; +} } \ No newline at end of file diff --git a/editor/src/Core/LogEntry.h b/editor/src/Core/LogEntry.h index 4f8e847a..abc97f84 100644 --- a/editor/src/Core/LogEntry.h +++ b/editor/src/Core/LogEntry.h @@ -4,11 +4,13 @@ #include -namespace UI { +namespace XCEngine { +namespace Editor { struct LogEntry { - XCEngine::Debug::LogLevel level; + ::XCEngine::Debug::LogLevel level; std::string message; }; } +} diff --git a/editor/src/Managers/LogSystem.cpp b/editor/src/Managers/LogSystem.cpp index 3a757c1f..e554db11 100644 --- a/editor/src/Managers/LogSystem.cpp +++ b/editor/src/Managers/LogSystem.cpp @@ -1,13 +1,14 @@ #include "LogSystem.h" -namespace UI { +namespace XCEngine { +namespace Editor { LogSystem& LogSystem::Get() { static LogSystem instance; return instance; } -void LogSystem::AddLog(XCEngine::Debug::LogLevel level, const std::string& message) { +void LogSystem::AddLog(::XCEngine::Debug::LogLevel level, const std::string& message) { m_logs.push_back({level, message}); if (m_callback) m_callback(); } @@ -16,4 +17,5 @@ void LogSystem::Clear() { m_logs.clear(); } +} } \ No newline at end of file diff --git a/editor/src/Managers/LogSystem.h b/editor/src/Managers/LogSystem.h index 966cd85c..3b062f2a 100644 --- a/editor/src/Managers/LogSystem.h +++ b/editor/src/Managers/LogSystem.h @@ -4,13 +4,14 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { class LogSystem { public: static LogSystem& Get(); - void AddLog(XCEngine::Debug::LogLevel level, const std::string& message); + void AddLog(::XCEngine::Debug::LogLevel level, const std::string& message); void Clear(); const std::vector& GetLogs() const { return m_logs; } @@ -24,3 +25,4 @@ private: }; } +} diff --git a/editor/src/Managers/ProjectManager.cpp b/editor/src/Managers/ProjectManager.cpp index 15d1d1e9..c10f4506 100644 --- a/editor/src/Managers/ProjectManager.cpp +++ b/editor/src/Managers/ProjectManager.cpp @@ -6,7 +6,8 @@ namespace fs = std::filesystem; -namespace UI { +namespace XCEngine { +namespace Editor { ProjectManager& ProjectManager::Get() { static ProjectManager instance; @@ -243,4 +244,5 @@ AssetItemPtr ProjectManager::CreateAssetItem(const std::wstring& path, const std return item; } +} } \ No newline at end of file diff --git a/editor/src/Managers/ProjectManager.h b/editor/src/Managers/ProjectManager.h index 525aa0ea..a54448e5 100644 --- a/editor/src/Managers/ProjectManager.h +++ b/editor/src/Managers/ProjectManager.h @@ -5,7 +5,8 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { class ProjectManager { public: @@ -46,4 +47,5 @@ private: std::string m_projectPath; }; +} } \ No newline at end of file diff --git a/editor/src/Managers/SceneManager.cpp b/editor/src/Managers/SceneManager.cpp index fa11fd1e..075b0d30 100644 --- a/editor/src/Managers/SceneManager.cpp +++ b/editor/src/Managers/SceneManager.cpp @@ -2,14 +2,15 @@ #include "SelectionManager.h" #include -namespace UI { +namespace XCEngine { +namespace Editor { -XCEngine::Components::GameObject* EditorSceneManager::CreateEntity(const std::string& name, XCEngine::Components::GameObject* parent) { +::XCEngine::Components::GameObject* EditorSceneManager::CreateEntity(const std::string& name, ::XCEngine::Components::GameObject* parent) { if (!m_scene) { - m_scene = new XCEngine::Components::Scene("EditorScene"); + m_scene = new ::XCEngine::Components::Scene("EditorScene"); } - XCEngine::Components::GameObject* entity = m_scene->CreateGameObject(name, parent); + ::XCEngine::Components::GameObject* entity = m_scene->CreateGameObject(name, parent); if (parent == nullptr) { m_rootEntities.push_back(entity); @@ -19,13 +20,13 @@ XCEngine::Components::GameObject* EditorSceneManager::CreateEntity(const std::st return entity; } -void EditorSceneManager::DeleteEntity(XCEngine::Components::GameObject::ID id) { +void EditorSceneManager::DeleteEntity(::XCEngine::Components::GameObject::ID id) { if (!m_scene) return; - XCEngine::Components::GameObject* entity = m_scene->Find(std::to_string(id)); + ::XCEngine::Components::GameObject* entity = m_scene->Find(std::to_string(id)); if (!entity) return; - std::vector children = entity->GetChildren(); + std::vector<::XCEngine::Components::GameObject*> children = entity->GetChildren(); for (auto* child : children) { DeleteEntity(child->GetID()); } @@ -42,11 +43,11 @@ void EditorSceneManager::DeleteEntity(XCEngine::Components::GameObject::ID id) { OnEntityDeleted.Invoke(id); } -EditorSceneManager::ClipboardData EditorSceneManager::CopyEntityRecursive(const XCEngine::Components::GameObject* entity) { +EditorSceneManager::ClipboardData EditorSceneManager::CopyEntityRecursive(const ::XCEngine::Components::GameObject* entity) { ClipboardData data; data.name = entity->GetName(); - if (auto* transform = entity->GetComponent()) { + if (auto* transform = entity->GetComponent<::XCEngine::Components::TransformComponent>()) { // Transform 数据会被复制 } @@ -57,22 +58,22 @@ EditorSceneManager::ClipboardData EditorSceneManager::CopyEntityRecursive(const return data; } -void EditorSceneManager::CopyEntity(XCEngine::Components::GameObject::ID id) { +void EditorSceneManager::CopyEntity(::XCEngine::Components::GameObject::ID id) { if (!m_scene) return; - XCEngine::Components::GameObject* entity = m_scene->Find(std::to_string(id)); + ::XCEngine::Components::GameObject* entity = m_scene->Find(std::to_string(id)); if (!entity) return; m_clipboard = CopyEntityRecursive(entity); } -XCEngine::Components::GameObject::ID EditorSceneManager::PasteEntityRecursive(const ClipboardData& data, XCEngine::Components::GameObject::ID parent) { - XCEngine::Components::GameObject* parentObj = nullptr; +::XCEngine::Components::GameObject::ID EditorSceneManager::PasteEntityRecursive(const ClipboardData& data, ::XCEngine::Components::GameObject::ID parent) { + ::XCEngine::Components::GameObject* parentObj = nullptr; if (parent != 0) { parentObj = m_scene->Find(std::to_string(parent)); } - XCEngine::Components::GameObject* newEntity = m_scene->CreateGameObject(data.name, parentObj); + ::XCEngine::Components::GameObject* newEntity = m_scene->CreateGameObject(data.name, parentObj); if (parentObj == nullptr) { m_rootEntities.push_back(newEntity); @@ -85,32 +86,32 @@ XCEngine::Components::GameObject::ID EditorSceneManager::PasteEntityRecursive(co return newEntity->GetID(); } -XCEngine::Components::GameObject::ID EditorSceneManager::PasteEntity(XCEngine::Components::GameObject::ID parent) { +::XCEngine::Components::GameObject::ID EditorSceneManager::PasteEntity(::XCEngine::Components::GameObject::ID parent) { if (!m_clipboard || !m_scene) return 0; return PasteEntityRecursive(*m_clipboard, parent); } -XCEngine::Components::GameObject::ID EditorSceneManager::DuplicateEntity(XCEngine::Components::GameObject::ID id) { +::XCEngine::Components::GameObject::ID EditorSceneManager::DuplicateEntity(::XCEngine::Components::GameObject::ID id) { if (!m_scene) return 0; - XCEngine::Components::GameObject* entity = m_scene->Find(std::to_string(id)); + ::XCEngine::Components::GameObject* entity = m_scene->Find(std::to_string(id)); if (!entity) return 0; CopyEntity(id); - XCEngine::Components::GameObject::ID parentId = 0; + ::XCEngine::Components::GameObject::ID parentId = 0; if (entity->GetParent()) { parentId = entity->GetParent()->GetID(); } return PasteEntity(parentId); } -void EditorSceneManager::MoveEntity(XCEngine::Components::GameObject::ID id, XCEngine::Components::GameObject::ID newParentId) { +void EditorSceneManager::MoveEntity(::XCEngine::Components::GameObject::ID id, ::XCEngine::Components::GameObject::ID newParentId) { if (!m_scene) return; - XCEngine::Components::GameObject* entity = m_scene->Find(std::to_string(id)); + ::XCEngine::Components::GameObject* entity = m_scene->Find(std::to_string(id)); if (!entity) return; - XCEngine::Components::GameObject* newParent = nullptr; + ::XCEngine::Components::GameObject* newParent = nullptr; if (newParentId != 0) { newParent = m_scene->Find(std::to_string(newParentId)); } @@ -123,26 +124,27 @@ void EditorSceneManager::CreateDemoScene() { if (m_scene) { delete m_scene; } - m_scene = new XCEngine::Components::Scene("DemoScene"); + m_scene = new ::XCEngine::Components::Scene("DemoScene"); m_rootEntities.clear(); m_clipboard.reset(); - XCEngine::Components::GameObject* camera = CreateEntity("Main Camera", nullptr); - camera->AddComponent(); + ::XCEngine::Components::GameObject* camera = CreateEntity("Main Camera", nullptr); + camera->AddComponent<::XCEngine::Components::TransformComponent>(); - XCEngine::Components::GameObject* light = CreateEntity("Directional Light", nullptr); + ::XCEngine::Components::GameObject* light = CreateEntity("Directional Light", nullptr); - XCEngine::Components::GameObject* cube = CreateEntity("Cube", nullptr); - cube->AddComponent(); + ::XCEngine::Components::GameObject* cube = CreateEntity("Cube", nullptr); + cube->AddComponent<::XCEngine::Components::TransformComponent>(); // MeshRendererComponent 需要添加到 Engine - XCEngine::Components::GameObject* sphere = CreateEntity("Sphere", nullptr); - sphere->AddComponent(); + ::XCEngine::Components::GameObject* sphere = CreateEntity("Sphere", nullptr); + sphere->AddComponent<::XCEngine::Components::TransformComponent>(); - XCEngine::Components::GameObject* player = CreateEntity("Player", nullptr); - XCEngine::Components::GameObject* weapon = CreateEntity("Weapon", player); + ::XCEngine::Components::GameObject* player = CreateEntity("Player", nullptr); + ::XCEngine::Components::GameObject* weapon = CreateEntity("Weapon", player); OnSceneChanged.Invoke(); } } +} diff --git a/editor/src/Managers/SceneManager.h b/editor/src/Managers/SceneManager.h index eea3360d..5194769c 100644 --- a/editor/src/Managers/SceneManager.h +++ b/editor/src/Managers/SceneManager.h @@ -9,7 +9,8 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { class EditorSceneManager { public: @@ -18,58 +19,59 @@ public: return instance; } - XCEngine::Components::GameObject* CreateEntity(const std::string& name, XCEngine::Components::GameObject* parent = nullptr); + ::XCEngine::Components::GameObject* CreateEntity(const std::string& name, ::XCEngine::Components::GameObject* parent = nullptr); - XCEngine::Components::GameObject* GetEntity(XCEngine::Components::GameObject::ID id) { + ::XCEngine::Components::GameObject* GetEntity(::XCEngine::Components::GameObject::ID id) { return m_scene ? m_scene->Find(std::to_string(id)) : nullptr; } - const XCEngine::Components::GameObject* GetEntity(XCEngine::Components::GameObject::ID id) const { + const ::XCEngine::Components::GameObject* GetEntity(::XCEngine::Components::GameObject::ID id) const { return m_scene ? m_scene->Find(std::to_string(id)) : nullptr; } - const std::vector& GetRootEntities() const { + const std::vector<::XCEngine::Components::GameObject*>& GetRootEntities() const { return m_rootEntities; } - void DeleteEntity(XCEngine::Components::GameObject::ID id); + void DeleteEntity(::XCEngine::Components::GameObject::ID id); - void RenameEntity(XCEngine::Components::GameObject::ID id, const std::string& newName) { + void RenameEntity(::XCEngine::Components::GameObject::ID id, const std::string& newName) { if (auto* entity = GetEntity(id)) { entity->SetName(newName); OnEntityChanged.Invoke(id); } } - void CopyEntity(XCEngine::Components::GameObject::ID id); - XCEngine::Components::GameObject::ID PasteEntity(XCEngine::Components::GameObject::ID parent = 0); - XCEngine::Components::GameObject::ID DuplicateEntity(XCEngine::Components::GameObject::ID id); - void MoveEntity(XCEngine::Components::GameObject::ID id, XCEngine::Components::GameObject::ID newParent); + void CopyEntity(::XCEngine::Components::GameObject::ID id); + ::XCEngine::Components::GameObject::ID PasteEntity(::XCEngine::Components::GameObject::ID parent = 0); + ::XCEngine::Components::GameObject::ID DuplicateEntity(::XCEngine::Components::GameObject::ID id); + void MoveEntity(::XCEngine::Components::GameObject::ID id, ::XCEngine::Components::GameObject::ID newParent); void CreateDemoScene(); bool HasClipboardData() const { return m_clipboard.has_value(); } - XCEngine::Core::Event OnEntityCreated; - XCEngine::Core::Event OnEntityDeleted; - XCEngine::Core::Event OnEntityChanged; - XCEngine::Core::Event<> OnSceneChanged; + ::XCEngine::Core::Event<::XCEngine::Components::GameObject::ID> OnEntityCreated; + ::XCEngine::Core::Event<::XCEngine::Components::GameObject::ID> OnEntityDeleted; + ::XCEngine::Core::Event<::XCEngine::Components::GameObject::ID> OnEntityChanged; + ::XCEngine::Core::Event<> OnSceneChanged; private: EditorSceneManager() = default; struct ClipboardData { std::string name; - std::vector> components; + std::vector> components; std::vector children; }; - ClipboardData CopyEntityRecursive(const XCEngine::Components::GameObject* entity); - XCEngine::Components::GameObject::ID PasteEntityRecursive(const ClipboardData& data, XCEngine::Components::GameObject::ID parent); + ClipboardData CopyEntityRecursive(const ::XCEngine::Components::GameObject* entity); + ::XCEngine::Components::GameObject::ID PasteEntityRecursive(const ClipboardData& data, ::XCEngine::Components::GameObject::ID parent); - XCEngine::Components::Scene* m_scene = nullptr; - std::vector m_rootEntities; + ::XCEngine::Components::Scene* m_scene = nullptr; + std::vector<::XCEngine::Components::GameObject*> m_rootEntities; std::optional m_clipboard; }; } +} diff --git a/editor/src/Managers/SelectionManager.h b/editor/src/Managers/SelectionManager.h index 1c81549a..376f4236 100644 --- a/editor/src/Managers/SelectionManager.h +++ b/editor/src/Managers/SelectionManager.h @@ -5,7 +5,8 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { class SelectionManager { public: @@ -14,9 +15,9 @@ public: return instance; } - XCEngine::Components::GameObject* GetSelectedEntity() const { return m_selectedEntity; } + ::XCEngine::Components::GameObject* GetSelectedEntity() const { return m_selectedEntity; } - void SetSelectedEntity(XCEngine::Components::GameObject* entity) { + void SetSelectedEntity(::XCEngine::Components::GameObject* entity) { m_selectedEntity = entity; OnSelectionChanged.Invoke(entity ? entity->GetID() : 0); } @@ -25,15 +26,16 @@ public: SetSelectedEntity(nullptr); } - bool IsSelected(XCEngine::Components::GameObject* entity) const { + bool IsSelected(::XCEngine::Components::GameObject* entity) const { return m_selectedEntity == entity; } - XCEngine::Core::Event OnSelectionChanged; + ::XCEngine::Core::Event OnSelectionChanged; private: SelectionManager() = default; - XCEngine::Components::GameObject* m_selectedEntity = nullptr; + ::XCEngine::Components::GameObject* m_selectedEntity = nullptr; }; } +} diff --git a/editor/src/Theme.cpp b/editor/src/Theme.cpp index 6c5d7d93..91537c28 100644 --- a/editor/src/Theme.cpp +++ b/editor/src/Theme.cpp @@ -1,7 +1,8 @@ #include "Theme.h" #include -namespace UI { +namespace XCEngine { +namespace Editor { void ApplyUnityDarkTheme() { ImGuiStyle& style = ImGui::GetStyle(); @@ -79,4 +80,5 @@ void ApplyUnityDarkTheme() { style.ItemInnerSpacing = ImVec2(6.0f, 4.0f); } +} } \ No newline at end of file diff --git a/editor/src/Theme.h b/editor/src/Theme.h index 6915ee9c..14690148 100644 --- a/editor/src/Theme.h +++ b/editor/src/Theme.h @@ -1,7 +1,9 @@ #pragma once -namespace UI { +namespace XCEngine { +inline namespace Editor { void ApplyUnityDarkTheme(); +} } \ No newline at end of file diff --git a/editor/src/UI/Core.h b/editor/src/UI/Core.h new file mode 100644 index 00000000..d049a161 --- /dev/null +++ b/editor/src/UI/Core.h @@ -0,0 +1,61 @@ +#pragma once + +#include + +namespace XCEngine { +namespace Editor { +namespace UI { + +inline void StyleVarPush(ImGuiStyleVar idx, float val) { + ImGui::PushStyleVar(idx, val); +} + +inline void StyleVarPush(ImGuiStyleVar idx, ImVec2 val) { + ImGui::PushStyleVar(idx, val); +} + +inline void StyleColorPush(ImGuiCol idx, ImU32 col) { + ImGui::PushStyleColor(idx, col); +} + +inline void StyleColorPush(ImGuiCol idx, ImVec4 col) { + ImGui::PushStyleColor(idx, col); +} + +inline void PopStyleVar(int count = 1) { + ImGui::PopStyleVar(count); +} + +inline void PopStyleColor(int count = 1) { + ImGui::PopStyleColor(count); +} + +inline bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0) { + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(12.0f, 10.0f)); + bool is_open = ImGui::BeginPopup(str_id, flags); + if (!is_open) { + ImGui::PopStyleVar(); + } + return is_open; +} + +inline void EndPopup() { + ImGui::EndPopup(); + ImGui::PopStyleVar(); +} + +inline void BeginDisabled(bool disabled = true) { + if (disabled) { + ImGui::BeginDisabled(); + } +} + +inline void EndDisabled(bool disabled = true) { + if (disabled) { + ImGui::EndDisabled(); + } +} + +} +} +} diff --git a/editor/src/UI/ScalarControls.h b/editor/src/UI/ScalarControls.h new file mode 100644 index 00000000..807bada0 --- /dev/null +++ b/editor/src/UI/ScalarControls.h @@ -0,0 +1,322 @@ +#pragma once + +#include + +namespace XCEngine { +namespace Editor { +namespace UI { + +inline bool DrawFloat( + const char* label, + float& value, + float columnWidth = 100.0f, + float dragSpeed = 0.1f, + float min = 0.0f, + float max = 0.0f, + const char* format = "%.2f" +) { + bool changed = false; + ImGui::PushID(label); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{0, 1}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 1}); + + if (ImGui::BeginTable("##FloatTable", 2, ImGuiTableFlags_NoSavedSettings)) { + ImGui::TableSetupColumn("##label", ImGuiTableColumnFlags_WidthFixed, columnWidth); + ImGui::TableSetupColumn("##control", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetFontSize() + 2.0f); + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text(label); + + ImGui::TableNextColumn(); + + if (max != min) { + if (ImGui::SliderFloat("##value", &value, min, max, format)) { + changed = true; + } + } else { + if (ImGui::DragFloat("##value", &value, dragSpeed, min, max, format)) { + changed = true; + } + } + + ImGui::EndTable(); + } + + ImGui::PopStyleVar(2); + ImGui::PopID(); + + return changed; +} + +inline bool DrawInt( + const char* label, + int& value, + float columnWidth = 100.0f, + int step = 1, + int min = 0, + int max = 0 +) { + bool changed = false; + ImGui::PushID(label); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{0, 1}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 1}); + + if (ImGui::BeginTable("##IntTable", 2, ImGuiTableFlags_NoSavedSettings)) { + ImGui::TableSetupColumn("##label", ImGuiTableColumnFlags_WidthFixed, columnWidth); + ImGui::TableSetupColumn("##control", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetFontSize() + 2.0f); + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text(label); + + ImGui::TableNextColumn(); + + if (ImGui::DragInt("##value", &value, static_cast(step), min, max)) { + changed = true; + } + + ImGui::EndTable(); + } + + ImGui::PopStyleVar(2); + ImGui::PopID(); + + return changed; +} + +inline bool DrawBool( + const char* label, + bool& value, + float columnWidth = 100.0f +) { + bool changed = false; + ImGui::PushID(label); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{0, 1}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 1}); + + if (ImGui::BeginTable("##BoolTable", 2, ImGuiTableFlags_NoSavedSettings)) { + ImGui::TableSetupColumn("##label", ImGuiTableColumnFlags_WidthFixed, columnWidth); + ImGui::TableSetupColumn("##control", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetFontSize() + 2.0f); + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text(label); + + ImGui::TableNextColumn(); + + if (ImGui::Checkbox("##value", &value)) { + changed = true; + } + + ImGui::EndTable(); + } + + ImGui::PopStyleVar(2); + ImGui::PopID(); + + return changed; +} + +inline bool DrawColor3( + const char* label, + float color[3], + float columnWidth = 100.0f +) { + bool changed = false; + ImGui::PushID(label); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{0, 1}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 1}); + + if (ImGui::BeginTable("##Color3Table", 2, ImGuiTableFlags_NoSavedSettings)) { + ImGui::TableSetupColumn("##label", ImGuiTableColumnFlags_WidthFixed, columnWidth); + ImGui::TableSetupColumn("##control", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetFontSize() + 2.0f); + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text(label); + + ImGui::TableNextColumn(); + + if (ImGui::ColorEdit3("##value", color, ImGuiColorEditFlags_NoInputs)) { + changed = true; + } + + ImGui::EndTable(); + } + + ImGui::PopStyleVar(2); + ImGui::PopID(); + + return changed; +} + +inline bool DrawColor4( + const char* label, + float color[4], + float columnWidth = 100.0f +) { + bool changed = false; + ImGui::PushID(label); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{0, 1}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 1}); + + if (ImGui::BeginTable("##Color4Table", 2, ImGuiTableFlags_NoSavedSettings)) { + ImGui::TableSetupColumn("##label", ImGuiTableColumnFlags_WidthFixed, columnWidth); + ImGui::TableSetupColumn("##control", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetFontSize() + 2.0f); + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text(label); + + ImGui::TableNextColumn(); + + if (ImGui::ColorEdit4("##value", color, ImGuiColorEditFlags_NoInputs)) { + changed = true; + } + + ImGui::EndTable(); + } + + ImGui::PopStyleVar(2); + ImGui::PopID(); + + return changed; +} + +inline bool DrawSliderFloat( + const char* label, + float& value, + float min, + float max, + float columnWidth = 100.0f, + const char* format = "%.2f" +) { + bool changed = false; + ImGui::PushID(label); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{0, 1}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 1}); + + if (ImGui::BeginTable("##SliderTable", 2, ImGuiTableFlags_NoSavedSettings)) { + ImGui::TableSetupColumn("##label", ImGuiTableColumnFlags_WidthFixed, columnWidth); + ImGui::TableSetupColumn("##control", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetFontSize() + 2.0f); + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text(label); + + ImGui::TableNextColumn(); + + if (ImGui::SliderFloat("##value", &value, min, max, format)) { + changed = true; + } + + ImGui::EndTable(); + } + + ImGui::PopStyleVar(2); + ImGui::PopID(); + + return changed; +} + +inline bool DrawSliderInt( + const char* label, + int& value, + int min, + int max, + float columnWidth = 100.0f +) { + bool changed = false; + ImGui::PushID(label); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{0, 1}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 1}); + + if (ImGui::BeginTable("##SliderIntTable", 2, ImGuiTableFlags_NoSavedSettings)) { + ImGui::TableSetupColumn("##label", ImGuiTableColumnFlags_WidthFixed, columnWidth); + ImGui::TableSetupColumn("##control", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetFontSize() + 2.0f); + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text(label); + + ImGui::TableNextColumn(); + + if (ImGui::SliderInt("##value", &value, min, max)) { + changed = true; + } + + ImGui::EndTable(); + } + + ImGui::PopStyleVar(2); + ImGui::PopID(); + + return changed; +} + +inline int DrawCombo( + const char* label, + int currentItem, + const char* const items[], + int itemCount, + float columnWidth = 100.0f, + int heightInItems = -1 +) { + ImGui::PushID(label); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{0, 1}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 1}); + + int changedItem = currentItem; + + if (ImGui::BeginTable("##ComboTable", 2, ImGuiTableFlags_NoSavedSettings)) { + ImGui::TableSetupColumn("##label", ImGuiTableColumnFlags_WidthFixed, columnWidth); + ImGui::TableSetupColumn("##control", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetFontSize() + 2.0f); + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text(label); + + ImGui::TableNextColumn(); + + ImGui::SetNextItemWidth(-1); + if (ImGui::Combo("##value", ¤tItem, items, itemCount, heightInItems)) { + changedItem = currentItem; + } + + ImGui::EndTable(); + } + + ImGui::PopStyleVar(2); + ImGui::PopID(); + + return changedItem; +} + +} +} +} diff --git a/editor/src/UI/UI.h b/editor/src/UI/UI.h new file mode 100644 index 00000000..7732618b --- /dev/null +++ b/editor/src/UI/UI.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Core.h" +#include "VectorControls.h" +#include "ScalarControls.h" + +namespace XCEngine { +namespace Editor { +namespace UI { +} + +} +} diff --git a/editor/src/UI/VectorControls.h b/editor/src/UI/VectorControls.h new file mode 100644 index 00000000..8aa4e760 --- /dev/null +++ b/editor/src/UI/VectorControls.h @@ -0,0 +1,150 @@ +#pragma once + +#include +#include +#include + +namespace XCEngine { +namespace Editor { +namespace UI { + +inline bool DrawVec3( + const char* label, + ::XCEngine::Math::Vector3& values, + float resetValue = 0.0f, + float columnWidth = 100.0f, + float dragSpeed = 0.1f +) { + bool changed = false; + ImGui::PushID(label); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{0, 1}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 1}); + + if (ImGui::BeginTable("##Vec3Table", 2, ImGuiTableFlags_NoSavedSettings)) { + ImGui::TableSetupColumn("##label", ImGuiTableColumnFlags_WidthFixed, columnWidth); + ImGui::TableSetupColumn("##controls", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetFontSize() + 2.0f); + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text(label); + + ImGui::TableNextColumn(); + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2{0, 0}); + + float lineHeight = ImGui::GetFontSize() + ImGui::GetStyle().FramePadding.y * 2.0f; + ImVec2 buttonSize = {lineHeight + 3.0f, lineHeight}; + float itemWidth = (ImGui::GetContentRegionAvail().x - buttonSize.x * 3.0f) / 3.0f; + + auto drawAxisControl = [&](const char* axisLabel, float& value, ImVec4 color, ImVec4 colorHovered) { + bool axisChanged = false; + + ImGui::PushStyleColor(ImGuiCol_Button, color); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, colorHovered); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, color); + + if (ImGui::Button(axisLabel, buttonSize)) { + value = resetValue; + axisChanged = true; + } + ImGui::PopStyleColor(3); + + ImGui::SameLine(); + ImGui::SetNextItemWidth(itemWidth); + + if (ImGui::DragFloat((std::string("##") + axisLabel).c_str(), &value, dragSpeed, 0.0f, 0.0f, "%.2f")) { + axisChanged = true; + } + ImGui::SameLine(); + + return axisChanged; + }; + + changed |= drawAxisControl("X", values.x, ImVec4{0.8f, 0.1f, 0.15f, 1.0f}, ImVec4{0.9f, 0.2f, 0.2f, 1.0f}); + changed |= drawAxisControl("Y", values.y, ImVec4{0.2f, 0.7f, 0.2f, 1.0f}, ImVec4{0.3f, 0.8f, 0.3f, 1.0f}); + changed |= drawAxisControl("Z", values.z, ImVec4{0.1f, 0.25f, 0.8f, 1.0f}, ImVec4{0.2f, 0.35f, 0.9f, 1.0f}); + + ImGui::PopStyleVar(); + ImGui::EndTable(); + } + + ImGui::PopStyleVar(2); + ImGui::PopID(); + + return changed; +} + +inline bool DrawVec2( + const char* label, + ::XCEngine::Math::Vector2& values, + float resetValue = 0.0f, + float columnWidth = 100.0f, + float dragSpeed = 0.1f +) { + bool changed = false; + ImGui::PushID(label); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{0, 1}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 1}); + + if (ImGui::BeginTable("##Vec2Table", 2, ImGuiTableFlags_NoSavedSettings)) { + ImGui::TableSetupColumn("##label", ImGuiTableColumnFlags_WidthFixed, columnWidth); + ImGui::TableSetupColumn("##controls", ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, ImGui::GetFontSize() + 2.0f); + + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text(label); + + ImGui::TableNextColumn(); + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2{0, 0}); + + float lineHeight = ImGui::GetFontSize() + ImGui::GetStyle().FramePadding.y * 2.0f; + ImVec2 buttonSize = {lineHeight + 3.0f, lineHeight}; + float itemWidth = (ImGui::GetContentRegionAvail().x - buttonSize.x * 2.0f) / 2.0f; + + auto drawAxisControl = [&](const char* axisLabel, float& value, ImVec4 color, ImVec4 colorHovered) { + bool axisChanged = false; + + ImGui::PushStyleColor(ImGuiCol_Button, color); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, colorHovered); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, color); + + if (ImGui::Button(axisLabel, buttonSize)) { + value = resetValue; + axisChanged = true; + } + ImGui::PopStyleColor(3); + + ImGui::SameLine(); + ImGui::SetNextItemWidth(itemWidth); + + if (ImGui::DragFloat((std::string("##") + axisLabel).c_str(), &value, dragSpeed, 0.0f, 0.0f, "%.2f")) { + axisChanged = true; + } + ImGui::SameLine(); + + return axisChanged; + }; + + changed |= drawAxisControl("X", values.x, ImVec4{0.8f, 0.1f, 0.15f, 1.0f}, ImVec4{0.9f, 0.2f, 0.2f, 1.0f}); + changed |= drawAxisControl("Y", values.y, ImVec4{0.2f, 0.7f, 0.2f, 1.0f}, ImVec4{0.3f, 0.8f, 0.3f, 1.0f}); + + ImGui::PopStyleVar(); + ImGui::EndTable(); + } + + ImGui::PopStyleVar(2); + ImGui::PopID(); + + return changed; +} + +} +} +} diff --git a/editor/src/main.cpp b/editor/src/main.cpp index 253643a2..582e7036 100644 --- a/editor/src/main.cpp +++ b/editor/src/main.cpp @@ -40,7 +40,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int nCmdShow) { printf("Window shown.\n"); printf("Initializing application...\n"); - if (!UI::Application::Get().Initialize(hwnd)) { + if (!XCEngine::Editor::Application::Get().Initialize(hwnd)) { printf("Failed to initialize application!\n"); UnregisterClassW(wc.lpszClassName, wc.hInstance); system("pause"); @@ -55,7 +55,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int nCmdShow) { TranslateMessage(&msg); DispatchMessageW(&msg); } else { - UI::Application::Get().Render(); + XCEngine::Editor::Application::Get().Render(); frameCount++; if (frameCount % 100 == 0) { printf("Frame %d\n", frameCount); @@ -64,7 +64,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int nCmdShow) { } printf("Shutting down...\n"); - UI::Application::Get().Shutdown(); + XCEngine::Editor::Application::Get().Shutdown(); UnregisterClassW(wc.lpszClassName, wc.hInstance); printf("Press any key to exit...\n"); @@ -81,7 +81,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_SIZE: if (wParam != SIZE_MINIMIZED) { - UI::Application::Get().OnResize((int)LOWORD(lParam), (int)HIWORD(lParam)); + XCEngine::Editor::Application::Get().OnResize((int)LOWORD(lParam), (int)HIWORD(lParam)); } return 0; case WM_SYSCOMMAND: diff --git a/editor/src/panels/ConsolePanel.cpp b/editor/src/panels/ConsolePanel.cpp index 124a46f9..a82478c3 100644 --- a/editor/src/panels/ConsolePanel.cpp +++ b/editor/src/panels/ConsolePanel.cpp @@ -3,14 +3,15 @@ #include "Core/LogEntry.h" #include -namespace UI { +namespace XCEngine { +namespace Editor { ConsolePanel::ConsolePanel() : Panel("Console") { - LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Info, "Engine initialized successfully"); - LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Info, "Loading default scene..."); - LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Warning, "Missing material on object 'Cube'"); - LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Error, "Failed to load texture: 'Assets/Textures/missing.png'"); - LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Info, "Scene loaded successfully"); + LogSystem::Get().AddLog(::XCEngine::Debug::LogLevel::Info, "Engine initialized successfully"); + LogSystem::Get().AddLog(::XCEngine::Debug::LogLevel::Info, "Loading default scene..."); + LogSystem::Get().AddLog(::XCEngine::Debug::LogLevel::Warning, "Missing material on object 'Cube'"); + LogSystem::Get().AddLog(::XCEngine::Debug::LogLevel::Error, "Failed to load texture: 'Assets/Textures/missing.png'"); + LogSystem::Get().AddLog(::XCEngine::Debug::LogLevel::Info, "Scene loaded successfully"); } void ConsolePanel::Render() { @@ -21,15 +22,15 @@ void ConsolePanel::Render() { } ImGui::SameLine(); if (ImGui::Button("Info")) { - LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Info, "Test info message"); + LogSystem::Get().AddLog(::XCEngine::Debug::LogLevel::Info, "Test info message"); } ImGui::SameLine(); if (ImGui::Button("Warn")) { - LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Warning, "Test warning message"); + LogSystem::Get().AddLog(::XCEngine::Debug::LogLevel::Warning, "Test warning message"); } ImGui::SameLine(); if (ImGui::Button("Error")) { - LogSystem::Get().AddLog(XCEngine::Debug::LogLevel::Error, "Test error message"); + LogSystem::Get().AddLog(::XCEngine::Debug::LogLevel::Error, "Test error message"); } ImGui::Separator(); @@ -41,15 +42,15 @@ void ConsolePanel::Render() { const char* prefix; switch (log.level) { - case XCEngine::Debug::LogLevel::Info: + case ::XCEngine::Debug::LogLevel::Info: color = ImVec4(0.7f, 0.7f, 0.7f, 1.0f); prefix = "[Info] "; break; - case XCEngine::Debug::LogLevel::Warning: + case ::XCEngine::Debug::LogLevel::Warning: color = ImVec4(1.0f, 0.8f, 0.0f, 1.0f); prefix = "[Warn] "; break; - case XCEngine::Debug::LogLevel::Error: + case ::XCEngine::Debug::LogLevel::Error: color = ImVec4(1.0f, 0.3f, 0.3f, 1.0f); prefix = "[Error]"; break; @@ -67,4 +68,5 @@ void ConsolePanel::Render() { ImGui::End(); } +} } \ No newline at end of file diff --git a/editor/src/panels/ConsolePanel.h b/editor/src/panels/ConsolePanel.h index 4d73ef58..1db4c571 100644 --- a/editor/src/panels/ConsolePanel.h +++ b/editor/src/panels/ConsolePanel.h @@ -2,7 +2,8 @@ #include "Panel.h" -namespace UI { +namespace XCEngine { +namespace Editor { class ConsolePanel : public Panel { public: @@ -13,4 +14,5 @@ private: bool m_scrollToBottom = false; }; +} } \ No newline at end of file diff --git a/editor/src/panels/GameViewPanel.cpp b/editor/src/panels/GameViewPanel.cpp index d4389e1e..2dc73f30 100644 --- a/editor/src/panels/GameViewPanel.cpp +++ b/editor/src/panels/GameViewPanel.cpp @@ -2,7 +2,8 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { GameViewPanel::GameViewPanel() : Panel("Game") {} @@ -29,3 +30,4 @@ void GameViewPanel::RenderGameView() { } } +} diff --git a/editor/src/panels/GameViewPanel.h b/editor/src/panels/GameViewPanel.h index f0797cdf..c30e6079 100644 --- a/editor/src/panels/GameViewPanel.h +++ b/editor/src/panels/GameViewPanel.h @@ -2,7 +2,8 @@ #include "Panel.h" -namespace UI { +namespace XCEngine { +namespace Editor { class GameViewPanel : public Panel { public: @@ -14,3 +15,4 @@ private: }; } +} diff --git a/editor/src/panels/HierarchyPanel.cpp b/editor/src/panels/HierarchyPanel.cpp index 9dc76ac6..0ef21551 100644 --- a/editor/src/panels/HierarchyPanel.cpp +++ b/editor/src/panels/HierarchyPanel.cpp @@ -4,10 +4,11 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { HierarchyPanel::HierarchyPanel() : Panel("Hierarchy") { - SceneManager::Get().CreateDemoScene(); + EditorSceneManager::Get().CreateDemoScene(); m_selectionHandlerId = SelectionManager::Get().OnSelectionChanged.Subscribe([this](uint64_t) { }); @@ -30,7 +31,7 @@ void HierarchyPanel::Render() { ImGui::BeginChild("EntityList"); - for (auto* entity : SceneManager::Get().GetRootEntities()) { + for (auto* entity : EditorSceneManager::Get().GetRootEntities()) { RenderEntity(entity, filter); } @@ -48,9 +49,9 @@ void HierarchyPanel::Render() { ImGui::InvisibleButton("##DragTarget", ImVec2(-1, -1)); if (ImGui::BeginDragDropTarget()) { if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITY_PTR")) { - XCEngine::Components::GameObject* sourceEntity = *(XCEngine::Components::GameObject**)payload->Data; + ::XCEngine::Components::GameObject* sourceEntity = *(::XCEngine::Components::GameObject**)payload->Data; if (sourceEntity && sourceEntity->GetParent() != nullptr) { - SceneManager::Get().MoveEntity(sourceEntity->GetID(), 0); + EditorSceneManager::Get().MoveEntity(sourceEntity->GetID(), 0); } } ImGui::EndDragDropTarget(); @@ -66,7 +67,7 @@ void HierarchyPanel::RenderSearchBar() { ImGui::InputTextWithHint("##Search", "Search...", m_searchBuffer, sizeof(m_searchBuffer)); } -void HierarchyPanel::RenderEntity(XCEngine::Components::GameObject* entity, const std::string& filter) { +void HierarchyPanel::RenderEntity(::XCEngine::Components::GameObject* entity, const std::string& filter) { if (!entity) return; if (!filter.empty() && !PassesFilter(entity, filter)) { @@ -94,7 +95,7 @@ void HierarchyPanel::RenderEntity(XCEngine::Components::GameObject* entity, cons ImGui::SetNextItemWidth(-1); if (ImGui::InputText("##Rename", m_renameBuffer, sizeof(m_renameBuffer), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)) { if (strlen(m_renameBuffer) > 0) { - SceneManager::Get().RenameEntity(entity->GetID(), m_renameBuffer); + EditorSceneManager::Get().RenameEntity(entity->GetID(), m_renameBuffer); } m_renaming = false; m_renamingEntity = nullptr; @@ -102,7 +103,7 @@ void HierarchyPanel::RenderEntity(XCEngine::Components::GameObject* entity, cons if (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0)) { if (strlen(m_renameBuffer) > 0) { - SceneManager::Get().RenameEntity(entity->GetID(), m_renameBuffer); + EditorSceneManager::Get().RenameEntity(entity->GetID(), m_renameBuffer); } m_renaming = false; m_renamingEntity = nullptr; @@ -139,8 +140,8 @@ void HierarchyPanel::RenderEntity(XCEngine::Components::GameObject* entity, cons ImGui::PopID(); } -void HierarchyPanel::RenderContextMenu(XCEngine::Components::GameObject* entity) { - auto& sceneManager = SceneManager::Get(); +void HierarchyPanel::RenderContextMenu(::XCEngine::Components::GameObject* entity) { + auto& sceneManager = EditorSceneManager::Get(); auto& selectionManager = SelectionManager::Get(); if (ImGui::BeginMenu("Create")) { @@ -181,8 +182,8 @@ void HierarchyPanel::RenderContextMenu(XCEngine::Components::GameObject* entity) } } -void HierarchyPanel::RenderCreateMenu(XCEngine::Components::GameObject* parent) { - auto& sceneManager = SceneManager::Get(); +void HierarchyPanel::RenderCreateMenu(::XCEngine::Components::GameObject* parent) { + auto& sceneManager = EditorSceneManager::Get(); auto& selectionManager = SelectionManager::Get(); if (ImGui::MenuItem("Empty Object")) { @@ -194,7 +195,7 @@ void HierarchyPanel::RenderCreateMenu(XCEngine::Components::GameObject* parent) if (ImGui::MenuItem("Camera")) { auto* newEntity = sceneManager.CreateEntity("Camera", parent); - newEntity->AddComponent(); + newEntity->AddComponent<::XCEngine::Components::TransformComponent>(); selectionManager.SetSelectedEntity(newEntity); } @@ -207,37 +208,39 @@ void HierarchyPanel::RenderCreateMenu(XCEngine::Components::GameObject* parent) if (ImGui::MenuItem("Cube")) { auto* newEntity = sceneManager.CreateEntity("Cube", parent); - newEntity->AddComponent(); + newEntity->AddComponent<::XCEngine::Components::TransformComponent>(); selectionManager.SetSelectedEntity(newEntity); } if (ImGui::MenuItem("Sphere")) { auto* newEntity = sceneManager.CreateEntity("Sphere", parent); - newEntity->AddComponent(); + newEntity->AddComponent<::XCEngine::Components::TransformComponent>(); selectionManager.SetSelectedEntity(newEntity); } if (ImGui::MenuItem("Plane")) { auto* newEntity = sceneManager.CreateEntity("Plane", parent); - newEntity->AddComponent(); + newEntity->AddComponent<::XCEngine::Components::TransformComponent>(); selectionManager.SetSelectedEntity(newEntity); } } -void HierarchyPanel::HandleDragDrop(XCEngine::Components::GameObject* entity) { +void HierarchyPanel::HandleDragDrop(::XCEngine::Components::GameObject* entity) { + auto& sceneManager = EditorSceneManager::Get(); + if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) { m_dragSource = entity; - ImGui::SetDragDropPayload("ENTITY_PTR", &entity, sizeof(XCEngine::Components::GameObject*)); + ImGui::SetDragDropPayload("ENTITY_PTR", &entity, sizeof(::XCEngine::Components::GameObject*)); ImGui::Text("%s", entity->GetName().c_str()); ImGui::EndDragDropSource(); } if (ImGui::BeginDragDropTarget()) { if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITY_PTR")) { - XCEngine::Components::GameObject* sourceEntity = *(XCEngine::Components::GameObject**)payload->Data; + ::XCEngine::Components::GameObject* sourceEntity = *(::XCEngine::Components::GameObject**)payload->Data; if (sourceEntity != entity && sourceEntity != nullptr) { bool isValidMove = true; - XCEngine::Components::GameObject* checkParent = entity; + ::XCEngine::Components::GameObject* checkParent = entity; while (checkParent != nullptr) { if (checkParent == sourceEntity) { isValidMove = false; @@ -256,10 +259,10 @@ void HierarchyPanel::HandleDragDrop(XCEngine::Components::GameObject* entity) { } void HierarchyPanel::HandleKeyboardShortcuts() { - auto& sceneManager = SceneManager::Get(); + auto& sceneManager = EditorSceneManager::Get(); auto& selectionManager = SelectionManager::Get(); - XCEngine::Components::GameObject* selectedEntity = selectionManager.GetSelectedEntity(); + ::XCEngine::Components::GameObject* selectedEntity = selectionManager.GetSelectedEntity(); if (ImGui::IsWindowFocused()) { if (ImGui::IsKeyPressed(ImGuiKey_Delete)) { @@ -300,7 +303,7 @@ void HierarchyPanel::HandleKeyboardShortcuts() { } } -bool HierarchyPanel::PassesFilter(XCEngine::Components::GameObject* entity, const std::string& filter) { +bool HierarchyPanel::PassesFilter(::XCEngine::Components::GameObject* entity, const std::string& filter) { if (!entity) return false; if (entity->GetName().find(filter) != std::string::npos) { @@ -317,3 +320,4 @@ bool HierarchyPanel::PassesFilter(XCEngine::Components::GameObject* entity, cons } } +} diff --git a/editor/src/panels/HierarchyPanel.h b/editor/src/panels/HierarchyPanel.h index e93745d0..a9a9099a 100644 --- a/editor/src/panels/HierarchyPanel.h +++ b/editor/src/panels/HierarchyPanel.h @@ -3,7 +3,8 @@ #include "Panel.h" #include -namespace UI { +namespace XCEngine { +namespace Editor { class HierarchyPanel : public Panel { public: @@ -14,21 +15,22 @@ public: private: void RenderSearchBar(); - void RenderEntity(XCEngine::Components::GameObject* entity, const std::string& filter); - void RenderContextMenu(XCEngine::Components::GameObject* entity); - void RenderCreateMenu(XCEngine::Components::GameObject* parent); - void HandleDragDrop(XCEngine::Components::GameObject* entity); + void RenderEntity(::XCEngine::Components::GameObject* entity, const std::string& filter); + void RenderContextMenu(::XCEngine::Components::GameObject* entity); + void RenderCreateMenu(::XCEngine::Components::GameObject* parent); + void HandleDragDrop(::XCEngine::Components::GameObject* entity); void HandleKeyboardShortcuts(); - bool PassesFilter(XCEngine::Components::GameObject* entity, const std::string& filter); + bool PassesFilter(::XCEngine::Components::GameObject* entity, const std::string& filter); uint64_t m_selectionHandlerId = 0; char m_searchBuffer[256] = ""; bool m_renaming = false; - XCEngine::Components::GameObject* m_renamingEntity = nullptr; + ::XCEngine::Components::GameObject* m_renamingEntity = nullptr; char m_renameBuffer[256] = ""; bool m_renameJustStarted = false; - XCEngine::Components::GameObject* m_dragSource = nullptr; + ::XCEngine::Components::GameObject* m_dragSource = nullptr; }; } +} diff --git a/editor/src/panels/InspectorPanel.cpp b/editor/src/panels/InspectorPanel.cpp index 042cf077..8d782c45 100644 --- a/editor/src/panels/InspectorPanel.cpp +++ b/editor/src/panels/InspectorPanel.cpp @@ -1,11 +1,12 @@ #include "InspectorPanel.h" #include "Managers/SceneManager.h" #include "Managers/SelectionManager.h" +#include "UI/UI.h" #include #include -#include -namespace UI { +namespace XCEngine { +namespace Editor { InspectorPanel::InspectorPanel() : Panel("Inspector") { m_selectionHandlerId = SelectionManager::Get().OnSelectionChanged.Subscribe([this](uint64_t) { @@ -19,7 +20,7 @@ InspectorPanel::~InspectorPanel() { void InspectorPanel::Render() { ImGui::Begin(m_name.c_str(), nullptr, ImGuiWindowFlags_None); - XCEngine::Components::GameObject* entity = SelectionManager::Get().GetSelectedEntity(); + ::XCEngine::Components::GameObject* entity = SelectionManager::Get().GetSelectedEntity(); if (entity) { RenderEntity(entity); @@ -31,17 +32,18 @@ void InspectorPanel::Render() { ImGui::End(); } -void InspectorPanel::RenderEntity(XCEngine::Components::GameObject* entity) { +void InspectorPanel::RenderEntity(::XCEngine::Components::GameObject* entity) { ImGui::Text("%s", entity->GetName().c_str()); ImGui::Separator(); - for (auto& component : entity->m_components) { - RenderComponent(component.get()); + auto components = entity->GetComponents<::XCEngine::Components::Component>(); + for (auto* component : components) { + RenderComponent(component); ImGui::Separator(); } } -void InspectorPanel::RenderComponent(XCEngine::Components::Component* component) { +void InspectorPanel::RenderComponent(::XCEngine::Components::Component* component) { if (!component) return; const char* name = component->GetName().c_str(); @@ -51,20 +53,20 @@ void InspectorPanel::RenderComponent(XCEngine::Components::Component* component) if (ImGui::CollapsingHeader(headerId.c_str(), ImGuiTreeNodeFlags_DefaultOpen)) { ImGui::Indent(10.0f); - if (auto* transform = dynamic_cast(component)) { - glm::vec3 position = transform->GetLocalPosition(); - glm::vec3 rotation = transform->GetLocalEulerAngles(); - glm::vec3 scale = transform->GetLocalScale(); + if (auto* transform = dynamic_cast<::XCEngine::Components::TransformComponent*>(component)) { + ::XCEngine::Math::Vector3 position = transform->GetLocalPosition(); + ::XCEngine::Math::Vector3 rotation = transform->GetLocalEulerAngles(); + ::XCEngine::Math::Vector3 scale = transform->GetLocalScale(); - if (ImGui::DragFloat3("Position", &position.x, 0.1f)) { + if (UI::DrawVec3("Position", position, 0.0f, 80.0f, 0.1f)) { transform->SetLocalPosition(position); } - if (ImGui::DragFloat3("Rotation", &rotation.x, 1.0f)) { + if (UI::DrawVec3("Rotation", rotation, 0.0f, 80.0f, 1.0f)) { transform->SetLocalEulerAngles(rotation); } - if (ImGui::DragFloat3("Scale", &scale.x, 0.1f)) { + if (UI::DrawVec3("Scale", scale, 1.0f, 80.0f, 0.1f)) { transform->SetLocalScale(scale); } } @@ -74,3 +76,4 @@ void InspectorPanel::RenderComponent(XCEngine::Components::Component* component) } } +} diff --git a/editor/src/panels/InspectorPanel.h b/editor/src/panels/InspectorPanel.h index 38437b6f..6cbca1d0 100644 --- a/editor/src/panels/InspectorPanel.h +++ b/editor/src/panels/InspectorPanel.h @@ -4,7 +4,8 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { class InspectorPanel : public Panel { public: @@ -14,10 +15,11 @@ public: void Render() override; private: - void RenderEntity(XCEngine::Components::GameObject* entity); - void RenderComponent(XCEngine::Components::Component* component); + void RenderEntity(::XCEngine::Components::GameObject* entity); + void RenderComponent(::XCEngine::Components::Component* component); uint64_t m_selectionHandlerId = 0; }; } +} diff --git a/editor/src/panels/MenuBar.cpp b/editor/src/panels/MenuBar.cpp index 9376a06f..5b1bc60d 100644 --- a/editor/src/panels/MenuBar.cpp +++ b/editor/src/panels/MenuBar.cpp @@ -1,7 +1,8 @@ #include "MenuBar.h" #include -namespace UI { +namespace XCEngine { +namespace Editor { MenuBar::MenuBar() : Panel("MenuBar") {} @@ -52,4 +53,5 @@ void MenuBar::ShowHelpMenu() { } } +} } \ No newline at end of file diff --git a/editor/src/panels/MenuBar.h b/editor/src/panels/MenuBar.h index b4481422..60aea6de 100644 --- a/editor/src/panels/MenuBar.h +++ b/editor/src/panels/MenuBar.h @@ -2,7 +2,8 @@ #include "Panel.h" -namespace UI { +namespace XCEngine { +namespace Editor { class MenuBar : public Panel { public: @@ -16,4 +17,5 @@ private: void ShowHelpMenu(); }; +} } \ No newline at end of file diff --git a/editor/src/panels/Panel.cpp b/editor/src/panels/Panel.cpp index bd3d0c3b..95ec7a32 100644 --- a/editor/src/panels/Panel.cpp +++ b/editor/src/panels/Panel.cpp @@ -1,4 +1,6 @@ #include "Panel.h" -namespace UI { +namespace XCEngine { +namespace Editor { +} } \ No newline at end of file diff --git a/editor/src/panels/Panel.h b/editor/src/panels/Panel.h index 81c4b501..fdbb8c8f 100644 --- a/editor/src/panels/Panel.h +++ b/editor/src/panels/Panel.h @@ -3,7 +3,8 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { class Panel { public: @@ -22,4 +23,5 @@ protected: bool m_isOpen; }; +} } \ No newline at end of file diff --git a/editor/src/panels/ProjectPanel.cpp b/editor/src/panels/ProjectPanel.cpp index a3b2e6e9..e25679ab 100644 --- a/editor/src/panels/ProjectPanel.cpp +++ b/editor/src/panels/ProjectPanel.cpp @@ -4,7 +4,8 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { const char* DRAG_DROP_TYPE = "ASSET_ITEM"; @@ -294,4 +295,5 @@ bool ProjectPanel::HandleDrop(const AssetItemPtr& targetFolder) { return false; } +} } \ No newline at end of file diff --git a/editor/src/panels/ProjectPanel.h b/editor/src/panels/ProjectPanel.h index 5aea84d7..a5123b20 100644 --- a/editor/src/panels/ProjectPanel.h +++ b/editor/src/panels/ProjectPanel.h @@ -3,7 +3,8 @@ #include "Panel.h" #include "Core/AssetItem.h" -namespace UI { +namespace XCEngine { +namespace Editor { class ProjectPanel : public Panel { public: @@ -23,4 +24,5 @@ private: std::string m_draggingPath; }; +} } \ No newline at end of file diff --git a/editor/src/panels/SceneViewPanel.cpp b/editor/src/panels/SceneViewPanel.cpp index 6fc8d98d..a1e13ff2 100644 --- a/editor/src/panels/SceneViewPanel.cpp +++ b/editor/src/panels/SceneViewPanel.cpp @@ -2,7 +2,8 @@ #include #include -namespace UI { +namespace XCEngine { +namespace Editor { SceneViewPanel::SceneViewPanel() : Panel("Scene") {} @@ -51,4 +52,5 @@ void SceneViewPanel::RenderGrid() { drawList->AddText(labelPos, IM_COL32(100, 100, 100, 255), label); } +} } \ No newline at end of file diff --git a/editor/src/panels/SceneViewPanel.h b/editor/src/panels/SceneViewPanel.h index d81c47ec..ab09cf06 100644 --- a/editor/src/panels/SceneViewPanel.h +++ b/editor/src/panels/SceneViewPanel.h @@ -2,7 +2,8 @@ #include "Panel.h" -namespace UI { +namespace XCEngine { +namespace Editor { class SceneViewPanel : public Panel { public: @@ -13,4 +14,5 @@ private: void RenderGrid(); }; +} } \ No newline at end of file