| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- /*******************************************************************************************
- *
- * 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;
- }
|