diff --git a/App/editor/AssetBrowserPanel.cpp b/App/editor/AssetBrowserPanel.cpp index d3052cb..0749ae2 100644 --- a/App/editor/AssetBrowserPanel.cpp +++ b/App/editor/AssetBrowserPanel.cpp @@ -111,15 +111,50 @@ void AssetBrowserPanel::Draw(const EditorContext& ctx) ImGui::Separator(); const std::filesystem::path root(kRootPaths[m_Root]); + // 根切换 / 首帧:当前目录回根。前缀比较手写(path::starts_with + // 是 libstdc++ 11 才补齐的成员,本机 GCC 没有);补 '/' 分隔校验 + // 防 "assets_x" 之类误匹配 + const std::string rootStr = root.generic_string(); + const std::string curStr = m_CurrentDir.generic_string(); + const bool under = curStr == rootStr || + (curStr.size() > rootStr.size() && + curStr.compare(0, rootStr.size(), rootStr) == 0 && + curStr[rootStr.size()] == '/'); + if (m_CurrentDir.empty() || !under) + { + m_CurrentDir = root; + } - // ---- 左:目录树 | 右:文件列表 ---- + // ---- 顶栏下:面包屑(当前目录相对根路径 + 回根按钮)---- + if (ImGui::Button("Root")) + { + m_CurrentDir = root; + } + ImGui::SameLine(); + std::string rel = std::filesystem::relative(m_CurrentDir, root) + .generic_string(); + ImGui::TextDisabled("%s/%s", kRootNames[m_Root], + rel.empty() ? "" : rel.c_str()); + ImGui::Separator(); + + // ---- 左:目录树 | 右:当前目录文件列表 ---- const float treeWidth = 180.0f; ImGui::BeginChild("##tree", ImVec2(treeWidth, 0.0f), ImGuiChildFlags_ResizeX | ImGuiChildFlags_Borders); if (std::filesystem::exists(root)) { + // 根节点也画进树(可点击选中) ImGui::SetNextItemOpen(true, ImGuiCond_Once); - DrawDirTree(ctx, root); + if (ImGui::TreeNodeEx(kRootNames[m_Root], + ImGuiTreeNodeFlags_OpenOnArrow)) + { + if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) + { + m_CurrentDir = root; + } + DrawDirTree(ctx, root); + ImGui::TreePop(); + } } else { @@ -130,9 +165,9 @@ void AssetBrowserPanel::Draw(const EditorContext& ctx) ImGui::SameLine(); ImGui::BeginChild("##files", ImVec2(0.0f, 0.0f), ImGuiChildFlags_Borders); - if (std::filesystem::exists(root)) + if (std::filesystem::exists(m_CurrentDir)) { - DrawFileList(ctx, root); + DrawFileList(ctx, m_CurrentDir); } ImGui::EndChild(); @@ -149,7 +184,15 @@ void AssetBrowserPanel::DrawDirTree(const EditorContext& ctx, continue; } const std::string name = entry.path().filename().string(); - if (ImGui::TreeNode(name.c_str())) + // OpenOnArrow:单击行 = 选中(列表切换),箭头 = 折叠 + const bool open = ImGui::TreeNodeEx( + name.c_str(), ImGuiTreeNodeFlags_OpenOnArrow | + ImGuiTreeNodeFlags_SpanFullWidth); + if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) + { + m_CurrentDir = entry.path(); + } + if (open) { DrawDirTree(ctx, entry.path()); ImGui::TreePop(); @@ -172,6 +215,16 @@ void AssetBrowserPanel::DrawFileList(const EditorContext& ctx, { if (entry.is_directory()) { + // 子目录也进列表:单行点击进入(树/列表双向导航) + const std::string dname = entry.path().filename().string(); + ImGui::PushID(dname.c_str()); + ImGui::TextUnformatted("[D]"); + ImGui::SameLine(); + if (ImGui::Selectable(dname.c_str())) + { + m_CurrentDir = entry.path(); + } + ImGui::PopID(); continue; } const Kind kind = KindOf(entry.path()); diff --git a/App/editor/AssetBrowserPanel.h b/App/editor/AssetBrowserPanel.h index e759281..c10c447 100644 --- a/App/editor/AssetBrowserPanel.h +++ b/App/editor/AssetBrowserPanel.h @@ -31,6 +31,8 @@ private: // 固定根(下标即身份):项目资产 / 场景文件 int m_Root = 0; + // 当前浏览目录(点目录树切换;列表显示这里的文件) + std::filesystem::path m_CurrentDir; // 类型过滤(0 = All;其余见 kTypeNames) int m_TypeFilter = 0; // 名字子串过滤(空 = 不过滤)