feat: 添加Project面板拖拽移动功能

This commit is contained in:
2026-03-12 19:48:51 +08:00
parent 1fc84b9538
commit 909f430c7a
5 changed files with 55 additions and 0 deletions

View File

@@ -10,6 +10,7 @@ struct AssetItem {
std::string name;
std::string type;
bool isFolder;
std::string fullPath;
std::vector<std::shared_ptr<AssetItem>> children;
};

View File

@@ -85,6 +85,7 @@ void ProjectManager::Initialize(const std::string& projectPath) {
m_rootFolder = ScanDirectory(assetsPath.wstring());
m_rootFolder->name = "Assets";
m_rootFolder->fullPath = WstringToUtf8(assetsPath.wstring());
m_path.clear();
m_path.push_back(m_rootFolder);
@@ -143,6 +144,27 @@ void ProjectManager::DeleteItem(int index) {
}
}
bool ProjectManager::MoveItem(const std::string& sourceFullPath, const std::string& destFolderFullPath) {
try {
fs::path sourcePath = Utf8ToWstring(sourceFullPath);
fs::path destPath = fs::path(Utf8ToWstring(destFolderFullPath)) / sourcePath.filename();
if (!fs::exists(sourcePath)) {
return false;
}
if (fs::exists(destPath)) {
return false;
}
fs::rename(sourcePath, destPath);
RefreshCurrentFolder();
return true;
} catch (...) {
return false;
}
}
AssetItemPtr ProjectManager::ScanDirectory(const std::wstring& path) {
auto folder = std::make_shared<AssetItem>();
folder->name = WstringToUtf8(fs::path(path).filename().wstring());
@@ -175,6 +197,7 @@ AssetItemPtr ProjectManager::CreateAssetItem(const std::wstring& path, const std
auto item = std::make_shared<AssetItem>();
item->name = WstringToUtf8(nameW);
item->isFolder = isFolder;
item->fullPath = WstringToUtf8(path);
if (isFolder) {
item->type = "Folder";

View File

@@ -26,6 +26,7 @@ public:
void CreateFolder(const std::string& name);
void DeleteItem(int index);
bool MoveItem(const std::string& sourceFullPath, const std::string& destFolderFullPath);
const std::string& GetProjectPath() const { return m_projectPath; }

View File

@@ -6,6 +6,8 @@
namespace UI {
const char* DRAG_DROP_TYPE = "ASSET_ITEM";
ProjectPanel::ProjectPanel() : Panel("Project") {
}
@@ -190,6 +192,29 @@ void ProjectPanel::RenderAssetItem(const AssetItemPtr& item, int index) {
drawList->AddText(ImVec2(min.x + textOffset, min.y + 60.0f), ImGui::GetColorU32(textColor), item->name.c_str());
ImGui::PopClipRect();
if (item->isFolder) {
if (ImGui::BeginDragDropTarget()) {
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(DRAG_DROP_TYPE)) {
const char* draggedPath = (const char*)payload->Data;
std::string sourcePath(draggedPath);
manager.MoveItem(sourcePath, item->fullPath);
}
ImGui::EndDragDropTarget();
}
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) {
ImDrawList* hoverDrawList = ImGui::GetWindowDrawList();
hoverDrawList->AddRect(min, ImVec2(min.x + buttonSize.x, min.y + buttonSize.y), IM_COL32(255, 255, 255, 80), 4.0f);
}
}
if (!item->fullPath.empty()) {
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
ImGui::SetDragDropPayload(DRAG_DROP_TYPE, item->fullPath.c_str(), item->fullPath.length() + 1);
ImGui::EndDragDropSource();
}
}
if (doubleClicked && item->isFolder) {
manager.NavigateToFolder(item);
}
@@ -206,4 +231,8 @@ void ProjectPanel::CreateNewFolder(const std::string& name) {
manager.CreateFolder(name);
}
bool ProjectPanel::HandleDrop(const AssetItemPtr& targetFolder) {
return false;
}
}

View File

@@ -14,6 +14,7 @@ public:
private:
void RenderAssetItem(const AssetItemPtr& item, int index);
void CreateNewFolder(const std::string& name);
bool HandleDrop(const AssetItemPtr& targetFolder);
char m_searchBuffer[256] = "";
bool m_showCreateFolderPopup = false;