Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] Make Menu/OptionButton item auto-highlight behave better #64636

Merged
merged 1 commit into from
Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions scene/gui/base_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions scene/gui/base_button.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class BaseButton : public Control {
bool toggle_mode;
bool shortcut_in_tooltip;
bool keep_pressed_outside;
bool was_mouse_pressed;
FocusMode enabled_focus_mode;
Ref<ShortCut> shortcut;

Expand Down Expand Up @@ -79,6 +80,8 @@ class BaseButton : public Control {
virtual void _unhandled_input(Ref<InputEvent> p_event);
void _notification(int p_what);

bool _was_pressed_by_mouse() const;

public:
enum DrawMode {
DRAW_NORMAL,
Expand Down
5 changes: 1 addition & 4 deletions scene/gui/menu_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
/*************************************************************************/

#include "menu_button.h"
#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "scene/main/viewport.h"

Expand Down Expand Up @@ -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);
}

Expand Down
5 changes: 1 addition & 4 deletions scene/gui/option_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
/*************************************************************************/

#include "option_button.h"
#include "core/os/input.h"
#include "core/print_string.h"

static const int NONE_SELECTED = -1;
Expand Down Expand Up @@ -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);
}

Expand Down
10 changes: 6 additions & 4 deletions scene/gui/popup_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}

Expand Down Expand Up @@ -299,13 +299,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);
}
Expand Down Expand Up @@ -1476,6 +1476,8 @@ void PopupMenu::popup(const Rect2 &p_bounds) {
}

PopupMenu::PopupMenu() {
activated_by_keyboard = false;

mouse_over = -1;
submenu_over = -1;
initial_button_mask = 0;
Expand Down
4 changes: 3 additions & 1 deletion scene/gui/popup_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class PopupMenu : public Popup {
}
};

bool activated_by_keyboard;

Timer *submenu_timer;
List<Rect2> autohide_areas;
Vector<Item> items;
Expand All @@ -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;
Expand Down