From b8009c85f4684b5fd153329bd7abffe31acb6207 Mon Sep 17 00:00:00 2001 From: Relintai Date: Thu, 22 Dec 2022 18:50:17 +0100 Subject: [PATCH] Ported: Add vector value linking - KoBeWi and timothyqiu https://github.com/godotengine/godot/commit/9499ebecee827b95eea036e58c9a788e13d0ddb2 --- core/global_constants.cpp | 4 +- core/object/object.h | 1 + doc/classes/@GlobalScope.xml | 5 +- editor/editor_properties.cpp | 358 ++++++++++++++++++++++++++++----- editor/editor_properties.h | 33 ++- editor/icons/icon_unlinked.svg | 1 + scene/2d/node_2d.cpp | 2 +- scene/3d/spatial.cpp | 2 +- scene/gui/control.cpp | 8 +- 9 files changed, 356 insertions(+), 58 deletions(-) create mode 100644 editor/icons/icon_unlinked.svg diff --git a/core/global_constants.cpp b/core/global_constants.cpp index 886f31590..e84ba4844 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -628,11 +628,13 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_OBJECT_TOO_BIG); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_NODE_PATH_VALID_TYPES); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_SAVE_FILE); + BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_LINK); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_MAX); + BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORAGE); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_NETWORK); - + BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_EDITOR_HELPER); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CHECKABLE); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CHECKED); diff --git a/core/object/object.h b/core/object/object.h index 45bcb91f6..821c96c5a 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -95,6 +95,7 @@ enum PropertyHint { PROPERTY_HINT_NODE_PATH_VALID_TYPES, PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog PROPERTY_HINT_ENUM_SUGGESTION, ///< hint_text= "val1,val2,val3,etc" + PROPERTY_HINT_LINK, PROPERTY_HINT_MAX, // When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit }; diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 2da0eef03..0fc506902 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -1547,7 +1547,10 @@ - + + Hints that a vector property should allow linking values (e.g. to edit both [code]x[/code] and [code]y[/code] together). + + The property is serialized and saved in the scene file (default). diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index ee5919027..f83988b67 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -30,10 +30,10 @@ #include "editor_properties.h" -#include "core/variant/array.h" -#include "core/object/class_db.h" -#include "core/variant/dictionary.h" +#include "core/config/project_settings.h" +#include "core/containers/rid.h" #include "core/error/error_macros.h" +#include "core/input/input_event.h" #include "core/math/aabb.h" #include "core/math/basis.h" #include "core/math/math_defs.h" @@ -45,14 +45,14 @@ #include "core/math/transform.h" #include "core/math/transform_2d.h" #include "core/math/vector3.h" +#include "core/object/class_db.h" #include "core/object/object.h" #include "core/object/object_id.h" -#include "core/input/input_event.h" -#include "core/os/memory.h" -#include "core/config/project_settings.h" -#include "core/containers/rid.h" #include "core/object/script_language.h" +#include "core/os/memory.h" #include "core/typedefs.h" +#include "core/variant/array.h" +#include "core/variant/dictionary.h" #include "editor/create_dialog.h" #include "editor/editor_data.h" #include "editor/editor_file_dialog.h" @@ -79,6 +79,7 @@ #include "scene/gui/popup.h" #include "scene/gui/popup_menu.h" #include "scene/gui/text_edit.h" +#include "scene/gui/texture_button.h" #include "scene/gui/tool_button.h" #include "scene/main/node.h" #include "scene/main/scene_tree.h" @@ -1544,6 +1545,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(); @@ -1556,6 +1569,19 @@ 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) { @@ -1567,13 +1593,31 @@ void EditorPropertyVector2::_notification(int p_what) { spin[i]->set_custom_label_color(true, c); } } + + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + Ref normal_icon = get_theme_icon("Unlinked", "EditorIcons"); + linked->set_custom_minimum_size(Vector2(normal_icon->get_width(), 0)); + linked->set_normal_texture(normal_icon); + linked->set_pressed_texture(get_theme_icon("Instance", "EditorIcons")); + + Color base = get_theme_color("accent_color", "Editor"); + for (int i = 0; i < 2; i++) { + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } break; + } } void EditorPropertyVector2::_bind_methods() { + ClassDB::bind_method(D_METHOD("_update_ratio"), &EditorPropertyVector2::_update_ratio); ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyVector2::_value_changed); } -void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, bool p_no_slider) { +void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link) { for (int i = 0; i < 2; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -1582,22 +1626,33 @@ void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, boo spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector2::EditorPropertyVector2() { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing"); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; 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++) { spin[i] = memnew(EditorSpinSlider); @@ -1611,6 +1666,15 @@ EditorPropertyVector2::EditorPropertyVector2() { } } + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_expand(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect("pressed", this, "_update_ratio"); + hb->add_child(linked); + + add_child(hb); + if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } @@ -1624,6 +1688,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(); @@ -1636,24 +1712,46 @@ 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) { - if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { - Color base = get_theme_color("accent_color", "Editor"); - for (int i = 0; i < 2; i++) { - Color c = base; - c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); - spin[i]->set_custom_label_color(true, c); - } + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + Ref normal_icon = get_theme_icon("Unlinked", "EditorIcons"); + linked->set_custom_minimum_size(Vector2(normal_icon->get_width(), 0)); + linked->set_normal_texture(normal_icon); + linked->set_pressed_texture(get_theme_icon("Instance", "EditorIcons")); + + Color base = get_theme_color("accent_color", "Editor"); + for (int i = 0; i < 2; i++) { + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } break; } } void EditorPropertyVector2i::_bind_methods() { + ClassDB::bind_method(D_METHOD("_update_ratio"), &EditorPropertyVector2i::_update_ratio); ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyVector2i::_value_changed); } -void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider) { +void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider, bool p_link) { for (int i = 0; i < 2; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -1662,22 +1760,33 @@ void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider) { spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector2i::EditorPropertyVector2i() { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing"); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; 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++) { spin[i] = memnew(EditorSpinSlider); @@ -1691,6 +1800,15 @@ EditorPropertyVector2i::EditorPropertyVector2i() { } } + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_expand(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect("pressed", this, "_update_ratio"); + hb->add_child(linked); + + add_child(hb); + if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } @@ -1868,6 +1986,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(); @@ -1885,6 +2022,8 @@ void EditorPropertyVector3::update_using_vector(Vector3 p_vector) { spin[1]->set_value(p_vector.y); spin[2]->set_value(p_vector.z); setting = false; + + _update_ratio(); } Vector3 EditorPropertyVector3::get_vector() { @@ -1895,21 +2034,50 @@ Vector3 EditorPropertyVector3::get_vector() { return v3; } +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::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { - Color base = get_theme_color("accent_color", "Editor"); - for (int i = 0; i < 3; i++) { - Color c = base; - c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); - spin[i]->set_custom_label_color(true, c); - } + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + Ref normal_icon = get_theme_icon("Unlinked", "EditorIcons"); + linked->set_custom_minimum_size(Vector2(normal_icon->get_width(), 0)); + linked->set_normal_texture(normal_icon); + linked->set_pressed_texture(get_theme_icon("Instance", "EditorIcons")); + + Color base = get_theme_color("accent_color", "Editor"); + for (int i = 0; i < 3; i++) { + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } break; } } void EditorPropertyVector3::_bind_methods() { + ClassDB::bind_method(D_METHOD("_update_ratio"), &EditorPropertyVector3::_update_ratio); ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyVector3::_value_changed); } -void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, bool p_no_slider) { +void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link) { for (int i = 0; i < 3; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -1918,22 +2086,33 @@ void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, boo spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector3::EditorPropertyVector3() { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; 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++) { spin[i] = memnew(EditorSpinSlider); @@ -1947,10 +2126,20 @@ EditorPropertyVector3::EditorPropertyVector3() { } } + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_expand(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect("pressed", this, "_update_ratio"); + hb->add_child(linked); + + add_child(hb); + if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } setting = false; + _update_ratio(); } ///////////////////// VECTOR3I ///////////////////////// @@ -1960,6 +2149,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(); @@ -1974,22 +2182,54 @@ 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) { - if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { - Color base = get_theme_color("accent_color", "Editor"); - for (int i = 0; i < 3; i++) { - Color c = base; - c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); - spin[i]->set_custom_label_color(true, c); - } + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + Ref normal_icon = get_theme_icon("Unlinked", "EditorIcons"); + linked->set_custom_minimum_size(Vector2(normal_icon->get_width(), 0)); + linked->set_normal_texture(normal_icon); + linked->set_pressed_texture(get_theme_icon("Instance", "EditorIcons")); + + Color base = get_theme_color("accent_color", "Editor"); + for (int i = 0; i < 3; i++) { + Color c = base; + c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v()); + spin[i]->set_custom_label_color(true, c); + } + } break; } } void EditorPropertyVector3i::_bind_methods() { + ClassDB::bind_method(D_METHOD("_update_ratio"), &EditorPropertyVector3i::_update_ratio); ClassDB::bind_method(D_METHOD("_value_changed"), &EditorPropertyVector3i::_value_changed); } -void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider) { +void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider, bool p_link) { for (int i = 0; i < 3; i++) { spin[i]->set_min(p_min); spin[i]->set_max(p_max); @@ -1998,22 +2238,33 @@ void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider) { spin[i]->set_allow_greater(true); spin[i]->set_allow_lesser(true); } + + if (!p_link) { + linked->hide(); + } else { + linked->set_pressed(true); + } } EditorPropertyVector3i::EditorPropertyVector3i() { bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + HBoxContainer *hb = memnew(HBoxContainer); + hb->set_h_size_flags(SIZE_EXPAND_FILL); + BoxContainer *bc; 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++) { spin[i] = memnew(EditorSpinSlider); @@ -2027,10 +2278,21 @@ EditorPropertyVector3i::EditorPropertyVector3i() { } } + linked = memnew(TextureButton); + linked->set_toggle_mode(true); + linked->set_expand(true); + linked->set_stretch_mode(TextureButton::STRETCH_KEEP_CENTERED); + linked->connect("pressed", this, "_update_ratio"); + hb->add_child(linked); + + add_child(hb); + if (!horizontal) { set_label_reference(spin[0]); //show text and buttons around this } setting = false; + + _update_ratio(); } ///////////////////// VECTOR4 ///////////////////////// @@ -3658,7 +3920,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ hide_slider = false; } - editor->setup(min, max, step, hide_slider); + editor->setup(min, max, step, hide_slider, p_hint == PROPERTY_HINT_LINK); add_property_editor(p_path, editor); } break; // 5 @@ -3673,7 +3935,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ hide_slider = false; } - editor->setup(min, max, hide_slider); + editor->setup(min, max, hide_slider, p_hint == PROPERTY_HINT_LINK); add_property_editor(p_path, editor); } break; @@ -3691,7 +3953,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ hide_slider = false; } - editor->setup(min, max, step, hide_slider); + editor->setup(min, max, step, hide_slider, p_hint == PROPERTY_HINT_LINK); add_property_editor(p_path, editor); } break; @@ -3706,7 +3968,7 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ hide_slider = false; } - editor->setup(min, max, hide_slider); + editor->setup(min, max, hide_slider, p_hint == PROPERTY_HINT_LINK); add_property_editor(p_path, editor); } break; diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 05d57b146..003733383 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -65,6 +65,7 @@ class PropertySelector; class SceneTreeDialog; class TextEdit; class VBoxContainer; +class TextureButton; class EditorPropertyNil : public EditorProperty { GDCLASS(EditorPropertyNil, EditorProperty); @@ -424,6 +425,10 @@ class EditorPropertyVector2 : public EditorProperty { GDCLASS(EditorPropertyVector2, EditorProperty); EditorSpinSlider *spin[2]; bool setting; + 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: @@ -432,7 +437,7 @@ protected: public: virtual void update_property(); - void setup(double p_min, double p_max, double p_step, bool p_no_slider); + void setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link = false); EditorPropertyVector2(); }; @@ -440,6 +445,10 @@ class EditorPropertyVector2i : public EditorProperty { GDCLASS(EditorPropertyVector2i, EditorProperty); EditorSpinSlider *spin[2]; bool setting; + 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: @@ -448,7 +457,7 @@ protected: public: virtual void update_property(); - void setup(int p_min, int p_max, bool p_no_slider); + void setup(int p_min, int p_max, bool p_no_slider, bool p_link = false); EditorPropertyVector2i(); }; @@ -488,6 +497,14 @@ class EditorPropertyVector3 : public EditorProperty { GDCLASS(EditorPropertyVector3, EditorProperty); EditorSpinSlider *spin[3]; bool setting; + 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: @@ -498,7 +515,7 @@ public: virtual void update_property(); 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); + void setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_link = false); EditorPropertyVector3(); }; @@ -506,6 +523,14 @@ class EditorPropertyVector3i : public EditorProperty { GDCLASS(EditorPropertyVector3i, EditorProperty); EditorSpinSlider *spin[3]; bool setting; + 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: @@ -514,7 +539,7 @@ protected: public: virtual void update_property(); - void setup(int p_min, int p_max, bool p_no_slider); + void setup(int p_min, int p_max, bool p_no_slider, bool p_link = false); EditorPropertyVector3i(); }; diff --git a/editor/icons/icon_unlinked.svg b/editor/icons/icon_unlinked.svg new file mode 100644 index 000000000..6c831eaca --- /dev/null +++ b/editor/icons/icon_unlinked.svg @@ -0,0 +1 @@ + diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 6ba9c90a7..c6e164d4b 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -425,7 +425,7 @@ void Node2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); - 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::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", 0), "set_transform", "get_transform"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position", PROPERTY_HINT_NONE, "", 0), "set_global_position", "get_global_position"); diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index e0dd270f6..2ab02cf24 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -991,7 +991,7 @@ void Spatial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "translation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_translation", "get_translation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_NONE, "", 0), "set_rotation", "get_rotation"); - 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::TRANSFORM, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "global_translation", PROPERTY_HINT_NONE, "", 0), "set_global_translation", "get_global_translation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "global_rotation", PROPERTY_HINT_NONE, "", 0), "set_global_rotation", "get_global_rotation"); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 8e604ae5d..606193538 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -30,14 +30,14 @@ #include "control.h" +#include "core/config/project_settings.h" +#include "core/input/shortcut.h" #include "core/object/message_queue.h" #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/string/print_string.h" -#include "core/config/project_settings.h" #include "scene/gui/label.h" #include "scene/gui/panel.h" -#include "core/input/shortcut.h" #include "scene/main/canvas_layer.h" #include "scene/main/node.h" #include "scene/main/timer.h" @@ -435,6 +435,10 @@ void Control::_validate_property(PropertyInfo &property) const { property.hint_string = hint_string; } + + if (property.name == "rect_scale") { + property.hint = PROPERTY_HINT_LINK; + } } Control *Control::get_parent_control() const {