- 修复 InspectorPanel InputText 使用 data()/capacity() 的错误 - 修复未使用变量警告 - 修复 ProjectManager 路径重复拼接 bug (Assets/Assets) - 返回按钮在 Assets 目录时禁用但保持显示 - 删除 ProjectPanel 创建按钮,调整 Refresh 位置 - 修复 ProjectPanel 搜索过滤时的 ID 冲突 - 修复 InspectorPanel CollapsingHeader ID 冲突
209 lines
6.2 KiB
C++
209 lines
6.2 KiB
C++
#include "ProjectPanel.h"
|
|
#include "Managers/ProjectManager.h"
|
|
#include "Core/AssetItem.h"
|
|
#include <imgui.h>
|
|
#include <imgui_internal.h>
|
|
|
|
namespace UI {
|
|
|
|
ProjectPanel::ProjectPanel() : Panel("Project") {
|
|
}
|
|
|
|
void ProjectPanel::Initialize(const std::string& projectPath) {
|
|
ProjectManager::Get().Initialize(projectPath);
|
|
}
|
|
|
|
void ProjectPanel::Render() {
|
|
ImGui::Begin(m_name.c_str(), &m_isOpen, ImGuiWindowFlags_None);
|
|
|
|
auto& manager = ProjectManager::Get();
|
|
|
|
bool canGoBack = manager.CanNavigateBack();
|
|
ImGui::BeginDisabled(!canGoBack);
|
|
if (ImGui::Button("<")) {
|
|
if (canGoBack) {
|
|
manager.NavigateBack();
|
|
}
|
|
}
|
|
ImGui::EndDisabled();
|
|
ImGui::SameLine();
|
|
|
|
ImGui::Text("%s", manager.GetCurrentPath().c_str());
|
|
|
|
ImGui::SameLine();
|
|
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 80.0f);
|
|
if (ImGui::Button("Refresh")) {
|
|
manager.RefreshCurrentFolder();
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
ImGui::PushItemWidth(-1);
|
|
ImGui::InputTextWithHint("##Search", "Search...", m_searchBuffer, sizeof(m_searchBuffer));
|
|
ImGui::PopItemWidth();
|
|
|
|
ImGui::Separator();
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10, 10));
|
|
|
|
float buttonWidth = 80.0f;
|
|
float padding = 10.0f;
|
|
float panelWidth = ImGui::GetContentRegionAvail().x;
|
|
int columns = (int)(panelWidth / (buttonWidth + padding));
|
|
if (columns < 1) columns = 1;
|
|
|
|
auto& items = manager.GetCurrentItems();
|
|
std::string searchStr = m_searchBuffer;
|
|
int itemIndex = 0;
|
|
|
|
for (int i = 0; i < (int)items.size(); i++) {
|
|
if (!searchStr.empty()) {
|
|
if (items[i]->name.find(searchStr) == std::string::npos) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (itemIndex > 0 && itemIndex % columns != 0) {
|
|
ImGui::SameLine();
|
|
}
|
|
RenderAssetItem(items[i], itemIndex);
|
|
itemIndex++;
|
|
}
|
|
|
|
ImGui::PopStyleVar();
|
|
|
|
if (ImGui::BeginPopup("ItemContextMenu")) {
|
|
if (m_contextMenuIndex >= 0 && m_contextMenuIndex < (int)items.size()) {
|
|
auto& item = items[m_contextMenuIndex];
|
|
if (item->isFolder) {
|
|
if (ImGui::MenuItem("Open")) {
|
|
manager.NavigateToFolder(item);
|
|
}
|
|
ImGui::Separator();
|
|
}
|
|
if (ImGui::MenuItem("Delete")) {
|
|
manager.DeleteItem(m_contextMenuIndex);
|
|
m_contextMenuIndex = -1;
|
|
}
|
|
}
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
if (ImGui::IsWindowHovered() && ImGui::IsMouseClicked(1) && !ImGui::IsAnyItemHovered()) {
|
|
ImGui::OpenPopup("EmptyContextMenu");
|
|
}
|
|
|
|
if (ImGui::BeginPopup("EmptyContextMenu")) {
|
|
if (ImGui::MenuItem("Create Folder")) {
|
|
m_showCreateFolderPopup = true;
|
|
strcpy_s(m_newFolderName, "NewFolder");
|
|
}
|
|
ImGui::Separator();
|
|
if (ImGui::MenuItem("Refresh")) {
|
|
manager.RefreshCurrentFolder();
|
|
}
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
if (m_showCreateFolderPopup) {
|
|
ImGui::OpenPopup("Create Folder");
|
|
m_showCreateFolderPopup = false;
|
|
}
|
|
|
|
if (ImGui::BeginPopupModal("Create Folder", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
|
ImGui::InputText("Name", m_newFolderName, sizeof(m_newFolderName));
|
|
ImGui::Separator();
|
|
if (ImGui::Button("Create", ImVec2(80, 0))) {
|
|
CreateNewFolder(m_newFolderName);
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::Button("Cancel", ImVec2(80, 0))) {
|
|
ImGui::CloseCurrentPopup();
|
|
}
|
|
ImGui::EndPopup();
|
|
}
|
|
}
|
|
|
|
void ProjectPanel::RenderAssetItem(const AssetItemPtr& item, int index) {
|
|
auto& manager = ProjectManager::Get();
|
|
bool isSelected = (manager.GetSelectedIndex() == index);
|
|
|
|
ImGui::PushID(index);
|
|
|
|
if (isSelected) {
|
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.40f, 0.40f, 0.40f, 0.50f));
|
|
}
|
|
|
|
ImVec2 buttonSize(80.0f, 90.0f);
|
|
|
|
if (ImGui::Button("##AssetBtn", buttonSize)) {
|
|
manager.SetSelectedIndex(index);
|
|
}
|
|
|
|
bool doubleClicked = false;
|
|
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) {
|
|
doubleClicked = true;
|
|
}
|
|
|
|
bool openContextMenu = false;
|
|
if (ImGui::IsItemClicked(1)) {
|
|
manager.SetSelectedIndex(index);
|
|
m_contextMenuIndex = index;
|
|
openContextMenu = true;
|
|
}
|
|
|
|
if (isSelected) {
|
|
ImGui::PopStyleColor();
|
|
}
|
|
|
|
ImVec2 min = ImGui::GetItemRectMin();
|
|
ImDrawList* drawList = ImGui::GetWindowDrawList();
|
|
|
|
ImU32 iconColor;
|
|
if (item->isFolder) {
|
|
iconColor = IM_COL32(200, 180, 100, 255);
|
|
} else if (item->type == "Texture") {
|
|
iconColor = IM_COL32(150, 200, 150, 255);
|
|
} else if (item->type == "Model") {
|
|
iconColor = IM_COL32(150, 150, 200, 255);
|
|
} else if (item->type == "Script") {
|
|
iconColor = IM_COL32(200, 150, 150, 255);
|
|
} else if (item->type == "Scene") {
|
|
iconColor = IM_COL32(200, 200, 150, 255);
|
|
} else {
|
|
iconColor = IM_COL32(100, 150, 200, 255);
|
|
}
|
|
|
|
float iconSize = 40.0f;
|
|
ImVec2 iconMin(min.x + (80.0f - iconSize) * 0.5f, min.y + 10.0f);
|
|
ImVec2 iconMax(iconMin.x + iconSize, iconMin.y + iconSize);
|
|
drawList->AddRectFilled(iconMin, iconMax, iconColor, 4.0f);
|
|
|
|
ImVec4 textColor = isSelected ? ImVec4(1.0f, 1.0f, 1.0f, 1.0f) : ImVec4(0.8f, 0.8f, 0.8f, 1.0f);
|
|
ImVec2 textSize = ImGui::CalcTextSize(item->name.c_str());
|
|
float textOffset = std::max(0.0f, (80.0f - textSize.x) * 0.5f);
|
|
|
|
ImGui::PushClipRect(min, ImVec2(min.x + 80.0f, min.y + 90.0f), true);
|
|
drawList->AddText(ImVec2(min.x + textOffset, min.y + 60.0f), ImGui::GetColorU32(textColor), item->name.c_str());
|
|
ImGui::PopClipRect();
|
|
|
|
if (doubleClicked && item->isFolder) {
|
|
manager.NavigateToFolder(item);
|
|
}
|
|
|
|
ImGui::PopID();
|
|
|
|
if (openContextMenu) {
|
|
ImGui::OpenPopup("ItemContextMenu");
|
|
}
|
|
}
|
|
|
|
void ProjectPanel::CreateNewFolder(const std::string& name) {
|
|
auto& manager = ProjectManager::Get();
|
|
manager.CreateFolder(name);
|
|
}
|
|
|
|
} |