diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-26 15:59:35 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-26 15:59:35 +0100 |
commit | f8d80b406dedaf363004e3e1f1a9c5cd6c1d2358 (patch) | |
tree | 311f56eaac6a4c1b59a33e6504220fb497293dc4 | |
parent | 3870861056ea8441707cab015d20e9f48337c61a (diff) | |
parent | 99bb7ab6922b4490cfe17d5f3b1a269c0b9851a5 (diff) |
Merge pull request #66688 from Sauermann/fix-control-get-global-rect-coordinates
Fix Control rect coordinate system inconsistency
-rw-r--r-- | doc/classes/Control.xml | 12 | ||||
-rw-r--r-- | scene/gui/control.cpp | 24 |
2 files changed, 15 insertions, 21 deletions
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 6f665ff98a..0d675112b8 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -383,7 +383,9 @@ <method name="get_global_rect" qualifiers="const"> <return type="Rect2" /> <description> - Returns the position and size of the control relative to the [CanvasLayer]. See [member global_position] and [member size]. + Returns the position and size of the control relative to the containing canvas. See [member global_position] and [member size]. + [b]Note:[/b] If the node itself or any parent [CanvasItem] between the node and the canvas have a non default rotation or skew, the resulting size is likely not meaningful. + [b]Note:[/b] Setting [member Viewport.gui_snap_controls_to_pixels] to [code]true[/code] can lead to rounding inaccuracies between the displayed control and the returned [Rect2]. </description> </method> <method name="get_minimum_size" qualifiers="const"> @@ -414,7 +416,9 @@ <method name="get_rect" qualifiers="const"> <return type="Rect2" /> <description> - Returns the position and size of the control relative to the top-left corner of the parent Control. See [member position] and [member size]. + Returns the position and size of the control in the coordinate system of the containing node. See [member position], [member scale] and [member size]. + [b]Note:[/b] If [member rotation] is not the default rotation, the resulting size is not meaningful. + [b]Note:[/b] Setting [member Viewport.gui_snap_controls_to_pixels] to [code]true[/code] can lead to rounding inaccuracies between the displayed control and the returned [Rect2]. </description> </method> <method name="get_screen_position" qualifiers="const"> @@ -992,7 +996,7 @@ By default, the node's pivot is its top-left corner. When you change its [member rotation] or [member scale], it will rotate or scale around this pivot. Set this property to [member size] / 2 to pivot around the Control's center. </member> <member name="position" type="Vector2" setter="_set_position" getter="get_position" default="Vector2(0, 0)"> - The node's position, relative to its parent. It corresponds to the rectangle's top-left corner. The property is not affected by [member pivot_offset]. + The node's position, relative to its containing node. It corresponds to the rectangle's top-left corner. The property is not affected by [member pivot_offset]. </member> <member name="rotation" type="float" setter="set_rotation" getter="get_rotation" default="0.0"> The node's rotation around its pivot, in radians. See [member pivot_offset] to change the pivot's position. @@ -1009,7 +1013,7 @@ The [Node] which must be a parent of the focused [Control] for the shortcut to be activated. If [code]null[/code], the shortcut can be activated when any control is focused (a global shortcut). This allows shortcuts to be accepted only when the user has a certain area of the GUI focused. </member> <member name="size" type="Vector2" setter="_set_size" getter="get_size" default="Vector2(0, 0)"> - The size of the node's bounding rectangle, in pixels. [Container] nodes update this property automatically. + The size of the node's bounding rectangle, in the node's coordinate system. [Container] nodes update this property automatically. </member> <member name="size_flags_horizontal" type="int" setter="set_h_size_flags" getter="get_h_size_flags" enum="Control.SizeFlags" default="1"> Tells the parent [Container] nodes how they should resize and place the node on the X axis. Use one of the [enum SizeFlags] constants to change the flags. See the constants to learn what each does. diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index fead0878fb..f7c056316d 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1387,13 +1387,7 @@ Point2 Control::get_global_position() const { Point2 Control::get_screen_position() const { ERR_FAIL_COND_V(!is_inside_tree(), Point2()); - Point2 global_pos = get_global_transform_with_canvas().get_origin(); - Window *w = Object::cast_to<Window>(get_viewport()); - if (w && !w->is_embedding_subwindows()) { - global_pos += w->get_position(); - } - - return global_pos; + return get_screen_transform().get_origin(); } void Control::_set_size(const Size2 &p_size) { @@ -1444,24 +1438,20 @@ void Control::set_rect(const Rect2 &p_rect) { } Rect2 Control::get_rect() const { - return Rect2(get_position(), get_size()); + Transform2D xform = get_transform(); + return Rect2(xform.get_origin(), xform.get_scale() * get_size()); } Rect2 Control::get_global_rect() const { - return Rect2(get_global_position(), get_size()); + Transform2D xform = get_global_transform(); + return Rect2(xform.get_origin(), xform.get_scale() * get_size()); } Rect2 Control::get_screen_rect() const { ERR_FAIL_COND_V(!is_inside_tree(), Rect2()); - Rect2 r(get_global_position(), get_size()); - - Window *w = Object::cast_to<Window>(get_viewport()); - if (w && !w->is_embedding_subwindows()) { - r.position += w->get_position(); - } - - return r; + Transform2D xform = get_screen_transform(); + return Rect2(xform.get_origin(), xform.get_scale() * get_size()); } Rect2 Control::get_anchorable_rect() const { |