Onyx-Engine/src/editor/Windows/FileBrowser.cpp

154 lines
5.4 KiB
C++
Raw Normal View History

2025-05-21 16:49:17 +00:00
#include "FileBrowser.h"
#include "systems/AssetManager.h"
#include "systems/assets/Texture2D.h"
2025-05-21 16:49:17 +00:00
#include "imgui.h"
#include <filesystem>
namespace OX
{
2025-05-21 16:49:17 +00:00
static std::string s_CurrentPath = "res://";
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);
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
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
}
}
// === 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();
ImGui::PopID();
2025-05-21 16:49:17 +00:00
}
ImGui::Columns(1);
ImGui::EndChild();
}
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;
}
void FileBrowser::Draw()
{
2025-05-21 16:49:17 +00:00
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();
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