Pārlūkot izejas kodu

Make `Menu/OptionButton` item auto-highlight behave better

(cherry picked from commit 50506e19a6fd0a8c692bab8e642a71dfa3ed26d2)
Michael Alexsander 3 gadi atpakaļ
vecāks
revīzija
4744a8a1a9

+ 7 - 0
scene/gui/base_button.cpp

@@ -64,6 +64,8 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) {
 
 	bool button_masked = mouse_button.is_valid() && ((1 << (mouse_button->get_button_index() - 1)) & button_mask) > 0;
 	if (button_masked || ui_accept) {
+		was_mouse_pressed = button_masked;
+
 		on_action_event(p_event);
 		return;
 	}
@@ -388,6 +390,10 @@ Ref<ButtonGroup> BaseButton::get_button_group() const {
 	return button_group;
 }
 
+bool BaseButton::_was_pressed_by_mouse() const {
+	return was_mouse_pressed;
+}
+
 void BaseButton::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("_gui_input"), &BaseButton::_gui_input);
 	ClassDB::bind_method(D_METHOD("_unhandled_input"), &BaseButton::_unhandled_input);
@@ -449,6 +455,7 @@ BaseButton::BaseButton() {
 	toggle_mode = false;
 	shortcut_in_tooltip = true;
 	keep_pressed_outside = false;
+	was_mouse_pressed = false;
 	status.pressed = false;
 	status.press_attempt = false;
 	status.hovering = false;

+ 3 - 0
scene/gui/base_button.h

@@ -49,6 +49,7 @@ private:
 	bool toggle_mode;
 	bool shortcut_in_tooltip;
 	bool keep_pressed_outside;
+	bool was_mouse_pressed;
 	FocusMode enabled_focus_mode;
 	Ref<ShortCut> shortcut;
 
@@ -79,6 +80,8 @@ protected:
 	virtual void _unhandled_input(Ref<InputEvent> p_event);
 	void _notification(int p_what);
 
+	bool _was_pressed_by_mouse() const;
+
 public:
 	enum DrawMode {
 		DRAW_NORMAL,

+ 1 - 4
scene/gui/menu_button.cpp

@@ -29,7 +29,6 @@
 /*************************************************************************/
 
 #include "menu_button.h"
-#include "core/os/input.h"
 #include "core/os/keyboard.h"
 #include "scene/main/viewport.h"
 
@@ -64,9 +63,7 @@ void MenuButton::pressed() {
 	popup->set_parent_rect(Rect2(Point2(gp - popup->get_global_position()), get_size()));
 
 	// If not triggered by the mouse, start the popup with its first item selected.
-	if (popup->get_item_count() > 0 &&
-			((get_action_mode() == ActionMode::ACTION_MODE_BUTTON_PRESS && Input::get_singleton()->is_action_just_pressed("ui_accept")) ||
-					(get_action_mode() == ActionMode::ACTION_MODE_BUTTON_RELEASE && Input::get_singleton()->is_action_just_released("ui_accept")))) {
+	if (popup->get_item_count() > 0 && !_was_pressed_by_mouse()) {
 		popup->set_current_index(0);
 	}
 

+ 1 - 4
scene/gui/option_button.cpp

@@ -29,7 +29,6 @@
 /*************************************************************************/
 
 #include "option_button.h"
-#include "core/os/input.h"
 #include "core/print_string.h"
 
 static const int NONE_SELECTED = -1;
@@ -114,9 +113,7 @@ void OptionButton::pressed() {
 	popup->set_scale(get_global_transform().get_scale());
 
 	// If not triggered by the mouse, start the popup with its first item selected.
-	if (popup->get_item_count() > 0 &&
-			((get_action_mode() == ActionMode::ACTION_MODE_BUTTON_PRESS && Input::get_singleton()->is_action_just_pressed("ui_accept")) ||
-					(get_action_mode() == ActionMode::ACTION_MODE_BUTTON_RELEASE && Input::get_singleton()->is_action_just_released("ui_accept")))) {
+	if (popup->get_item_count() > 0 && !_was_pressed_by_mouse()) {
 		popup->set_current_index(0);
 	}
 

+ 6 - 4
scene/gui/popup_menu.cpp

@@ -145,7 +145,7 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
 	return -1;
 }
 
-void PopupMenu::_activate_submenu(int over) {
+void PopupMenu::_activate_submenu(int over, bool p_by_keyboard) {
 	Node *n = get_node(items[over].submenu);
 	ERR_FAIL_COND_MSG(!n, "Item subnode does not exist: " + items[over].submenu + ".");
 	Popup *pm = Object::cast_to<Popup>(n);
@@ -172,7 +172,7 @@ void PopupMenu::_activate_submenu(int over) {
 	PopupMenu *pum = Object::cast_to<PopupMenu>(pm);
 	if (pum) {
 		// If not triggered by the mouse, start the popup with its first item selected.
-		if (pum->get_item_count() > 0 && Input::get_singleton()->is_action_just_pressed("ui_accept")) {
+		if (pum->get_item_count() > 0 && p_by_keyboard) {
 			pum->set_current_index(0);
 		}
 
@@ -300,13 +300,13 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_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);
+				_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) {
-					_activate_submenu(mouse_over);
+					_activate_submenu(mouse_over, true);
 				} else {
 					activate_item(mouse_over);
 				}
@@ -1478,6 +1478,8 @@ void PopupMenu::popup(const Rect2 &p_bounds) {
 }
 
 PopupMenu::PopupMenu() {
+	activated_by_keyboard = false;
+
 	mouse_over = -1;
 	submenu_over = -1;
 	initial_button_mask = 0;

+ 3 - 1
scene/gui/popup_menu.h

@@ -76,6 +76,8 @@ class PopupMenu : public Popup {
 		}
 	};
 
+	bool activated_by_keyboard;
+
 	Timer *submenu_timer;
 	List<Rect2> autohide_areas;
 	Vector<Item> items;
@@ -89,7 +91,7 @@ class PopupMenu : public Popup {
 	virtual Size2 get_minimum_size() const;
 	void _scroll(float p_factor, const Point2 &p_over);
 	void _gui_input(const Ref<InputEvent> &p_event);
-	void _activate_submenu(int over);
+	void _activate_submenu(int over, bool p_by_keyboard = false);
 	void _submenu_timeout();
 
 	bool invalidated_click;