Fixed issues with tree listing element

This commit is contained in:
Yousef Khadadeh 2026-04-07 14:35:34 +03:00
parent c97266769b
commit 267a66dd32
3 changed files with 67 additions and 40 deletions

View file

@ -443,7 +443,7 @@ NetworkingObjects::NetObjOrderedListIterator<BookmarkListItem> BookmarkManager::
}
void BookmarkManager::remove_bookmark(const GUIStuff::TreeListingObjIndexList& objIndex) {
editing_bookmark_check();
refresh_gui_data();
class DeleteBookmarkWorldUndoAction : public WorldUndoAction {
public:

View file

@ -66,57 +66,65 @@ void TreeListing::layout(const Clay_ElementId& id, const Data& newDisplayData) {
else
backgroundColor = gui.io.theme->backColor2;
uint16_t borderWidth = (isDragging && i == dragIndexEnd && dragIndexStart != dragIndexEnd) ? 1 : 0;
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),
.border = {
.color = convert_vec4<Clay_Color>(gui.io.theme->frontColor1),
.width = {
.left = 0,
.right = 0,
.top = borderWidth,
.bottom = 0,
.betweenChildren = 0
}
}
.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)}}
}) {}
}
uint16_t topBorderWidth = (isDragging && dragFromTop && i == dragIndexEnd && dragIndexStart != dragIndexEnd) ? 1 : 0;
uint16_t bottomBorderWidth = (isDragging && !dragFromTop && i == dragIndexEnd && dragIndexStart != dragIndexEnd) ? 1 : 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();
}
}
});
});
.layout = {
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}
},
.border = {
.color = convert_vec4<Clay_Color>(gui.io.theme->frontColor1),
.width = {
.left = 0,
.right = 0,
.top = topBorderWidth,
.bottom = bottomBorderWidth,
.betweenChildren = 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);
}
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([&, i, buttonClicks = button.clicks]{
gui.set_post_callback_func([&, i, button, l]{
auto& objIndex = flattenedIndexList[i].objIndex;
if(d.selectedIndices) {
auto it = d.selectedIndices->find(objIndex);
@ -135,11 +143,11 @@ void TreeListing::layout(const Clay_ElementId& id, const Data& newDisplayData) {
d.selectedIndices->erase(it);
if(d.onSelectChange) d.onSelectChange();
}
else if(buttonClicks == 2) {
else if(button.clicks == 2) {
if(d.onDoubleClick) d.onDoubleClick(objIndex);
}
else {
if(buttonClicks == 2 && d.onDoubleClick) d.onDoubleClick(objIndex);
if(button.clicks == 2 && d.onDoubleClick) d.onDoubleClick(objIndex);
if(!wasSelected) {
d.selectedIndices->clear();
d.selectedIndices->emplace(objIndex);
@ -147,18 +155,24 @@ void TreeListing::layout(const Clay_ElementId& id, const Data& newDisplayData) {
}
isDragging = true;
dragIndexStart = dragIndexEnd = i;
dragFromTop = button.pos.y() - l->get_bb().value().min.y() < ENTRY_HEIGHT * 0.5f;
}
}
else if(buttonClicks == 2)
else if(button.clicks == 2)
if(d.onDoubleClick) d.onDoubleClick(objIndex);
});
gui.set_to_layout();
}
},
.mouseMotion = [&, i] (LayoutElement* l, const InputManager::MouseMotionCallbackArgs& motion) {
if(isDragging && l->mouseHovering && dragIndexEnd != i) {
dragIndexEnd = i;
gui.set_to_layout();
if(isDragging && l->mouseHovering) {
size_t newDragIndexEnd = i;
bool newDragFromTop = motion.pos.y() - l->get_bb().value().min.y() < ENTRY_HEIGHT * 0.5f;
if(dragIndexEnd != newDragIndexEnd || dragFromTop != newDragFromTop) {
dragIndexEnd = newDragIndexEnd;
dragFromTop = newDragFromTop;
gui.set_to_layout();
}
}
}
});
@ -194,6 +208,18 @@ void TreeListing::layout(const Clay_ElementId& id, const Data& newDisplayData) {
void TreeListing::move_selected_objects() {
if(d.selectedIndices && dragIndexEnd < flattenedIndexList.size()) {
TreeListingObjIndexList objIndexToMoveTo = flattenedIndexList[dragIndexEnd].objIndex;
if(!dragFromTop) {
if(flattenedIndexList[dragIndexEnd].isOpen) // Drag into open directory
objIndexToMoveTo.emplace_back(0);
else {
objIndexToMoveTo.back() += 1;
if(dragIndexStart < flattenedIndexList.size()) {
if(objIndexToMoveTo == flattenedIndexList[dragIndexStart].objIndex)
objIndexToMoveTo.back() += 1;
}
}
}
// Check if object is about to move into itself (wrong movement)
bool wrongMovement = false;
for(const TreeListingObjIndexList& o : *d.selectedIndices) {

View file

@ -51,6 +51,7 @@ class TreeListing : public Element {
bool isDragging = false;
size_t dragIndexStart;
size_t dragIndexEnd;
bool dragFromTop;
std::vector<ObjInfo> flattenedIndexList;
Data d;