Explorar el Código

Make `MenuButton`'s `switch_on_hover` work again

Michael Alexsander hace 4 años
padre
commit
a690cd9251
Se han modificado 5 ficheros con 39 adiciones y 16 borrados
  1. 27 6
      scene/gui/menu_button.cpp
  2. 2 0
      scene/gui/menu_button.h
  3. 0 1
      scene/gui/popup_menu.h
  4. 8 8
      scene/main/viewport.cpp
  5. 2 1
      scene/main/viewport.h

+ 27 - 6
scene/gui/menu_button.cpp

@@ -55,6 +55,11 @@ void MenuButton::_unhandled_key_input(Ref<InputEvent> p_event) {
 	}
 }
 
+void MenuButton::_popup_visibility_changed(bool p_visible) {
+	set_pressed(p_visible);
+	set_process_internal(p_visible);
+}
+
 void MenuButton::pressed() {
 	Size2 size = get_size();
 
@@ -94,10 +99,26 @@ bool MenuButton::is_switch_on_hover() {
 }
 
 void MenuButton::_notification(int p_what) {
-	if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-		if (!is_visible_in_tree()) {
-			popup->hide();
-		}
+	switch (p_what) {
+		case NOTIFICATION_VISIBILITY_CHANGED: {
+			if (!is_visible_in_tree()) {
+				popup->hide();
+			}
+		} break;
+		case NOTIFICATION_INTERNAL_PROCESS: {
+			if (switch_on_hover) {
+				Window *window = Object::cast_to<Window>(get_viewport());
+				if (window) {
+					Vector2i mouse_pos = DisplayServer::get_singleton()->mouse_get_position() - window->get_position();
+					MenuButton *menu_btn_other = Object::cast_to<MenuButton>(window->gui_find_control(mouse_pos));
+					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();
+					}
+				}
+			}
+		} break;
 	}
 }
 
@@ -130,8 +151,8 @@ MenuButton::MenuButton() {
 	popup = memnew(PopupMenu);
 	popup->hide();
 	add_child(popup);
-	popup->connect("about_to_popup", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(true)); // For when switching from another MenuButton.
-	popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(false));
+	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));
 }
 
 MenuButton::~MenuButton() {

+ 2 - 0
scene/gui/menu_button.h

@@ -47,6 +47,8 @@ class MenuButton : public Button {
 
 	void _gui_input(Ref<InputEvent> p_event) override;
 
+	void _popup_visibility_changed(bool p_visible);
+
 protected:
 	void _notification(int p_what);
 	static void _bind_methods();

+ 0 - 1
scene/gui/popup_menu.h

@@ -140,7 +140,6 @@ class PopupMenu : public Popup {
 	void _close_pressed();
 
 protected:
-	friend class MenuButton;
 	void _notification(int p_what);
 	static void _bind_methods();
 

+ 8 - 8
scene/main/viewport.cpp

@@ -1710,7 +1710,7 @@ void Viewport::_gui_call_notification(Control *p_control, int p_what) {
 	//_unblock();
 }
 
-Control *Viewport::_gui_find_control(const Point2 &p_global) {
+Control *Viewport::gui_find_control(const Point2 &p_global) {
 	//aca va subwindows
 	_gui_sort_roots();
 
@@ -1850,7 +1850,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 					parent_xform=data.parent_canvas_item->get_global_transform();
 				*/
 
-				gui.mouse_focus = _gui_find_control(pos);
+				gui.mouse_focus = gui_find_control(pos);
 				gui.last_mouse_focus = gui.mouse_focus;
 
 				if (!gui.mouse_focus) {
@@ -1991,7 +1991,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 			if (gui.mouse_focus) {
 				over = gui.mouse_focus;
 			} else {
-				over = _gui_find_control(mpos);
+				over = gui_find_control(mpos);
 			}
 
 			if (gui.mouse_focus_mask == 0 && over != gui.mouse_over) {
@@ -2074,7 +2074,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 		if (gui.mouse_focus) {
 			over = gui.mouse_focus;
 		} else {
-			over = _gui_find_control(mpos);
+			over = gui_find_control(mpos);
 		}
 
 		if (over != gui.mouse_over) {
@@ -2262,7 +2262,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 				Transform2D ai = (viewport_under->get_final_transform().affine_inverse() * viewport_under->_get_input_pre_xform());
 				viewport_pos = ai.xform(viewport_pos);
 				//find control under at pos
-				gui.drag_mouse_over = viewport_under->_gui_find_control(viewport_pos);
+				gui.drag_mouse_over = viewport_under->gui_find_control(viewport_pos);
 				if (gui.drag_mouse_over) {
 					Transform2D localizer = gui.drag_mouse_over->get_global_transform_with_canvas().affine_inverse();
 					gui.drag_mouse_over_pos = localizer.xform(viewport_pos);
@@ -2290,7 +2290,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 	if (touch_event.is_valid()) {
 		Size2 pos = touch_event->get_position();
 		if (touch_event->is_pressed()) {
-			Control *over = _gui_find_control(pos);
+			Control *over = gui_find_control(pos);
 			if (over) {
 				if (over->can_process()) {
 					touch_event = touch_event->xformed_by(Transform2D()); //make a copy
@@ -2325,7 +2325,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 
 		Size2 pos = gesture_event->get_position();
 
-		Control *over = _gui_find_control(pos);
+		Control *over = gui_find_control(pos);
 		if (over) {
 			if (over->can_process()) {
 				gesture_event = gesture_event->xformed_by(Transform2D()); //make a copy
@@ -2346,7 +2346,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 	if (drag_event.is_valid()) {
 		Control *over = gui.mouse_focus;
 		if (!over) {
-			over = _gui_find_control(drag_event->get_position());
+			over = gui_find_control(drag_event->get_position());
 		}
 		if (over) {
 			if (over->can_process()) {

+ 2 - 1
scene/main/viewport.h

@@ -404,7 +404,6 @@ private:
 	void _gui_call_notification(Control *p_control, int p_what);
 
 	void _gui_sort_roots();
-	Control *_gui_find_control(const Point2 &p_global);
 	Control *_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_global, const Transform2D &p_xform, Transform2D &r_inv_xform);
 
 	void _gui_input_event(Ref<InputEvent> p_event);
@@ -629,6 +628,8 @@ public:
 
 	bool gui_is_dragging() const;
 
+	Control *gui_find_control(const Point2 &p_global);
+
 	void set_sdf_oversize(SDFOversize p_sdf_oversize);
 	SDFOversize get_sdf_oversize() const;