diff --git a/doc/classes/GraphElement.xml b/doc/classes/GraphElement.xml index 7cd6496773f..1f810b3c2d3 100644 --- a/doc/classes/GraphElement.xml +++ b/doc/classes/GraphElement.xml @@ -19,6 +19,9 @@ If [code]true[/code], the user can resize the GraphElement. [b]Note:[/b] Dragging the handle will only emit the [signal resize_request] and [signal resize_end] signals, the GraphElement needs to be resized manually. + + If [code]true[/code], [PopupMenu]s that are descendants of the GraphElement are scaled with the [GraphEdit] zoom. + If [code]true[/code], the user can select the GraphElement. diff --git a/scene/gui/graph_element.cpp b/scene/gui/graph_element.cpp index 118637e2e55..0d69e3750de 100644 --- a/scene/gui/graph_element.cpp +++ b/scene/gui/graph_element.cpp @@ -213,6 +213,14 @@ bool GraphElement::is_selectable() { return selectable; } +void GraphElement::set_scaling_menus(bool p_scaling_menus) { + scaling_menus = p_scaling_menus; +} + +bool GraphElement::is_scaling_menus() const { + return scaling_menus; +} + void GraphElement::_bind_methods() { ClassDB::bind_method(D_METHOD("set_resizable", "resizable"), &GraphElement::set_resizable); ClassDB::bind_method(D_METHOD("is_resizable"), &GraphElement::is_resizable); @@ -226,6 +234,9 @@ void GraphElement::_bind_methods() { ClassDB::bind_method(D_METHOD("set_selected", "selected"), &GraphElement::set_selected); ClassDB::bind_method(D_METHOD("is_selected"), &GraphElement::is_selected); + ClassDB::bind_method(D_METHOD("set_scaling_menus", "scaling_menus"), &GraphElement::set_scaling_menus); + ClassDB::bind_method(D_METHOD("is_scaling_menus"), &GraphElement::is_scaling_menus); + ClassDB::bind_method(D_METHOD("set_position_offset", "offset"), &GraphElement::set_position_offset); ClassDB::bind_method(D_METHOD("get_position_offset"), &GraphElement::get_position_offset); @@ -234,6 +245,7 @@ void GraphElement::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draggable"), "set_draggable", "is_draggable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selectable"), "set_selectable", "is_selectable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selected"), "set_selected", "is_selected"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scaling_menus"), "set_scaling_menus", "is_scaling_menus"); ADD_SIGNAL(MethodInfo("node_selected")); ADD_SIGNAL(MethodInfo("node_deselected")); diff --git a/scene/gui/graph_element.h b/scene/gui/graph_element.h index 3bef5859c48..d7e2e5d3df4 100644 --- a/scene/gui/graph_element.h +++ b/scene/gui/graph_element.h @@ -48,6 +48,8 @@ protected: Vector2 position_offset; + bool scaling_menus = false; + struct ThemeCache { Ref resizer; } theme_cache; @@ -84,6 +86,9 @@ public: void set_selectable(bool p_selectable); bool is_selectable(); + void set_scaling_menus(bool p_scaling_menus); + bool is_scaling_menus() const; + virtual Size2 get_minimum_size() const override; bool is_resizing() const { diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 7da96642d5e..82b1409ad75 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -35,6 +35,7 @@ #include "core/input/input.h" #include "core/os/keyboard.h" #include "core/os/os.h" +#include "scene/gui/graph_element.h" #include "scene/gui/menu_bar.h" #include "scene/gui/panel_container.h" #include "scene/main/timer.h" @@ -3372,12 +3373,29 @@ void PopupMenu::_popup_base(const Rect2i &p_bounds) { } void PopupMenu::_pre_popup() { - Size2 scale = get_force_native() ? get_parent_viewport()->get_popup_base_transform_native().get_scale() : get_parent_viewport()->get_popup_base_transform().get_scale(); - CanvasItem *c = Object::cast_to(get_parent()); - if (c) { - scale *= c->get_global_transform_with_canvas().get_scale(); + real_t popup_scale = 1.0; + bool scale_with_parent = true; + + // Disable content scaling to avoid too tiny or too big menus when using GraphEdit zoom, applied only if menu is a child of GraphElement. + Node *p = get_parent(); + while (p) { + GraphElement *ge = Object::cast_to(p); + if (ge) { + scale_with_parent = ge->is_scaling_menus(); + break; + } + p = p->get_parent(); } - real_t popup_scale = MIN(scale.x, scale.y); + + if (scale_with_parent) { + Size2 scale = get_force_native() ? get_parent_viewport()->get_popup_base_transform_native().get_scale() : get_parent_viewport()->get_popup_base_transform().get_scale(); + CanvasItem *c = Object::cast_to(get_parent()); + if (c) { + scale *= c->get_global_transform_with_canvas().get_scale(); + } + popup_scale = MIN(scale.x, scale.y); + } + set_content_scale_factor(popup_scale); if (is_wrapping_controls()) { Size2 minsize = get_contents_minimum_size() * popup_scale;