diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2022-07-29 19:29:52 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-29 19:29:52 +0200 |
commit | 74d92bf459758404cf48a7ae0249b381613bfab1 (patch) | |
tree | 4b8ccf40d06831145f15debe64970c16d9f9edd1 | |
parent | 7199314eb39408da4f9f7286452c980a3d3da1c9 (diff) | |
parent | 44cf3c22acb140cc2f19f1062c0a4c0a931fd27b (diff) |
Merge pull request #43081 from KoBeWi/property_keeper
Keep property values when extending script
-rw-r--r-- | editor/editor_properties.cpp | 8 | ||||
-rw-r--r-- | editor/inspector_dock.cpp | 28 | ||||
-rw-r--r-- | editor/inspector_dock.h | 4 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 40 |
4 files changed, 71 insertions, 9 deletions
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index fa23f83492..215a44482e 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -3603,7 +3603,10 @@ void EditorPropertyResource::_resource_selected(const Ref<Resource> &p_resource, void EditorPropertyResource::_resource_changed(const Ref<Resource> &p_resource) { // Make visual script the correct type. Ref<Script> s = p_resource; + bool is_script = false; if (get_edited_object() && s.is_valid()) { + is_script = true; + InspectorDock::get_singleton()->store_script_properties(get_edited_object()); s->call("set_instance_base_type", get_edited_object()->get_class()); } @@ -3629,6 +3632,11 @@ void EditorPropertyResource::_resource_changed(const Ref<Resource> &p_resource) emit_changed(get_edited_property(), p_resource); update_property(); + if (is_script) { + // Restore properties if script was changed. + InspectorDock::get_singleton()->apply_script_properties(get_edited_object()); + } + // Automatically suggest setting up the path for a ViewportTexture. if (vpt.is_valid() && vpt->get_viewport_path_in_scene().is_empty()) { if (!scene_tree) { diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 28edd6a76c..e0dd5610ee 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -453,6 +453,9 @@ void InspectorDock::_bind_methods() { ClassDB::bind_method("edit_resource", &InspectorDock::edit_resource); + ClassDB::bind_method("store_script_properties", &InspectorDock::store_script_properties); + ClassDB::bind_method("apply_script_properties", &InspectorDock::apply_script_properties); + ADD_SIGNAL(MethodInfo("request_help")); } @@ -565,6 +568,31 @@ EditorPropertyNameProcessor::Style InspectorDock::get_property_name_style() cons return property_name_style; } +void InspectorDock::store_script_properties(Object *p_object) { + ERR_FAIL_NULL(p_object); + ScriptInstance *si = p_object->get_script_instance(); + if (!si) { + return; + } + si->get_property_state(stored_properties); +} + +void InspectorDock::apply_script_properties(Object *p_object) { + ERR_FAIL_NULL(p_object); + ScriptInstance *si = p_object->get_script_instance(); + if (!si) { + return; + } + + for (const Pair<StringName, Variant> &E : stored_properties) { + Variant current; + if (si->get(E.first, current) && current.get_type() == E.second.get_type()) { + si->set(E.first, E.second); + } + } + stored_properties.clear(); +} + InspectorDock::InspectorDock(EditorData &p_editor_data) { singleton = this; set_name("Inspector"); diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h index 536852c0f2..e3d35c2157 100644 --- a/editor/inspector_dock.h +++ b/editor/inspector_dock.h @@ -100,6 +100,7 @@ class InspectorDock : public VBoxContainer { Tree *unique_resources_list_tree = nullptr; EditorPropertyNameProcessor::Style property_name_style; + List<Pair<StringName, Variant>> stored_properties; void _prepare_menu(); void _menu_option(int p_option); @@ -149,6 +150,9 @@ public: EditorPropertyNameProcessor::Style get_property_name_style() const; + void store_script_properties(Object *p_object); + void apply_script_properties(Object *p_object); + InspectorDock(EditorData &p_editor_data); ~InspectorDock(); }; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index ced1eb5abf..944012c84f 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1952,17 +1952,36 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) { return; } - editor_data->get_undo_redo().create_action(TTR("Attach Script")); - for (Node *E : selected) { - Ref<Script> existing = E->get_script(); - editor_data->get_undo_redo().add_do_method(E, "set_script", p_script); - editor_data->get_undo_redo().add_undo_method(E, "set_script", existing); + if (selected.size() == 1) { + Node *node = selected.front()->get(); + Ref<Script> existing = node->get_script(); + + editor_data->get_undo_redo().create_action(TTR("Attach Script")); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "store_script_properties", node); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "store_script_properties", node); + editor_data->get_undo_redo().add_do_method(node, "set_script", p_script); + editor_data->get_undo_redo().add_undo_method(node, "set_script", existing); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "apply_script_properties", node); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", node); editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); + editor_data->get_undo_redo().commit_action(); + } else { + editor_data->get_undo_redo().create_action(TTR("Attach Script")); + for (List<Node *>::Element *E = selected.front(); E; E = E->next()) { + Ref<Script> existing = E->get()->get_script(); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "store_script_properties", E->get()); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "store_script_properties", E->get()); + editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script); + editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "apply_script_properties", E->get()); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", E->get()); + editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); + editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); + } + editor_data->get_undo_redo().commit_action(); } - editor_data->get_undo_redo().commit_action(); - _push_item(p_script.operator->()); _update_script_button(); } @@ -2586,11 +2605,14 @@ void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) { Ref<Script> scr = ResourceLoader::load(p_file); ERR_FAIL_COND(!scr.is_valid()); - Node *n = get_node(p_to); - if (n) { + if (Node *n = get_node(p_to)) { editor_data->get_undo_redo().create_action(TTR("Attach Script")); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "store_script_properties", n); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "store_script_properties", n); editor_data->get_undo_redo().add_do_method(n, "set_script", scr); editor_data->get_undo_redo().add_undo_method(n, "set_script", n->get_script()); + editor_data->get_undo_redo().add_do_method(InspectorDock::get_singleton(), "apply_script_properties", n); + editor_data->get_undo_redo().add_undo_method(InspectorDock::get_singleton(), "apply_script_properties", n); editor_data->get_undo_redo().add_do_method(this, "_update_script_button"); editor_data->get_undo_redo().add_undo_method(this, "_update_script_button"); editor_data->get_undo_redo().commit_action(); |