aboutsummaryrefslogtreecommitdiff
path: root/vendor/rlImGui-main/examples/asset_browser
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rlImGui-main/examples/asset_browser')
-rw-r--r--vendor/rlImGui-main/examples/asset_browser/asset_browser.cpp280
-rw-r--r--vendor/rlImGui-main/examples/asset_browser/asset_browser.h95
-rw-r--r--vendor/rlImGui-main/examples/asset_browser/imgui_utils.cpp94
-rw-r--r--vendor/rlImGui-main/examples/asset_browser/imgui_utils.h19
-rw-r--r--vendor/rlImGui-main/examples/asset_browser/item_view.h47
-rw-r--r--vendor/rlImGui-main/examples/asset_browser/item_views.cpp53
-rw-r--r--vendor/rlImGui-main/examples/asset_browser/main.cpp96
7 files changed, 684 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
diff --git a/vendor/rlImGui-main/examples/asset_browser/asset_browser.h b/vendor/rlImGui-main/examples/asset_browser/asset_browser.h
new file mode 100644
index 0000000..206e699
--- /dev/null
+++ b/vendor/rlImGui-main/examples/asset_browser/asset_browser.h
@@ -0,0 +1,95 @@
+/*******************************************************************************************
+*
+* 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
+*
+********************************************************************************************/
+
+#pragma once
+
+#include "item_view.h"
+#include "raylib.h"
+
+#include <string>
+#include <vector>
+#include <list>
+
+class AssetBrowserPanel
+{
+public:
+ AssetBrowserPanel();
+
+ void Show();
+
+private:
+ std::string AssetRoot;
+
+ class AssetItemInfo : public ViewableItem
+ {
+ protected:
+ bool File = false;
+
+ public:
+ AssetItemInfo(bool file) : File(file) {}
+ bool IsFile() const { return File; }
+ };
+
+ class FileInfo : public AssetItemInfo
+ {
+ public:
+ FileInfo() : AssetItemInfo(true) {}
+
+ std::string FullPath;
+ };
+
+ class FolderInfo : public AssetItemInfo
+ {
+ public:
+ FolderInfo() : AssetItemInfo(false) {}
+
+ std::string FullPath;
+ FolderInfo* Parent = nullptr;
+ std::list<FolderInfo> Children;
+
+ bool ForceOpenNextFrame = false;
+
+ void PopulateChildren();
+ };
+
+ FolderInfo FolderRoot;
+
+ class AssetContainer : public ViewableItemContainer
+ {
+ public:
+ ViewableItem* Reset() override;
+ size_t Count() override;
+ ViewableItem* Next() override;
+
+ FolderInfo* Folder = nullptr;
+ std::vector<FileInfo> Files;
+
+ std::vector<FileInfo>::iterator FileItr;
+ std::list<FolderInfo>::iterator FolderItr;
+ };
+
+ AssetContainer CurrentFolderContents;
+
+ ListItemView ListView;
+
+ ItemView* CurrentView = nullptr;
+
+ void RebuildFolderTree();
+
+ void SetCurrentFolder(FolderInfo* folder);
+
+ bool ShowFolderTreeNode(FolderInfo& folder);
+ void ShowFolderTree();
+ void ShowFilePane();
+ void ShowHeader();
+
+ const char* GetFileIcon(const char* filename);
+}; \ No newline at end of file
diff --git a/vendor/rlImGui-main/examples/asset_browser/imgui_utils.cpp b/vendor/rlImGui-main/examples/asset_browser/imgui_utils.cpp
new file mode 100644
index 0000000..da87520
--- /dev/null
+++ b/vendor/rlImGui-main/examples/asset_browser/imgui_utils.cpp
@@ -0,0 +1,94 @@
+/*******************************************************************************************
+*
+* 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
+*
+********************************************************************************************/
+
+#include "imgui_utils.h"
+
+#include "imgui.h"
+#include "imgui_internal.h"
+
+namespace ImGuiUtils
+{
+
+ bool IsSpace(char aCharacter)
+ {
+ // all space characters are values 32 or less (space is 32)
+ // so we can convert them to a bitmask and use a single condition
+ const int mask = (1 << (' ' - 1)) | (1 << ('\f' - 1)) | (1 << ('\n' - 1)) | (1 << ('\r' - 1)) | (1 << ('\t' - 1)) | (1 << ('\v' - 1));
+ return (mask & (1 << ((aCharacter && aCharacter <= 32) * (aCharacter - 1)))) != 0;
+ }
+
+ //-------------------------------------------------------------------------------------------------
+ // Todo: Add support for soft-hyphens when using word boundaries?
+ //-------------------------------------------------------------------------------------------------
+ void TextWithEllipsis(const char* string, float aMaxWidth, bool useWordBoundaries, float aSpacing)
+ {
+ char const* partStart = string;
+ char const* partEnd = string;
+
+ ImWchar elipsisChar = ImGui::GetFont()->EllipsisChar;
+ char elipsisText[8];
+ ImTextStrToUtf8(elipsisText, sizeof(elipsisText), &elipsisChar, (&elipsisChar) + 1);
+
+ if (aSpacing < 0.0f) aSpacing = ImGui::GetStyle().ItemSpacing.x;
+
+ float const ellipsisWidth = ImGui::CalcTextSize(elipsisText).x + aSpacing;
+ float width = 0;
+ bool addElipsis = false;
+
+ while (*partStart != 0 )
+ {
+ // Add space to next segment
+ while (IsSpace(*partEnd))
+ partEnd++;
+
+ if (useWordBoundaries)
+ {
+ // get next 'word' by looking for space after non-space
+ while (*partEnd != 0 && !IsSpace(*partEnd))
+ ++partEnd;
+ }
+ else
+ {
+ if (*partEnd != 0)
+ ++partEnd;
+ }
+
+ ImVec2 const wordSize = ImGui::CalcTextSize(partStart, partEnd);
+
+ // Clearly we have space for this word so just add it
+ if (wordSize.x + width + ellipsisWidth < aMaxWidth)
+ {
+ width += wordSize.x;
+ partStart = partEnd;
+ }
+ // If we're just at the end of the word and we just fit then we can commit here
+ else if (*partEnd == 0 && wordSize.x + width < aMaxWidth)
+ {
+ width += wordSize.x;
+ partStart = partEnd;
+ }
+ // we're done so add elipsis where the current segment starts
+ else
+ {
+ addElipsis = true;
+ break;
+ }
+ }
+
+ ImGui::TextUnformatted(string, partStart);
+
+ if (addElipsis)
+ {
+ ImGui::SameLine(0.0f, aSpacing);
+ ImGui::TextUnformatted(elipsisText);
+ }
+ }
+} \ No newline at end of file
diff --git a/vendor/rlImGui-main/examples/asset_browser/imgui_utils.h b/vendor/rlImGui-main/examples/asset_browser/imgui_utils.h
new file mode 100644
index 0000000..124ff8b
--- /dev/null
+++ b/vendor/rlImGui-main/examples/asset_browser/imgui_utils.h
@@ -0,0 +1,19 @@
+/*******************************************************************************************
+*
+* 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
+*
+********************************************************************************************/
+
+#pragma once
+
+#include <string>
+
+namespace ImGuiUtils
+{
+ void TextWithEllipsis(const char* string, float maxWidth, bool useWordBoundaries = false, float aSpacing = 0);
+} \ No newline at end of file
diff --git a/vendor/rlImGui-main/examples/asset_browser/item_view.h b/vendor/rlImGui-main/examples/asset_browser/item_view.h
new file mode 100644
index 0000000..c70191b
--- /dev/null
+++ b/vendor/rlImGui-main/examples/asset_browser/item_view.h
@@ -0,0 +1,47 @@
+/*******************************************************************************************
+*
+* 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
+*
+********************************************************************************************/
+
+#pragma once
+
+#include <string>
+#include "raylib.h"
+
+class ViewableItem
+{
+public:
+ virtual ~ViewableItem() = default;
+
+ std::string Name;
+ std::string Icon;
+ Color Tint = BLANK;
+};
+
+class ViewableItemContainer
+{
+public:
+ virtual ~ViewableItemContainer() = default;
+ virtual ViewableItem* Reset() = 0;
+ virtual size_t Count() = 0;
+ virtual ViewableItem* Next() = 0;
+};
+
+class ItemView
+{
+public:
+ virtual ~ItemView() = default;
+ virtual ViewableItem* Show(ViewableItemContainer& container) = 0;
+};
+
+class ListItemView : public ItemView
+{
+public:
+ ViewableItem* Show(ViewableItemContainer& container) override;
+};
diff --git a/vendor/rlImGui-main/examples/asset_browser/item_views.cpp b/vendor/rlImGui-main/examples/asset_browser/item_views.cpp
new file mode 100644
index 0000000..0c66a57
--- /dev/null
+++ b/vendor/rlImGui-main/examples/asset_browser/item_views.cpp
@@ -0,0 +1,53 @@
+/*******************************************************************************************
+*
+* 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
+*
+********************************************************************************************/
+
+#include "item_view.h"
+
+#include "imgui.h"
+#include "imgui_utils.h"
+#include "rlImGuiColors.h"
+#include "raylib.h"
+
+extern ImFont* IconFont;
+
+ViewableItem* ListItemView::Show(ViewableItemContainer& container)
+{
+ ViewableItem* item = container.Reset();
+
+ ViewableItem* selected = nullptr;
+ while (item)
+ {
+ float x = ImGui::GetCursorPosX();
+
+ const char* name = TextFormat("###%s", item->Name.c_str());
+ if (item->Tint.a > 0)
+ ImGui::TextColored(rlImGuiColors::Convert(item->Tint), " %s", item->Icon.c_str());
+ else
+ ImGui::Text(" %s", item->Icon.c_str());
+
+ ImGui::SameLine(0, 0);
+ ImGui::Text(" %s", item->Name.c_str());
+ ImGui::SameLine(0, 0);
+
+ ImGui::SetCursorPosX(x);
+ //ImGui::SetItemAllowOverlap();
+
+ ImGui::Selectable(name);
+ if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0))
+ {
+ selected = item;
+ }
+
+ item = container.Next();
+ }
+
+ return selected;
+} \ No newline at end of file
diff --git a/vendor/rlImGui-main/examples/asset_browser/main.cpp b/vendor/rlImGui-main/examples/asset_browser/main.cpp
new file mode 100644
index 0000000..5119ce9
--- /dev/null
+++ b/vendor/rlImGui-main/examples/asset_browser/main.cpp
@@ -0,0 +1,96 @@
+/*******************************************************************************************
+*
+* 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
+*
+********************************************************************************************/
+
+
+#include "raylib.h"
+#include "raymath.h"
+
+#include "imgui.h"
+#include "rlImGui.h"
+#include "rlImGuiColors.h"
+#include "extras/FA6FreeSolidFontData.h"
+
+#include "asset_browser.h"
+
+#include <limits>
+
+
+ImFont* IconFont = nullptr;
+
+int main(int argc, char* argv[])
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ int screenWidth = 1900;
+ int screenHeight = 900;
+
+ SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT);
+ InitWindow(screenWidth, screenHeight, "raylib-Extras [ImGui] example - Asset browser");
+ SetTargetFPS(144);
+
+ rlImGuiBeginInitImGui();
+ ImGui::StyleColorsDark();
+
+
+ static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
+ ImFontConfig icons_config;
+ icons_config.MergeMode = true;
+ icons_config.PixelSnapH = true;
+ icons_config.FontDataOwnedByAtlas = false;
+
+ icons_config.GlyphMaxAdvanceX = std::numeric_limits<float>::max();
+ icons_config.RasterizerMultiply = 1.0f;
+ icons_config.OversampleH = 2;
+ icons_config.OversampleV = 1;
+
+ icons_config.GlyphRanges = icons_ranges;
+
+ ImGuiIO& io = ImGui::GetIO();
+ io.Fonts->AddFontFromMemoryCompressedTTF((void*)fa_solid_900_compressed_data, fa_solid_900_compressed_size, 12, &icons_config, icons_ranges);
+
+ icons_config.MergeMode = false;
+ IconFont = io.Fonts->AddFontFromMemoryCompressedTTF((void*)fa_solid_900_compressed_data, fa_solid_900_compressed_size, 72, &icons_config, icons_ranges);
+
+ rlImGuiEndInitImGui();
+
+ AssetBrowserPanel assetBrowser;
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+
+ BeginDrawing();
+ ClearBackground(DARKGRAY);
+
+ rlImGuiBegin();
+
+ ImGui::SetNextWindowPos(ImVec2(0, 0));
+ ImGui::SetNextWindowSize(ImVec2(float(GetScreenWidth()), float(GetScreenHeight())));
+ if (ImGui::Begin("Frame", 0, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings))
+ {
+ assetBrowser.Show();
+ }
+ ImGui::End();
+
+ rlImGuiEnd();
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+ rlImGuiShutdown();
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file