Skip to content

Commit

Permalink
feat: Content browser pools & custom folders
Browse files Browse the repository at this point in the history
  • Loading branch information
diegomrno committed Nov 24, 2024
1 parent 7ce6a2e commit 54b4787
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 59 deletions.
4 changes: 2 additions & 2 deletions main/include/vortex_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ struct VxIO
std::vector<std::shared_ptr<ContentBrowserCustomFolder>> contentbrowser_customfolders;
std::string contentbrowser_mainpool;
std::string contentbrowser_absolute_mainpool;
std::vector<std::string> contentbrowser_pools;
std::vector<std::pair<std::string,std::string>> contentbrowser_pools;
std::vector<std::string> copy_selection;
std::vector<std::string> cut_selection;
float past_state; // from 0.0f (0%) to 1.0f (100%)
Expand Down Expand Up @@ -324,7 +324,7 @@ namespace VortexMaker

// Publish to ROM
VORTEX_API void PublishContentBrowserCustomFolder(const std::string& path, const std::string &hex_color, const bool& isFav);
VORTEX_API void PublishPool(const std::string& absolute_pool_path);
VORTEX_API void PublishPool(const std::string& absolute_pool_path, const std::string& name);
VORTEX_API void PostCustomFolderToJson();
VORTEX_API void PostPoolsToJson();

Expand Down
25 changes: 16 additions & 9 deletions main/src/vortex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ VORTEX_API void VortexMaker::PostCustomFolderToJson()
VortexMaker::PopulateJSON(json_data, file_path);
}

VORTEX_API void VortexMaker::PublishPool(const std::string &absolute_pool_path)
VORTEX_API void VortexMaker::PublishPool(const std::string &absolute_pool_path, const std::string& name)
{
VxContext &ctx = *CVortexMaker;

Expand All @@ -615,15 +615,15 @@ VORTEX_API void VortexMaker::PublishPool(const std::string &absolute_pool_path)
endPos--;
}

for (auto path : ctx.IO.contentbrowser_pools)
for (auto pool : ctx.IO.contentbrowser_pools)
{
if (path == absolute_pool_path)
if (pool.first == absolute_pool_path)
{
return;
}
}

ctx.IO.contentbrowser_pools.push_back(absolute_pool_path);
ctx.IO.contentbrowser_pools.push_back({absolute_pool_path, name});

VortexMaker::PostPoolsToJson();
}
Expand Down Expand Up @@ -727,7 +727,9 @@ VORTEX_API void VortexMaker::FetchPools()
std::string file_path = path + "/pools.json";

nlohmann::json json_data;

json_data["main_pool"] = ctx.projectPath.string();
json_data["pools"] = nlohmann::json::array();

VortexMaker::createJsonFileIfNotExists(file_path, json_data);

std::ifstream file(file_path);
Expand All @@ -741,10 +743,12 @@ VORTEX_API void VortexMaker::FetchPools()
ctx.IO.contentbrowser_absolute_mainpool = projectPath + "/" + ctx.IO.contentbrowser_mainpool;

// From other pool absolute paths
for (auto directory : json_data["other_pools"])
ctx.IO.contentbrowser_pools.clear();
for (auto directory : json_data["pools"])
{
std::string path = directory["path"].get<std::string>();
ctx.IO.contentbrowser_pools.push_back(path);
std::string name = directory["name"].get<std::string>();
ctx.IO.contentbrowser_pools.push_back({path, name});
}
}

Expand All @@ -761,10 +765,11 @@ VORTEX_API void VortexMaker::PostPoolsToJson()
json_data["pools"] = nlohmann::json::array();
json_data["main_pool"] = ctx.IO.contentbrowser_mainpool;

for (const std::string &path : ctx.IO.contentbrowser_pools)
for (const auto &pool : ctx.IO.contentbrowser_pools)
{
nlohmann::json folder_data;
folder_data["path"] = path;
folder_data["name"] = pool.second;
folder_data["path"] = pool.first;

json_data["pools"].push_back(folder_data);
}
Expand All @@ -788,6 +793,8 @@ VORTEX_API void VortexMaker::FetchCustomFolders()

file >> json_data;

ctx.IO.contentbrowser_customfolders.clear();

for (auto directory : json_data["custom_folders"])
{
std::shared_ptr<ContentBrowserCustomFolder> new_folder = std::make_shared<ContentBrowserCustomFolder>();
Expand Down
146 changes: 100 additions & 46 deletions ui/editor/app/instances/content_browser/content_browser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ using namespace Cherry;

/*
TODO
- FIX Favortie/Colors/Pools
- centered folders
- Fix side navigation
- Add pools
- Home on Pathbar
- cpy/paste
- creation & add
- custom item & callbacks
*/

// To move in class members
Expand All @@ -21,6 +20,7 @@ static char pathRename[256];

static bool pool_add_mode = false;
static char pool_add_path[512];
static char pool_add_name[512];

static std::string _parent;
static char ProjectSearch[256];
Expand Down Expand Up @@ -453,9 +453,8 @@ namespace VortexEditor
static std::vector<std::pair<std::shared_ptr<ContenBrowserItem>, std::string>> recognized_modules_items;
void ContentBrowserAppWindow::DrawPathBar(const std::string &path)
{
// Calculer automatiquement la taille en fonction du contenu
ImVec2 contentSize(ImGui::CalcTextSize(path.c_str()).x + 70.0f, 0);
ImGui::BeginChild("PathBar", ImVec2(contentSize.x, 0), ImGuiWindowFlags_NoScrollbar); // Réduire la hauteur à 25 (ou une valeur ajustée)
ImGui::BeginChild("PathBar", ImVec2(contentSize.x, 0), ImGuiWindowFlags_NoScrollbar);

#ifdef _WIN32
const char separator = '\\';
Expand All @@ -467,13 +466,11 @@ namespace VortexEditor
std::stringstream ss(path);
std::string segment;

// Découper le chemin en segments
while (std::getline(ss, segment, separator))
{
elements.push_back(segment);
}

// Affichage des segments du chemin
for (size_t i = 0; i < elements.size(); ++i)
{
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), "%s", elements[i].c_str());
Expand All @@ -491,12 +488,48 @@ namespace VortexEditor
ImGui::EndChild();
}

void ContentBrowserAppWindow::RefreshCustomFolders()
{
VortexMaker::FetchCustomFolders();
m_FavoriteFolders.clear();
m_FolderColors.clear();
for (auto custom_folder : VortexMaker::GetCurrentContext()->IO.contentbrowser_customfolders)
{
if (custom_folder->m_IsFav)
{
m_FavoriteFolders.push_back(custom_folder->path);
}

if (custom_folder->m_Color != "#fdaa00" || custom_folder->m_Color != m_DefaultFolderColor)
{
if (custom_folder->m_Color.size() <= 7)
{
custom_folder->m_Color = custom_folder->m_Color + "ff"; // + ff to add a opaque bg if not provided
}
m_FolderColors.push_back({custom_folder->path, custom_folder->m_Color});
}
}
}

void ContentBrowserAppWindow::RefreshPools()
{
VortexMaker::FetchPools();
m_Pools.clear();
for (auto pool : VortexMaker::GetCurrentContext()->IO.contentbrowser_pools)
{
m_Pools.push_back(pool);
}
}

ContentBrowserAppWindow::ContentBrowserAppWindow(const std::string &name, const std::string &start_path)
{
m_AppWindow = std::make_shared<AppWindow>(name, name);
m_AppWindow->SetIcon(Cherry::GetPath("resources/imgs/icons/misc/icon_collection.png"));
std::shared_ptr<AppWindow> win = m_AppWindow;

RefreshCustomFolders();
RefreshPools();

cp_SaveButton = Application::Get().CreateComponent<ImageTextButtonSimple>("save_button", Application::Get().GetLocale("loc.window.content.content_browser.save") + "####content_browser.save_all", Application::CookPath("resources/imgs/icons/misc/icon_save.png"));
cp_SaveButton->SetScale(0.85f);
cp_SaveButton->SetLogoSize(15, 15);
Expand Down Expand Up @@ -529,20 +562,6 @@ namespace VortexEditor
cp_DirectoryUndo->SetBackgroundColorIdle("#00000000");
cp_DirectoryUndo->SetBorderColorIdle("#00000000");
cp_DirectoryUndo->SetScale(0.85f);

for (auto custom_folder : VortexMaker::GetCurrentContext()->IO.contentbrowser_customfolders)
{
if (custom_folder->m_IsFav)
{
m_FavoriteFolders.push_back(custom_folder->path);
}

if (custom_folder->m_Color != "#fdaa00" || custom_folder->m_Color != m_DefaultFolderColor)
{
m_FolderColors.push_back({custom_folder->path, custom_folder->m_Color});
}
}

m_AppWindow->SetLeftMenubarCallback([this]()
{
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.4f, 0.4f, 0.4f, 0.7f));
Expand Down Expand Up @@ -1101,37 +1120,67 @@ if (ImGui::BeginPopup("ContextMenu"))

void ContentBrowserAppWindow::DrawHierarchy(std::filesystem::path path, bool isDir, const std::string &label = "")
{
if (!isDir)
return;

ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 12.0f);
std::string tree_label = "???";
if (label.empty())
{
tree_label = path.filename().string() + "###treenode";
}
else
{
tree_label = label + "###treenode";
}

std::string uniqueID = path.string() + "###treenode";

std::string tree_label = label.empty()
? path.filename().string() + "###" + uniqueID + label + path.string()
: label + "###" + uniqueID + label + path.string();

ImGuiTreeNodeFlags treeNodeFlags = ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_FramePadding;

ImVec2 cursorPos = ImGui::GetCursorPos();
ImGui::SetItemAllowOverlap();

ImVec2 pos = ImGui::GetCursorScreenPos();
ImU32 col;

DrawFolderIcon(pos, ImVec2(12, 12), HexToImU32(GetContentBrowserFolderColor(path)));

if (ImGui::TreeNode(tree_label.c_str()))
{
for (auto &dirEntry : std::filesystem::directory_iterator(path))
ChangeDirectory(path);

try
{
const std::filesystem::path &otherPath = dirEntry.path();
std::vector<std::filesystem::directory_entry> entries;
for (auto &dirEntry : std::filesystem::directory_iterator(path))
{
if (dirEntry.is_directory())
{
entries.push_back(dirEntry);
}
}

std::sort(entries.begin(), entries.end(), [](const auto &a, const auto &b)
{ return a.path().filename() < b.path().filename(); });

DrawHierarchy(otherPath, dirEntry.is_directory());
for (const auto &dirEntry : entries)
{
try
{
const std::filesystem::path &otherPath = dirEntry.path();
DrawHierarchy(otherPath, dirEntry.is_directory());
}
catch (const std::exception &e)
{
std::cerr << "Error while display the directory "
<< dirEntry.path() << " - " << e.what() << std::endl;
continue;
}
}
}
catch (const std::exception &e)
{
std::cerr << "Error while display the directory "
<< path << " - " << e.what() << std::endl;
}

ImGui::TreePop();
}

ImVec2 finalCursorPos = ImGui::GetCursorPos();
ImVec2 size = ImGui::GetItemRectSize();
}
Expand All @@ -1150,8 +1199,8 @@ if (ImGui::BeginPopup("ContextMenu"))

CustomCollapsingHeaderLogo("Pools & Collections", Application::CookPath("resources/imgs/icons/misc/icon_collection.png"), [this]()
{
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 2.0f));

ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 2.0f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.4f, 0.4f, 0.4f, 0.7f));
if (!pool_add_mode)
{
Expand All @@ -1164,10 +1213,17 @@ if (ImGui::BeginPopup("ContextMenu"))
{
ImGui::Text("Please enter a path");
ImGui::SetNextItemWidth(-FLT_MIN);
ImGui::InputText("###AddPool", pool_add_path, sizeof(pool_add_path));
ImGui::Text("Name ");
ImGui::SameLine();
ImGui::InputText("###AddPoolName", pool_add_name, sizeof(pool_add_name));

ImGui::Text("Path ");
ImGui::SameLine();
ImGui::InputText("###AddPoolPath", pool_add_path, sizeof(pool_add_path));
if (ImGui::ImageButtonWithText(Application::Get().GetCurrentRenderedWindow()->get_texture("/usr/local/include/Vortex/imgs/vortex.png"), "Add", ImVec2(0, 0), ImVec2(0, 0), ImVec2(1, 1), -1, ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)))
{
VortexMaker::PublishPool(pool_add_path);
VortexMaker::PublishPool(pool_add_path, pool_add_name);
RefreshPools();
pool_add_mode = false;
}
ImGui::SameLine();
Expand All @@ -1176,17 +1232,15 @@ if (ImGui::BeginPopup("ContextMenu"))
pool_add_mode = false;
}
}
ImGui::PopStyleVar();
ImGui::PopStyleColor(); });

for (auto custom_dir : m_Pools)
for (auto pool : m_Pools)
{
std::size_t lastSlashPos = custom_dir.find_last_of("/\\");
DrawHierarchy(pool.first, true, pool.second);
}

std::string name = custom_dir.substr(lastSlashPos + 1);
ImGui::PopStyleVar();
ImGui::PopStyleColor(); });

DrawHierarchy(custom_dir, true, name);
}
}

void ContentBrowserAppWindow::RenderFiltersBar()
Expand Down
17 changes: 15 additions & 2 deletions ui/editor/app/instances/content_browser/content_browser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ namespace VortexEditor
public:
ContentBrowserAppWindow(const std::string &name, const std::string &start_path);

void RefreshCustomFolders();
void RefreshPools();

std::shared_ptr<Cherry::AppWindow> &GetAppWindow();
static std::shared_ptr<ContentBrowserAppWindow> Create(const std::string &name, const std::string &base_path);
void SetupRenderCallback();
Expand Down Expand Up @@ -223,7 +226,17 @@ namespace VortexEditor
}

void AddReconizedItem(const std::shared_ptr<ContenBrowserItem> &item) {};
bool IsPathFavorite(const std::string &path) { return false; };
bool IsPathFavorite(const std::string &path) {
for(auto fav_folder : m_FavoriteFolders)
{
if(fav_folder == path)
{
return true;
}
}
return false;
};

void SetColoredFolder(const std::string &path, const std::string &hex_color) {};

std::vector<ContentBrowserChild> m_Childs;
Expand Down Expand Up @@ -265,7 +278,7 @@ namespace VortexEditor
// Path/Color
std::vector<std::pair<std::string, std::string>> m_FolderColors;
std::vector<std::string> m_FavoriteFolders;
std::vector<std::string> m_Pools;
std::vector<std::pair<std::string,std::string>> m_Pools;
std::vector<std::shared_ptr<ContenBrowserItem>> m_ItemToReconize;

std::vector<std::filesystem::path> m_Favorites;
Expand Down

0 comments on commit 54b4787

Please sign in to comment.