Browse Source

Allow to circle back in 'PopupMenu' even if the first/last item is non-selectable

Michael Alexsander 4 years ago
parent
commit
bb39088201
1 changed files with 32 additions and 0 deletions
  1. 32 0
      scene/gui/popup_menu.cpp

+ 32 - 0
scene/gui/popup_menu.cpp

@@ -238,6 +238,7 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
 			search_from = 0;
 			search_from = 0;
 		}
 		}
 
 
+		bool match_found = false;
 		for (int i = search_from; i < items.size(); i++) {
 		for (int i = search_from; i < items.size(); i++) {
 			if (!items[i].separator && !items[i].disabled) {
 			if (!items[i].separator && !items[i].disabled) {
 				mouse_over = i;
 				mouse_over = i;
@@ -245,15 +246,31 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
 				_scroll_to_item(i);
 				_scroll_to_item(i);
 				control->update();
 				control->update();
 				set_input_as_handled();
 				set_input_as_handled();
+				match_found = true;
 				break;
 				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);
+					_scroll_to_item(i);
+					control->update();
+					set_input_as_handled();
+					break;
+				}
+			}
+		}
 	} else if (p_event->is_action("ui_up") && p_event->is_pressed()) {
 	} else if (p_event->is_action("ui_up") && p_event->is_pressed()) {
 		int search_from = mouse_over - 1;
 		int search_from = mouse_over - 1;
 		if (search_from < 0) {
 		if (search_from < 0) {
 			search_from = items.size() - 1;
 			search_from = items.size() - 1;
 		}
 		}
 
 
+		bool match_found = false;
 		for (int i = search_from; i >= 0; i--) {
 		for (int i = search_from; i >= 0; i--) {
 			if (!items[i].separator && !items[i].disabled) {
 			if (!items[i].separator && !items[i].disabled) {
 				mouse_over = i;
 				mouse_over = i;
@@ -261,9 +278,24 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
 				_scroll_to_item(i);
 				_scroll_to_item(i);
 				control->update();
 				control->update();
 				set_input_as_handled();
 				set_input_as_handled();
+				match_found = true;
 				break;
 				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);
+					_scroll_to_item(i);
+					control->update();
+					set_input_as_handled();
+					break;
+				}
+			}
+		}
 	} else if (p_event->is_action("ui_left") && p_event->is_pressed()) {
 	} else if (p_event->is_action("ui_left") && p_event->is_pressed()) {
 		Node *n = get_parent();
 		Node *n = get_parent();
 		if (n && Object::cast_to<PopupMenu>(n)) {
 		if (n && Object::cast_to<PopupMenu>(n)) {