diff options
Diffstat (limited to 'scene/gui/menu_button.cpp')
-rw-r--r-- | scene/gui/menu_button.cpp | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 316fee53fe..786f23873e 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -36,23 +36,16 @@ void MenuButton::shortcut_input(const Ref<InputEvent> &p_event) { ERR_FAIL_COND(p_event.is_null()); - if (!_is_focus_owner_in_shortcut_context()) { + if (disable_shortcuts) { return; } - if (disable_shortcuts) { + if (p_event->is_pressed() && !p_event->is_echo() && !is_disabled() && is_visible_in_tree() && popup->activate_item_by_event(p_event, false)) { + accept_event(); return; } - if (p_event->is_pressed() && !p_event->is_echo() && (Object::cast_to<InputEventKey>(p_event.ptr()) || Object::cast_to<InputEventJoypadButton>(p_event.ptr()) || Object::cast_to<InputEventAction>(*p_event) || Object::cast_to<InputEventShortcut>(*p_event))) { - if (!get_parent() || !is_visible_in_tree() || is_disabled()) { - return; - } - - if (popup->activate_item_by_event(p_event, false)) { - accept_event(); - } - } + Button::shortcut_input(p_event); } void MenuButton::_popup_visibility_changed(bool p_visible) { @@ -64,19 +57,19 @@ void MenuButton::_popup_visibility_changed(bool p_visible) { } if (switch_on_hover) { - Window *window = Object::cast_to<Window>(get_viewport()); - if (window) { - mouse_pos_adjusted = window->get_position(); - - if (window->is_embedded()) { - Window *window_parent = Object::cast_to<Window>(window->get_parent()->get_viewport()); - while (window_parent) { - if (!window_parent->is_embedded()) { - mouse_pos_adjusted += window_parent->get_position(); + Window *wnd = Object::cast_to<Window>(get_viewport()); + if (wnd) { + mouse_pos_adjusted = wnd->get_position(); + + if (wnd->is_embedded()) { + Window *wnd_parent = Object::cast_to<Window>(wnd->get_parent()->get_viewport()); + while (wnd_parent) { + if (!wnd_parent->is_embedded()) { + mouse_pos_adjusted += wnd_parent->get_position(); break; } - window_parent = Object::cast_to<Window>(window_parent->get_parent()->get_viewport()); + wnd_parent = Object::cast_to<Window>(wnd_parent->get_parent()->get_viewport()); } } @@ -86,6 +79,23 @@ void MenuButton::_popup_visibility_changed(bool p_visible) { } void MenuButton::pressed() { + if (popup->is_visible()) { + popup->hide(); + return; + } + + show_popup(); +} + +PopupMenu *MenuButton::get_popup() const { + return popup; +} + +void MenuButton::show_popup() { + if (!get_viewport()) { + return; + } + emit_signal(SNAME("about_to_popup")); Size2 size = get_size() * get_viewport()->get_canvas_transform().get_scale(); @@ -98,24 +108,19 @@ void MenuButton::pressed() { popup->set_position(gp); popup->set_parent_rect(Rect2(Point2(gp - popup->get_position()), 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")))) { - popup->set_current_index(0); + // If not triggered by the mouse, start the popup with its first enabled item focused. + if (!_was_pressed_by_mouse()) { + for (int i = 0; i < popup->get_item_count(); i++) { + if (!popup->is_item_disabled(i)) { + popup->set_focused_item(i); + break; + } + } } popup->popup(); } -void MenuButton::gui_input(const Ref<InputEvent> &p_event) { - BaseButton::gui_input(p_event); -} - -PopupMenu *MenuButton::get_popup() const { - return popup; -} - void MenuButton::set_switch_on_hover(bool p_enabled) { switch_on_hover = p_enabled; } @@ -126,6 +131,11 @@ bool MenuButton::is_switch_on_hover() { void MenuButton::set_item_count(int p_count) { ERR_FAIL_COND(p_count < 0); + + if (popup->get_item_count() == p_count) { + return; + } + popup->set_item_count(p_count); notify_property_list_changed(); } @@ -153,7 +163,10 @@ void MenuButton::_notification(int p_what) { if (menu_btn_other && menu_btn_other != this && menu_btn_other->is_switch_on_hover() && !menu_btn_other->is_disabled() && (get_parent()->is_ancestor_of(menu_btn_other) || menu_btn_other->get_parent()->is_ancestor_of(popup))) { popup->hide(); + menu_btn_other->pressed(); + // As the popup wasn't triggered by a mouse click, the item focus needs to be removed manually. + menu_btn_other->get_popup()->set_focused_item(-1); } } break; } @@ -210,6 +223,7 @@ void MenuButton::_get_property_list(List<PropertyInfo> *p_list) const { void MenuButton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_popup"), &MenuButton::get_popup); + ClassDB::bind_method(D_METHOD("show_popup"), &MenuButton::show_popup); ClassDB::bind_method(D_METHOD("set_switch_on_hover", "enable"), &MenuButton::set_switch_on_hover); ClassDB::bind_method(D_METHOD("is_switch_on_hover"), &MenuButton::is_switch_on_hover); ClassDB::bind_method(D_METHOD("set_disable_shortcuts", "disabled"), &MenuButton::set_disable_shortcuts); @@ -239,8 +253,8 @@ MenuButton::MenuButton(const String &p_text) : popup = memnew(PopupMenu); popup->hide(); add_child(popup, false, INTERNAL_MODE_FRONT); - popup->connect("about_to_popup", callable_mp(this, &MenuButton::_popup_visibility_changed), varray(true)); - popup->connect("popup_hide", callable_mp(this, &MenuButton::_popup_visibility_changed), varray(false)); + popup->connect("about_to_popup", callable_mp(this, &MenuButton::_popup_visibility_changed).bind(true)); + popup->connect("popup_hide", callable_mp(this, &MenuButton::_popup_visibility_changed).bind(false)); } MenuButton::~MenuButton() { |