From e46e12906a729d1cfaeeba99c2388c6a5b12b61f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Wed, 1 Mar 2017 02:59:08 +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 caae3a1c9be..c22a2090405 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..72c9c46b710 --- /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::_AABB: { + + SETUP_TYPE(AABB) + + /**/ 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::MATRIX32: { + + SETUP_TYPE(Matrix32) + + /**/ 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::MATRIX3: { + + SETUP_TYPE(Matrix3) + + /**/ 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 47b776ed06d..189658acca5 100644 --- a/tools/editor/multi_node_edit.cpp +++ b/tools/editor/multi_node_edit.cpp @@ -28,9 +28,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; @@ -58,7 +64,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)); @@ -166,6 +180,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 170a11221a5..07d469429b4 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 551b3a09f2d..4c6ca914afc 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -30,6 +30,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 "object_type_db.h" #include "print_string.h" #include "globals.h" @@ -233,6 +235,7 @@ Variant CustomPropertyEditor::get_variant() const { return v; } + String CustomPropertyEditor::get_name() const { return name; @@ -244,6 +247,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(); @@ -441,22 +445,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) ); @@ -465,11 +467,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) ); @@ -477,12 +478,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 ) ); @@ -492,12 +492,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 ) ); @@ -507,14 +506,13 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::_AABB: { - 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); AABB aabb=v; value_editor[0]->set_text( String::num( aabb.pos.x ) ); @@ -527,14 +525,13 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::MATRIX32: { - 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); Matrix32 basis=v; for(int i=0;i<6;i++) { @@ -545,17 +542,16 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::MATRIX3: { - 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); Matrix3 basis=v; for(int i=0;i<9;i++) { @@ -567,20 +563,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++) { @@ -818,6 +813,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: { @@ -1371,7 +1374,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; @@ -1388,7 +1391,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: { @@ -1406,7 +1409,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: { @@ -1424,7 +1427,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::_AABB: { @@ -1448,7 +1451,7 @@ void CustomPropertyEditor::_modified(String p_string) { size.z=value_editor[5]->get_text().to_double(); } v=AABB(pos,size); - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; case Variant::MATRIX32: { @@ -1463,7 +1466,7 @@ void CustomPropertyEditor::_modified(String p_string) { } v=m; - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; case Variant::MATRIX3: { @@ -1479,7 +1482,7 @@ void CustomPropertyEditor::_modified(String p_string) { } v=m; - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; case Variant::TRANSFORM: { @@ -1507,7 +1510,7 @@ void CustomPropertyEditor::_modified(String p_string) { } v=Transform(basis,origin); - emit_signal("variant_changed"); + _emit_changed_whole_or_field(); } break; @@ -1573,6 +1576,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; @@ -1594,6 +1606,7 @@ void CustomPropertyEditor::_focus_enter() { case Variant::TRANSFORM: { for (int i=0;ihas_focus()) { + focused_value_editor=i; value_editor[i]->select_all(); break; } @@ -1704,6 +1717,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() { @@ -1724,6 +1738,7 @@ CustomPropertyEditor::CustomPropertyEditor() { value_editor[i]->connect("focus_enter", this, "_focus_enter"); value_editor[i]->connect("focus_exit", this, "_focus_exit"); } + focused_value_editor=-1; for(int i=0;i<4;i++) { @@ -3464,7 +3479,7 @@ void PropertyEditor::_item_selected() { } -void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) { +void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value, const String& p_changed_field) { if (autoclear) { TreeItem *item = tree->get_selected(); @@ -3474,13 +3489,17 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) { } } - 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); _changed_callbacks(obj,p_name); 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 { @@ -3665,10 +3684,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(), p_field_name); +} + void PropertyEditor::_custom_editor_request(bool p_arrow) { TreeItem * item = tree->get_edited(); @@ -3936,6 +3964,7 @@ void PropertyEditor::_bind_methods() { ObjectTypeDB::bind_method( "_item_selected",&PropertyEditor::_item_selected); ObjectTypeDB::bind_method( "_custom_editor_request",&PropertyEditor::_custom_editor_request); ObjectTypeDB::bind_method( "_custom_editor_edited",&PropertyEditor::_custom_editor_edited); + ObjectTypeDB::bind_method( "_custom_editor_edited_field",&PropertyEditor::_custom_editor_edited_field,DEFVAL("")); ObjectTypeDB::bind_method( "_resource_edit_request",&PropertyEditor::_resource_edit_request); ObjectTypeDB::bind_method( "_node_removed",&PropertyEditor::_node_removed); ObjectTypeDB::bind_method( "_edit_button",&PropertyEditor::_edit_button); @@ -4079,6 +4108,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 fce9673a52c..fd66f36c16b 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -84,9 +84,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]; @@ -131,6 +133,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: @@ -193,6 +197,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(); @@ -214,7 +219,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); + void _edit_set(const String& p_name, const Variant& p_value, const String& p_changed_field=""); void _draw_flags(Object *ti,const Rect2& p_rect); bool _might_be_in_instance();