Skip to content

Commit

Permalink
Add render transform to Control nodes
Browse files Browse the repository at this point in the history
Co-authored-by: Micky <[email protected]>
  • Loading branch information
timoschwarzer and Mickeon committed Aug 13, 2024
1 parent 06fbc83 commit 0d77a96
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 0 deletions.
18 changes: 18 additions & 0 deletions doc/classes/Control.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,24 @@
<member name="position" type="Vector2" setter="_set_position" getter="get_position" default="Vector2(0, 0)">
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="render_offset" type="Vector2" setter="set_render_offset" getter="get_render_offset" default="Vector2(0, 0)">
Position offset applied after layouting. If [member render_offset_relative_to_size] is [code]true[/code], the offset is relative to the node's [member size].
</member>
<member name="render_offset_relative_to_size" type="bool" setter="set_render_offset_relative_to_size" getter="get_render_offset_relative_to_size" default="true">
If [code]true[/code], [member render_offset] is relative to the node's [member size], otherwise it is absolute pixel values.
</member>
<member name="render_rotation" type="float" setter="set_render_rotation" getter="get_render_rotation" default="0.0">
Rotation applied after layouting. The rotation pivot is defined by [member render_transform_pivot].
</member>
<member name="render_scale" type="Vector2" setter="set_render_scale" getter="get_render_scale" default="Vector2(1, 1)">
Scale applied after layouting. The scale pivot is defined by [member render_transform_pivot].
</member>
<member name="render_transform_pivot" type="Vector2" setter="set_render_transform_pivot" getter="get_render_transform_pivot" default="Vector2(0, 0)">
Pivot used for [member render_rotation] and [member render_scale]. If [member render_transform_pivot_relative_to_size] is [code]true[/code], the pivot is relative to the node's size, otherwise it represents absolute pixel values.
</member>
<member name="render_transform_pivot_relative_to_size" type="bool" setter="set_render_transform_pivot_relative_to_size" getter="get_render_transform_pivot_relative_to_size" default="true">
If [code]true[/code], [member render_transform_pivot] is relative to the node's [member size], otherwise it is absolute pixel values.
</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.
[b]Note:[/b] This property is edited in the inspector in degrees. If you want to use degrees in a script, use [member rotation_degrees].
Expand Down
121 changes: 121 additions & 0 deletions scene/gui/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,18 @@ void Control::_validate_property(PropertyInfo &p_property) const {
p_property.hint = PROPERTY_HINT_LINK;
}

if (p_property.name == "render_offset") {
p_property.hint_string = data.render_offset_relative_to_size
? ""
: "suffix:px";
}

if (p_property.name == "render_transform_pivot") {
p_property.hint_string = data.render_transform_pivot_relative_to_size
? ""
: "suffix:px";
}

// Validate which positioning properties should be displayed depending on the parent and the layout mode.
Node *parent_node = get_parent_control();
if (!parent_node) {
Expand Down Expand Up @@ -699,6 +711,24 @@ void Control::_update_canvas_item_transform() {
xform[2] = (xform[2] + Vector2(0.5, 0.5)).floor();
}

Vector2 absolute_render_offset = data.render_offset;
Vector2 absolute_render_transform_pivot = data.render_transform_pivot;

if (data.render_offset_relative_to_size) {
absolute_render_offset *= get_size();
}

if (data.render_transform_pivot_relative_to_size) {
absolute_render_transform_pivot *= get_size();
}

xform *= Transform2D()
.translated(-absolute_render_transform_pivot)
.rotated(data.render_rotation)
.scaled(data.render_scale)
.translated(absolute_render_transform_pivot)
.translated(absolute_render_offset);

RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), xform);
}

Expand Down Expand Up @@ -1677,6 +1707,76 @@ Size2 Control::get_custom_minimum_size() const {
return data.custom_minimum_size;
}

void Control::set_render_offset(const Vector2 &p_offset) {
data.render_offset = p_offset;
queue_redraw();
_notify_transform();
}

Vector2 Control::get_render_offset() const {
return data.render_offset;
}

void Control::set_render_offset_relative_to_size(bool p_relative) {
if (data.render_offset_relative_to_size == p_relative) {
return;
}

data.render_offset_relative_to_size = p_relative;
queue_redraw();
_notify_transform();
notify_property_list_changed();
}

bool Control::get_render_offset_relative_to_size() const {
return data.render_offset_relative_to_size;
}

void Control::set_render_scale(const Vector2 &p_scale) {
data.render_scale = p_scale;
queue_redraw();
_notify_transform();
}

Vector2 Control::get_render_scale() const {
return data.render_scale;
}

void Control::set_render_rotation(real_t p_rotation) {
data.render_rotation = p_rotation;
queue_redraw();
_notify_transform();
}

real_t Control::get_render_rotation() const {
return data.render_rotation;
}

void Control::set_render_transform_pivot(const Vector2 &p_pivot) {
data.render_transform_pivot = p_pivot;
queue_redraw();
_notify_transform();
}

Vector2 Control::get_render_transform_pivot() const {
return data.render_transform_pivot;
}

void Control::set_render_transform_pivot_relative_to_size(bool p_relative) {
if (data.render_transform_pivot_relative_to_size == p_relative) {
return;
}

data.render_transform_pivot_relative_to_size = p_relative;
queue_redraw();
_notify_transform();
notify_property_list_changed();
}

bool Control::get_render_transform_pivot_relative_to_size() const {
return data.render_transform_pivot_relative_to_size;
}

void Control::_update_minimum_size_cache() {
Size2 minsize = get_minimum_size();
minsize = minsize.max(data.custom_minimum_size);
Expand Down Expand Up @@ -3425,6 +3525,19 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("find_next_valid_focus"), &Control::find_next_valid_focus);
ClassDB::bind_method(D_METHOD("find_valid_focus_neighbor", "side"), &Control::find_valid_focus_neighbor);

ClassDB::bind_method(D_METHOD("set_render_offset", "offset"), &Control::set_render_offset);
ClassDB::bind_method(D_METHOD("get_render_offset"), &Control::get_render_offset);
ClassDB::bind_method(D_METHOD("set_render_offset_relative_to_size", "relative"), &Control::set_render_offset_relative_to_size);
ClassDB::bind_method(D_METHOD("get_render_offset_relative_to_size"), &Control::get_render_offset_relative_to_size);
ClassDB::bind_method(D_METHOD("set_render_scale", "scale"), &Control::set_render_scale);
ClassDB::bind_method(D_METHOD("get_render_scale"), &Control::get_render_scale);
ClassDB::bind_method(D_METHOD("set_render_rotation", "rotation"), &Control::set_render_rotation);
ClassDB::bind_method(D_METHOD("get_render_rotation"), &Control::get_render_rotation);
ClassDB::bind_method(D_METHOD("set_render_transform_pivot", "pivot"), &Control::set_render_transform_pivot);
ClassDB::bind_method(D_METHOD("get_render_transform_pivot"), &Control::get_render_transform_pivot);
ClassDB::bind_method(D_METHOD("set_render_transform_pivot_relative_to_size", "relative"), &Control::set_render_transform_pivot_relative_to_size);
ClassDB::bind_method(D_METHOD("get_render_transform_pivot_relative_to_size"), &Control::get_render_transform_pivot_relative_to_size);

ClassDB::bind_method(D_METHOD("set_h_size_flags", "flags"), &Control::set_h_size_flags);
ClassDB::bind_method(D_METHOD("get_h_size_flags"), &Control::get_h_size_flags);

Expand Down Expand Up @@ -3588,6 +3701,14 @@ void Control::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_vertical", PROPERTY_HINT_FLAGS, "Fill:1,Expand:2,Shrink Center:4,Shrink End:8"), "set_v_size_flags", "get_v_size_flags");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,20,0.01,or_greater"), "set_stretch_ratio", "get_stretch_ratio");

ADD_GROUP("Render Transform", "render_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "render_offset", PROPERTY_HINT_NONE), "set_render_offset", "get_render_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_offset_relative_to_size"), "set_render_offset_relative_to_size", "get_render_offset_relative_to_size");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "render_scale"), "set_render_scale", "get_render_scale");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "render_rotation", PROPERTY_HINT_NONE, "-360,360,0.1,or_less,or_greater,radians_as_degrees"), "set_render_rotation", "get_render_rotation");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "render_transform_pivot", PROPERTY_HINT_NONE), "set_render_transform_pivot", "get_render_transform_pivot");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_transform_pivot_relative_to_size"), "set_render_transform_pivot_relative_to_size", "get_render_transform_pivot_relative_to_size");

ADD_GROUP("Localization", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "localize_numeral_system"), "set_localize_numeral_system", "is_localizing_numeral_system");

Expand Down
21 changes: 21 additions & 0 deletions scene/gui/control.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ class Control : public CanvasItem {
Vector2 scale = Vector2(1, 1);
Vector2 pivot_offset;

Vector2 render_offset;
bool render_offset_relative_to_size = true;
Vector2 render_scale = Vector2(1, 1);
real_t render_rotation = 0.0;
Vector2 render_transform_pivot;
bool render_transform_pivot_relative_to_size = true;

Point2 pos_cache;
Size2 size_cache;
Size2 minimum_size_cache;
Expand Down Expand Up @@ -493,6 +500,20 @@ class Control : public CanvasItem {
void set_custom_minimum_size(const Size2 &p_custom);
Size2 get_custom_minimum_size() const;

// Render transform.
void set_render_offset(const Vector2 &p_offset);
Vector2 get_render_offset() const;
void set_render_offset_relative_to_size(bool p_relative);
bool get_render_offset_relative_to_size() const;
void set_render_scale(const Vector2 &p_scale);
Vector2 get_render_scale() const;
void set_render_rotation(real_t p_rotation);
real_t get_render_rotation() const;
void set_render_transform_pivot(const Vector2 &p_pivot);
Vector2 get_render_transform_pivot() const;
void set_render_transform_pivot_relative_to_size(bool p_relative);
bool get_render_transform_pivot_relative_to_size() const;

// Container sizing.

void set_h_size_flags(BitField<SizeFlags> p_flags);
Expand Down

0 comments on commit 0d77a96

Please sign in to comment.