From 5553e27fe8346eed22ca4a47728fedcf2a7d7ffd Mon Sep 17 00:00:00 2001 From: kobewi Date: Tue, 5 Apr 2022 02:58:21 +0200 Subject: [PATCH] Add vector value linking Co-authored-by: redlamp <244062+redlamp@users.noreply.github.com> --- core/core_constants.cpp | 1 + core/object/object.h | 1 + doc/classes/@GlobalScope.xml | 79 ++++++----- editor/editor_properties.cpp | 264 +++++++++++++++++++++++++++++++---- editor/editor_properties.h | 34 ++++- editor/icons/Unlinked.svg | 1 + scene/2d/node_2d.cpp | 2 +- scene/3d/node_3d.cpp | 2 +- scene/gui/control.cpp | 4 + 9 files changed, 312 insertions(+), 76 deletions(-) create mode 100644 editor/icons/Unlinked.svg diff --git a/core/core_constants.cpp b/core/core_constants.cpp index bbc937d5754..4f22c996569 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -552,6 +552,7 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM_SUGGESTION); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_EXP_EASING); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LENGTH); + BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LINK); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_KEY_ACCEL); BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_FLAGS); diff --git a/core/object/object.h b/core/object/object.h index 988d261d773..69531ee5f52 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -52,6 +52,7 @@ enum PropertyHint { PROPERTY_HINT_ENUM_SUGGESTION, ///< hint_text= "val1,val2,val3,etc" PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout") PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer) + PROPERTY_HINT_LINK, PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer) PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags) PROPERTY_HINT_LAYERS_2D_RENDER, diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index dce96fb315b..18ea29857bc 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2419,63 +2419,66 @@ Deprecated hint, unused. - + + Hints that a vector property should allow linking values (e.g. to edit both [code]x[/code] and [code]y[/code] together). + + Deprecated hint, unused. - + Hints that an integer property is a bitmask with named bit flags. For example, to allow toggling bits 0, 1, 2 and 4, the hint could be something like [code]"Bit0,Bit1,Bit2,,Bit4"[/code]. - + Hints that an integer property is a bitmask using the optionally named 2D render layers. - + Hints that an integer property is a bitmask using the optionally named 2D physics layers. - + Hints that an integer property is a bitmask using the optionally named 2D navigation layers. - + Hints that an integer property is a bitmask using the optionally named 3D render layers. - + Hints that an integer property is a bitmask using the optionally named 3D physics layers. - + Hints that an integer property is a bitmask using the optionally named 2D navigation layers. - + Hints that a string property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code]. - + Hints that a string property is a path to a directory. Editing it will show a file dialog for picking the path. - + Hints that a string property is an absolute path to a file outside the project folder. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code]. - + Hints that a string property is an absolute path to a directory outside the project folder. Editing it will show a file dialog for picking the path. - + Hints that a property is an instance of a [Resource]-derived type, optionally specified via the hint string (e.g. [code]"Texture2D"[/code]). Editing it will show a popup menu of valid resource types to instantiate. - + Hints that a string property is text with line breaks. Editing it will show a text input field where line breaks can be typed. - + Hints that a string property should have a placeholder text visible on its input field, whenever the property is empty. The hint string is the placeholder text to use. - + Hints that a color property should be edited without changing its alpha component, i.e. only R, G and B channels are edited. - + Hints that an image is compressed using lossy compression. - + Hints that an image is compressed using lossless compression. - + - + Hint that a property represents a particular type. If a property is [constant TYPE_STRING], allows to set a type from the create dialog. If you need to create an [Array] to contain elements of a specific type, the [code]hint_string[/code] must encode nested types using [code]":"[/code] and [code]"/"[/code] for specifying [Resource] types. For instance: [codeblock] hint_string = "%s:" % [TYPE_INT] # Array of inteters. @@ -2485,43 +2488,43 @@ [/codeblock] [b]Note:[/b] The final colon is required to specify for properly detecting built-in types. - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + Hints that a string property is a locale code. Editing it will show a locale dialog for picking language and country. - + Hints that a dictionary property is string translation map. Dictionary keys are locale codes and, values are translated strings. - + diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index ddf1974070a..a5c02c70d9d 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1597,6 +1597,18 @@ void EditorPropertyVector2::_value_changed(double val, const String &p_name) { return; } + if (linked->is_pressed()) { + setting = true; + if (p_name == "x") { + spin[1]->set_value(spin[0]->get_value() * ratio_yx); + } + + if (p_name == "y") { + spin[0]->set_value(spin[1]->get_value() * ratio_xy); + } + setting = false; + } + Vector2 v2; v2.x = spin[0]->get_value(); v2.y = spin[1]->get_value(); @@ -1609,12 +1621,28 @@ void EditorPropertyVector2::update_property() { spin[0]->set_value(val.x); spin[1]->set_value(val.y); setting = false; + _update_ratio(); +} + +void EditorPropertyVector2::_update_ratio() { + linked->set_modulate(Color(1, 1, 1, linked->is_pressed() ? 1.0 : 0.5)); + + if (spin[0]->get_value() != 0 && spin[1]->get_value() != 0) { + ratio_xy = spin[0]->get_value() / spin[1]->get_value(); + ratio_yx = spin[1]->get_value() / spin[0]->get_value(); + } else { + ratio_xy = 1.0; + ratio_yx = 1.0; + } } void EditorPropertyVector2::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { + linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + const Color *colors = _get_property_colors(); for (int i = 0; i < 2; i++) { spin[i]->add_theme_color_override("label_color", colors[i]); @@ -1623,10 +1651,7 @@ void EditorPropertyVector2::_notification(int p_what) { } } -void EditorPropertyVector2::_bind_methods() { -} - -void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { +void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link, const String &p_suffix) { for (int i = 0; i < 2; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -1636,24 +1661,34 @@ void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, boo spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector2_editing")); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); - add_child(bc); + hb->add_child(bc); } else if (horizontal) { bc = memnew(HBoxContainer); - add_child(bc); - set_bottom_editor(bc); + hb->add_child(bc); + set_bottom_editor(hb); } else { bc = memnew(VBoxContainer); - add_child(bc); + hb->add_child(bc); } + bc->set_h_size_flags(SIZE_EXPAND_FILL); static const char *desc[2] = { "x", "y" }; for (int i = 0; i < 2; i++) { @@ -1668,6 +1703,13 @@ EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) { } } + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyVector2::_update_ratio)); + hb->add_child(linked); + + add_child(hb); if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } @@ -1789,6 +1831,25 @@ void EditorPropertyVector3::_value_changed(double val, const String &p_name) { return; } + if (linked->is_pressed()) { + setting = true; + if (p_name == "x") { + spin[1]->set_value(spin[0]->get_value() * ratio_yx); + spin[2]->set_value(spin[0]->get_value() * ratio_zx); + } + + if (p_name == "y") { + spin[0]->set_value(spin[1]->get_value() * ratio_xy); + spin[2]->set_value(spin[1]->get_value() * ratio_zy); + } + + if (p_name == "z") { + spin[0]->set_value(spin[2]->get_value() * ratio_xz); + spin[1]->set_value(spin[2]->get_value() * ratio_yz); + } + setting = false; + } + Vector3 v3; v3.x = spin[0]->get_value(); v3.y = spin[1]->get_value(); @@ -1803,6 +1864,27 @@ void EditorPropertyVector3::_value_changed(double val, const String &p_name) { void EditorPropertyVector3::update_property() { update_using_vector(get_edited_object()->get(get_edited_property())); + _update_ratio(); +} + +void EditorPropertyVector3::_update_ratio() { + linked->set_modulate(Color(1, 1, 1, linked->is_pressed() ? 1.0 : 0.5)); + + if (spin[0]->get_value() != 0 && spin[1]->get_value() != 0) { + ratio_yx = spin[1]->get_value() / spin[0]->get_value(); + ratio_zx = spin[2]->get_value() / spin[0]->get_value(); + ratio_xy = spin[0]->get_value() / spin[1]->get_value(); + ratio_zy = spin[2]->get_value() / spin[1]->get_value(); + ratio_xz = spin[0]->get_value() / spin[2]->get_value(); + ratio_yz = spin[1]->get_value() / spin[2]->get_value(); + } else { + ratio_yx = 1.0; + ratio_zx = 1.0; + ratio_xy = 1.0; + ratio_zy = 1.0; + ratio_xz = 1.0; + ratio_yz = 1.0; + } } void EditorPropertyVector3::update_using_vector(Vector3 p_vector) { @@ -1836,6 +1918,9 @@ void EditorPropertyVector3::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { + linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + const Color *colors = _get_property_colors(); for (int i = 0; i < 3; i++) { spin[i]->add_theme_color_override("label_color", colors[i]); @@ -1847,7 +1932,7 @@ void EditorPropertyVector3::_notification(int p_what) { void EditorPropertyVector3::_bind_methods() { } -void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix, bool p_angle_in_radians) { +void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link, const String &p_suffix, bool p_angle_in_radians) { angle_in_radians = p_angle_in_radians; for (int i = 0; i < 3; i++) { spin[i]->set_min(p_min); @@ -1858,24 +1943,34 @@ void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, boo spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); - add_child(bc); + hb->add_child(bc); } else if (horizontal) { bc = memnew(HBoxContainer); - add_child(bc); - set_bottom_editor(bc); + hb->add_child(bc); + set_bottom_editor(hb); } else { bc = memnew(VBoxContainer); - add_child(bc); + hb->add_child(bc); } + bc->set_h_size_flags(SIZE_EXPAND_FILL); static const char *desc[3] = { "x", "y", "z" }; for (int i = 0; i < 3; i++) { @@ -1890,6 +1985,13 @@ EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) { } } + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyVector3::_update_ratio)); + hb->add_child(linked); + + add_child(hb); if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } @@ -1908,6 +2010,18 @@ void EditorPropertyVector2i::_value_changed(double val, const String &p_name) { return; } + if (linked->is_pressed()) { + setting = true; + if (p_name == "x") { + spin[1]->set_value(spin[0]->get_value() * ratio_yx); + } + + if (p_name == "y") { + spin[0]->set_value(spin[1]->get_value() * ratio_xy); + } + setting = false; + } + Vector2i v2; v2.x = spin[0]->get_value(); v2.y = spin[1]->get_value(); @@ -1920,12 +2034,28 @@ void EditorPropertyVector2i::update_property() { spin[0]->set_value(val.x); spin[1]->set_value(val.y); setting = false; + _update_ratio(); +} + +void EditorPropertyVector2i::_update_ratio() { + linked->set_modulate(Color(1, 1, 1, linked->is_pressed() ? 1.0 : 0.5)); + + if (spin[0]->get_value() != 0 && spin[1]->get_value() != 0) { + ratio_xy = spin[0]->get_value() / spin[1]->get_value(); + ratio_yx = spin[1]->get_value() / spin[0]->get_value(); + } else { + ratio_xy = 1.0; + ratio_yx = 1.0; + } } void EditorPropertyVector2i::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { + linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + const Color *colors = _get_property_colors(); for (int i = 0; i < 2; i++) { spin[i]->add_theme_color_override("label_color", colors[i]); @@ -1934,10 +2064,7 @@ void EditorPropertyVector2i::_notification(int p_what) { } } -void EditorPropertyVector2i::_bind_methods() { -} - -void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider, const String &p_suffix) { +void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider, bool p_link, const String &p_suffix) { for (int i = 0; i < 2; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -1947,24 +2074,34 @@ void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider, const spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector2_editing")); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); - add_child(bc); + hb->add_child(bc); } else if (horizontal) { bc = memnew(HBoxContainer); - add_child(bc); - set_bottom_editor(bc); + hb->add_child(bc); + set_bottom_editor(hb); } else { bc = memnew(VBoxContainer); - add_child(bc); + hb->add_child(bc); } + bc->set_h_size_flags(SIZE_EXPAND_FILL); static const char *desc[2] = { "x", "y" }; for (int i = 0; i < 2; i++) { @@ -1979,6 +2116,13 @@ EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) { } } + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyVector2i::_update_ratio)); + hb->add_child(linked); + + add_child(hb); if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } @@ -2100,6 +2244,25 @@ void EditorPropertyVector3i::_value_changed(double val, const String &p_name) { return; } + if (linked->is_pressed()) { + setting = true; + if (p_name == "x") { + spin[1]->set_value(spin[0]->get_value() * ratio_yx); + spin[2]->set_value(spin[0]->get_value() * ratio_zx); + } + + if (p_name == "y") { + spin[0]->set_value(spin[1]->get_value() * ratio_xy); + spin[2]->set_value(spin[1]->get_value() * ratio_zy); + } + + if (p_name == "z") { + spin[0]->set_value(spin[2]->get_value() * ratio_xz); + spin[1]->set_value(spin[2]->get_value() * ratio_yz); + } + setting = false; + } + Vector3i v3; v3.x = spin[0]->get_value(); v3.y = spin[1]->get_value(); @@ -2114,12 +2277,36 @@ void EditorPropertyVector3i::update_property() { spin[1]->set_value(val.y); spin[2]->set_value(val.z); setting = false; + _update_ratio(); +} + +void EditorPropertyVector3i::_update_ratio() { + linked->set_modulate(Color(1, 1, 1, linked->is_pressed() ? 1.0 : 0.5)); + + if (spin[0]->get_value() != 0 && spin[1]->get_value() != 0) { + ratio_yx = spin[1]->get_value() / spin[0]->get_value(); + ratio_zx = spin[2]->get_value() / spin[0]->get_value(); + ratio_xy = spin[0]->get_value() / spin[1]->get_value(); + ratio_zy = spin[2]->get_value() / spin[1]->get_value(); + ratio_xz = spin[0]->get_value() / spin[2]->get_value(); + ratio_yz = spin[1]->get_value() / spin[2]->get_value(); + } else { + ratio_yx = 1.0; + ratio_zx = 1.0; + ratio_xy = 1.0; + ratio_zy = 1.0; + ratio_xz = 1.0; + ratio_yz = 1.0; + } } void EditorPropertyVector3i::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { + linked->set_normal_texture(get_theme_icon(SNAME("Unlinked"), SNAME("EditorIcons"))); + linked->set_pressed_texture(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons"))); + const Color *colors = _get_property_colors(); for (int i = 0; i < 3; i++) { spin[i]->add_theme_color_override("label_color", colors[i]); @@ -2131,7 +2318,7 @@ void EditorPropertyVector3i::_notification(int p_what) { void EditorPropertyVector3i::_bind_methods() { } -void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider, const String &p_suffix) { +void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider, bool p_link, const String &p_suffix) { for (int i = 0; i < 3; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -2141,22 +2328,31 @@ void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider, const spin[i]->set_allow_lesser(true); spin[i]->set_suffix(p_suffix); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) { bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; if (p_force_wide) { bc = memnew(HBoxContainer); - add_child(bc); + hb->add_child(bc); } else if (horizontal) { bc = memnew(HBoxContainer); - add_child(bc); - set_bottom_editor(bc); + hb->add_child(bc); + set_bottom_editor(hb); } else { bc = memnew(VBoxContainer); - add_child(bc); + hb->add_child(bc); } static const char *desc[3] = { "x", "y", "z" }; @@ -2171,7 +2367,15 @@ EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) { spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); } } + bc->set_h_size_flags(SIZE_EXPAND_FILL); + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect(SNAME("pressed"), callable_mp(this, &EditorPropertyVector3i::_update_ratio)); + hb->add_child(linked); + + add_child(hb); if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } @@ -3608,14 +3812,14 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ EditorPropertyVector2 *editor = memnew(EditorPropertyVector2(p_wide)); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); - editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.suffix); + editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, p_hint == PROPERTY_HINT_LINK, hint.suffix); return editor; } break; case Variant::VECTOR2I: { EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i(p_wide)); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); - editor->setup(hint.min, hint.max, hint.hide_slider, hint.suffix); + editor->setup(hint.min, hint.max, hint.hide_slider, p_hint == PROPERTY_HINT_LINK, hint.suffix); return editor; } break; @@ -3635,14 +3839,14 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ case Variant::VECTOR3: { EditorPropertyVector3 *editor = memnew(EditorPropertyVector3(p_wide)); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); - editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.suffix, hint.radians); + editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, p_hint == PROPERTY_HINT_LINK, hint.suffix, hint.radians); return editor; } break; case Variant::VECTOR3I: { EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i(p_wide)); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); - editor->setup(hint.min, hint.max, hint.hide_slider, hint.suffix); + editor->setup(hint.min, hint.max, hint.hide_slider, p_hint == PROPERTY_HINT_LINK, hint.suffix); return editor; } break; diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 6513eb0390c..a3b98b77247 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -451,16 +451,19 @@ class EditorPropertyVector2 : public EditorProperty { GDCLASS(EditorPropertyVector2, EditorProperty); EditorSpinSlider *spin[2]; bool setting = false; + double ratio_xy = 1.0; + double ratio_yx = 1.0; + TextureButton *linked = nullptr; + void _update_ratio(); void _value_changed(double p_val, const String &p_name); protected: virtual void _set_read_only(bool p_read_only) override; void _notification(int p_what); - static void _bind_methods(); public: virtual void update_property() override; - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + void setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link = false, const String &p_suffix = String()); EditorPropertyVector2(bool p_force_wide = false); }; @@ -486,6 +489,14 @@ class EditorPropertyVector3 : public EditorProperty { EditorSpinSlider *spin[3]; bool setting = false; bool angle_in_radians = false; + double ratio_yx = 1.0; + double ratio_zx = 1.0; + double ratio_xy = 1.0; + double ratio_zy = 1.0; + double ratio_xz = 1.0; + double ratio_yz = 1.0; + TextureButton *linked = nullptr; + void _update_ratio(); void _value_changed(double p_val, const String &p_name); protected: @@ -497,7 +508,7 @@ public: virtual void update_property() override; virtual void update_using_vector(Vector3 p_vector); virtual Vector3 get_vector(); - void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String(), bool p_angle_in_radians = false); + void setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link = false, const String &p_suffix = String(), bool p_angle_in_radians = false); EditorPropertyVector3(bool p_force_wide = false); }; @@ -505,16 +516,19 @@ class EditorPropertyVector2i : public EditorProperty { GDCLASS(EditorPropertyVector2i, EditorProperty); EditorSpinSlider *spin[2]; bool setting = false; + double ratio_xy = 1.0; + double ratio_yx = 1.0; + TextureButton *linked = nullptr; + void _update_ratio(); void _value_changed(double p_val, const String &p_name); protected: virtual void _set_read_only(bool p_read_only) override; void _notification(int p_what); - static void _bind_methods(); public: virtual void update_property() override; - void setup(int p_min, int p_max, bool p_no_slider, const String &p_suffix = String()); + void setup(int p_min, int p_max, bool p_no_slider, bool p_link = false, const String &p_suffix = String()); EditorPropertyVector2i(bool p_force_wide = false); }; @@ -539,6 +553,14 @@ class EditorPropertyVector3i : public EditorProperty { GDCLASS(EditorPropertyVector3i, EditorProperty); EditorSpinSlider *spin[3]; bool setting = false; + double ratio_yx = 1.0; + double ratio_zx = 1.0; + double ratio_xy = 1.0; + double ratio_zy = 1.0; + double ratio_xz = 1.0; + double ratio_yz = 1.0; + TextureButton *linked = nullptr; + void _update_ratio(); void _value_changed(double p_val, const String &p_name); protected: @@ -548,7 +570,7 @@ protected: public: virtual void update_property() override; - void setup(int p_min, int p_max, bool p_no_slider, const String &p_suffix = String()); + void setup(int p_min, int p_max, bool p_no_slider, bool p_link = false, const String &p_suffix = String()); EditorPropertyVector3i(bool p_force_wide = false); }; diff --git a/editor/icons/Unlinked.svg b/editor/icons/Unlinked.svg new file mode 100644 index 00000000000..6c831eacadc --- /dev/null +++ b/editor/icons/Unlinked.svg @@ -0,0 +1 @@ + diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 6fa18d393e9..b2b848d3809 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -439,7 +439,7 @@ void Node2D::_bind_methods() { ADD_GROUP("Transform", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_RANGE, "-99999,99999,0.001,or_lesser,or_greater,noslider,suffix:px"), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians"), "set_rotation", "get_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale", PROPERTY_HINT_LINK), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1,radians"), "set_skew", "get_skew"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "suffix:px", PROPERTY_USAGE_NONE), "set_transform", "get_transform"); diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index a76d57a09fc..6e36815f2b3 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -984,7 +984,7 @@ void Node3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater,radians", PROPERTY_USAGE_EDITOR), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::QUATERNION, "quaternion", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_quaternion", "get_quaternion"); ADD_PROPERTY(PropertyInfo(Variant::BASIS, "basis", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_basis", "get_basis"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_scale", "get_scale"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale", PROPERTY_HINT_LINK, "", PROPERTY_USAGE_EDITOR), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_edit_mode", PROPERTY_HINT_ENUM, "Euler,Quaternion,Basis"), "set_rotation_edit_mode", "get_rotation_edit_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_order", PROPERTY_HINT_ENUM, "XYZ,XZY,YXZ,YZX,ZXY,ZYX"), "set_rotation_order", "get_rotation_order"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "top_level"), "set_as_top_level", "is_set_as_top_level"); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 3db1719226a..5ddc38a0b98 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -478,6 +478,10 @@ void Control::_validate_property(PropertyInfo &property) const { } } + if (property.name == "scale") { + property.hint = PROPERTY_HINT_LINK; + } + // Validate which positioning properties should be displayed depending on the parent and the layout mode. Node *parent_node = get_parent_control(); if (!parent_node) {