Make `Menu/OptionButton` item auto-highlight behave better
(cherry picked from commit 50506e19a6
)
This commit is contained in:
parent
5c9ced191b
commit
4744a8a1a9
|
@ -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;
|
bool button_masked = mouse_button.is_valid() && ((1 << (mouse_button->get_button_index() - 1)) & button_mask) > 0;
|
||||||
if (button_masked || ui_accept) {
|
if (button_masked || ui_accept) {
|
||||||
|
was_mouse_pressed = button_masked;
|
||||||
|
|
||||||
on_action_event(p_event);
|
on_action_event(p_event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -388,6 +390,10 @@ Ref<ButtonGroup> BaseButton::get_button_group() const {
|
||||||
return button_group;
|
return button_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BaseButton::_was_pressed_by_mouse() const {
|
||||||
|
return was_mouse_pressed;
|
||||||
|
}
|
||||||
|
|
||||||
void BaseButton::_bind_methods() {
|
void BaseButton::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("_gui_input"), &BaseButton::_gui_input);
|
ClassDB::bind_method(D_METHOD("_gui_input"), &BaseButton::_gui_input);
|
||||||
ClassDB::bind_method(D_METHOD("_unhandled_input"), &BaseButton::_unhandled_input);
|
ClassDB::bind_method(D_METHOD("_unhandled_input"), &BaseButton::_unhandled_input);
|
||||||
|
@ -449,6 +455,7 @@ BaseButton::BaseButton() {
|
||||||
toggle_mode = false;
|
toggle_mode = false;
|
||||||
shortcut_in_tooltip = true;
|
shortcut_in_tooltip = true;
|
||||||
keep_pressed_outside = false;
|
keep_pressed_outside = false;
|
||||||
|
was_mouse_pressed = false;
|
||||||
status.pressed = false;
|
status.pressed = false;
|
||||||
status.press_attempt = false;
|
status.press_attempt = false;
|
||||||
status.hovering = false;
|
status.hovering = false;
|
||||||
|
|
|
@ -49,6 +49,7 @@ private:
|
||||||
bool toggle_mode;
|
bool toggle_mode;
|
||||||
bool shortcut_in_tooltip;
|
bool shortcut_in_tooltip;
|
||||||
bool keep_pressed_outside;
|
bool keep_pressed_outside;
|
||||||
|
bool was_mouse_pressed;
|
||||||
FocusMode enabled_focus_mode;
|
FocusMode enabled_focus_mode;
|
||||||
Ref<ShortCut> shortcut;
|
Ref<ShortCut> shortcut;
|
||||||
|
|
||||||
|
@ -79,6 +80,8 @@ protected:
|
||||||
virtual void _unhandled_input(Ref<InputEvent> p_event);
|
virtual void _unhandled_input(Ref<InputEvent> p_event);
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
|
||||||
|
bool _was_pressed_by_mouse() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum DrawMode {
|
enum DrawMode {
|
||||||
DRAW_NORMAL,
|
DRAW_NORMAL,
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#include "menu_button.h"
|
#include "menu_button.h"
|
||||||
#include "core/os/input.h"
|
|
||||||
#include "core/os/keyboard.h"
|
#include "core/os/keyboard.h"
|
||||||
#include "scene/main/viewport.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()));
|
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 not triggered by the mouse, start the popup with its first item selected.
|
||||||
if (popup->get_item_count() > 0 &&
|
if (popup->get_item_count() > 0 && !_was_pressed_by_mouse()) {
|
||||||
((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")))) {
|
|
||||||
popup->set_current_index(0);
|
popup->set_current_index(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#include "option_button.h"
|
#include "option_button.h"
|
||||||
#include "core/os/input.h"
|
|
||||||
#include "core/print_string.h"
|
#include "core/print_string.h"
|
||||||
|
|
||||||
static const int NONE_SELECTED = -1;
|
static const int NONE_SELECTED = -1;
|
||||||
|
@ -114,9 +113,7 @@ void OptionButton::pressed() {
|
||||||
popup->set_scale(get_global_transform().get_scale());
|
popup->set_scale(get_global_transform().get_scale());
|
||||||
|
|
||||||
// If not triggered by the mouse, start the popup with its first item selected.
|
// If not triggered by the mouse, start the popup with its first item selected.
|
||||||
if (popup->get_item_count() > 0 &&
|
if (popup->get_item_count() > 0 && !_was_pressed_by_mouse()) {
|
||||||
((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")))) {
|
|
||||||
popup->set_current_index(0);
|
popup->set_current_index(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
|
||||||
return -1;
|
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);
|
Node *n = get_node(items[over].submenu);
|
||||||
ERR_FAIL_COND_MSG(!n, "Item subnode does not exist: " + items[over].submenu + ".");
|
ERR_FAIL_COND_MSG(!n, "Item subnode does not exist: " + items[over].submenu + ".");
|
||||||
Popup *pm = Object::cast_to<Popup>(n);
|
Popup *pm = Object::cast_to<Popup>(n);
|
||||||
|
@ -172,7 +172,7 @@ void PopupMenu::_activate_submenu(int over) {
|
||||||
PopupMenu *pum = Object::cast_to<PopupMenu>(pm);
|
PopupMenu *pum = Object::cast_to<PopupMenu>(pm);
|
||||||
if (pum) {
|
if (pum) {
|
||||||
// If not triggered by the mouse, start the popup with its first item selected.
|
// 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);
|
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()) {
|
} 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) {
|
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();
|
accept_event();
|
||||||
}
|
}
|
||||||
} else if (p_event->is_action("ui_accept") && p_event->is_pressed()) {
|
} 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 (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) {
|
||||||
if (items[mouse_over].submenu != "" && submenu_over != mouse_over) {
|
if (items[mouse_over].submenu != "" && submenu_over != mouse_over) {
|
||||||
_activate_submenu(mouse_over);
|
_activate_submenu(mouse_over, true);
|
||||||
} else {
|
} else {
|
||||||
activate_item(mouse_over);
|
activate_item(mouse_over);
|
||||||
}
|
}
|
||||||
|
@ -1478,6 +1478,8 @@ void PopupMenu::popup(const Rect2 &p_bounds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupMenu::PopupMenu() {
|
PopupMenu::PopupMenu() {
|
||||||
|
activated_by_keyboard = false;
|
||||||
|
|
||||||
mouse_over = -1;
|
mouse_over = -1;
|
||||||
submenu_over = -1;
|
submenu_over = -1;
|
||||||
initial_button_mask = 0;
|
initial_button_mask = 0;
|
||||||
|
|
|
@ -76,6 +76,8 @@ class PopupMenu : public Popup {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool activated_by_keyboard;
|
||||||
|
|
||||||
Timer *submenu_timer;
|
Timer *submenu_timer;
|
||||||
List<Rect2> autohide_areas;
|
List<Rect2> autohide_areas;
|
||||||
Vector<Item> items;
|
Vector<Item> items;
|
||||||
|
@ -89,7 +91,7 @@ class PopupMenu : public Popup {
|
||||||
virtual Size2 get_minimum_size() const;
|
virtual Size2 get_minimum_size() const;
|
||||||
void _scroll(float p_factor, const Point2 &p_over);
|
void _scroll(float p_factor, const Point2 &p_over);
|
||||||
void _gui_input(const Ref<InputEvent> &p_event);
|
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();
|
void _submenu_timeout();
|
||||||
|
|
||||||
bool invalidated_click;
|
bool invalidated_click;
|
||||||
|
|
Loading…
Reference in New Issue