Refactor editor dock and panel chrome styling

This commit is contained in:
2026-03-26 16:43:06 +08:00
parent e174862b8a
commit 45842e961e
13 changed files with 623 additions and 328 deletions

View File

@@ -5,6 +5,8 @@
#include "Core/IUndoManager.h"
#include "Core/EditorEvents.h"
#include "Core/EventBus.h"
#include "UI/Core.h"
#include "UI/PanelChrome.h"
#include "Utils/UndoUtils.h"
#include <XCEngine/Core/Math/Vector3.h>
#include <XCEngine/Core/Math/Quaternion.h>
@@ -16,6 +18,12 @@
namespace XCEngine {
namespace Editor {
namespace {
constexpr float kHierarchyToolbarHeight = 34.0f;
} // namespace
HierarchyPanel::HierarchyPanel() : Panel("Hierarchy") {
}
@@ -38,18 +46,22 @@ void HierarchyPanel::OnSelectionChanged(const SelectionChangedEvent& event) {
}
void HierarchyPanel::Render() {
ImGui::Begin(m_name.c_str(), nullptr, ImGuiWindowFlags_None);
UI::PanelWindowScope panel(m_name.c_str());
if (!panel.IsOpen()) {
return;
}
RenderSearchBar();
ImGui::Separator();
HandleKeyboardShortcuts();
std::string filter = m_searchBuffer;
ImGui::BeginChild("EntityList");
UI::PanelContentScope content("EntityList");
if (!content.IsOpen()) {
return;
}
auto& sceneManager = m_context->GetSceneManager();
auto rootEntities = sceneManager.GetRootEntities();
SortEntities(const_cast<std::vector<::XCEngine::Components::GameObject*>&>(rootEntities));
@@ -93,21 +105,39 @@ void HierarchyPanel::Render() {
ImGui::EndDragDropTarget();
}
ImGui::EndChild();
ImGui::End();
}
void HierarchyPanel::RenderSearchBar() {
ImGui::SetNextItemWidth(120);
const char* sortLabels[] = { "Name", "Components", "Transform First" };
int currentSort = static_cast<int>(m_sortMode);
if (ImGui::Combo("##Sort", &currentSort, sortLabels, 3)) {
m_sortMode = static_cast<SortMode>(currentSort);
UI::PanelToolbarScope toolbar("HierarchyToolbar", kHierarchyToolbarHeight);
if (!toolbar.IsOpen()) {
return;
}
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(7.0f, 4.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0f);
const float buttonWidth = 26.0f;
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - buttonWidth - 4.0f);
ImGui::InputTextWithHint("##Search", "Search hierarchy", m_searchBuffer, sizeof(m_searchBuffer));
ImGui::SameLine();
ImGui::SetNextItemWidth(-1);
ImGui::InputTextWithHint("##Search", "Search...", m_searchBuffer, sizeof(m_searchBuffer));
if (UI::ToolbarButton("...", false, ImVec2(buttonWidth, 0.0f))) {
ImGui::OpenPopup("HierarchyOptions");
}
if (ImGui::BeginPopup("HierarchyOptions")) {
if (ImGui::MenuItem("Sort By Name", nullptr, m_sortMode == SortMode::Name)) {
m_sortMode = SortMode::Name;
}
if (ImGui::MenuItem("Sort By Component Count", nullptr, m_sortMode == SortMode::ComponentCount)) {
m_sortMode = SortMode::ComponentCount;
}
if (ImGui::MenuItem("Transform First", nullptr, m_sortMode == SortMode::TransformFirst)) {
m_sortMode = SortMode::TransformFirst;
}
ImGui::EndPopup();
}
ImGui::PopStyleVar(2);
}
void HierarchyPanel::RenderEntity(::XCEngine::Components::GameObject* gameObject, const std::string& filter) {
@@ -119,7 +149,10 @@ void HierarchyPanel::RenderEntity(::XCEngine::Components::GameObject* gameObject
ImGui::PushID(static_cast<int>(gameObject->GetID()));
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth;
ImGuiTreeNodeFlags flags =
ImGuiTreeNodeFlags_OpenOnArrow |
ImGuiTreeNodeFlags_SpanAvailWidth |
ImGuiTreeNodeFlags_FramePadding;
if (gameObject->GetChildCount() == 0) {
flags |= ImGuiTreeNodeFlags_Leaf;
@@ -156,7 +189,9 @@ void HierarchyPanel::RenderEntity(::XCEngine::Components::GameObject* gameObject
m_renamingEntity = nullptr;
}
} else {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0f, 3.0f));
bool isOpen = ImGui::TreeNodeEx((void*)gameObject->GetUUID(), flags, "%s", gameObject->GetName().c_str());
ImGui::PopStyleVar();
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) {
ImGuiIO& io = ImGui::GetIO();