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;