#include "FileBrowser.h" #include "systems/AssetManager.h" #include "systems/assets/Texture2D.h" #include "imgui.h" #include namespace OX { static std::string s_CurrentPath = "res://"; static void DrawGrid(const std::shared_ptr &node) { const float thumbSize = 64.0f; const float padding = 8.0f; const float labelHeight = 20.0f; const float cellWidth = thumbSize + padding * 2; const float cellHeight = thumbSize + labelHeight + padding; ImVec2 region = ImGui::GetContentRegionAvail(); int columns = std::max(1, (int) (region.x / cellWidth)); ImGui::BeginChild("FileGrid", ImVec2(0, 0), false, ImGuiWindowFlags_AlwaysUseWindowPadding); ImGui::Columns(columns, nullptr, false); for (const auto &child: node->children) { ImGui::PushID(child->path.c_str()); // Unique ID per item ImGui::BeginGroup(); std::string tooltip; std::string label = child->name; ImVec2 cellSize(cellWidth, cellHeight); ImGui::InvisibleButton("Cell", cellSize); bool hovered = ImGui::IsItemHovered(); bool clicked = ImGui::IsItemClicked(); // Background ImVec2 min = ImGui::GetItemRectMin(); ImVec2 max = ImGui::GetItemRectMax(); ImGui::GetWindowDrawList()->AddRectFilled(min, max, IM_COL32(40, 40, 40, 255), 4.0f); ImVec2 center = ImVec2(min.x + padding, min.y + padding); // === Thumbnail === if (child->isDirectory) { ImGui::SetCursorScreenPos(center); ImGui::Text("[Folder]"); } else { auto asset = AssetManager::Get(child->path); if (asset) { std::string type = asset->GetTypeName(); if (type == "texture2D") { auto tex = std::static_pointer_cast(asset); if (tex->GetID() != 0) { ImGui::SetCursorScreenPos(center); ImGui::Image((ImTextureID) (intptr_t) tex->GetID(), ImVec2(thumbSize, thumbSize), ImVec2(0, 1), ImVec2(1, 0)); tooltip += "Name: " + child->name + "\n"; tooltip += "ID: " + std::to_string(tex->GetID()) + "\n"; tooltip += "Size: " + std::to_string(tex->GetWidth()) + "x" + std::to_string( tex->GetHeight()) + "\n"; tooltip += "Path: " + child->path + "\n"; label += " (ID: " + std::to_string(tex->GetID()) + ")"; } else { ImGui::SetCursorScreenPos(center); ImGui::Text("[Loading]"); } } else { ImGui::SetCursorScreenPos(center); ImGui::Text("[Type: %s]", type.c_str()); } } else { ImGui::SetCursorScreenPos(center); ImGui::Text("[Unloaded]"); } } // === Label === ImGui::SetCursorScreenPos(ImVec2(min.x + padding, max.y - labelHeight)); ImGui::PushTextWrapPos(min.x + cellWidth); ImGui::TextUnformatted(label.c_str()); ImGui::PopTextWrapPos(); // Click handling if (clicked && child->isDirectory) { s_CurrentPath = child->path; } if (hovered && !tooltip.empty()) { ImGui::BeginTooltip(); ImGui::TextUnformatted(tooltip.c_str()); ImGui::EndTooltip(); } ImGui::EndGroup(); ImGui::NextColumn(); ImGui::PopID(); } ImGui::Columns(1); ImGui::EndChild(); } static std::shared_ptr FindNode(const std::shared_ptr &root, const std::string &targetPath) { if (root->path == targetPath) return root; for (const auto &child: root->children) { if (child->isDirectory) { auto found = FindNode(child, targetPath); if (found) return found; } } return nullptr; } void FileBrowser::Draw() { ImGui::Begin("File Browser"); // === Back Button === if (s_CurrentPath != "res://") { if (ImGui::Button("..")) { size_t lastSlash = s_CurrentPath.find_last_of('/'); if (lastSlash != std::string::npos && lastSlash > 6) { // skip 'res://' s_CurrentPath = s_CurrentPath.substr(0, lastSlash); } else { s_CurrentPath = "res://"; } } } ImGui::SameLine(); ImGui::Text("Current Path: %s", s_CurrentPath.c_str()); ImGui::Separator(); auto root = AssetManager::GetFileTree(); auto currentNode = FindNode(root, s_CurrentPath); if (currentNode) { DrawGrid(currentNode); } else { ImGui::Text("Path not found: %s", s_CurrentPath.c_str()); } ImGui::End(); } } // namespace OX