2025-05-21 16:49:17 +00:00
|
|
|
#include "FileBrowser.h"
|
|
|
|
#include "systems/AssetManager.h"
|
2025-05-21 18:59:27 +00:00
|
|
|
#include "systems/assets/Texture2D.h"
|
2025-05-21 16:49:17 +00:00
|
|
|
#include "imgui.h"
|
|
|
|
#include <filesystem>
|
|
|
|
|
2025-05-21 18:59:27 +00:00
|
|
|
namespace OX
|
|
|
|
{
|
2025-05-21 16:49:17 +00:00
|
|
|
static std::string s_CurrentPath = "res://";
|
|
|
|
|
2025-05-21 18:59:27 +00:00
|
|
|
static void DrawGrid(const std::shared_ptr<ResourceTreeNode> &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));
|
2025-05-21 16:49:17 +00:00
|
|
|
|
|
|
|
ImGui::BeginChild("FileGrid", ImVec2(0, 0), false, ImGuiWindowFlags_AlwaysUseWindowPadding);
|
|
|
|
ImGui::Columns(columns, nullptr, false);
|
|
|
|
|
2025-05-21 18:59:27 +00:00
|
|
|
for (const auto &child: node->children) {
|
|
|
|
ImGui::PushID(child->path.c_str()); // Unique ID per item
|
|
|
|
|
|
|
|
ImGui::BeginGroup();
|
2025-05-21 16:49:17 +00:00
|
|
|
|
2025-05-21 18:59:27 +00:00
|
|
|
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<Texture2D>(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]");
|
2025-05-21 16:49:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-05-21 18:59:27 +00:00
|
|
|
|
|
|
|
// === 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();
|
2025-05-21 16:49:17 +00:00
|
|
|
ImGui::NextColumn();
|
2025-05-21 18:59:27 +00:00
|
|
|
ImGui::PopID();
|
2025-05-21 16:49:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::Columns(1);
|
|
|
|
ImGui::EndChild();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-05-21 18:59:27 +00:00
|
|
|
static std::shared_ptr<ResourceTreeNode> FindNode(const std::shared_ptr<ResourceTreeNode> &root,
|
|
|
|
const std::string &targetPath)
|
|
|
|
{
|
|
|
|
if (root->path == targetPath) return root;
|
|
|
|
for (const auto &child: root->children) {
|
2025-05-21 16:49:17 +00:00
|
|
|
if (child->isDirectory) {
|
|
|
|
auto found = FindNode(child, targetPath);
|
|
|
|
if (found) return found;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2025-05-21 18:59:27 +00:00
|
|
|
void FileBrowser::Draw()
|
|
|
|
{
|
2025-05-21 16:49:17 +00:00
|
|
|
ImGui::Begin("File Browser");
|
|
|
|
|
2025-05-21 18:59:27 +00:00
|
|
|
// === 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();
|
2025-05-21 16:49:17 +00:00
|
|
|
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
|