From 4fe554933c2acd1d0dd8847068f433beead44fdf Mon Sep 17 00:00:00 2001 From: Michael Alexsander Date: Thu, 10 Dec 2020 09:32:02 -0300 Subject: [PATCH] Allow to circle back in 'PopupMenu' even if the first/last item is non-selectable (cherry picked from commit bb39088201c721d60d97bdd48a3062da7320b078) --- scene/gui/popup_menu.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 997307f1daa..d368019a3f8 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -221,6 +221,7 @@ void PopupMenu::_gui_input(const Ref &p_event) { if (search_from >= items.size()) search_from = 0; + bool match_found = false; for (int i = search_from; i < items.size(); i++) { if (i < 0 || i >= items.size()) @@ -232,15 +233,30 @@ void PopupMenu::_gui_input(const Ref &p_event) { emit_signal("id_focused", i); update(); accept_event(); + match_found = true; break; } } + + if (!match_found) { + // If the last item is not selectable, try re-searching from the start. + for (int i = 0; i < search_from; i++) { + if (!items[i].separator && !items[i].disabled) { + mouse_over = i; + emit_signal("id_focused", i); + update(); + accept_event(); + break; + } + } + } } else if (p_event->is_action("ui_up") && p_event->is_pressed()) { int search_from = mouse_over - 1; if (search_from < 0) search_from = items.size() - 1; + bool match_found = false; for (int i = search_from; i >= 0; i--) { if (i >= items.size()) @@ -252,9 +268,23 @@ void PopupMenu::_gui_input(const Ref &p_event) { emit_signal("id_focused", i); update(); accept_event(); + match_found = true; break; } } + + if (!match_found) { + // If the first item is not selectable, try re-searching from the end. + for (int i = items.size() - 1; i >= search_from; i--) { + if (!items[i].separator && !items[i].disabled) { + mouse_over = i; + emit_signal("id_focused", i); + update(); + accept_event(); + break; + } + } + } } else if (p_event->is_action("ui_left") && p_event->is_pressed()) { Node *n = get_parent();