From 0d69da8c0ec1df3d8486208a45979187b97d56ec Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 25 Nov 2018 10:46:26 -0300 Subject: Rewrite code for unfolding and make it automatic on scene load, which works better. --- editor/editor_folding.cpp | 85 +++++++++++++++++++++++++++++++++++ editor/editor_folding.h | 5 +++ editor/editor_inspector.cpp | 106 ++++++++++++++++---------------------------- editor/editor_inspector.h | 12 +++-- editor/editor_node.cpp | 9 +++- editor/inspector_dock.cpp | 1 - 6 files changed, 143 insertions(+), 75 deletions(-) diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp index 011fe20564..776342582c 100644 --- a/editor/editor_folding.cpp +++ b/editor/editor_folding.cpp @@ -2,6 +2,7 @@ #include "core/os/file_access.h" #include "editor_settings.h" +#include "editor_inspector.h" PoolVector EditorFolding::_get_unfolds(const Object *p_object) { @@ -171,5 +172,89 @@ bool EditorFolding::has_folding_data(const String &p_path) { return FileAccess::exists(file); } + +void EditorFolding::_do_object_unfolds(Object *p_object, Set &resources) { + + List plist; + p_object->get_property_list(&plist); + String group_base; + String group; + + Set unfold_group; + + for (List::Element *E = plist.front(); E; E = E->next()) { + + if (E->get().usage & PROPERTY_USAGE_CATEGORY) { + group=""; + group_base=""; + } + if (E->get().usage & PROPERTY_USAGE_GROUP) { + group = E->get().name; + group_base = E->get().hint_string; + if (group_base.ends_with("_")) { + group_base=group_base.substr(0,group_base.length()-1); + } + } + + //can unfold + if (E->get().usage & PROPERTY_USAGE_EDITOR) { + + + if (group != "") { //group + if (group_base==String() || E->get().name.begins_with(group_base)) { + bool can_revert = EditorPropertyRevert::can_property_revert(p_object,E->get().name); + if (can_revert) { + unfold_group.insert(group); + } + } + } else { //path + int last = E->get().name.find_last("/"); + if (last!=-1) { + bool can_revert = EditorPropertyRevert::can_property_revert(p_object,E->get().name); + if (can_revert) { + unfold_group.insert(E->get().name.substr(0,last)); + } + } + } + } + + if (E->get().type == Variant::OBJECT) { + RES res = p_object->get(E->get().name); + if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) { + + resources.insert(res); + _do_object_unfolds(res.ptr(),resources); + } + } + } + + for (Set::Element *E=unfold_group.front();E;E=E->next()) { + p_object->editor_set_section_unfold(E->get(),true); + } +} + +void EditorFolding::_do_node_unfolds(Node *p_root, Node *p_node, Set &resources) { + if (p_root != p_node) { + if (!p_node->get_owner()) { + return; //not owned, bye + } + if (p_node->get_owner() != p_root && !p_root->is_editable_instance(p_node)) { + return; + } + } + + _do_object_unfolds(p_node,resources); + + for (int i = 0; i < p_node->get_child_count(); i++) { + _do_node_unfolds(p_root, p_node->get_child(i), resources); + } +} + +void EditorFolding::unfold_scene(Node *p_scene) { + + Set resources; + _do_node_unfolds(p_scene,p_scene,resources); +} + EditorFolding::EditorFolding() { } diff --git a/editor/editor_folding.h b/editor/editor_folding.h index cfd4b5466d..dc03e2d284 100644 --- a/editor/editor_folding.h +++ b/editor/editor_folding.h @@ -10,6 +10,9 @@ class EditorFolding { void _fill_folds(const Node *p_root, const Node *p_node, Array &p_folds, Array &resource_folds, Set &resources); + void _do_object_unfolds(Object *p_object, Set &resources); + void _do_node_unfolds(Node *p_root, Node *p_node, Set &resources); + public: void save_resource_folding(const RES &p_resource, const String &p_path); void load_resource_folding(RES p_resource, const String &p_path); @@ -17,6 +20,8 @@ public: void save_scene_folding(const Node *p_scene, const String &p_path); void load_scene_folding(Node *p_scene, const String &p_path); + void unfold_scene(Node *p_scene); + bool has_folding_data(const String &p_path); EditorFolding(); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index a564a2a113..b50af93352 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -297,16 +297,12 @@ bool EditorProperty::is_read_only() const { return read_only; } -bool EditorProperty::_might_be_in_instance() { - - if (!object) - return false; - - Node *node = Object::cast_to(object); +bool EditorPropertyRevert::may_node_be_in_instance(Node *p_node) { Node *edited_scene = EditorNode::get_singleton()->get_edited_scene(); bool might_be = false; + Node *node = p_node; while (node) { @@ -328,13 +324,9 @@ bool EditorProperty::_might_be_in_instance() { return might_be; // or might not be } -bool EditorProperty::_get_instanced_node_original_property(const StringName &p_prop, Variant &value) { - - Node *node = Object::cast_to(object); - - if (!node) - return false; +bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, const StringName &p_prop, Variant &value) { + Node *node = p_node; Node *orig = node; Node *edited_scene = EditorNode::get_singleton()->get_edited_scene(); @@ -376,7 +368,7 @@ bool EditorProperty::_get_instanced_node_original_property(const StringName &p_p if (!found) { //if not found, try default class value - Variant attempt = ClassDB::class_get_default_property_value(object->get_class_name(), property); + Variant attempt = ClassDB::class_get_default_property_value(node->get_class_name(), p_prop); if (attempt.get_type() != Variant::NIL) { found = true; value = attempt; @@ -386,14 +378,14 @@ bool EditorProperty::_get_instanced_node_original_property(const StringName &p_p return found; } -bool EditorProperty::_is_property_different(const Variant &p_current, const Variant &p_orig) { +bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Variant &p_current, const Variant &p_orig) { // this is a pretty difficult function, because a property may not be saved but may have // the flag to not save if one or if zero //make sure there is an actual state { - Node *node = Object::cast_to(object); + Node *node = p_node; if (!node) return false; @@ -435,46 +427,55 @@ bool EditorProperty::_is_property_different(const Variant &p_current, const Vari return bool(Variant::evaluate(Variant::OP_NOT_EQUAL, p_current, p_orig)); } -void EditorProperty::update_reload_status() { +bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringName &p_property) { - if (property == StringName()) - return; //no property, so nothing to do + bool has_revert = false; - bool has_reload = false; + Node *node = Object::cast_to(p_object); - if (_might_be_in_instance()) { + if (node && EditorPropertyRevert::may_node_be_in_instance(node)) { //check for difference including instantiation Variant vorig; - if (_get_instanced_node_original_property(property, vorig)) { - Variant v = object->get(property); + if (EditorPropertyRevert::get_instanced_node_original_property(node, p_property, vorig)) { + Variant v = p_object->get(p_property); - if (_is_property_different(v, vorig)) { - has_reload = true; + if (EditorPropertyRevert::is_node_property_different(node, v, vorig)) { + has_revert = true; } } } else { //check for difference against default class value instead - Variant default_value = ClassDB::class_get_default_property_value(object->get_class_name(), property); - if (default_value != Variant() && default_value != object->get(property)) { - has_reload = true; + Variant default_value = ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property); + if (default_value != Variant() && default_value != p_object->get(p_property)) { + has_revert = true; } } - if (object->call("property_can_revert", property).operator bool()) { + if (p_object->call("property_can_revert", p_property).operator bool()) { - has_reload = true; + has_revert = true; } - if (!has_reload && !object->get_script().is_null()) { - Ref