From 0aebc3053fc6094fbc90f7fbdd3c283aebda8c63 Mon Sep 17 00:00:00 2001 From: Sri Sham Haran Date: Sun, 30 Oct 2022 18:26:49 +0800 Subject: [PATCH] Asset browser (currently only displays asset and can drag drop for setting of mesh. except setting mesh in inspector doesnt work) --- .../AssetBrowser/SHAssetBrowser.cpp | 154 +++++++++++++----- .../AssetBrowser/SHAssetBrowser.h | 13 +- SHADE_Engine/src/Editor/SHEditor.cpp | 2 +- 3 files changed, 128 insertions(+), 41 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index 238ca085..8c71eb8f 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -4,14 +4,16 @@ #include "Editor/IconsMaterialDesign.h" #include "Editor/SHImGuiHelpers.hpp" #include +#include #include "Assets/SHAssetManager.h" +#include "Editor/IconsFontAwesome6.h" #include "Editor/DragDrop/SHDragDrop.hpp" namespace SHADE { SHAssetBrowser::SHAssetBrowser() - :SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar) + :SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder) { } @@ -23,62 +25,140 @@ namespace SHADE void SHAssetBrowser::Update() { SHEditorWindow::Update(); - if(Begin()) + if (Begin()) { + RecursivelyDrawTree(rootFolder); DrawMenuBar(); - auto const& assets = SHAssetManager::GetAllAssets(); - if(ImGui::BeginTable("AssetBrowserTable", 3)) - { - ImGui::TableNextColumn(); - ImGui::TableHeader("Asset ID"); - ImGui::TableNextColumn(); - ImGui::TableHeader("Name"); - ImGui::TableNextColumn(); - ImGui::TableHeader("Type"); - for(SHAsset const& asset : assets) - { - DrawAsset(asset); - } - ImGui::EndTable(); - } + DrawCurrentFolder(); } ImGui::End(); } void SHAssetBrowser::DrawMenuBar() { - if(ImGui::BeginMenuBar()) + if (ImGui::BeginMenuBar()) { ImGui::EndMenuBar(); } } - void SHAssetBrowser::DrawAsset(SHAsset const& asset) + ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder) { - ImGui::PushID(asset.id); - ImGui::BeginGroup(); + auto const& subFolders = folder->subFolders; + auto const& files = folder->files; + const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end(); + ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow; + if (isSelected) + flags |= ImGuiTreeNodeFlags_Selected; + if (folder == rootFolder) + flags |= ImGuiTreeNodeFlags_DefaultOpen; + + bool isOpen = ImGui::TreeNodeEx(folder, flags, "%s %s", ICON_MD_FOLDER, folder->name.data()); + const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); + if(ImGui::IsItemClicked()) + { + selectedFolders.clear(); + selectedFolders.push_back(folder); + } + if (isOpen) + { + const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark); + const float horizontalOffset = 0.0f; + ImDrawList* drawList = ImGui::GetWindowDrawList(); + ImVec2 vertLineStart = ImGui::GetCursorScreenPos(); + vertLineStart.x += horizontalOffset; + ImVec2 vertLineEnd = vertLineStart; + for (auto const& subFolder : subFolders) + { + const float horizontalLineSize = 8.0f; + const ImRect childRect = RecursivelyDrawTree(subFolder); + const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; + drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); + vertLineEnd.y = midPoint; + } + for (auto const& file : files) + { + const float horizontalLineSize = 25.0f; + const ImRect childRect = DrawFile(file); + const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; + drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); + vertLineEnd.y = midPoint; + } + drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1); + ImGui::TreePop(); + } + return nodeRect; + } - ImGui::TableNextColumn(); - ImGui::Selectable(std::format("{}", asset.id).data(), false, ImGuiSelectableFlags_SpanAllColumns); + void SHAssetBrowser::DrawCurrentFolder() + { + //auto const& subFolders = currentFolder->subFolders; + //ImVec2 initialCursorPos = ImGui::GetCursorPos(); + //ImVec2 initialRegionAvail = ImGui::GetContentRegionAvail(); + //int maxTiles = initialRegionAvail.x / tileWidth; + //float maxX = (maxTiles - 1)*tileWidth; + //ImVec2 tilePos = initialCursorPos; + //for (auto const& subFolder : subFolders) + //{ + // ImGui::SetCursorPos(tilePos); + // ImGui::BeginGroup(); + // ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, {0.0f, 0.0f}); + // ImGui::Button(ICON_MD_FOLDER, {tileWidth}); + // ImGui::Text(subFolder->name.data()); + // ImGui::PopStyleVar(); + // ImGui::EndGroup(); + // if(tilePos.x >= maxX) + // { + // tilePos.x = initialCursorPos.x; + // } + // else + // { + // ImGui::SameLine(); + // tilePos.x += tileWidth; + // } + //} + } + + ImRect SHAssetBrowser::DrawFile(SHFile const& file) noexcept + { + if (file.assetMeta == nullptr) + return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); + const bool isSelected = std::ranges::find(selectedAssets, file.assetMeta->id) != selectedAssets.end(); + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf; + if (isSelected) + flags |= ImGuiTreeNodeFlags_Selected; + std::string icon{}; + + switch(file.assetMeta->type) + { + case AssetType::INVALID: break; + case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break; + case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break; + case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break; + case AssetType::MESH: icon = ICON_FA_CUBES; break; + case AssetType::SCENE: icon = ICON_MD_IMAGE; break; + case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break; + case AssetType::MATERIAL: break; + case AssetType::MAX_COUNT: break; + default: ; + } + + ImGui::TreeNodeEx(file.assetMeta, flags, "%s %s", icon.data(), file.assetMeta->name.data()); + const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); if(SHDragDrop::BeginSource()) { - auto id = asset.id; - ImGui::Text("Moving Asset: %zu", id); + auto id = file.assetMeta->id; + ImGui::Text("Moving Asset: %s [%zu]", file.name.data(), file.assetMeta->id); SHDragDrop::SetPayload(SHDragDrop::DRAG_RESOURCE, &id); SHDragDrop::EndSource(); } - - ImGui::TableNextColumn(); - ImGui::Text("%s", asset.name.c_str()); - - ImGui::TableNextColumn(); - ImGui::Text("%s", "Type"); - - ImGui::EndGroup(); - ImGui::PopID(); - - - + if(ImGui::IsItemClicked()) + { + selectedAssets.clear(); + selectedAssets.push_back(file.assetMeta->id); + } + ImGui::TreePop(); + return nodeRect; } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h index 0e3053bc..d56fc029 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.h @@ -1,7 +1,9 @@ #pragma once +#include "imgui_internal.h" #include "Assets/SHAsset.h" #include "Editor/EditorWindow/SHEditorWindow.h" +#include "Filesystem/SHFolder.h" namespace SHADE { @@ -16,9 +18,14 @@ namespace SHADE void Refresh(); private: void DrawMenuBar(); - void DrawAsset(SHAsset const& asset); + ImRect RecursivelyDrawTree(FolderPointer folder); + void DrawCurrentFolder(); + ImRect DrawFile(SHFile const& file) noexcept; - float idColumnWidth, nameColumnWidth, typeColumnWidth; + FolderPointer rootFolder, prevFolder, currentFolder; + std::vector selectedFolders; + std::vector selectedAssets; + static constexpr float tileWidth = 50.0f; }; -} \ No newline at end of file +} diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 6ae94cdc..cf5056a5 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -175,7 +175,7 @@ namespace SHADE ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f; constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path - constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_MD, 0 }; + constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path io->Fonts->Build(); }