diff --git a/src/Bookmarks/BookmarkManager.cpp b/src/Bookmarks/BookmarkManager.cpp index 7071a20..9370bd8 100644 --- a/src/Bookmarks/BookmarkManager.cpp +++ b/src/Bookmarks/BookmarkManager.cpp @@ -1,6 +1,8 @@ #include "BookmarkManager.hpp" #include "../World.hpp" #include "../MainProgram.hpp" +#include "Helpers/NetworkingObjects/NetObjOrderedList.hpp" +#include "Helpers/NetworkingObjects/NetObjTemporaryPtr.decl.hpp" BookmarkManager::BookmarkManager(World& w): world(w) @@ -51,5 +53,59 @@ void BookmarkManager::init() { } } +void BookmarkManager::setup_list_gui(const std::string& id) { + using namespace NetworkingObjects; + if(bookmarkListRoot) { + std::optional toDeleteParent; + std::optional toDeleteObject; + auto& gui = world.main.toolbar.gui; + gui.tree_listing(id, bookmarkListRoot.get_net_id(), GUIStuff::TreeListing::DisplayData{ + .getObjInListAtIndex = [&](NetObjID parentId, size_t index) -> std::optional { + NetObjOrderedList& bookmarkParentFolder = *world.netObjMan.get_obj_temporary_ref_from_id(parentId)->get_folder_list(); + if(bookmarkParentFolder.size() <= index) + return std::nullopt; + return GUIStuff::TreeListing::DisplayData::ObjInList{ + .id = bookmarkParentFolder.at(index)->obj.get_net_id(), + .isDirectory = bookmarkParentFolder.at(index)->obj->is_folder(), + .isDirectoryOpen = bookmarkParentFolder.at(index)->obj->is_folder() ? bookmarkParentFolder.at(index)->obj->is_folder_open() : false + }; + }, + .setDirectoryOpen = [&](NetObjID netID, bool newDirectoryOpen) { + world.netObjMan.get_obj_temporary_ref_from_id(netID)->set_folder_open(newDirectoryOpen); + }, + .drawNonDirectoryObjIconGUI = [&](NetObjID netID) { + CLAY_AUTO_ID({ + .layout = { + .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, + .padding = CLAY_PADDING_ALL(2), + }, + }) { + gui.svg_icon("bookmark ico", "data/icons/bookmark.svg"); + } + return false; + }, + .drawObjGUI = [&](NetObjID parentNetID, NetObjID netID) { + CLAY_AUTO_ID({ + .layout = { + .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, + .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} + }, + }) { + gui.text_label(world.netObjMan.get_obj_temporary_ref_from_id(netID)->get_name()); + } + if(gui.svg_icon_button_transparent("delete button", "data/icons/trash.svg", false, GUIStuff::TreeListing::ENTRY_HEIGHT)) { + toDeleteParent = parentNetID; + toDeleteObject = netID; + } + return false; + } + }); + if(toDeleteObject.has_value()) { + auto& folderList = world.netObjMan.get_obj_temporary_ref_from_id(toDeleteParent.value())->get_folder_list(); + folderList->erase(folderList, toDeleteObject.value()); + } + } +} + void BookmarkManager::scale_up(const WorldScalar& scaleUpAmount) { } diff --git a/src/Bookmarks/BookmarkManager.hpp b/src/Bookmarks/BookmarkManager.hpp index 15eb674..6db040b 100644 --- a/src/Bookmarks/BookmarkManager.hpp +++ b/src/Bookmarks/BookmarkManager.hpp @@ -11,6 +11,7 @@ class BookmarkManager { BookmarkManager(World& w); void init(); void scale_up(const WorldScalar& scaleUpAmount); + void setup_list_gui(const std::string& id); template void save(Archive& a) const { } diff --git a/src/GUIStuff/Elements/TreeListing.cpp b/src/GUIStuff/Elements/TreeListing.cpp index 2203ac0..8c2218a 100644 --- a/src/GUIStuff/Elements/TreeListing.cpp +++ b/src/GUIStuff/Elements/TreeListing.cpp @@ -2,11 +2,9 @@ #include "../GUIManager.hpp" #include "Helpers/ConvertVec.hpp" -constexpr float ENTRY_HEIGHT = 25.0f; - namespace GUIStuff { -void TreeListing::update(UpdateInputData& io, GUIManager& gui, const NetworkingObjects::NetObjTemporaryPtr>& bookmarkList) { +void TreeListing::update(UpdateInputData& io, GUIManager& gui, NetworkingObjects::NetObjID rootObjID, const DisplayData& displayData) { CLAY_AUTO_ID({ .layout = { .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)} @@ -22,7 +20,7 @@ void TreeListing::update(UpdateInputData& io, GUIManager& gui, const NetworkingO .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT * itemCountToStartAt)} } }) {} - recursive_gui(io, gui, bookmarkList, itemCount, itemCountToStartAt, itemCountToEndAt, 0); + recursive_gui(io, gui, displayData, rootObjID, itemCount, itemCountToStartAt, itemCountToEndAt, 0); if(itemCount > itemCountToEndAt) { CLAY_AUTO_ID({ .layout = { @@ -34,66 +32,65 @@ void TreeListing::update(UpdateInputData& io, GUIManager& gui, const NetworkingO } } -void TreeListing::recursive_gui(UpdateInputData& io, GUIManager& gui, const NetworkingObjects::NetObjTemporaryPtr>& bookmarkList, size_t& itemCount, size_t itemCountToStartAt, size_t itemCountToEndAt, size_t listDepth) { - std::optional toDelete; - for(auto& bookmarkItem : bookmarkList->get_data()) { - if(itemCount >= itemCountToStartAt && itemCount < itemCountToEndAt) { - gui.push_id(itemCount); - bool buttonClicked = false; - CLAY_AUTO_ID({ - .layout = { - .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT)}, - .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} - }, - .backgroundColor = convert_vec4((objSelected.has_value() && objSelected.value() == bookmarkItem->obj.get_net_id()) ? io.theme->backColor1 : io.theme->backColor2), - }) { - if(listDepth != 0) { - CLAY_AUTO_ID({ - .layout = { - .sizing = {.width = CLAY_SIZING_FIXED(ENTRY_HEIGHT * listDepth), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT)} - }, - }) {} - } - if(bookmarkItem->obj->is_folder()) { - if(gui.svg_icon_button_transparent("ico", bookmarkItem->obj->is_folder_open() ? "data/icons/droparrow.svg" : "data/icons/droparrowclose.svg", false, ENTRY_HEIGHT)) { - bookmarkItem->obj->set_folder_open(!bookmarkItem->obj->is_folder_open()); - buttonClicked = true; - } - } - else { - CLAY_AUTO_ID({ - .layout = { - .sizing = {.width = CLAY_SIZING_FIXED(ENTRY_HEIGHT), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT)}, - .padding = CLAY_PADDING_ALL(2) - } - }) { - gui.svg_icon("ico", "data/icons/bookmark.svg"); - } - } +void TreeListing::recursive_gui(UpdateInputData& io, GUIManager& gui, const DisplayData& displayData, NetworkingObjects::NetObjID objID, size_t& itemCount, size_t itemCountToStartAt, size_t itemCountToEndAt, size_t listDepth) { + for(size_t i = 0;; i++) { + std::optional objInListOptional = displayData.getObjInListAtIndex(objID, i); + if(!objInListOptional.has_value()) + break; + else { + auto& objInList = objInListOptional.value(); + if(itemCount >= itemCountToStartAt && itemCount < itemCountToEndAt) { + gui.push_id(itemCount); + bool buttonClicked = false; CLAY_AUTO_ID({ .layout = { - .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, + .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT)}, .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} - } + }, + .backgroundColor = convert_vec4((objSelected.has_value() && objSelected.value() == objInList.id) ? io.theme->backColor1 : io.theme->backColor2), }) { - gui.text_label(bookmarkItem->obj->get_name()); + if(listDepth != 0) { + CLAY_AUTO_ID({ + .layout = { + .sizing = {.width = CLAY_SIZING_FIXED(ENTRY_HEIGHT * listDepth), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT)} + }, + }) {} + } + if(objInList.isDirectory) { + if(gui.svg_icon_button_transparent("ico", objInList.isDirectoryOpen ? "data/icons/droparrow.svg" : "data/icons/droparrowclose.svg", false, ENTRY_HEIGHT)) { + displayData.setDirectoryOpen(objInList.id, !objInList.isDirectoryOpen); + buttonClicked = true; + } + } + else { + CLAY_AUTO_ID({ + .layout = { + .sizing = {.width = CLAY_SIZING_FIXED(ENTRY_HEIGHT), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT)}, + .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} + }, + }) { + buttonClicked |= displayData.drawNonDirectoryObjIconGUI(objInList.id); + } + } + CLAY_AUTO_ID({ + .layout = { + .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}, + .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER} + } + }) { + buttonClicked |= displayData.drawObjGUI(objID, objInList.id); + } + + if(Clay_Hovered() && io.mouse.leftClick && !buttonClicked) + objSelected = objInList.id; } - if(gui.svg_icon_button_transparent("delete", "data/icons/trash.svg", false, ENTRY_HEIGHT)) { - toDelete = bookmarkItem->obj.get_net_id(); - buttonClicked = true; - } - if(Clay_Hovered() && io.mouse.leftClick && !buttonClicked) - objSelected = bookmarkItem->obj.get_net_id(); + gui.pop_id(); } - gui.pop_id(); + itemCount++; + if(objInList.isDirectoryOpen) + recursive_gui(io, gui, displayData, objInList.id, itemCount, itemCountToStartAt, itemCountToEndAt, listDepth + 1); } - - itemCount++; - if(bookmarkItem->obj->is_folder() && bookmarkItem->obj->is_folder_open()) - recursive_gui(io, gui, bookmarkItem->obj->get_folder_list(), itemCount, itemCountToStartAt, itemCountToEndAt, listDepth + 1); } - if(toDelete.has_value()) - bookmarkList->erase(bookmarkList, toDelete.value()); } void TreeListing::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command) { diff --git a/src/GUIStuff/Elements/TreeListing.hpp b/src/GUIStuff/Elements/TreeListing.hpp index 5d72805..fcffbe3 100644 --- a/src/GUIStuff/Elements/TreeListing.hpp +++ b/src/GUIStuff/Elements/TreeListing.hpp @@ -1,7 +1,6 @@ #pragma once #include "Element.hpp" -#include "../../Bookmarks/BookmarkListItem.hpp" -#include +#include namespace GUIStuff { @@ -9,10 +8,22 @@ class GUIManager; class TreeListing : public Element { public: - void update(UpdateInputData& io, GUIManager& gui, const NetworkingObjects::NetObjTemporaryPtr>& bookmarkList); + static constexpr float ENTRY_HEIGHT = 25.0f; + struct DisplayData { + struct ObjInList { + NetworkingObjects::NetObjID id; + bool isDirectory = false; + bool isDirectoryOpen = false; + }; + std::function(NetworkingObjects::NetObjID, size_t)> getObjInListAtIndex; + std::function setDirectoryOpen; + std::function drawNonDirectoryObjIconGUI; + std::function drawObjGUI; + }; + void update(UpdateInputData& io, GUIManager& gui, NetworkingObjects::NetObjID rootObjID, const DisplayData& displayData); virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command) override; private: - void recursive_gui(UpdateInputData& io, GUIManager& gui, const NetworkingObjects::NetObjTemporaryPtr>& bookmarkList, size_t& itemCount, size_t itemCountToStartAt, size_t itemCountToEndAt, size_t listDepth); + void recursive_gui(UpdateInputData& io, GUIManager& gui, const DisplayData& displayData, NetworkingObjects::NetObjID objID, size_t& itemCount, size_t itemCountToStartAt, size_t itemCountToEndAt, size_t listDepth); std::optional objSelected; }; diff --git a/src/GUIStuff/GUIManager.cpp b/src/GUIStuff/GUIManager.cpp index 56584ee..1ef32c1 100644 --- a/src/GUIStuff/GUIManager.cpp +++ b/src/GUIStuff/GUIManager.cpp @@ -897,9 +897,9 @@ void GUIManager::list_popup_menu(const std::string& id, Vector2f popupPos, const } } -void GUIManager::tree_listing(const std::string& id, const NetworkingObjects::NetObjTemporaryPtr>& bookmarkList) { +void GUIManager::tree_listing(const std::string& id, NetworkingObjects::NetObjID rootObjID, const TreeListing::DisplayData& displayData) { push_id(id); - insert_element()->update(*io, *this, bookmarkList); + insert_element()->update(*io, *this, rootObjID, displayData); pop_id(); } diff --git a/src/GUIStuff/GUIManager.hpp b/src/GUIStuff/GUIManager.hpp index c15a7f0..31c3e67 100644 --- a/src/GUIStuff/GUIManager.hpp +++ b/src/GUIStuff/GUIManager.hpp @@ -102,7 +102,7 @@ class GUIManager { void paint_circle_popup_menu(const std::string& id, const Vector2f& centerPos, const PaintCircleMenu::Data& val, const std::function& elemUpdate = nullptr); void list_popup_menu(const std::string& id, Vector2f popupPos, const std::function& elemUpdate); - void tree_listing(const std::string& id, const NetworkingObjects::NetObjTemporaryPtr>& bookmarkList); + void tree_listing(const std::string& id, NetworkingObjects::NetObjID rootObjID, const TreeListing::DisplayData& displayData); void obstructing_window(); diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index a88467c..34d0d5f 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -801,7 +801,7 @@ void Toolbar::bookmark_menu(bool justOpened) { }) { gui.obstructing_window(); gui.text_label_centered("Bookmarks"); - gui.tree_listing("bookmark listing", main.world->bMan.bookmarkListRoot->get_folder_list()); + main.world->bMan.setup_list_gui("bookmark menu list"); if(io->mouse.leftClick && !Clay_Hovered() && !justOpened) bookMenu.popupOpen = false; }