From f0d380c9fd7e285b4ea0bb1dd334ef4bed3422f5 Mon Sep 17 00:00:00 2001 From: Michael Alexsander Date: Sat, 27 Aug 2022 18:26:31 -0300 Subject: [PATCH] Fix crash when pressing up on an empty `PopupMenu` --- scene/gui/popup_menu.cpp | 126 ++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 96f5ad5a187..9e9cfe15574 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -223,93 +223,95 @@ void PopupMenu::_scroll(float p_factor, const Point2 &p_over) { void PopupMenu::_gui_input(const Ref &p_event) { ERR_FAIL_COND(p_event.is_null()); - if (p_event->is_action("ui_down") && p_event->is_pressed()) { - int search_from = mouse_over + 1; - 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()) { - continue; + if (!items.empty()) { + if (p_event->is_action("ui_down") && p_event->is_pressed()) { + int search_from = mouse_over + 1; + if (search_from >= items.size()) { + search_from = 0; } - if (!items[i].separator && !items[i].disabled) { - mouse_over = i; - emit_signal("id_focused", i); - update(); - accept_event(); - match_found = true; - break; - } - } + bool match_found = false; + for (int i = search_from; i < items.size(); i++) { + if (i < 0 || i >= items.size()) { + continue; + } - 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(); + match_found = true; 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()) { - continue; + 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; } - if (!items[i].separator && !items[i].disabled) { - mouse_over = i; - emit_signal("id_focused", i); - update(); - accept_event(); - match_found = true; - break; - } - } + bool match_found = false; + for (int i = search_from; i >= 0; i--) { + if (i >= items.size()) { + continue; + } - 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(); + match_found = true; break; } } - } - } else if (p_event->is_action("ui_left") && p_event->is_pressed()) { - Node *n = get_parent(); - if (n && Object::cast_to(n)) { - hide(); - accept_event(); - } - } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { - if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && items[mouse_over].submenu != "" && submenu_over != mouse_over) { - _activate_submenu(mouse_over, true); - accept_event(); - } - } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { - if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) { - if (items[mouse_over].submenu != "" && submenu_over != mouse_over) { + + 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(); + if (n && Object::cast_to(n)) { + hide(); + accept_event(); + } + } else if (p_event->is_action("ui_right") && p_event->is_pressed()) { + if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && items[mouse_over].submenu != "" && submenu_over != mouse_over) { _activate_submenu(mouse_over, true); - } else { - activate_item(mouse_over); + accept_event(); + } + } else if (p_event->is_action("ui_accept") && p_event->is_pressed()) { + if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) { + if (items[mouse_over].submenu != "" && submenu_over != mouse_over) { + _activate_submenu(mouse_over, true); + } else { + activate_item(mouse_over); + } + accept_event(); } - accept_event(); } }