Readded bookmark menu
This commit is contained in:
parent
b7bd2efc71
commit
915fbe598b
10 changed files with 711 additions and 813 deletions
|
|
@ -1,284 +1,147 @@
|
|||
#include "TreeListing.hpp"
|
||||
#include "../GUIManager.hpp"
|
||||
#include "Helpers/ConvertVec.hpp"
|
||||
#include <chrono>
|
||||
#include "../../TimePoint.hpp"
|
||||
#include "ScrollArea.hpp"
|
||||
#include "../GUIManager.hpp"
|
||||
|
||||
#include "../ElementHelpers/ScrollAreaHelpers.hpp"
|
||||
#include "../ElementHelpers/ButtonHelpers.hpp"
|
||||
#include "LayoutElement.hpp"
|
||||
|
||||
#define TIME_TO_HOVER_TO_OPEN_DIRECTORY std::chrono::milliseconds(700)
|
||||
|
||||
bool operator<(const GUIStuff::TreeListingObjIndexList& a, const GUIStuff::TreeListingObjIndexList& b) {
|
||||
size_t biggestIndexSize = std::max(a.size(), b.size());
|
||||
for(size_t i = 0; i < biggestIndexSize; i++) {
|
||||
if(i == a.size())
|
||||
return true;
|
||||
else if(i == b.size())
|
||||
return false;
|
||||
else if(a[i] < b[i])
|
||||
return true;
|
||||
else if(a[i] > b[i])
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
using namespace ElementHelpers;
|
||||
|
||||
TreeListing::TreeListing(GUIManager& gui):
|
||||
Element(gui) {}
|
||||
|
||||
void TreeListing::layout(const Clay_ElementId& id, NetworkingObjects::NetObjID rootObjID, const DisplayData& displayData, SelectionData& selectionData) {
|
||||
//auto& io = *gui.io;
|
||||
void TreeListing::layout(const Clay_ElementId& id, const Data& newDisplayData) {
|
||||
d = newDisplayData;
|
||||
|
||||
//if(!io.mouse.leftHeld)
|
||||
// dragHoldSelected = false;
|
||||
flattenedIndexList.clear();
|
||||
recursive_visible_flattened_obj_list(flattenedIndexList, {});
|
||||
|
||||
//selectionData.orderedObjsSelected.clear();
|
||||
//std::optional<ParentObjectIDStack> hoveredObject;
|
||||
CLAY(id, {
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}}
|
||||
}) {
|
||||
scroll_area_many_entries(gui, "scroll", {
|
||||
.entryHeight = ENTRY_HEIGHT,
|
||||
.entryCount = flattenedIndexList.size(),
|
||||
.elementContent = [&](size_t i) {
|
||||
const ObjInfo& objInfo = flattenedIndexList[i];
|
||||
gui.element<LayoutElement>("elem", [&](LayoutElement*, const Clay_ElementId& lId) {
|
||||
SkColor4f backgroundColor;
|
||||
if(d.selectedIndices && d.selectedIndices->contains(flattenedIndexList[i].objIndex))
|
||||
backgroundColor = gui.io.theme->backColor1;
|
||||
else
|
||||
backgroundColor = gui.io.theme->backColor2;
|
||||
|
||||
//CLAY_AUTO_ID({
|
||||
// .layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}}
|
||||
//}) {
|
||||
// Clay_ElementId localID = CLAY_ID_LOCAL("scroll area");
|
||||
// float setScrollAmount;
|
||||
// float setScrollContentHeight;
|
||||
// CLAY(localID, {
|
||||
// .layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}}
|
||||
// }) {
|
||||
// gui.scroll_bar_area("scroll area", true, [&](float scrollContentHeight, float containerHeight, float& scrollAmount) {
|
||||
// setScrollAmount = scrollAmount;
|
||||
// setScrollContentHeight = scrollContentHeight;
|
||||
// size_t itemCount = 0;
|
||||
// size_t itemCountToStartAt = -scrollAmount / ENTRY_HEIGHT;
|
||||
// size_t itemCountToEndAt = (containerHeight - scrollAmount) / ENTRY_HEIGHT;
|
||||
// itemCountToEndAt++;
|
||||
// std::vector<NetworkingObjects::NetObjID> parentIDStack;
|
||||
// CLAY_AUTO_ID({
|
||||
// .layout = {
|
||||
// .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT * itemCountToStartAt)}
|
||||
// }
|
||||
// }) {}
|
||||
// recursive_gui(io, gui, displayData, selectionData, rootObjID, itemCount, itemCountToStartAt, itemCountToEndAt, 0, hoveredObject, parentIDStack, false);
|
||||
// if(itemCount > itemCountToEndAt) {
|
||||
// CLAY_AUTO_ID({
|
||||
// .layout = {
|
||||
// .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT * (itemCount - itemCountToEndAt))}
|
||||
// }
|
||||
// }) {}
|
||||
// }
|
||||
// }, false);
|
||||
// }
|
||||
// Clay_ElementData scrollAreaBB = Clay_GetElementData(localID);
|
||||
// if(scrollAreaBB.found) {
|
||||
// // Clamp by fabs(scrollcontentheight - 3), small offset is added to account for error (when youre at the very edge it might assume youre at the top of an element)
|
||||
// float mouseRelativeYPos = std::clamp(std::fabs(io.mouse.pos.y() - scrollAreaBB.boundingBox.y - setScrollAmount), 0.0f, std::fabs(setScrollContentHeight - 3.0f));
|
||||
// topHalfOfHovered = std::fmod(mouseRelativeYPos, ENTRY_HEIGHT) < (ENTRY_HEIGHT / 2.0f);
|
||||
// }
|
||||
//}
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(backgroundColor)
|
||||
}) {
|
||||
if(objInfo.objIndex.size() > 1) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_FIXED((objInfo.objIndex.size() - 1) * ICON_SIZE), .height = CLAY_SIZING_GROW(0)}}
|
||||
}) {}
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_FIXED(ICON_SIZE), .height = CLAY_SIZING_FIXED(ICON_SIZE)}}
|
||||
}) {
|
||||
if(!objInfo.isDirectory)
|
||||
d.drawNonDirectoryObjIconGUI(objInfo.objIndex);
|
||||
else {
|
||||
gui.set_z_index_keep_clipping_region(gui.get_z_index() + 1, [&] {
|
||||
svg_icon_button(gui, "open dir button", objInfo.isOpen ? "data/icons/droparrow.svg" : "data/icons/droparrowclose.svg", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.size = ICON_SIZE,
|
||||
.onClick = [&] {
|
||||
d.setDirectoryOpen(objInfo.objIndex, !objInfo.isOpen);
|
||||
if(d.selectedIndices) {
|
||||
d.selectedIndices->clear();
|
||||
if(d.onSelectChange) d.onSelectChange();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
d.drawObjGUI(objInfo.objIndex);
|
||||
}
|
||||
}, LayoutElement::Callbacks {
|
||||
.mouseButton = [&, i] (LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(l->mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) {
|
||||
gui.set_post_callback_func([&]{
|
||||
auto& objIndex = flattenedIndexList[i].objIndex;
|
||||
if(d.selectedIndices) {
|
||||
auto it = d.selectedIndices->find(objIndex);
|
||||
bool wasSelected = it != d.selectedIndices->end();
|
||||
|
||||
//// Any objects that were part of a collapsed directory will be unselected
|
||||
//selectionData.objsSelected.clear();
|
||||
//for(auto& [parent, object] : selectionData.orderedObjsSelected)
|
||||
// selectionData.objsSelected.emplace(object);
|
||||
|
||||
//if(objDragged.has_value()) {
|
||||
// if(hoveredObject.has_value() && !selectionData.objsSelected.contains(hoveredObject.value().object) && (std::chrono::steady_clock::now() - timeStartedHoveringOverObject) >= TIME_TO_HOVER_TO_OPEN_DIRECTORY) {
|
||||
// ParentObjectIDStack& hoveredObjVal = hoveredObject.value();
|
||||
// size_t hoveredObjIndex = displayData.getIndexOfObjInList({hoveredObjVal.parents.back(), hoveredObjVal.object});
|
||||
// std::optional<DisplayData::ObjInList> objHoveringOver = displayData.getObjInListAtIndex(hoveredObjVal.parents.back(), hoveredObjIndex);
|
||||
// if(objHoveringOver.value().isDirectory && !objHoveringOver.value().isDirectoryOpen)
|
||||
// displayData.setDirectoryOpen(hoveredObjVal.object, true);
|
||||
// }
|
||||
|
||||
// ParentObjectIDPair& objDraggedVal = objDragged.value();
|
||||
// if(!selectionData.objsSelected.contains(objDraggedVal.object))
|
||||
// objDragged = std::nullopt;
|
||||
// else if(!io.mouse.leftHeld) {
|
||||
// if(!hoveredObject.has_value())
|
||||
// set_single_selected_object(selectionData);
|
||||
// else {
|
||||
// ParentObjectIDStack hoveredObjValToUse = hoveredObject.value(); // By value since it'll be edited
|
||||
// size_t indexToMoveFrom = displayData.getIndexOfObjInList(objDraggedVal);
|
||||
// size_t indexToMoveTo = displayData.getIndexOfObjInList({hoveredObjValToUse.parents.back(), hoveredObjValToUse.object});
|
||||
// std::optional<DisplayData::ObjInList> objHoveringOver = displayData.getObjInListAtIndex(hoveredObjValToUse.parents.back(), indexToMoveTo);
|
||||
// if(objHoveringOver.value().isDirectoryOpen && !topHalfOfHovered) { // Move to front of the directory object
|
||||
// hoveredObjValToUse.parents.emplace_back(hoveredObjValToUse.object);
|
||||
// indexToMoveTo = 0;
|
||||
// }
|
||||
// else if(!topHalfOfHovered)
|
||||
// indexToMoveTo++;
|
||||
// if((indexToMoveFrom == indexToMoveTo || (indexToMoveFrom + 1) == indexToMoveTo) && objDraggedVal.parent == hoveredObjValToUse.parents.back())
|
||||
// set_single_selected_object(selectionData);
|
||||
// else {
|
||||
// bool wrongMovement = false;
|
||||
// // Check if object is about to move into itself
|
||||
// for(const NetworkingObjects::NetObjID& parent : hoveredObjValToUse.parents) {
|
||||
// if(selectionData.objsSelected.contains(parent)) {
|
||||
// wrongMovement = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if(!wrongMovement) {
|
||||
// displayData.moveObjectsToListAtIndex(hoveredObjValToUse.parents.back(), indexToMoveTo, selectionData.orderedObjsSelected);
|
||||
// selectionData.objsSelected.clear();
|
||||
// selectionData.orderedObjsSelected.clear();
|
||||
// }
|
||||
// else
|
||||
// set_single_selected_object(selectionData);
|
||||
// }
|
||||
// }
|
||||
// objDragged = std::nullopt;
|
||||
// }
|
||||
//}
|
||||
|
||||
//oldHoveredObject = hoveredObject;
|
||||
if(gui.io.input->key(InputManager::KEY_GENERIC_LSHIFT).held) {
|
||||
if(!wasSelected) {
|
||||
d.selectedIndices->emplace(objIndex);
|
||||
if(d.onSelectChange) d.onSelectChange();
|
||||
}
|
||||
}
|
||||
else if(gui.io.input->key(InputManager::KEY_GENERIC_LCTRL).held) {
|
||||
if(!wasSelected)
|
||||
d.selectedIndices->emplace(objIndex);
|
||||
else
|
||||
d.selectedIndices->erase(it);
|
||||
if(d.onSelectChange) d.onSelectChange();
|
||||
}
|
||||
else if(!wasSelected || d.selectedIndices->size() != 1) {
|
||||
d.selectedIndices->clear();
|
||||
d.selectedIndices->emplace(objIndex);
|
||||
if(d.onSelectChange) d.onSelectChange();
|
||||
}
|
||||
else if(button.clicks == 2)
|
||||
if(d.onDoubleClick) d.onDoubleClick(objIndex);
|
||||
}
|
||||
else if(button.clicks == 2)
|
||||
if(d.onDoubleClick) d.onDoubleClick(objIndex);
|
||||
});
|
||||
gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void TreeListing::set_single_selected_object(SelectionData& selectionData) {
|
||||
//selectionData.objsSelected.clear();
|
||||
//selectionData.orderedObjsSelected.clear();
|
||||
//selectionData.objsSelected.emplace(objDragged.value().object);
|
||||
//selectionData.orderedObjsSelected.emplace_back(objDragged.value());
|
||||
}
|
||||
|
||||
void TreeListing::recursive_gui(UpdateInputData& io, GUIManager& gui, const DisplayData& displayData, SelectionData& selectionData, NetworkingObjects::NetObjID objID, size_t& itemCount, size_t itemCountToStartAt, size_t itemCountToEndAt, size_t listDepth, std::optional<ParentObjectIDStack>& hoveredObject, std::vector<NetworkingObjects::NetObjID>& parentIDStack, bool parentJustSelected) {
|
||||
//parentIDStack.emplace_back(objID);
|
||||
//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();
|
||||
// bool selfJustSelected = false;
|
||||
// if(itemCount >= itemCountToStartAt && itemCount < itemCountToEndAt) {
|
||||
// gui.push_id(itemCount);
|
||||
// bool buttonClicked = false;
|
||||
// uint16_t topOutlineWidth = 0;
|
||||
// uint16_t bottomOutlineWidth = 0;
|
||||
|
||||
// bool isOldHoveredObject = oldHoveredObject.has_value() && oldHoveredObject.value().object == objInList.id;
|
||||
// SkColor4f backgroundColor;
|
||||
// if(selectionData.objsSelected.contains(objInList.id))
|
||||
// backgroundColor = io.theme->backColor1;
|
||||
// else if(isOldHoveredObject && objInList.isDirectory && !objInList.isDirectoryOpen && objDragged.has_value())
|
||||
// backgroundColor = lerp_vec(io.theme->backColor2, io.theme->fillColor1, std::clamp(std::chrono::duration<float, std::chrono::milliseconds::period>(std::chrono::steady_clock::now() - timeStartedHoveringOverObject) / TIME_TO_HOVER_TO_OPEN_DIRECTORY, 0.0f, 1.0f));
|
||||
// else
|
||||
// backgroundColor = io.theme->backColor2;
|
||||
|
||||
// if(oldHoveredObject.has_value() && oldHoveredObject.value().object == objInList.id) {
|
||||
// if(objDragged.has_value()) {
|
||||
// ParentObjectIDPair& objDraggedVal = objDragged.value();
|
||||
// if(objDraggedVal.object != objInList.id) {
|
||||
// if(topHalfOfHovered)
|
||||
// topOutlineWidth = 1;
|
||||
// else
|
||||
// bottomOutlineWidth = 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// 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>(backgroundColor)
|
||||
// }) {
|
||||
// if(listDepth != 0) {
|
||||
// CLAY_AUTO_ID({
|
||||
// .layout = {
|
||||
// .sizing = {.width = CLAY_SIZING_FIXED(ENTRY_HEIGHT * listDepth), .height = CLAY_SIZING_FIXED(ENTRY_HEIGHT)}
|
||||
// },
|
||||
// }) {}
|
||||
// }
|
||||
// CLAY_AUTO_ID({
|
||||
// .layout = {
|
||||
// .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}
|
||||
// },
|
||||
// .border = {
|
||||
// .color = convert_vec4<Clay_Color>(io.theme->frontColor1),
|
||||
// .width = {
|
||||
// .left = 0,
|
||||
// .right = 0,
|
||||
// .top = topOutlineWidth,
|
||||
// .bottom = bottomOutlineWidth,
|
||||
// .betweenChildren = 0
|
||||
// }
|
||||
// }
|
||||
// }) {
|
||||
// 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()) {
|
||||
// hoveredObject = {parentIDStack, objInList.id};
|
||||
// if(!isOldHoveredObject)
|
||||
// timeStartedHoveringOverObject = std::chrono::steady_clock::now();
|
||||
// if(io.mouse.leftClick && !buttonClicked && !parentJustSelected) {
|
||||
// if(io.key.leftShift)
|
||||
// dragHoldSelected = true;
|
||||
// else if(io.key.leftCtrl) {
|
||||
// bool alreadySelected = selectionData.objsSelected.contains(objInList.id);
|
||||
// if(alreadySelected)
|
||||
// selectionData.objsSelected.erase(objInList.id);
|
||||
// else {
|
||||
// select_and_unselect_parents(parentIDStack, objInList.id, selectionData);
|
||||
// selfJustSelected = true;
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// if(!selectionData.objsSelected.contains(objInList.id)) {
|
||||
// selectionData.objsSelected.clear();
|
||||
// selectionData.orderedObjsSelected.clear();
|
||||
// selectionData.objsSelected.emplace(objInList.id);
|
||||
// selfJustSelected = true;
|
||||
// }
|
||||
// objDragged = {objID, objInList.id};
|
||||
// }
|
||||
// }
|
||||
// if(io.key.leftShift && dragHoldSelected && !parentJustSelected) {
|
||||
// select_and_unselect_parents(parentIDStack, objInList.id, selectionData);
|
||||
// selfJustSelected = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// gui.pop_id();
|
||||
// }
|
||||
// if(!parentJustSelected) {
|
||||
// if(selectionData.objsSelected.contains(objInList.id))
|
||||
// selectionData.orderedObjsSelected.emplace_back(objID, objInList.id);
|
||||
// }
|
||||
// else
|
||||
// unselect_object(objInList.id, selectionData);
|
||||
// itemCount++;
|
||||
// if(objInList.isDirectoryOpen)
|
||||
// recursive_gui(io, gui, displayData, selectionData, objInList.id, itemCount, itemCountToStartAt, itemCountToEndAt, listDepth + 1, hoveredObject, parentIDStack, selfJustSelected | parentJustSelected);
|
||||
// }
|
||||
//}
|
||||
//parentIDStack.pop_back();
|
||||
}
|
||||
|
||||
void TreeListing::unselect_object(NetworkingObjects::NetObjID id, SelectionData& selectionData) {
|
||||
//selectionData.objsSelected.erase(id);
|
||||
//std::erase_if(selectionData.orderedObjsSelected, [&id](const auto& p) {
|
||||
// return p.object == id;
|
||||
//});
|
||||
}
|
||||
|
||||
void TreeListing::select_and_unselect_parents(const std::vector<NetworkingObjects::NetObjID>& parentIDStack, NetworkingObjects::NetObjID newSelectedObj, SelectionData& selectionData) {
|
||||
//for(const NetworkingObjects::NetObjID& parent : parentIDStack) {
|
||||
// if(selectionData.objsSelected.contains(parent)) {
|
||||
// unselect_object(parent, selectionData);
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
//selectionData.objsSelected.emplace(newSelectedObj);
|
||||
void TreeListing::recursive_visible_flattened_obj_list(std::vector<ObjInfo>& objs, const TreeListingObjIndexList& objIndex) {
|
||||
std::optional<DirectoryInfo> dirInfo = d.dirInfo(objIndex);
|
||||
bool isRoot = objIndex.empty();
|
||||
if(!isRoot)
|
||||
objs.emplace_back(objIndex, dirInfo.has_value(), dirInfo.has_value() ? dirInfo.value().isOpen : false);
|
||||
if(dirInfo.has_value() && (dirInfo.value().isOpen || isRoot)) {
|
||||
TreeListingObjIndexList childObjIndex = objIndex;
|
||||
childObjIndex.emplace_back();
|
||||
for(size_t i = 0; i < dirInfo.value().dirSize; i++) {
|
||||
childObjIndex.back() = i;
|
||||
recursive_visible_flattened_obj_list(objs, childObjIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
#pragma once
|
||||
#include "Element.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjID.hpp>
|
||||
#include <set>
|
||||
|
||||
namespace GUIStuff {
|
||||
typedef std::vector<size_t> TreeListingObjIndexList;
|
||||
}
|
||||
|
||||
bool operator<(const GUIStuff::TreeListingObjIndexList& a, const GUIStuff::TreeListingObjIndexList& b);
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
|
|
@ -9,54 +16,37 @@ class GUIManager;
|
|||
class TreeListing : public Element {
|
||||
public:
|
||||
static constexpr float ENTRY_HEIGHT = 25.0f;
|
||||
static constexpr float ICON_SIZE = 25.0f;
|
||||
|
||||
struct ParentObjectIDPair {
|
||||
NetworkingObjects::NetObjID parent;
|
||||
NetworkingObjects::NetObjID object;
|
||||
bool operator==(const ParentObjectIDPair&) const = default;
|
||||
struct ObjInfo {
|
||||
TreeListingObjIndexList objIndex;
|
||||
bool isDirectory = false;
|
||||
bool isOpen = false;
|
||||
};
|
||||
|
||||
struct ParentObjectIDStack {
|
||||
std::vector<NetworkingObjects::NetObjID> parents;
|
||||
NetworkingObjects::NetObjID object;
|
||||
struct DirectoryInfo {
|
||||
size_t dirSize;
|
||||
bool isOpen;
|
||||
};
|
||||
|
||||
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<size_t(const ParentObjectIDPair&)> getIndexOfObjInList;
|
||||
std::function<void(NetworkingObjects::NetObjID, bool)> setDirectoryOpen;
|
||||
std::function<bool(NetworkingObjects::NetObjID)> drawNonDirectoryObjIconGUI;
|
||||
std::function<bool(const ParentObjectIDPair&)> drawObjGUI;
|
||||
std::function<void(NetworkingObjects::NetObjID, size_t, const std::vector<ParentObjectIDPair>&)> moveObjectsToListAtIndex;
|
||||
};
|
||||
|
||||
struct SelectionData {
|
||||
std::vector<ParentObjectIDPair> orderedObjsSelected;
|
||||
std::unordered_set<NetworkingObjects::NetObjID> objsSelected;
|
||||
struct Data {
|
||||
std::set<TreeListingObjIndexList>* selectedIndices = nullptr;
|
||||
std::function<std::optional<DirectoryInfo>(const TreeListingObjIndexList& objIndex)> dirInfo;
|
||||
std::function<void(const TreeListingObjIndexList& objIndex, bool isOpen)> setDirectoryOpen;
|
||||
std::function<void(const TreeListingObjIndexList& objIndex)> drawNonDirectoryObjIconGUI;
|
||||
std::function<void(const TreeListingObjIndexList& objIndex)> drawObjGUI;
|
||||
std::function<void(const TreeListingObjIndexList& objIndex)> onDoubleClick;
|
||||
std::function<void()> onSelectChange;
|
||||
std::function<void(const std::vector<TreeListingObjIndexList>& objIndices, const TreeListingObjIndexList& newObjIndex)> moveObj;
|
||||
};
|
||||
|
||||
TreeListing(GUIManager& gui);
|
||||
void layout(const Clay_ElementId& id, NetworkingObjects::NetObjID rootObjID, const DisplayData& displayData, SelectionData& selectionData);
|
||||
void layout(const Clay_ElementId& id, const Data& newDisplayData);
|
||||
private:
|
||||
bool dragHoldSelected = false;
|
||||
void recursive_visible_flattened_obj_list(std::vector<ObjInfo>& objs, const TreeListingObjIndexList& objIndex);
|
||||
|
||||
void set_single_selected_object(SelectionData& selectionData);
|
||||
|
||||
void recursive_gui(UpdateInputData& io, GUIManager& gui, const DisplayData& displayData, SelectionData& selectionData, NetworkingObjects::NetObjID objID, size_t& itemCount, size_t itemCountToStartAt, size_t itemCountToEndAt, size_t listDepth, std::optional<ParentObjectIDStack>& hoveredObject, std::vector<NetworkingObjects::NetObjID>& parentIDStack, bool parentJustSelected);
|
||||
|
||||
void select_and_unselect_parents(const std::vector<NetworkingObjects::NetObjID>& parentIDStack, NetworkingObjects::NetObjID newSelectedObj, SelectionData& selectionData);
|
||||
|
||||
void unselect_object(NetworkingObjects::NetObjID id, SelectionData& selectionData);
|
||||
|
||||
bool topHalfOfHovered = false;
|
||||
std::optional<ParentObjectIDPair> objDragged;
|
||||
std::optional<ParentObjectIDStack> oldHoveredObject;
|
||||
std::chrono::steady_clock::time_point timeStartedHoveringOverObject;
|
||||
std::vector<ObjInfo> flattenedIndexList;
|
||||
Data d;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue