Made tree listing more generic

This commit is contained in:
Yousef Khadadeh 2025-12-21 00:33:04 +03:00
parent 180c930474
commit 86063f373b
7 changed files with 129 additions and 64 deletions

View file

@ -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<NetworkingObjects::NetObjOrderedList<BookmarkListItem>>& 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<NetworkingObjects::NetObjOrderedList<BookmarkListItem>>& bookmarkList, size_t& itemCount, size_t itemCountToStartAt, size_t itemCountToEndAt, size_t listDepth) {
std::optional<NetworkingObjects::NetObjID> 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<Clay_Color>((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<DisplayData::ObjInList> 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<Clay_Color>((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) {

View file

@ -1,7 +1,6 @@
#pragma once
#include "Element.hpp"
#include "../../Bookmarks/BookmarkListItem.hpp"
#include <Helpers/NetworkingObjects/NetObjOrderedList.hpp>
#include <Helpers/NetworkingObjects/NetObjID.hpp>
namespace GUIStuff {
@ -9,10 +8,22 @@ class GUIManager;
class TreeListing : public Element {
public:
void update(UpdateInputData& io, GUIManager& gui, const NetworkingObjects::NetObjTemporaryPtr<NetworkingObjects::NetObjOrderedList<BookmarkListItem>>& bookmarkList);
static constexpr float ENTRY_HEIGHT = 25.0f;
struct DisplayData {
struct ObjInList {
NetworkingObjects::NetObjID id;
bool isDirectory = false;
bool isDirectoryOpen = false;
};
std::function<std::optional<ObjInList>(NetworkingObjects::NetObjID, size_t)> getObjInListAtIndex;
std::function<void(NetworkingObjects::NetObjID, bool)> setDirectoryOpen;
std::function<bool(NetworkingObjects::NetObjID)> drawNonDirectoryObjIconGUI;
std::function<bool(NetworkingObjects::NetObjID, NetworkingObjects::NetObjID)> 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<NetworkingObjects::NetObjOrderedList<BookmarkListItem>>& 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<NetworkingObjects::NetObjID> objSelected;
};