From 54b354573666bb9ff990e551b584f7aefb90887b Mon Sep 17 00:00:00 2001 From: gymnast86 Date: Tue, 16 Jun 2026 05:14:32 -0400 Subject: [PATCH] properly refocus child element after deleting a seed --- src/dusk/ui/pane.cpp | 38 ++++++++++++++++++++++++++++++++++++ src/dusk/ui/pane.hpp | 7 +++++++ src/dusk/ui/rando_config.cpp | 37 +++++++++-------------------------- 3 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/dusk/ui/pane.cpp b/src/dusk/ui/pane.cpp index bed8abfe02..902ffbd2ca 100644 --- a/src/dusk/ui/pane.cpp +++ b/src/dusk/ui/pane.cpp @@ -202,4 +202,42 @@ void Pane::clear() { finalized = false; } +float Pane::get_focused_child_y() { + float childToFocusY = -1.f; + for (const auto& child : children()) { + if (child->root()->IsPseudoClassSet("focus")) { + childToFocusY = child->root()->GetAbsoluteTop(); + } + } + return childToFocusY; +} + +// Focuses the child closest to the given y position +bool Pane::focus_closest_child(float posY) { + Rml::Element* closestchild = nullptr; + // If the y-pos is less than 0, focus the middle child + if (posY < 0.f && !children().empty()) { + closestchild = children().at(children().size() / 2)->root(); + // Otherwise, choose the closest one + } else if (posY >= 0.f) { + float closestRightChildDistance = std::numeric_limits::max(); + for (const auto& child : children()) { + float distance = std::abs(posY - child->root()->GetAbsoluteTop()); + if (distance < closestRightChildDistance) { + closestchild = child->root(); + closestRightChildDistance = distance; + } + } + } + + // If we found a child, focus it + if (closestchild) { + closestchild->SetPseudoClass("focus-visible", true); + closestchild->Focus(); + return true; + } + + return false; +} + } // namespace dusk::ui diff --git a/src/dusk/ui/pane.hpp b/src/dusk/ui/pane.hpp index e63c984f39..d21b2ce68d 100644 --- a/src/dusk/ui/pane.hpp +++ b/src/dusk/ui/pane.hpp @@ -34,6 +34,13 @@ public: void finalize(); void clear(); + // Returns the y-position of the first focused child + float get_focused_child_y(); + + // Focuses the child closest to the given y position + // Returns true if a child was focused, false otherwise + bool focus_closest_child(float posY); + private: Type mType; bool mBottomSpacer = true; diff --git a/src/dusk/ui/rando_config.cpp b/src/dusk/ui/rando_config.cpp index 2d2da61b2c..dd872bcc3a 100644 --- a/src/dusk/ui/rando_config.cpp +++ b/src/dusk/ui/rando_config.cpp @@ -652,39 +652,17 @@ void RandomizerWindow::rando_excluded_locations_update_left_pane(Pane& innerLeft // Focus the closest child in the next Pane. Returns true if a child was found to focus bool focus_closest_child_on_next_pane(Pane& currentPane, Pane& nextPane) { - float childToFocusY = 0.f; - for (const auto& child : currentPane.children()) { - if (child->root()->IsPseudoClassSet("focus")) { - childToFocusY = child->root()->GetAbsoluteTop(); - } - } - Rml::Element* closestchild = nullptr; - // If there was no focused child in this pane, select the middle one of the next pane - if (childToFocusY == 0.f && !nextPane.children().empty()) { - closestchild = nextPane.children().at(nextPane.children().size() / 2)->root(); - // Otherwise, choose the closest one - } else if (childToFocusY > 0.f) { - float closestRightChildDistance = 100000.f; - for (const auto& child : nextPane.children()) { - float distance = std::abs(childToFocusY - child->root()->GetAbsoluteTop()); - if (distance < closestRightChildDistance) { - closestchild = child->root(); - closestRightChildDistance = distance; - } - } - } + auto childToFocusY = currentPane.get_focused_child_y(); + return nextPane.focus_closest_child(childToFocusY); - if (closestchild) { - closestchild->SetPseudoClass("focus-visible", true); - closestchild->Focus(); - return true; - } - - return false; } void delete_seed_callback(Pane& pane) { + + // Get the Y position to focus the child nearest to after we rebuild this pane + auto childToFocusY = pane.get_focused_child_y(); + pane.clear(); std::filesystem::path seedDirectory = GetRandomizerSeedsPath(); @@ -724,6 +702,9 @@ void delete_seed_callback(Pane& pane) { }); } } + + // Refocus the closest child to the seed we just deleted + pane.focus_closest_child(childToFocusY); }; RandomizerWindow::RandomizerWindow(dFile_select_c* fileSelect /*= nullptr*/) : mFileSelectMenu(fileSelect) {