Files
XCEngine/editor/src/panels/ProjectPanel.cpp

131 lines
4.1 KiB
C++
Raw Normal View History

2026-03-26 22:10:43 +08:00
#include "Actions/ActionRouting.h"
2026-03-26 23:52:05 +08:00
#include "Actions/ProjectActionRouter.h"
2026-03-26 21:18:33 +08:00
#include "Commands/ProjectCommands.h"
#include "ProjectPanel.h"
#include "Core/IEditorContext.h"
#include "Core/IProjectManager.h"
#include "Core/AssetItem.h"
2026-03-26 21:18:33 +08:00
#include "UI/UI.h"
#include <imgui.h>
namespace XCEngine {
namespace Editor {
ProjectPanel::ProjectPanel() : Panel("Project") {
}
void ProjectPanel::Initialize(const std::string& projectPath) {
m_context->GetProjectManager().Initialize(projectPath);
}
void ProjectPanel::Render() {
UI::PanelWindowScope panel(m_name.c_str());
if (!panel.IsOpen()) {
return;
}
2026-03-26 22:10:43 +08:00
Actions::ObserveFocusedActionRoute(*m_context, EditorActionRoute::Project);
auto& manager = m_context->GetProjectManager();
2026-03-26 21:18:33 +08:00
UI::PanelToolbarScope toolbar("ProjectToolbar", UI::ProjectPanelToolbarHeight());
if (toolbar.IsOpen()) {
Actions::DrawProjectNavigateBackAction(manager);
ImGui::SameLine();
size_t pathDepth = manager.GetPathDepth();
2026-03-26 21:18:33 +08:00
UI::DrawToolbarBreadcrumbs(
"Assets",
pathDepth,
[&](size_t index) { return manager.GetPathName(index); },
[&](size_t index) { manager.NavigateToIndex(index); });
2026-03-26 21:18:33 +08:00
UI::DrawToolbarRowGap();
UI::ToolbarSearchField("##Search", "Search assets", m_searchBuffer, sizeof(m_searchBuffer));
}
UI::PanelContentScope content(
"ProjectContent",
UI::AssetPanelContentPadding(),
ImGuiWindowFlags_None,
true,
2026-03-26 21:18:33 +08:00
UI::AssetGridSpacing());
if (!content.IsOpen()) {
return;
}
2026-03-26 21:18:33 +08:00
const float tileWidth = UI::AssetTileSize().x;
const float spacing = UI::AssetGridSpacing().x;
const float panelWidth = ImGui::GetContentRegionAvail().x;
int columns = static_cast<int>((panelWidth + spacing) / (tileWidth + spacing));
if (columns < 1) columns = 1;
auto& items = manager.GetCurrentItems();
std::string searchStr = m_searchBuffer;
int displayedCount = 0;
for (int i = 0; i < (int)items.size(); i++) {
if (!searchStr.empty()) {
if (items[i]->name.find(searchStr) == std::string::npos) {
continue;
}
}
if (displayedCount > 0 && displayedCount % columns != 0) {
ImGui::SameLine();
}
RenderAssetItem(items[i], i);
displayedCount++;
}
2026-03-26 21:18:33 +08:00
if (displayedCount == 0) {
UI::DrawEmptyState(
searchStr.empty() ? "No Assets" : "No Search Results",
searchStr.empty() ? "Current folder is empty" : "No assets match the current search");
}
Actions::HandleProjectBackgroundPrimaryClick(manager);
Actions::DrawProjectItemContextPopup(*m_context, m_itemContextMenu);
Actions::RequestProjectEmptyContextPopup(m_emptyContextMenu);
Actions::DrawProjectEmptyContextPopup(m_emptyContextMenu, m_createFolderDialog);
2026-03-26 23:52:05 +08:00
Actions::DrawProjectCreateFolderDialog(*m_context, m_createFolderDialog);
}
void ProjectPanel::RenderAssetItem(const AssetItemPtr& item, int index) {
auto& manager = m_context->GetProjectManager();
bool isSelected = (manager.GetSelectedIndex() == index);
ImGui::PushID(index);
const bool isDraggingThisItem = Actions::IsProjectAssetBeingDragged(item);
2026-03-26 21:18:33 +08:00
const UI::AssetIconKind iconKind = item->isFolder ? UI::AssetIconKind::Folder : UI::AssetIconKind::File;
const UI::AssetTileResult tile = UI::DrawAssetTile(
item->name.c_str(),
isSelected,
isDraggingThisItem,
[&](ImDrawList* drawList, const ImVec2& iconMin, const ImVec2& iconMax) {
UI::DrawAssetIcon(drawList, iconMin, iconMax, iconKind);
});
if (tile.clicked) {
Actions::HandleProjectItemSelection(manager, index);
}
2026-03-26 21:18:33 +08:00
if (tile.contextRequested) {
Actions::HandleProjectItemContextRequest(manager, index, item, m_itemContextMenu);
}
Actions::AcceptProjectAssetDrop(manager, item);
Actions::BeginProjectAssetDrag(item, iconKind);
2026-03-26 21:18:33 +08:00
if (tile.openRequested) {
Actions::OpenProjectAsset(*m_context, item);
}
ImGui::PopID();
}
}
}