diff options
author | Robert Yevdokimov <robert.yevdokimov@autStand.com> | 2024-01-08 00:07:24 -0500 |
---|---|---|
committer | Robert Yevdokimov <robert.yevdokimov@autStand.com> | 2024-01-14 17:45:52 -0500 |
commit | 06c2cda848b4bca8ee2f54a09417a97a7c1384d3 (patch) | |
tree | 4bc3b75b7a8b8c89cfe356e168a1644ac59965fb | |
parent | 89cc635c0554cb2e518c830969ca4c5eedda0f4e (diff) | |
download | redot-engine-06c2cda848b4bca8ee2f54a09417a97a7c1384d3.tar.gz |
Fix selecting popup menu items on mouse release
-rw-r--r-- | scene/gui/popup_menu.cpp | 91 | ||||
-rw-r--r-- | scene/gui/popup_menu.h | 4 |
2 files changed, 50 insertions, 45 deletions
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 8af05bd205..9ca97021ed 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -438,6 +438,9 @@ void PopupMenu::_input_from_window(const Ref<InputEvent> &p_event) { } void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) { + Ref<InputEventMouseButton> b = p_event; + Ref<InputEventMouseMotion> m = p_event; + if (!items.is_empty()) { Input *input = Input::get_singleton(); Ref<InputEventJoypadMotion> joypadmotion_event = p_event; @@ -566,52 +569,57 @@ void PopupMenu::_input_from_window_internal(const Ref<InputEvent> &p_event) { } } - Ref<InputEventMouseButton> b = p_event; + if (m.is_valid() && drag_to_press) { + BitField<MouseButtonMask> initial_button_mask = m->get_button_mask(); + if (!initial_button_mask.has_flag(mouse_button_to_mask(MouseButton::LEFT)) && !initial_button_mask.has_flag(mouse_button_to_mask(MouseButton::RIGHT))) { + mouse_is_pressed = false; + } - if (b.is_valid()) { - if (!item_clickable_area.has_point(b->get_position())) { - return; + if (!item_clickable_area.has_point(m->get_position()) && !mouse_is_pressed) { + drag_to_press = false; } + } - MouseButton button_idx = b->get_button_index(); - if (!b->is_pressed()) { - // Activate the item on release of either the left mouse button or - // any mouse button held down when the popup was opened. - // This allows for opening the popup and triggering an action in a single mouse click. - if (button_idx == MouseButton::LEFT || initial_button_mask.has_flag(mouse_button_to_mask(button_idx))) { - bool was_during_grabbed_click = during_grabbed_click; - during_grabbed_click = false; - initial_button_mask.clear(); - - // Disable clicks under a time threshold to avoid selection right when opening the popup. - uint64_t now = OS::get_singleton()->get_ticks_msec(); - uint64_t diff = now - popup_time_msec; - if (diff < 150) { - return; - } + if ((b.is_valid() && b->is_pressed()) || (!mouse_is_pressed && drag_to_press)) { + if (b.is_valid()) { + MouseButton button_idx = b->get_button_index(); + if (button_idx != MouseButton::LEFT && button_idx != MouseButton::RIGHT) { + return; + } + } else { + uint64_t now = OS::get_singleton()->get_ticks_msec(); + uint64_t diff = now - popup_time_msec; + if (diff < 250) { + drag_to_press = false; + return; + } + } - int over = _get_mouse_over(b->get_position()); - if (over < 0) { - if (!was_during_grabbed_click) { - hide(); - } - return; - } + drag_to_press = false; - if (items[over].separator || items[over].disabled) { - return; - } + int over = -1; - if (!items[over].submenu.is_empty()) { - _activate_submenu(over); - return; - } - activate_item(over); - } + if (m.is_valid()) { + over = _get_mouse_over(m->get_position()); + } else if (b.is_valid()) { + over = _get_mouse_over(b->get_position()); } - } - Ref<InputEventMouseMotion> m = p_event; + if (over < 0) { + hide(); + return; + } + + if (items[over].separator || items[over].disabled) { + return; + } + + if (!items[over].submenu.is_empty()) { + _activate_submenu(over); + return; + } + activate_item(over); + } if (m.is_valid()) { if (m->get_velocity().is_zero_approx()) { @@ -1046,11 +1054,6 @@ void PopupMenu::_notification(int p_what) { } } break; - case NOTIFICATION_POST_POPUP: { - initial_button_mask = Input::get_singleton()->get_mouse_button_mask(); - during_grabbed_click = (bool)initial_button_mask; - } break; - case NOTIFICATION_INTERNAL_PROCESS: { Input *input = Input::get_singleton(); @@ -2844,6 +2847,8 @@ void PopupMenu::popup(const Rect2i &p_bounds) { moved = Vector2(); popup_time_msec = OS::get_singleton()->get_ticks_msec(); Popup::popup(p_bounds); + drag_to_press = true; + mouse_is_pressed = true; } PopupMenu::PopupMenu() { diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 9783f9d57b..df0c99c831 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -101,8 +101,8 @@ class PopupMenu : public Popup { Timer *submenu_timer = nullptr; List<Rect2> autohide_areas; Vector<Item> items; - BitField<MouseButtonMask> initial_button_mask; - bool during_grabbed_click = false; + bool mouse_is_pressed = true; + bool drag_to_press = true; int mouse_over = -1; int submenu_over = -1; String _get_accel_text(const Item &p_item) const; |