From 1e867cb9d439f1e989f44730b936e2a00e213100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Thu, 2 Mar 2017 10:42:05 +0100 Subject: [PATCH] Implement single-field property change for multinode edit --- core/SCsub | 1 + core/helper/SCsub | 7 ++ core/helper/math_fieldwise.cpp | 171 ++++++++++++++++++++++++++++ core/helper/math_fieldwise.h | 40 +++++++ tools/editor/multi_node_edit.cpp | 21 +++- tools/editor/multi_node_edit.h | 4 + tools/editor/property_editor.cpp | 190 ++++++++++++++++++------------- tools/editor/property_editor.h | 7 +- 8 files changed, 359 insertions(+), 82 deletions(-) create mode 100644 core/helper/SCsub create mode 100644 core/helper/math_fieldwise.cpp create mode 100644 core/helper/math_fieldwise.h diff --git a/core/SCsub b/core/SCsub index a9721a10526..77c8288846e 100644 --- a/core/SCsub +++ b/core/SCsub @@ -61,6 +61,7 @@ SConscript('os/SCsub') SConscript('math/SCsub') SConscript('io/SCsub') SConscript('bind/SCsub') +SConscript('helper/SCsub') lib = env.Library("core", env.core_sources) diff --git a/core/helper/SCsub b/core/helper/SCsub new file mode 100644 index 00000000000..4efc9027176 --- /dev/null +++ b/core/helper/SCsub @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +Import('env') + +env.add_source_files(env.core_sources, "*.cpp") + +Export('env') diff --git a/core/helper/math_fieldwise.cpp b/core/helper/math_fieldwise.cpp new file mode 100644 index 00000000000..204c431e1d1 --- /dev/null +++ b/core/helper/math_fieldwise.cpp @@ -0,0 +1,171 @@ +/*************************************************************************/ +/* fieldwise.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifdef TOOLS_ENABLED + +#include "core/helper/math_fieldwise.h" + +#define SETUP_TYPE(m_type) m_type source=p_source; m_type target=p_target; +#define TRY_TRANSFER_FIELD(m_name,m_member) if (p_field==m_name) { target.m_member=source.m_member; } + +Variant fieldwise_assign(const Variant& p_target, const Variant& p_source, const String& p_field) { + + ERR_FAIL_COND_V(p_target.get_type()!=p_source.get_type(),p_target); + + switch (p_source.get_type()) { + + case Variant::VECTOR2: { + + SETUP_TYPE(Vector2) + + /**/ TRY_TRANSFER_FIELD("x",x) + else TRY_TRANSFER_FIELD("y",y) + + return target; + } + + case Variant::RECT2: { + + SETUP_TYPE(Rect2) + + /**/ TRY_TRANSFER_FIELD("x",pos.x) + else TRY_TRANSFER_FIELD("y",pos.y) + else TRY_TRANSFER_FIELD("w",size.x) + else TRY_TRANSFER_FIELD("h",size.y) + + return target; + } + + case Variant::VECTOR3: { + + SETUP_TYPE(Vector3) + + /**/ TRY_TRANSFER_FIELD("x",x) + else TRY_TRANSFER_FIELD("y",y) + else TRY_TRANSFER_FIELD("z",z) + + return target; + } + + case Variant::PLANE: { + + SETUP_TYPE(Plane) + + /**/ TRY_TRANSFER_FIELD("x",normal.x) + else TRY_TRANSFER_FIELD("y",normal.y) + else TRY_TRANSFER_FIELD("z",normal.z) + else TRY_TRANSFER_FIELD("d",d) + + return target; + } + + case Variant::QUAT: { + + SETUP_TYPE(Quat) + + /**/ TRY_TRANSFER_FIELD("x",x) + else TRY_TRANSFER_FIELD("y",y) + else TRY_TRANSFER_FIELD("z",z) + else TRY_TRANSFER_FIELD("w",w) + + return target; + } + + case Variant::RECT3: { + + SETUP_TYPE(Rect3) + + /**/ TRY_TRANSFER_FIELD("px",pos.x) + else TRY_TRANSFER_FIELD("py",pos.y) + else TRY_TRANSFER_FIELD("pz",pos.z) + else TRY_TRANSFER_FIELD("sx",size.x) + else TRY_TRANSFER_FIELD("sy",size.y) + else TRY_TRANSFER_FIELD("sz",size.z) + + return target; + } + + case Variant::TRANSFORM2D: { + + SETUP_TYPE(Transform2D) + + /**/ TRY_TRANSFER_FIELD("xx",elements[0][0]) + else TRY_TRANSFER_FIELD("xy",elements[0][1]) + else TRY_TRANSFER_FIELD("yx",elements[1][0]) + else TRY_TRANSFER_FIELD("yy",elements[1][1]) + else TRY_TRANSFER_FIELD("ox",elements[2][0]) + else TRY_TRANSFER_FIELD("oy",elements[2][1]) + + return target; + } + + case Variant::BASIS: { + + SETUP_TYPE(Basis) + + /**/ TRY_TRANSFER_FIELD("xx",elements[0][0]) + else TRY_TRANSFER_FIELD("xy",elements[0][1]) + else TRY_TRANSFER_FIELD("xz",elements[0][2]) + else TRY_TRANSFER_FIELD("yx",elements[1][0]) + else TRY_TRANSFER_FIELD("yy",elements[1][1]) + else TRY_TRANSFER_FIELD("yz",elements[1][2]) + else TRY_TRANSFER_FIELD("zx",elements[2][0]) + else TRY_TRANSFER_FIELD("zy",elements[2][1]) + else TRY_TRANSFER_FIELD("zz",elements[2][2]) + + return target; + } + + case Variant::TRANSFORM: { + + SETUP_TYPE(Transform) + + /**/ TRY_TRANSFER_FIELD("xx",basis.elements[0][0]) + else TRY_TRANSFER_FIELD("xy",basis.elements[0][1]) + else TRY_TRANSFER_FIELD("xz",basis.elements[0][2]) + else TRY_TRANSFER_FIELD("yx",basis.elements[1][0]) + else TRY_TRANSFER_FIELD("yy",basis.elements[1][1]) + else TRY_TRANSFER_FIELD("yz",basis.elements[1][2]) + else TRY_TRANSFER_FIELD("zx",basis.elements[2][0]) + else TRY_TRANSFER_FIELD("zy",basis.elements[2][1]) + else TRY_TRANSFER_FIELD("zz",basis.elements[2][2]) + else TRY_TRANSFER_FIELD("xo",origin.x) + else TRY_TRANSFER_FIELD("yo",origin.y) + else TRY_TRANSFER_FIELD("zo",origin.z) + + return target; + } + + default: { + ERR_FAIL_V(p_target); + } + } +} + +#endif // TOOLS_ENABLED diff --git a/core/helper/math_fieldwise.h b/core/helper/math_fieldwise.h new file mode 100644 index 00000000000..31f9af8d0b1 --- /dev/null +++ b/core/helper/math_fieldwise.h @@ -0,0 +1,40 @@ +/*************************************************************************/ +/* fieldwise.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef MATH_FIELDWISE_H +#define MATH_FIELDWISE_H + +#ifdef TOOLS_ENABLED + +#include "core/variant.h" + +Variant fieldwise_assign(const Variant& p_target, const Variant& p_source, const String& p_field); + +#endif // TOOLS_ENABLED + +#endif // MATH_FIELDWISE_H diff --git a/tools/editor/multi_node_edit.cpp b/tools/editor/multi_node_edit.cpp index 27bb6d66fcd..0428d7ef303 100644 --- a/tools/editor/multi_node_edit.cpp +++ b/tools/editor/multi_node_edit.cpp @@ -29,9 +29,15 @@ #include "multi_node_edit.h" #include "editor_node.h" +#include "core/helper/math_fieldwise.h" bool MultiNodeEdit::_set(const StringName& p_name, const Variant& p_value){ + return _set_impl(p_name, p_value, ""); +} + +bool MultiNodeEdit::_set_impl(const StringName& p_name, const Variant& p_value, const String& p_field) { + Node *es = EditorNode::get_singleton()->get_edited_scene(); if (!es) return false; @@ -59,7 +65,15 @@ bool MultiNodeEdit::_set(const StringName& p_name, const Variant& p_value){ NodePath p_path = n->get_path_to(tonode); ur->add_do_property(n,name,p_path); } else { - ur->add_do_property(n,name,p_value); + Variant new_value; + if (p_field=="") { + // whole value + new_value=p_value; + } else { + // only one field + new_value=fieldwise_assign(n->get(name),p_value,p_field); + } + ur->add_do_property(n,name,new_value); } ur->add_undo_property(n,name,n->get(name)); @@ -167,6 +181,11 @@ void MultiNodeEdit::add_node(const NodePath& p_node){ nodes.push_back(p_node); } +void MultiNodeEdit::set_property_field(const StringName& p_property, const Variant& p_value, const String& p_field) { + + _set_impl(p_property, p_value, p_field); +} + MultiNodeEdit::MultiNodeEdit() { } diff --git a/tools/editor/multi_node_edit.h b/tools/editor/multi_node_edit.h index 290c529d489..26e557c1cbe 100644 --- a/tools/editor/multi_node_edit.h +++ b/tools/editor/multi_node_edit.h @@ -41,6 +41,8 @@ class MultiNodeEdit : public Reference { PropertyInfo info; }; + bool _set_impl(const StringName& p_name, const Variant& p_value, const String& p_field); + protected: @@ -55,6 +57,8 @@ public: void clear_nodes(); void add_node(const NodePath& p_node); + void set_property_field(const StringName& p_property, const Variant& p_value, const String& p_field); + MultiNodeEdit(); }; diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index ec1de03bd64..533a5b156b3 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -31,6 +31,8 @@ #include "scene/gui/label.h" #include "io/resource_loader.h" #include "io/image_loader.h" +#include "os/input.h" +#include "os/keyboard.h" #include "class_db.h" #include "print_string.h" #include "global_config.h" @@ -280,6 +282,7 @@ Variant CustomPropertyEditor::get_variant() const { return v; } + String CustomPropertyEditor::get_name() const { return name; @@ -291,6 +294,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty updating=true; name=p_name; v=p_variant; + field_names.clear(); hint=p_hint; hint_text=p_hint_text; type_button->hide(); @@ -667,22 +671,20 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::VECTOR2: { - List names; - names.push_back("x"); - names.push_back("y"); - config_value_editors(2,2,10,names); + field_names.push_back("x"); + field_names.push_back("y"); + config_value_editors(2,2,10,field_names); Vector2 vec=v; value_editor[0]->set_text( String::num( vec.x) ); value_editor[1]->set_text( String::num( vec.y) ); } break; case Variant::RECT2: { - List names; - names.push_back("x"); - names.push_back("y"); - names.push_back("w"); - names.push_back("h"); - config_value_editors(4,4,10,names); + field_names.push_back("x"); + field_names.push_back("y"); + field_names.push_back("w"); + field_names.push_back("h"); + config_value_editors(4,4,10,field_names); Rect2 r=v; value_editor[0]->set_text( String::num( r.pos.x) ); value_editor[1]->set_text( String::num( r.pos.y) ); @@ -691,11 +693,10 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::VECTOR3: { - List names; - names.push_back("x"); - names.push_back("y"); - names.push_back("z"); - config_value_editors(3,3,10,names); + field_names.push_back("x"); + field_names.push_back("y"); + field_names.push_back("z"); + config_value_editors(3,3,10,field_names); Vector3 vec=v; value_editor[0]->set_text( String::num( vec.x) ); value_editor[1]->set_text( String::num( vec.y) ); @@ -703,12 +704,11 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::PLANE: { - List names; - names.push_back("x"); - names.push_back("y"); - names.push_back("z"); - names.push_back("d"); - config_value_editors(4,4,10,names); + field_names.push_back("x"); + field_names.push_back("y"); + field_names.push_back("z"); + field_names.push_back("d"); + config_value_editors(4,4,10,field_names); Plane plane=v; value_editor[0]->set_text( String::num( plane.normal.x ) ); value_editor[1]->set_text( String::num( plane.normal.y ) ); @@ -718,12 +718,11 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::QUAT: { - List names; - names.push_back("x"); - names.push_back("y"); - names.push_back("z"); - names.push_back("w"); - config_value_editors(4,4,10,names); + field_names.push_back("x"); + field_names.push_back("y"); + field_names.push_back("z"); + field_names.push_back("w"); + config_value_editors(4,4,10,field_names); Quat q=v; value_editor[0]->set_text( String::num( q.x ) ); value_editor[1]->set_text( String::num( q.y ) ); @@ -733,14 +732,13 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::RECT3: { - List names; - names.push_back("px"); - names.push_back("py"); - names.push_back("pz"); - names.push_back("sx"); - names.push_back("sy"); - names.push_back("sz"); - config_value_editors(6,3,16,names); + field_names.push_back("px"); + field_names.push_back("py"); + field_names.push_back("pz"); + field_names.push_back("sx"); + field_names.push_back("sy"); + field_names.push_back("sz"); + config_value_editors(6,3,16,field_names); Rect3 aabb=v; value_editor[0]->set_text( String::num( aabb.pos.x ) ); @@ -753,14 +751,13 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::TRANSFORM2D: { - List names; - names.push_back("xx"); - names.push_back("xy"); - names.push_back("yx"); - names.push_back("yy"); - names.push_back("ox"); - names.push_back("oy"); - config_value_editors(6,2,16,names); + field_names.push_back("xx"); + field_names.push_back("xy"); + field_names.push_back("yx"); + field_names.push_back("yy"); + field_names.push_back("ox"); + field_names.push_back("oy"); + config_value_editors(6,2,16,field_names); Transform2D basis=v; for(int i=0;i<6;i++) { @@ -771,17 +768,16 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::BASIS: { - List names; - names.push_back("xx"); - names.push_back("xy"); - names.push_back("xz"); - names.push_back("yx"); - names.push_back("yy"); - names.push_back("yz"); - names.push_back("zx"); - names.push_back("zy"); - names.push_back("zz"); - config_value_editors(9,3,16,names); + field_names.push_back("xx"); + field_names.push_back("xy"); + field_names.push_back("xz"); + field_names.push_back("yx"); + field_names.push_back("yy"); + field_names.push_back("yz"); + field_names.push_back("zx"); + field_names.push_back("zy"); + field_names.push_back("zz"); + config_value_editors(9,3,16,field_names); Basis basis=v; for(int i=0;i<9;i++) { @@ -793,20 +789,19 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty case Variant::TRANSFORM: { - List names; - names.push_back("xx"); - names.push_back("xy"); - names.push_back("xz"); - names.push_back("xo"); - names.push_back("yx"); - names.push_back("yy"); - names.push_back("yz"); - names.push_back("yo"); - names.push_back("zx"); - names.push_back("zy"); - names.push_back("zz"); - names.push_back("zo"); - config_value_editors(12,4,16,names); + field_names.push_back("xx"); + field_names.push_back("xy"); + field_names.push_back("xz"); + field_names.push_back("xo"); + field_names.push_back("yx"); + field_names.push_back("yy"); + field_names.push_back("yz"); + field_names.push_back("yo"); + field_names.push_back("zx"); + field_names.push_back("zy"); + field_names.push_back("zz"); + field_names.push_back("zo"); + config_value_editors(12,4,16,field_names); Transform tr=v; for(int i=0;i<9;i++) { @@ -1050,6 +1045,14 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty return true; } +////void CustomPropertyEditor::_save_properties_values(List p_names) { +//// +//// field_names=p_names; +//// for (int i=0;iget_text().to_double(); } v=vec; - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; case Variant::RECT2: { @@ -1661,7 +1664,7 @@ void CustomPropertyEditor::_modified(String p_string) { r2.size.y=value_editor[3]->get_text().to_double(); } v=r2; - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; @@ -1678,7 +1681,7 @@ void CustomPropertyEditor::_modified(String p_string) { vec.z=value_editor[2]->get_text().to_double(); } v=vec; - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; case Variant::PLANE: { @@ -1696,7 +1699,7 @@ void CustomPropertyEditor::_modified(String p_string) { pl.d=value_editor[3]->get_text().to_double(); } v=pl; - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; case Variant::QUAT: { @@ -1714,7 +1717,7 @@ void CustomPropertyEditor::_modified(String p_string) { q.w=value_editor[3]->get_text().to_double(); } v=q; - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; case Variant::RECT3: { @@ -1738,7 +1741,7 @@ void CustomPropertyEditor::_modified(String p_string) { size.z=value_editor[5]->get_text().to_double(); } v=Rect3(pos,size); - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; case Variant::TRANSFORM2D: { @@ -1753,7 +1756,7 @@ void CustomPropertyEditor::_modified(String p_string) { } v=m; - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; case Variant::BASIS: { @@ -1769,7 +1772,7 @@ void CustomPropertyEditor::_modified(String p_string) { } v=m; - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; case Variant::TRANSFORM: { @@ -1797,7 +1800,7 @@ void CustomPropertyEditor::_modified(String p_string) { } v=Transform(basis,origin); - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; @@ -1864,6 +1867,15 @@ void CustomPropertyEditor::_modified(String p_string) { updating=false; } +void CustomPropertyEditor::_emit_changed_whole_or_field() { + + if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { + emit_signal("variant_changed"); + } else { + emit_signal("variant_field_changed",field_names[focused_value_editor]); + } +} + void CustomPropertyEditor::_range_modified(double p_value) { v=p_value; @@ -1885,6 +1897,7 @@ void CustomPropertyEditor::_focus_enter() { case Variant::TRANSFORM: { for (int i=0;ihas_focus()) { + focused_value_editor=i; value_editor[i]->select_all(); break; } @@ -1997,6 +2010,7 @@ void CustomPropertyEditor::_bind_methods() { ADD_SIGNAL( MethodInfo("variant_changed") ); + ADD_SIGNAL( MethodInfo("variant_field_changed",PropertyInfo(Variant::STRING,"field")) ); ADD_SIGNAL( MethodInfo("resource_edit_request") ); } CustomPropertyEditor::CustomPropertyEditor() { @@ -2017,6 +2031,7 @@ CustomPropertyEditor::CustomPropertyEditor() { value_editor[i]->connect("focus_entered", this, "_focus_enter"); value_editor[i]->connect("focus_exited", this, "_focus_exit"); } + focused_value_editor=-1; for(int i=0;i<4;i++) { @@ -3904,7 +3919,7 @@ void PropertyEditor::_item_selected() { } -void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value, bool p_refresh_all) { +void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value, bool p_refresh_all, const String& p_changed_field) { if (autoclear) { TreeItem *item = tree->get_selected(); @@ -3914,7 +3929,7 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value, boo } } - if (!undo_redo || obj->cast_to() || obj->cast_to()) { //kind of hacky + if (!undo_redo|| obj->cast_to()) { //kind of hacky obj->set(p_name,p_value); if (p_refresh_all) @@ -3924,7 +3939,11 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value, boo emit_signal(_prop_edited,p_name); + } else if (obj->cast_to()) { + obj->cast_to()->set_property_field(p_name,p_value,p_changed_field); + _changed_callbacks(obj,p_name); + emit_signal(_prop_edited,p_name); } else { undo_redo->create_action(TTR("Set")+" "+p_name,UndoRedo::MERGE_ENDS); @@ -4129,10 +4148,19 @@ void PropertyEditor::_custom_editor_edited() { if (!obj) return; - _edit_set(custom_editor->get_name(), custom_editor->get_variant()); } +void PropertyEditor::_custom_editor_edited_field(const String& p_field_name) { + + ERR_FAIL_COND(p_field_name==""); + + if (!obj) + return; + + _edit_set(custom_editor->get_name(), custom_editor->get_variant(), false, p_field_name); +} + void PropertyEditor::_custom_editor_request(bool p_arrow) { TreeItem * item = tree->get_edited(); @@ -4405,6 +4433,7 @@ void PropertyEditor::_bind_methods() { ClassDB::bind_method( "_item_selected",&PropertyEditor::_item_selected); ClassDB::bind_method( "_custom_editor_request",&PropertyEditor::_custom_editor_request); ClassDB::bind_method( "_custom_editor_edited",&PropertyEditor::_custom_editor_edited); + ClassDB::bind_method( "_custom_editor_edited_field",&PropertyEditor::_custom_editor_edited_field,DEFVAL("")); ClassDB::bind_method( "_resource_edit_request",&PropertyEditor::_resource_edit_request); ClassDB::bind_method( "_node_removed",&PropertyEditor::_node_removed); ClassDB::bind_method( "_edit_button",&PropertyEditor::_edit_button); @@ -4551,6 +4580,7 @@ PropertyEditor::PropertyEditor() { tree->connect("custom_popup_edited", this,"_custom_editor_request"); tree->connect("button_pressed", this,"_edit_button"); custom_editor->connect("variant_changed", this,"_custom_editor_edited"); + custom_editor->connect("variant_field_changed", this,"_custom_editor_edited_field"); custom_editor->connect("resource_edit_request", this,"_resource_edit_request",make_binds(),CONNECT_DEFERRED); tree->set_hide_folding(true); diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index 817b2716f0a..e31a3313c1d 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -88,9 +88,11 @@ class CustomPropertyEditor : public Popup { String name; Variant::Type type; Variant v; + List field_names; int hint; String hint_text; LineEdit *value_editor[MAX_VALUE_EDITORS]; + int focused_value_editor; Label *value_label[MAX_VALUE_EDITORS]; HScrollBar *scroll[4]; Button *action_buttons[MAX_ACTION_BUTTONS]; @@ -141,6 +143,8 @@ class CustomPropertyEditor : public Popup { void config_value_editors(int p_amount, int p_columns,int p_label_w,const List& p_strings); void config_action_buttons(const List& p_strings); + void _emit_changed_whole_or_field(); + protected: @@ -204,6 +208,7 @@ class PropertyEditor : public Control { void _resource_edit_request(); void _custom_editor_edited(); + void _custom_editor_edited_field(const String& p_field_name); void _custom_editor_request(bool p_arrow); void _item_selected(); @@ -225,7 +230,7 @@ class PropertyEditor : public Control { void _node_removed(Node *p_node); friend class ProjectExportDialog; - void _edit_set(const String& p_name, const Variant& p_value,bool p_refresh_all=false); + void _edit_set(const String& p_name, const Variant& p_value,bool p_refresh_all=false, const String& p_changed_field=""); void _draw_flags(Object *ti,const Rect2& p_rect); bool _might_be_in_instance();