diff options
Diffstat (limited to 'vendor/rlImGui-main/examples/asset_browser/asset_browser.cpp')
| -rw-r--r-- | vendor/rlImGui-main/examples/asset_browser/asset_browser.cpp | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/vendor/rlImGui-main/examples/asset_browser/asset_browser.cpp b/vendor/rlImGui-main/examples/asset_browser/asset_browser.cpp new file mode 100644 index 0000000..a09070a --- /dev/null +++ b/vendor/rlImGui-main/examples/asset_browser/asset_browser.cpp @@ -0,0 +1,280 @@ +/******************************************************************************************* +* +* raylib-extras [ImGui] example - asset browser +* +* This is a more complex ImGui Integration +* It shows how to build windows on top of 2d and 3d views using a render texture +* +* Copyright (c) 2024 Jeffery Myers +* +********************************************************************************************/ + +#define _CRT_NONSTDC_NO_WARNINGS + +#include "asset_browser.h" +#include "imgui_utils.h" +#include "imgui.h" +#include "imgui_internal.h" +#include "raylib.h" +#include "extras/IconsFontAwesome6.h" + +#include <algorithm> + + +AssetBrowserPanel::AssetBrowserPanel() +{ + AssetRoot = GetWorkingDirectory(); + RebuildFolderTree(); + SetCurrentFolder(&FolderRoot); + + CurrentView = &ListView; +} + +void AssetBrowserPanel::Show() +{ + ShowHeader(); + + ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_Borders; + + if (ImGui::BeginTable("AssetBrowserTab", 2, flags, ImGui::GetContentRegionAvail())) + { + ImGui::TableSetupColumn("FolderView", ImGuiTableColumnFlags_None, 0.25f); + ImGui::TableSetupColumn("AssetView", ImGuiTableColumnFlags_None, 0.75f); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + if (ImGui::BeginChild("FolderList", ImGui::GetContentRegionAvail(),ImGuiChildFlags_None, ImGuiWindowFlags_None)) + { + ShowFolderTree(); + ImGui::EndChild(); + } + + ImGui::TableNextColumn(); + ShowFilePane(); + ImGui::EndTable(); + } +} + +void AssetBrowserPanel::RebuildFolderTree() +{ + FolderRoot.Children.clear(); + + FolderRoot.FullPath = AssetRoot; + FolderRoot.Name = GetFileNameWithoutExt(AssetRoot.c_str()); + FolderRoot.Parent = nullptr; + FolderRoot.Icon = ICON_FA_SERVER; + FolderRoot.ForceOpenNextFrame = true; + FolderRoot.PopulateChildren(); +} + +void AssetBrowserPanel::SetCurrentFolder(FolderInfo* folder) +{ + if (CurrentFolderContents.Folder == folder) + return; + + CurrentFolderContents.Folder = folder; + CurrentFolderContents.Files.clear(); + + if (folder == nullptr) + return; + + FolderInfo* openFolder = folder; + while (openFolder != nullptr) + { + openFolder->ForceOpenNextFrame = true; + openFolder = openFolder->Parent; + } + + auto files = LoadDirectoryFiles(CurrentFolderContents.Folder->FullPath.c_str()); + + for (unsigned int i = 0; i < files.count; i++) + { + if (DirectoryExists(files.paths[i])) + continue; + + const char* name = GetFileName(files.paths[i]); + if (!name || *name == '.') + continue; + + FileInfo& file = CurrentFolderContents.Files.emplace_back(); + file.FullPath = files.paths[i]; + file.Name = name; + file.Icon = GetFileIcon(name); + } + + UnloadDirectoryFiles(files); +} + +void AssetBrowserPanel::FolderInfo::PopulateChildren() +{ + constexpr Color folderColor = { 255,255,145,255 }; + + auto folders = LoadDirectoryFiles(FullPath.c_str()); + + for (unsigned int i = 0; i < folders.count; i++) + { + if (DirectoryExists(folders.paths[i])) + { + const char* name = GetFileNameWithoutExt(folders.paths[i]); + if (!name || *name == '.') + continue; + + FolderInfo& child = Children.emplace_back(); + child.FullPath = folders.paths[i]; + child.Name = name; + child.Parent = this; + child.Tint = folderColor; + child.Icon = ICON_FA_FOLDER; + child.PopulateChildren(); + } + } + UnloadDirectoryFiles(folders); +} + +bool AssetBrowserPanel::ShowFolderTreeNode(FolderInfo& info) +{ + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick; + if (info.Children.empty()) + flags |= ImGuiTreeNodeFlags_Leaf; + + if (CurrentFolderContents.Folder == &info) + flags |= ImGuiTreeNodeFlags_Selected; + + if (info.ForceOpenNextFrame) + { + ImGui::SetNextItemOpen(true); + } + + bool open = ImGui::TreeNodeEx(info.Name.c_str(), flags, "%s %s", info.Icon.c_str(), info.Name.c_str()); + + if (info.ForceOpenNextFrame && CurrentFolderContents.Folder == &info) + ImGui::ScrollToItem(ImGuiScrollFlags_KeepVisibleCenterY); + + info.ForceOpenNextFrame = false; + if (ImGui::IsItemClicked()) + SetCurrentFolder(&info); + + if (open) + { + for (auto& node : info.Children) + ShowFolderTreeNode(node); + + ImGui::TreePop(); + } + + return CurrentFolderContents.Folder == &info; +} + +void AssetBrowserPanel::ShowHeader() +{ + ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 1); + if (ImGui::BeginChild("Header", ImVec2{ ImGui::GetContentRegionAvail().x, ImGui::GetFrameHeight() })) + { + ImGui::Text("%s Root", ICON_FA_FOLDER_OPEN); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x * 0.33f); + ImGui::InputText("###Path", (char*)(CurrentFolderContents.Folder->FullPath.c_str() + AssetRoot.size()), CurrentFolderContents.Folder->FullPath.size(), ImGuiInputTextFlags_ReadOnly); + + ImGui::EndChild(); + } + ImGui::PopStyleVar(); +} + +void AssetBrowserPanel::ShowFolderTree() +{ + ShowFolderTreeNode(FolderRoot); +} + +void AssetBrowserPanel::ShowFilePane() +{ + if (ImGui::BeginChild("FileList", ImGui::GetContentRegionAvail(), ImGuiChildFlags_None, ImGuiWindowFlags_None)) + { + if (CurrentView) + { + auto *item = CurrentView->Show(CurrentFolderContents); + if (item) + { + AssetItemInfo* assetItem = static_cast<AssetItemInfo*>(item); + if (!assetItem->IsFile()) + SetCurrentFolder(static_cast<FolderInfo*>(item)); + } + } + ImGui::EndChild(); + } +} + +ViewableItem* AssetBrowserPanel::AssetContainer::Reset() +{ + FileItr = Files.begin(); + FolderItr = Folder->Children.begin(); + if (FileItr != Files.end()) + return &(*FileItr); + if (FolderItr != Folder->Children.end()) + return &(*FolderItr); + + return nullptr; +} + +size_t AssetBrowserPanel::AssetContainer::Count() +{ + return Files.size() + Folder->Children.size(); +} + +ViewableItem* AssetBrowserPanel::AssetContainer::Next() +{ + if (FileItr != Files.end()) + { + FileItr++; + if (FileItr != Files.end()) + return &(*FileItr); + else + { + if (FolderItr != Folder->Children.end()) + return &(*FolderItr); + else + return nullptr; + } + } + + if (FolderItr != Folder->Children.end()) + { + FolderItr++; + if (FolderItr != Folder->Children.end()) + return &(*FolderItr); + } + + return nullptr; +} + +const char* AssetBrowserPanel::GetFileIcon(const char* filename) +{ + const char* e = GetFileExtension(filename); + + if (e == nullptr) + return ICON_FA_FILE; + + std::string ext = e; + + std::transform(ext.begin(), ext.end(), ext.begin(), + [](unsigned char c) { return std::tolower(c); } // correct + ); + + if (!ext.empty()) + { + if (ext==".png") + return ICON_FA_FILE_IMAGE; + + if (ext==".wav" || ext==".mp3" || ext==".oog") + return ICON_FA_FILE_AUDIO; + + if (ext==".ttf" || ext==".otf" || ext==".fnt") + return ICON_FA_FONT; + + if (ext==".txt" || ext==".md") + return ICON_FA_FILE_LINES; + + if (ext==".lua" || ext==".c" || ext==".h" || ext==".cpp") + return ICON_FA_FILE_CODE; + } + return ICON_FA_FILE; +}
\ No newline at end of file |
