diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/connections_dialog.cpp | 3 | ||||
-rw-r--r-- | editor/doc_tools.cpp (renamed from editor/doc_data.cpp) | 208 | ||||
-rw-r--r-- | editor/doc_tools.h (renamed from editor/doc_data.h) | 111 | ||||
-rw-r--r-- | editor/editor_file_system.cpp | 30 | ||||
-rw-r--r-- | editor/editor_help.cpp | 218 | ||||
-rw-r--r-- | editor/editor_help.h | 7 | ||||
-rw-r--r-- | editor/editor_inspector.cpp | 5 | ||||
-rw-r--r-- | editor/import/editor_import_collada.cpp | 16 | ||||
-rw-r--r-- | editor/import/editor_scene_importer_gltf.cpp | 3 | ||||
-rw-r--r-- | editor/import/resource_importer_obj.cpp | 10 | ||||
-rw-r--r-- | editor/import/resource_importer_obj.h | 1 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.cpp | 4 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.h | 1 | ||||
-rw-r--r-- | editor/node_3d_editor_gizmos.cpp | 48 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 73 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 76 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.h | 1 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.cpp | 113 | ||||
-rw-r--r-- | editor/plugins/visual_shader_editor_plugin.h | 4 | ||||
-rw-r--r-- | editor/property_selector.cpp | 3 |
20 files changed, 517 insertions, 418 deletions
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index a04065a463..2630589912 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -31,6 +31,7 @@ #include "connections_dialog.h" #include "core/string/print_string.h" +#include "editor/doc_tools.h" #include "editor_node.h" #include "editor_scale.h" #include "editor_settings.h" @@ -998,7 +999,7 @@ void ConnectionsDock::update_tree() { } if (!found) { - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(base); while (F && descr == String()) { for (int i = 0; i < F->get().signals.size(); i++) { diff --git a/editor/doc_data.cpp b/editor/doc_tools.cpp index 165a5c8546..5ee9abb183 100644 --- a/editor/doc_data.cpp +++ b/editor/doc_tools.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* doc_data.cpp */ +/* doc_tools.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "doc_data.h" +#include "doc_tools.h" #include "core/config/engine.h" #include "core/config/project_settings.h" @@ -43,22 +43,22 @@ // Used for a hack preserving Mono properties on non-Mono builds. #include "modules/modules_enabled.gen.h" -void DocData::merge_from(const DocData &p_data) { - for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { - ClassDoc &c = E->get(); +void DocTools::merge_from(const DocTools &p_data) { + for (Map<String, DocData::ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { + DocData::ClassDoc &c = E->get(); if (!p_data.class_list.has(c.name)) { continue; } - const ClassDoc &cf = p_data.class_list[c.name]; + const DocData::ClassDoc &cf = p_data.class_list[c.name]; c.description = cf.description; c.brief_description = cf.brief_description; c.tutorials = cf.tutorials; for (int i = 0; i < c.methods.size(); i++) { - MethodDoc &m = c.methods.write[i]; + DocData::MethodDoc &m = c.methods.write[i]; for (int j = 0; j < cf.methods.size(); j++) { if (cf.methods[j].name != m.name) { @@ -95,7 +95,7 @@ void DocData::merge_from(const DocData &p_data) { continue; } - const MethodDoc &mf = cf.methods[j]; + const DocData::MethodDoc &mf = cf.methods[j]; m.description = mf.description; break; @@ -103,13 +103,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.signals.size(); i++) { - MethodDoc &m = c.signals.write[i]; + DocData::MethodDoc &m = c.signals.write[i]; for (int j = 0; j < cf.signals.size(); j++) { if (cf.signals[j].name != m.name) { continue; } - const MethodDoc &mf = cf.signals[j]; + const DocData::MethodDoc &mf = cf.signals[j]; m.description = mf.description; break; @@ -117,13 +117,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.constants.size(); i++) { - ConstantDoc &m = c.constants.write[i]; + DocData::ConstantDoc &m = c.constants.write[i]; for (int j = 0; j < cf.constants.size(); j++) { if (cf.constants[j].name != m.name) { continue; } - const ConstantDoc &mf = cf.constants[j]; + const DocData::ConstantDoc &mf = cf.constants[j]; m.description = mf.description; break; @@ -131,13 +131,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.properties.size(); i++) { - PropertyDoc &p = c.properties.write[i]; + DocData::PropertyDoc &p = c.properties.write[i]; for (int j = 0; j < cf.properties.size(); j++) { if (cf.properties[j].name != p.name) { continue; } - const PropertyDoc &pf = cf.properties[j]; + const DocData::PropertyDoc &pf = cf.properties[j]; p.description = pf.description; break; @@ -145,13 +145,13 @@ void DocData::merge_from(const DocData &p_data) { } for (int i = 0; i < c.theme_properties.size(); i++) { - PropertyDoc &p = c.theme_properties.write[i]; + DocData::PropertyDoc &p = c.theme_properties.write[i]; for (int j = 0; j < cf.theme_properties.size(); j++) { if (cf.theme_properties[j].name != p.name) { continue; } - const PropertyDoc &pf = cf.theme_properties[j]; + const DocData::PropertyDoc &pf = cf.theme_properties[j]; p.description = pf.description; break; @@ -177,57 +177,29 @@ void DocData::merge_from(const DocData &p_data) { } } -void DocData::remove_from(const DocData &p_data) { - for (Map<String, ClassDoc>::Element *E = p_data.class_list.front(); E; E = E->next()) { +void DocTools::remove_from(const DocTools &p_data) { + for (Map<String, DocData::ClassDoc>::Element *E = p_data.class_list.front(); E; E = E->next()) { if (class_list.has(E->key())) { class_list.erase(E->key()); } } } -static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo) { - if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { - p_method.return_enum = p_retinfo.class_name; - if (p_method.return_enum.begins_with("_")) { //proxy class - p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length()); - } - p_method.return_type = "int"; - } else if (p_retinfo.class_name != StringName()) { - p_method.return_type = p_retinfo.class_name; - } else if (p_retinfo.type == Variant::ARRAY && p_retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) { - p_method.return_type = p_retinfo.hint_string + "[]"; - } else if (p_retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { - p_method.return_type = p_retinfo.hint_string; - } else if (p_retinfo.type == Variant::NIL && p_retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { - p_method.return_type = "Variant"; - } else if (p_retinfo.type == Variant::NIL) { - p_method.return_type = "void"; - } else { - p_method.return_type = Variant::get_type_name(p_retinfo.type); - } +void DocTools::add_doc(const DocData::ClassDoc &p_class_doc) { + ERR_FAIL_COND(p_class_doc.name == ""); + class_list[p_class_doc.name] = p_class_doc; } -static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo) { - p_argument.name = p_arginfo.name; +void DocTools::remove_doc(const String &p_class_name) { + ERR_FAIL_COND(p_class_name == "" || !class_list.has(p_class_name)); + class_list.erase(p_class_name); +} - if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { - p_argument.enumeration = p_arginfo.class_name; - if (p_argument.enumeration.begins_with("_")) { //proxy class - p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length()); - } - p_argument.type = "int"; - } else if (p_arginfo.class_name != StringName()) { - p_argument.type = p_arginfo.class_name; - } else if (p_arginfo.type == Variant::ARRAY && p_arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) { - p_argument.type = p_arginfo.hint_string + "[]"; - } else if (p_arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) { - p_argument.type = p_arginfo.hint_string; - } else if (p_arginfo.type == Variant::NIL) { - // Parameters cannot be void, so PROPERTY_USAGE_NIL_IS_VARIANT is not necessary - p_argument.type = "Variant"; - } else { - p_argument.type = Variant::get_type_name(p_arginfo.type); +bool DocTools::has_doc(const String &p_class_name) { + if (p_class_name == "") { + return false; } + return class_list.has(p_class_name); } static Variant get_documentation_default_value(const StringName &p_class_name, const StringName &p_property_name, bool &r_default_value_valid) { @@ -253,7 +225,7 @@ static Variant get_documentation_default_value(const StringName &p_class_name, c return default_value; } -void DocData::generate(bool p_basic_types) { +void DocTools::generate(bool p_basic_types) { List<StringName> classes; ClassDB::get_class_list(&classes); classes.sort_custom<StringName::AlphCompare>(); @@ -277,8 +249,8 @@ void DocData::generate(bool p_basic_types) { cname = cname.substr(1, name.length()); } - class_list[cname] = ClassDoc(); - ClassDoc &c = class_list[cname]; + class_list[cname] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[cname]; c.name = cname; c.inherits = ClassDB::get_parent_class(name); @@ -305,7 +277,7 @@ void DocData::generate(bool p_basic_types) { continue; } - PropertyDoc prop; + DocData::PropertyDoc prop; prop.name = E->get().name; @@ -409,7 +381,7 @@ void DocData::generate(bool p_basic_types) { } } - MethodDoc method; + DocData::MethodDoc method; method.name = E->get().name; @@ -432,12 +404,12 @@ void DocData::generate(bool p_basic_types) { for (int i = -1; i < E->get().arguments.size(); i++) { if (i == -1) { #ifdef DEBUG_METHODS_ENABLED - return_doc_from_retinfo(method, E->get().return_val); + DocData::return_doc_from_retinfo(method, E->get().return_val); #endif } else { const PropertyInfo &arginfo = E->get().arguments[i]; - ArgumentDoc argument; - argument_doc_from_arginfo(argument, arginfo); + DocData::ArgumentDoc argument; + DocData::argument_doc_from_arginfo(argument, arginfo); int darg_idx = i - (E->get().arguments.size() - E->get().default_arguments.size()); if (darg_idx >= 0) { @@ -457,12 +429,12 @@ void DocData::generate(bool p_basic_types) { if (signal_list.size()) { for (List<MethodInfo>::Element *EV = signal_list.front(); EV; EV = EV->next()) { - MethodDoc signal; + DocData::MethodDoc signal; signal.name = EV->get().name; for (int i = 0; i < EV->get().arguments.size(); i++) { const PropertyInfo &arginfo = EV->get().arguments[i]; - ArgumentDoc argument; - argument_doc_from_arginfo(argument, arginfo); + DocData::ArgumentDoc argument; + DocData::argument_doc_from_arginfo(argument, arginfo); signal.arguments.push_back(argument); } @@ -475,7 +447,7 @@ void DocData::generate(bool p_basic_types) { ClassDB::get_integer_constant_list(name, &constant_list, true); for (List<String>::Element *E = constant_list.front(); E; E = E->next()) { - ConstantDoc constant; + DocData::ConstantDoc constant; constant.name = E->get(); constant.value = itos(ClassDB::get_integer_constant(name, E->get())); constant.is_value_valid = true; @@ -489,7 +461,7 @@ void DocData::generate(bool p_basic_types) { List<StringName> l; Theme::get_default()->get_constant_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "int"; pd.default_value = itos(Theme::get_default()->get_constant(E->get(), cname)); @@ -499,7 +471,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_color_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "Color"; pd.default_value = Variant(Theme::get_default()->get_color(E->get(), cname)).get_construct_string(); @@ -509,7 +481,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_icon_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "Texture2D"; c.theme_properties.push_back(pd); @@ -517,7 +489,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_font_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "Font"; c.theme_properties.push_back(pd); @@ -525,7 +497,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_font_size_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "int"; c.theme_properties.push_back(pd); @@ -533,7 +505,7 @@ void DocData::generate(bool p_basic_types) { l.clear(); Theme::get_default()->get_stylebox_list(cname, &l); for (List<StringName>::Element *E = l.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; pd.name = E->get(); pd.type = "StyleBox"; c.theme_properties.push_back(pd); @@ -545,7 +517,7 @@ void DocData::generate(bool p_basic_types) { { // So we can document the concept of Variant even if it's not a usable class per se. - class_list["Variant"] = ClassDoc(); + class_list["Variant"] = DocData::ClassDoc(); class_list["Variant"].name = "Variant"; } @@ -564,8 +536,8 @@ void DocData::generate(bool p_basic_types) { String cname = Variant::get_type_name(Variant::Type(i)); - class_list[cname] = ClassDoc(); - ClassDoc &c = class_list[cname]; + class_list[cname] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[cname]; c.name = cname; Callable::CallError cerror; @@ -642,7 +614,7 @@ void DocData::generate(bool p_basic_types) { for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { MethodInfo &mi = E->get(); - MethodDoc method; + DocData::MethodDoc method; method.name = mi.name; if (method.name == cname) { @@ -653,8 +625,8 @@ void DocData::generate(bool p_basic_types) { for (int j = 0; j < mi.arguments.size(); j++) { PropertyInfo arginfo = mi.arguments[j]; - ArgumentDoc ad; - argument_doc_from_arginfo(ad, mi.arguments[j]); + DocData::ArgumentDoc ad; + DocData::argument_doc_from_arginfo(ad, mi.arguments[j]); ad.name = arginfo.name; int darg_idx = mi.default_arguments.size() - mi.arguments.size() + j; @@ -666,7 +638,7 @@ void DocData::generate(bool p_basic_types) { method.arguments.push_back(ad); } - return_doc_from_retinfo(method, mi.return_val); + DocData::return_doc_from_retinfo(method, mi.return_val); if (mi.flags & METHOD_FLAG_VARARG) { if (method.qualifiers != "") { @@ -682,7 +654,7 @@ void DocData::generate(bool p_basic_types) { v.get_property_list(&properties); for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { PropertyInfo pi = E->get(); - PropertyDoc property; + DocData::PropertyDoc property; property.name = pi.name; property.type = Variant::get_type_name(pi.type); property.default_value = v.get(pi.name).get_construct_string(); @@ -694,7 +666,7 @@ void DocData::generate(bool p_basic_types) { Variant::get_constants_for_type(Variant::Type(i), &constants); for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { - ConstantDoc constant; + DocData::ConstantDoc constant; constant.name = E->get(); Variant value = Variant::get_constant_value(Variant::Type(i), E->get()); constant.value = value.get_type() == Variant::INT ? itos(value) : value.get_construct_string(); @@ -707,12 +679,12 @@ void DocData::generate(bool p_basic_types) { { String cname = "@GlobalScope"; - class_list[cname] = ClassDoc(); - ClassDoc &c = class_list[cname]; + class_list[cname] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[cname]; c.name = cname; for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) { - ConstantDoc cd; + DocData::ConstantDoc cd; cd.name = CoreConstants::get_global_constant_name(i); if (!CoreConstants::get_ignore_value_in_docs(i)) { cd.value = itos(CoreConstants::get_global_constant_value(i)); @@ -729,7 +701,7 @@ void DocData::generate(bool p_basic_types) { //servers (this is kind of hackish) for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) { - PropertyDoc pd; + DocData::PropertyDoc pd; Engine::Singleton &s = E->get(); if (!s.ptr) { continue; @@ -749,7 +721,7 @@ void DocData::generate(bool p_basic_types) { Variant::get_utility_function_list(&utility_functions); utility_functions.sort_custom<StringName::AlphCompare>(); for (List<StringName>::Element *E = utility_functions.front(); E; E = E->next()) { - MethodDoc md; + DocData::MethodDoc md; md.name = E->get(); //return if (Variant::has_utility_function_return_value(E->get())) { @@ -759,7 +731,7 @@ void DocData::generate(bool p_basic_types) { pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; } DocData::ArgumentDoc ad; - argument_doc_from_arginfo(ad, pi); + DocData::argument_doc_from_arginfo(ad, pi); md.return_type = ad.type; } @@ -774,7 +746,7 @@ void DocData::generate(bool p_basic_types) { pi.usage = PROPERTY_USAGE_NIL_IS_VARIANT; } DocData::ArgumentDoc ad; - argument_doc_from_arginfo(ad, pi); + DocData::argument_doc_from_arginfo(ad, pi); md.arguments.push_back(ad); } } @@ -791,7 +763,7 @@ void DocData::generate(bool p_basic_types) { for (int i = 0; i < ScriptServer::get_language_count(); i++) { ScriptLanguage *lang = ScriptServer::get_language(i); String cname = "@" + lang->get_name(); - ClassDoc c; + DocData::ClassDoc c; c.name = cname; // Get functions. @@ -800,7 +772,7 @@ void DocData::generate(bool p_basic_types) { for (List<MethodInfo>::Element *E = minfo.front(); E; E = E->next()) { MethodInfo &mi = E->get(); - MethodDoc md; + DocData::MethodDoc md; md.name = mi.name; if (mi.flags & METHOD_FLAG_VARARG) { @@ -810,11 +782,11 @@ void DocData::generate(bool p_basic_types) { md.qualifiers += "vararg"; } - return_doc_from_retinfo(md, mi.return_val); + DocData::return_doc_from_retinfo(md, mi.return_val); for (int j = 0; j < mi.arguments.size(); j++) { - ArgumentDoc ad; - argument_doc_from_arginfo(ad, mi.arguments[j]); + DocData::ArgumentDoc ad; + DocData::argument_doc_from_arginfo(ad, mi.arguments[j]); int darg_idx = j - (mi.arguments.size() - mi.default_arguments.size()); if (darg_idx >= 0) { @@ -833,7 +805,7 @@ void DocData::generate(bool p_basic_types) { lang->get_public_constants(&cinfo); for (List<Pair<String, Variant>>::Element *E = cinfo.front(); E; E = E->next()) { - ConstantDoc cd; + DocData::ConstantDoc cd; cd.name = E->get().first; cd.value = E->get().second; cd.is_value_valid = true; @@ -911,7 +883,7 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> & return OK; } -Error DocData::load_classes(const String &p_dir) { +Error DocTools::load_classes(const String &p_dir) { Error err; DirAccessRef da = DirAccess::open(p_dir, &err); if (!da) { @@ -939,7 +911,7 @@ Error DocData::load_classes(const String &p_dir) { return OK; } -Error DocData::erase_classes(const String &p_dir) { +Error DocTools::erase_classes(const String &p_dir) { Error err; DirAccessRef da = DirAccess::open(p_dir, &err); if (!da) { @@ -967,7 +939,7 @@ Error DocData::erase_classes(const String &p_dir) { return OK; } -Error DocData::_load(Ref<XMLParser> parser) { +Error DocTools::_load(Ref<XMLParser> parser) { Error err = OK; while ((err = parser->read()) == OK) { @@ -983,8 +955,8 @@ Error DocData::_load(Ref<XMLParser> parser) { ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); String name = parser->get_attribute_value("name"); - class_list[name] = ClassDoc(); - ClassDoc &c = class_list[name]; + class_list[name] = DocData::ClassDoc(); + DocData::ClassDoc &c = class_list[name]; c.name = name; if (parser->has_attribute("inherits")) { @@ -1012,7 +984,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "link") { - TutorialDoc tutorial; + DocData::TutorialDoc tutorial; if (parser->has_attribute("title")) { tutorial.title = parser->get_attribute_value("title"); } @@ -1041,7 +1013,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "member") { - PropertyDoc prop2; + DocData::PropertyDoc prop2; ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); prop2.name = parser->get_attribute_value("name"); @@ -1078,7 +1050,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "theme_item") { - PropertyDoc prop2; + DocData::PropertyDoc prop2; ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); prop2.name = parser->get_attribute_value("name"); @@ -1106,7 +1078,7 @@ Error DocData::_load(Ref<XMLParser> parser) { String name3 = parser->get_node_name(); if (name3 == "constant") { - ConstantDoc constant2; + DocData::ConstantDoc constant2; ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT); constant2.name = parser->get_attribute_value("name"); ERR_FAIL_COND_V(!parser->has_attribute("value"), ERR_FILE_CORRUPT); @@ -1155,9 +1127,9 @@ static void _write_string(FileAccess *f, int p_tablevel, const String &p_string) f->store_string(tab + p_string + "\n"); } -Error DocData::save_classes(const String &p_default_path, const Map<String, String> &p_class_path) { - for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { - ClassDoc &c = E->get(); +Error DocTools::save_classes(const String &p_default_path, const Map<String, String> &p_class_path) { + for (Map<String, DocData::ClassDoc>::Element *E = class_list.front(); E; E = E->next()) { + DocData::ClassDoc &c = E->get(); String save_path; if (p_class_path.has(c.name)) { @@ -1192,7 +1164,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<tutorials>"); for (int i = 0; i < c.tutorials.size(); i++) { - TutorialDoc tutorial = c.tutorials.get(i); + DocData::TutorialDoc tutorial = c.tutorials.get(i); String title_attribute = (!tutorial.title.empty()) ? " title=\"" + tutorial.title.xml_escape() + "\"" : ""; _write_string(f, 2, "<link" + title_attribute + ">" + tutorial.link.xml_escape() + "</link>"); } @@ -1203,7 +1175,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri c.methods.sort(); for (int i = 0; i < c.methods.size(); i++) { - const MethodDoc &m = c.methods[i]; + const DocData::MethodDoc &m = c.methods[i]; String qualifiers; if (m.qualifiers != "") { @@ -1222,7 +1194,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri } for (int j = 0; j < m.arguments.size(); j++) { - const ArgumentDoc &a = m.arguments[j]; + const DocData::ArgumentDoc &a = m.arguments[j]; String enum_text; if (a.enumeration != String()) { @@ -1261,7 +1233,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri additional_attributes += " default=\"" + c.properties[i].default_value.xml_escape(true) + "\""; } - const PropertyDoc &p = c.properties[i]; + const DocData::PropertyDoc &p = c.properties[i]; if (c.properties[i].overridden) { _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" override=\"true\"" + additional_attributes + " />"); @@ -1279,10 +1251,10 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<signals>"); for (int i = 0; i < c.signals.size(); i++) { - const MethodDoc &m = c.signals[i]; + const DocData::MethodDoc &m = c.signals[i]; _write_string(f, 2, "<signal name=\"" + m.name + "\">"); for (int j = 0; j < m.arguments.size(); j++) { - const ArgumentDoc &a = m.arguments[j]; + const DocData::ArgumentDoc &a = m.arguments[j]; _write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\">"); _write_string(f, 3, "</argument>"); } @@ -1300,7 +1272,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<constants>"); for (int i = 0; i < c.constants.size(); i++) { - const ConstantDoc &k = c.constants[i]; + const DocData::ConstantDoc &k = c.constants[i]; if (k.is_value_valid) { if (k.enumeration != String()) { _write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">"); @@ -1325,7 +1297,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri _write_string(f, 1, "<theme_items>"); for (int i = 0; i < c.theme_properties.size(); i++) { - const PropertyDoc &p = c.theme_properties[i]; + const DocData::PropertyDoc &p = c.theme_properties[i]; if (p.default_value != "") { _write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\" default=\"" + p.default_value.xml_escape(true) + "\">"); @@ -1346,7 +1318,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri return OK; } -Error DocData::load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size) { +Error DocTools::load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size) { Vector<uint8_t> data; data.resize(p_uncompressed_size); Compression::decompress(data.ptrw(), p_uncompressed_size, p_data, p_compressed_size, Compression::MODE_DEFLATE); diff --git a/editor/doc_data.h b/editor/doc_tools.h index 2cb475d137..db27e38c8b 100644 --- a/editor/doc_data.h +++ b/editor/doc_tools.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* doc_data.h */ +/* doc_tools.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,113 +28,28 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef DOC_DATA_H -#define DOC_DATA_H +#ifndef DOC_TOOLS_H +#define DOC_TOOLS_H -#include "core/io/xml_parser.h" -#include "core/templates/map.h" -#include "core/variant/variant.h" +#include "core/doc_data.h" -class DocData { +class DocTools { public: - struct ArgumentDoc { - String name; - String type; - String enumeration; - String default_value; - bool operator<(const ArgumentDoc &p_arg) const { - if (name == p_arg.name) { - return type < p_arg.type; - } - return name < p_arg.name; - } - }; - - struct MethodDoc { - String name; - String return_type; - String return_enum; - String qualifiers; - String description; - Vector<ArgumentDoc> arguments; - bool operator<(const MethodDoc &p_method) const { - if (name == p_method.name) { - // Must be a constructor since there is no overloading. - // We want this arbitrary order for a class "Foo": - // - 1. Default constructor: Foo() - // - 2. Copy constructor: Foo(Foo) - // - 3+. Other constructors Foo(Bar, ...) based on first argument's name - if (arguments.size() == 0 || p_method.arguments.size() == 0) { // 1. - return arguments.size() < p_method.arguments.size(); - } - if (arguments[0].type == return_type || p_method.arguments[0].type == p_method.return_type) { // 2. - return (arguments[0].type == return_type) || (p_method.arguments[0].type != p_method.return_type); - } - return arguments[0] < p_method.arguments[0]; - } - return name < p_method.name; - } - }; - - struct ConstantDoc { - String name; - String value; - bool is_value_valid; - String enumeration; - String description; - bool operator<(const ConstantDoc &p_const) const { - return name < p_const.name; - } - }; - - struct PropertyDoc { - String name; - String type; - String enumeration; - String description; - String setter, getter; - String default_value; - bool overridden = false; - bool operator<(const PropertyDoc &p_prop) const { - return name < p_prop.name; - } - }; - - struct TutorialDoc { - String link; - String title; - }; - - struct ClassDoc { - String name; - String inherits; - String category; - String brief_description; - String description; - Vector<TutorialDoc> tutorials; - Vector<MethodDoc> methods; - Vector<MethodDoc> signals; - Vector<ConstantDoc> constants; - Vector<PropertyDoc> properties; - Vector<PropertyDoc> theme_properties; - bool operator<(const ClassDoc &p_class) const { - return name < p_class.name; - } - }; - String version; + Map<String, DocData::ClassDoc> class_list; - Map<String, ClassDoc> class_list; - Error _load(Ref<XMLParser> parser); + static Error erase_classes(const String &p_dir); -public: - void merge_from(const DocData &p_data); - void remove_from(const DocData &p_data); + void merge_from(const DocTools &p_data); + void remove_from(const DocTools &p_data); + void add_doc(const DocData::ClassDoc &p_class_doc); + void remove_doc(const String &p_class_name); + bool has_doc(const String &p_class_name); void generate(bool p_basic_types = false); Error load_classes(const String &p_dir); - static Error erase_classes(const String &p_dir); Error save_classes(const String &p_default_path, const Map<String, String> &p_class_path); + Error _load(Ref<XMLParser> parser); Error load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size); }; diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index c66bc9b3fa..738b88a86b 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -357,10 +357,12 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo List<String> to_check; + String importer_name; String source_file = ""; String source_md5 = ""; Vector<String> dest_files; String dest_md5 = ""; + int version = 0; while (true) { assign = Variant(); @@ -384,6 +386,10 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo for (int i = 0; i < fa.size(); i++) { to_check.push_back(fa[i]); } + } else if (assign == "importer_version") { + version = value; + } else if (assign == "importer") { + importer_name = value; } else if (!p_only_imported_files) { if (assign == "source_file") { source_file = value; @@ -399,6 +405,12 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo memdelete(f); + Ref<ResourceImporter> importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name); + + if (importer->get_format_version() > version) { + return true; // version changed, reimport + } + // Read the md5's from a separate file (so the import parameters aren't dependent on the file version String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_path); FileAccess *md5s = FileAccess::open(base_path + ".md5", FileAccess::READ, &err); @@ -799,6 +811,20 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess } } + for (int i = 0; i < ScriptServer::get_language_count(); i++) { + ScriptLanguage *lang = ScriptServer::get_language(i); + if (lang->supports_documentation() && fi->type == lang->get_type()) { + Ref<Script> script = ResourceLoader::load(path); + if (script == nullptr) { + continue; + } + const Vector<DocData::ClassDoc> &docs = script->get_documentation(); + for (int j = 0; j < docs.size(); j++) { + EditorHelp::get_doc_data()->add_doc(docs[j]); + } + } + } + p_dir->files.push_back(fi); p_progress.update(idx, total); } @@ -1562,6 +1588,10 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector f->store_line("[remap]"); f->store_line(""); f->store_line("importer=\"" + importer->get_importer_name() + "\""); + int version = importer->get_format_version(); + if (version > 0) { + f->store_line("importer_version=" + itos(importer->get_format_version())); + } if (importer->get_resource_type() != "") { f->store_line("type=\"" + importer->get_resource_type() + "\""); } diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 2c49782fd2..4c553950a7 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -40,7 +40,7 @@ #define CONTRIBUTE_URL "https://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html" -DocData *EditorHelp::doc = nullptr; +DocTools *EditorHelp::doc = nullptr; void EditorHelp::_init_colors() { title_color = get_theme_color("accent_color", "Editor"); @@ -388,7 +388,7 @@ void EditorHelp::_update_doc() { } // Descendents - if (ClassDB::class_exists(cd.name)) { + if (cd.is_script_doc || ClassDB::class_exists(cd.name)) { bool found = false; bool prev = false; @@ -494,7 +494,19 @@ void EditorHelp::_update_doc() { Set<String> skip_methods; bool property_descr = false; - if (cd.properties.size()) { + bool has_properties = cd.properties.size() != 0; + if (cd.is_script_doc) { + has_properties = false; + for (int i = 0; i < cd.properties.size(); i++) { + if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.empty()) { + continue; + } + has_properties = true; + break; + } + } + + if (has_properties) { section_line.push_back(Pair<String, int>(TTR("Properties"), class_desc->get_line_count() - 2)); class_desc->push_color(title_color); class_desc->push_font(doc_title_font); @@ -509,6 +521,10 @@ void EditorHelp::_update_doc() { class_desc->set_table_column_expand(1, true); for (int i = 0; i < cd.properties.size(); i++) { + // Ignore undocumented private. + if (cd.properties[i].name.begins_with("_") && cd.properties[i].description.empty()) { + continue; + } property_line[cd.properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description class_desc->push_cell(); @@ -565,6 +581,32 @@ void EditorHelp::_update_doc() { class_desc->pop(); } + if (cd.is_script_doc && (cd.properties[i].setter != "" || cd.properties[i].getter != "")) { + class_desc->push_color(symbol_color); + class_desc->add_text(" [" + TTR("property:") + " "); + class_desc->pop(); // color + + if (cd.properties[i].setter != "") { + class_desc->push_color(value_color); + class_desc->add_text("setter"); + class_desc->pop(); // color + } + if (cd.properties[i].getter != "") { + if (cd.properties[i].setter != "") { + class_desc->push_color(symbol_color); + class_desc->add_text(", "); + class_desc->pop(); // color + } + class_desc->push_color(value_color); + class_desc->add_text("getter"); + class_desc->pop(); // color + } + + class_desc->push_color(symbol_color); + class_desc->add_text("]"); + class_desc->pop(); // color + } + class_desc->pop(); class_desc->pop(); @@ -590,6 +632,10 @@ void EditorHelp::_update_doc() { continue; } } + // Ignore undocumented private. + if (cd.methods[i].name.begins_with("_") && cd.methods[i].description.empty()) { + continue; + } methods.push_back(cd.methods[i]); } @@ -802,13 +848,17 @@ void EditorHelp::_update_doc() { Vector<DocData::ConstantDoc> constants; for (int i = 0; i < cd.constants.size(); i++) { - if (cd.constants[i].enumeration != String()) { + if (!cd.constants[i].enumeration.empty()) { if (!enums.has(cd.constants[i].enumeration)) { enums[cd.constants[i].enumeration] = Vector<DocData::ConstantDoc>(); } enums[cd.constants[i].enumeration].push_back(cd.constants[i]); } else { + // Ignore undocumented private. + if (cd.constants[i].name.begins_with("_") && cd.constants[i].description.empty()) { + continue; + } constants.push_back(cd.constants[i]); } } @@ -848,6 +898,19 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); class_desc->add_newline(); + // Enum description. + if (e != "@unnamed_enums" && cd.enums.has(e)) { + class_desc->push_color(text_color); + class_desc->push_font(doc_font); + class_desc->push_indent(1); + _add_text(cd.enums[e]); + class_desc->pop(); + class_desc->pop(); + class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); + } + class_desc->push_indent(1); Vector<DocData::ConstantDoc> enum_list = E->get(); @@ -1018,60 +1081,89 @@ void EditorHelp::_update_doc() { class_desc->pop(); // color } + if (cd.is_script_doc && (cd.properties[i].setter != "" || cd.properties[i].getter != "")) { + class_desc->push_color(symbol_color); + class_desc->add_text(" [" + TTR("property:") + " "); + class_desc->pop(); // color + + if (cd.properties[i].setter != "") { + class_desc->push_color(value_color); + class_desc->add_text("setter"); + class_desc->pop(); // color + } + if (cd.properties[i].getter != "") { + if (cd.properties[i].setter != "") { + class_desc->push_color(symbol_color); + class_desc->add_text(", "); + class_desc->pop(); // color + } + class_desc->push_color(value_color); + class_desc->add_text("getter"); + class_desc->pop(); // color + } + + class_desc->push_color(symbol_color); + class_desc->add_text("]"); + class_desc->pop(); // color + } + class_desc->pop(); // font class_desc->pop(); // cell - Map<String, DocData::MethodDoc> method_map; - for (int j = 0; j < methods.size(); j++) { - method_map[methods[j].name] = methods[j]; - } + // Script doc doesn't have setter, getter. + if (!cd.is_script_doc) { + Map<String, DocData::MethodDoc> method_map; + for (int j = 0; j < methods.size(); j++) { + method_map[methods[j].name] = methods[j]; + } - if (cd.properties[i].setter != "") { - class_desc->push_cell(); - class_desc->pop(); // cell + if (cd.properties[i].setter != "") { + class_desc->push_cell(); + class_desc->pop(); // cell - class_desc->push_cell(); - class_desc->push_font(doc_code_font); - class_desc->push_color(text_color); - if (method_map[cd.properties[i].setter].arguments.size() > 1) { - // Setters with additional arguments are exposed in the method list, so we link them here for quick access. - class_desc->push_meta("@method " + cd.properties[i].setter); - class_desc->add_text(cd.properties[i].setter + TTR("(value)")); - class_desc->pop(); - } else { - class_desc->add_text(cd.properties[i].setter + TTR("(value)")); + class_desc->push_cell(); + class_desc->push_font(doc_code_font); + class_desc->push_color(text_color); + if (method_map[cd.properties[i].setter].arguments.size() > 1) { + // Setters with additional arguments are exposed in the method list, so we link them here for quick access. + class_desc->push_meta("@method " + cd.properties[i].setter); + class_desc->add_text(cd.properties[i].setter + TTR("(value)")); + class_desc->pop(); + } else { + class_desc->add_text(cd.properties[i].setter + TTR("(value)")); + } + class_desc->pop(); // color + class_desc->push_color(comment_color); + class_desc->add_text(" setter"); + class_desc->pop(); // color + class_desc->pop(); // font + class_desc->pop(); // cell + method_line[cd.properties[i].setter] = property_line[cd.properties[i].name]; } - class_desc->pop(); // color - class_desc->push_color(comment_color); - class_desc->add_text(" setter"); - class_desc->pop(); // color - class_desc->pop(); // font - class_desc->pop(); // cell - method_line[cd.properties[i].setter] = property_line[cd.properties[i].name]; - } - if (cd.properties[i].getter != "") { - class_desc->push_cell(); - class_desc->pop(); // cell + if (cd.properties[i].getter != "") { + class_desc->push_cell(); + class_desc->pop(); // cell - class_desc->push_cell(); - class_desc->push_font(doc_code_font); - class_desc->push_color(text_color); - if (method_map[cd.properties[i].getter].arguments.size() > 0) { - // Getters with additional arguments are exposed in the method list, so we link them here for quick access. - class_desc->push_meta("@method " + cd.properties[i].getter); - class_desc->add_text(cd.properties[i].getter + "()"); - class_desc->pop(); - } else { - class_desc->add_text(cd.properties[i].getter + "()"); + class_desc->push_cell(); + class_desc->push_font(doc_code_font); + class_desc->push_color(text_color); + if (method_map[cd.properties[i].getter].arguments.size() > 0) { + // Getters with additional arguments are exposed in the method list, so we link them here for quick access. + class_desc->push_meta("@method " + cd.properties[i].getter); + class_desc->add_text(cd.properties[i].getter + "()"); + class_desc->pop(); + } else { + class_desc->add_text(cd.properties[i].getter + "()"); + } + class_desc->pop(); //color + class_desc->push_color(comment_color); + class_desc->add_text(" getter"); + class_desc->pop(); //color + class_desc->pop(); //font + class_desc->pop(); //cell + method_line[cd.properties[i].getter] = property_line[cd.properties[i].name]; } - class_desc->pop(); //color - class_desc->push_color(comment_color); - class_desc->add_text(" getter"); - class_desc->pop(); //color - class_desc->pop(); //font - class_desc->pop(); //cell - method_line[cd.properties[i].getter] = property_line[cd.properties[i].name]; } class_desc->pop(); // table @@ -1082,13 +1174,17 @@ void EditorHelp::_update_doc() { class_desc->push_color(text_color); class_desc->push_font(doc_font); class_desc->push_indent(1); - if (cd.properties[i].description.strip_edges() != String()) { + if (!cd.properties[i].description.strip_edges().empty()) { _add_text(DTR(cd.properties[i].description)); } else { class_desc->add_image(get_theme_icon("Error", "EditorIcons")); class_desc->add_text(" "); class_desc->push_color(comment_color); - class_desc->append_bbcode(TTR("There is currently no description for this property. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text)); + if (cd.is_script_doc) { + class_desc->append_bbcode(TTR("There is currently no description for this property.")); + } else { + class_desc->append_bbcode(TTR("There is currently no description for this property. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text)); + } class_desc->pop(); } class_desc->pop(); @@ -1133,13 +1229,17 @@ void EditorHelp::_update_doc() { class_desc->push_color(text_color); class_desc->push_font(doc_font); class_desc->push_indent(1); - if (methods_filtered[i].description.strip_edges() != String()) { + if (!methods_filtered[i].description.strip_edges().empty()) { _add_text(DTR(methods_filtered[i].description)); } else { class_desc->add_image(get_theme_icon("Error", "EditorIcons")); class_desc->add_text(" "); class_desc->push_color(comment_color); - class_desc->append_bbcode(TTR("There is currently no description for this method. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text)); + if (cd.is_script_doc) { + class_desc->append_bbcode(TTR("There is currently no description for this method.")); + } else { + class_desc->append_bbcode(TTR("There is currently no description for this method. Please help us by [color=$color][url=$url]contributing one[/url][/color]!").replace("$url", CONTRIBUTE_URL).replace("$color", link_color_text)); + } class_desc->pop(); } @@ -1223,7 +1323,7 @@ void EditorHelp::_help_callback(const String &p_topic) { } static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { - DocData *doc = EditorHelp::get_doc_data(); + DocTools *doc = EditorHelp::get_doc_data(); String base_path; Ref<Font> doc_font = p_rt->get_theme_font("doc", "EditorFonts"); @@ -1518,9 +1618,9 @@ void EditorHelp::_add_text(const String &p_bbcode) { } void EditorHelp::generate_doc() { - doc = memnew(DocData); + doc = memnew(DocTools); doc->generate(true); - DocData compdoc; + DocTools compdoc; compdoc.load_compressed(_doc_data_compressed, _doc_data_compressed_size, _doc_data_uncompressed_size); doc->merge_from(compdoc); //ensure all is up to date } @@ -1549,6 +1649,12 @@ void EditorHelp::go_to_class(const String &p_class, int p_scroll) { _goto_desc(p_class, p_scroll); } +void EditorHelp::update_doc() { + ERR_FAIL_COND(!doc->class_list.has(edited_class)); + ERR_FAIL_COND(!doc->class_list[edited_class].is_script_doc); + _update_doc(); +} + Vector<Pair<String, int>> EditorHelp::get_sections() { Vector<Pair<String, int>> sections; diff --git a/editor/editor_help.h b/editor/editor_help.h index cdb674cffd..737f841d30 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -32,7 +32,7 @@ #define EDITOR_HELP_H #include "editor/code_editor.h" -#include "editor/doc_data.h" +#include "editor/doc_tools.h" #include "editor/editor_plugin.h" #include "scene/gui/margin_container.h" #include "scene/gui/menu_button.h" @@ -118,7 +118,7 @@ class EditorHelp : public VBoxContainer { RichTextLabel *class_desc; HSplitContainer *h_split; - static DocData *doc; + static DocTools *doc; ConfirmationDialog *search_dialog; LineEdit *search; @@ -166,10 +166,11 @@ protected: public: static void generate_doc(); - static DocData *get_doc_data() { return doc; } + static DocTools *get_doc_data() { return doc; } void go_to_help(const String &p_help); void go_to_class(const String &p_class, int p_scroll = 0); + void update_doc(); Vector<Pair<String, int>> get_sections(); void scroll_to_section(int p_section_index); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 0c419168c0..d88a0e3ff8 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -32,6 +32,7 @@ #include "array_property_edit.h" #include "dictionary_property_edit.h" +#include "editor/doc_tools.h" #include "editor_feature_profile.h" #include "editor_node.h" #include "editor_scale.h" @@ -1708,7 +1709,7 @@ void EditorInspector::update_tree() { StringName type2 = p.name; if (!class_descr_cache.has(type2)) { String descr; - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(type2); if (E) { descr = DTR(E->get().brief_description); @@ -1878,7 +1879,7 @@ void EditorInspector::update_tree() { } if (!found) { - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(classname); while (F && descr == String()) { for (int i = 0; i < F->get().properties.size(); i++) { diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 12cbaaa885..41099dc8ea 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -844,19 +844,19 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me for (int k = 0; k < vertex_array.size(); k++) { if (normal_src) { - surftool->add_normal(vertex_array[k].normal); + surftool->set_normal(vertex_array[k].normal); if (binormal_src && tangent_src) { - surftool->add_tangent(vertex_array[k].tangent); + surftool->set_tangent(vertex_array[k].tangent); } } if (uv_src) { - surftool->add_uv(Vector2(vertex_array[k].uv.x, vertex_array[k].uv.y)); + surftool->set_uv(Vector2(vertex_array[k].uv.x, vertex_array[k].uv.y)); } if (uv2_src) { - surftool->add_uv2(Vector2(vertex_array[k].uv2.x, vertex_array[k].uv2.y)); + surftool->set_uv2(Vector2(vertex_array[k].uv2.x, vertex_array[k].uv2.y)); } if (color_src) { - surftool->add_color(vertex_array[k].color); + surftool->set_color(vertex_array[k].color); } if (has_weights) { @@ -876,8 +876,8 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me } } - surftool->add_bones(bones); - surftool->add_weights(weights); + surftool->set_bones(bones); + surftool->set_weights(weights); } surftool->add_vertex(vertex_array[k].vertex); @@ -923,7 +923,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me mr.push_back(a); } - p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, d, mr, Dictionary(), p_use_compression ? Mesh::ARRAY_COMPRESS_DEFAULT : 0); + p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, d, mr, Dictionary(), 0); if (material.is_valid()) { if (p_use_mesh_material) { diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 0c860a8965..c1877895ce 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -970,8 +970,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) { return OK; } - bool compress_vert_data = state.import_flags & IMPORT_USE_COMPRESSION; - uint32_t mesh_flags = compress_vert_data ? Mesh::ARRAY_COMPRESS_DEFAULT : 0; + uint32_t mesh_flags = 0; Array meshes = state.json["meshes"]; for (GLTFMeshIndex i = 0; i < meshes.size(); i++) { diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 49b47bf4be..d4560a2984 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -210,7 +210,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ bool generate_tangents = p_generate_tangents; Vector3 scale_mesh = p_scale_mesh; Vector3 offset_mesh = p_offset_mesh; - int mesh_flags = p_optimize ? Mesh::ARRAY_COMPRESS_DEFAULT : 0; + int mesh_flags = 0; Vector<Vector3> vertices; Vector<Vector3> normals; @@ -294,7 +294,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ norm += normals.size() + 1; } ERR_FAIL_INDEX_V(norm, normals.size(), ERR_FILE_CORRUPT); - surf_tool->add_normal(normals[norm]); + surf_tool->set_normal(normals[norm]); } if (face[idx].size() >= 2 && face[idx][1] != String()) { @@ -303,7 +303,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ uv += uvs.size() + 1; } ERR_FAIL_INDEX_V(uv, uvs.size(), ERR_FILE_CORRUPT); - surf_tool->add_uv(uvs[uv]); + surf_tool->set_uv(uvs[uv]); } int vtx = face[idx][0].to_int() - 1; @@ -473,6 +473,10 @@ String ResourceImporterOBJ::get_resource_type() const { return "Mesh"; } +int ResourceImporterOBJ::get_format_version() const { + return 1; +} + int ResourceImporterOBJ::get_preset_count() const { return 0; } diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h index 4083bc7403..97f747b33c 100644 --- a/editor/import/resource_importer_obj.h +++ b/editor/import/resource_importer_obj.h @@ -54,6 +54,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const override; virtual String get_save_extension() const override; virtual String get_resource_type() const override; + virtual int get_format_version() const override; virtual int get_preset_count() const override; virtual String get_preset_name(int p_idx) const override; diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 5dcdf6bec4..fc4f673ec4 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -172,6 +172,10 @@ String ResourceImporterScene::get_resource_type() const { return "PackedScene"; } +int ResourceImporterScene::get_format_version() const { + return 1; +} + bool ResourceImporterScene::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { if (p_option.begins_with("animation/")) { if (p_option != "animation/import" && !bool(p_options["animation/import"])) { diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 465d11116b..cd61ec01f2 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -133,6 +133,7 @@ public: virtual void get_recognized_extensions(List<String> *p_extensions) const override; virtual String get_save_extension() const override; virtual String get_resource_type() const override; + virtual int get_format_version() const override; virtual int get_preset_count() const override; virtual String get_preset_name(int p_idx) const override; diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp index b7f7d637d2..97bafdd167 100644 --- a/editor/node_3d_editor_gizmos.cpp +++ b/editor/node_3d_editor_gizmos.cpp @@ -1625,13 +1625,13 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { int pointidx = 0; for (int j = 0; j < 3; j++) { bones.write[0] = parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(rootcolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(rootcolor); surface_tool->add_vertex(v0 - grests[parent].basis[j].normalized() * dist * 0.05); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(rootcolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(rootcolor); surface_tool->add_vertex(v0 + grests[parent].basis[j].normalized() * dist * 0.05); if (j == closest) { @@ -1654,24 +1654,24 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { point += axis * dist * 0.1; bones.write[0] = parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(v0); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(point); bones.write[0] = parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(point); bones.write[0] = i; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(v1); points[pointidx++] = point; } @@ -1680,13 +1680,13 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { SWAP(points[1], points[2]); for (int j = 0; j < 4; j++) { bones.write[0] = parent; - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(points[j]); - surface_tool->add_bones(bones); - surface_tool->add_weights(weights); - surface_tool->add_color(bonecolor); + surface_tool->set_bones(bones); + surface_tool->set_weights(weights); + surface_tool->set_color(bonecolor); surface_tool->add_vertex(points[(j + 1) % 4]); } diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index ccf868b3d5..d0928683fd 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -63,12 +63,15 @@ #define GIZMO_SCALE_OFFSET (GIZMO_CIRCLE_SIZE + 0.3) #define GIZMO_ARROW_OFFSET (GIZMO_CIRCLE_SIZE + 0.3) -#define ZOOM_MIN_DISTANCE 0.001 -#define ZOOM_MULTIPLIER 1.08 -#define ZOOM_INDICATOR_DELAY_S 1.5 - -#define FREELOOK_MIN_SPEED 0.01 -#define FREELOOK_SPEED_MULTIPLIER 1.08 +#define ZOOM_FREELOOK_MIN 0.01 +#define ZOOM_FREELOOK_MULTIPLIER 1.08 +#define ZOOM_FREELOOK_INDICATOR_DELAY_S 1.5 + +#ifdef REAL_T_IS_DOUBLE +#define ZOOM_FREELOOK_MAX 1'000'000'000'000 +#else +#define ZOOM_FREELOOK_MAX 10'000 +#endif #define MIN_Z 0.01 #define MAX_Z 1000000.0 @@ -1117,7 +1120,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (b.is_valid()) { emit_signal("clicked", this); - float zoom_factor = 1 + (ZOOM_MULTIPLIER - 1) * b->get_factor(); + float zoom_factor = 1 + (ZOOM_FREELOOK_MULTIPLIER - 1) * b->get_factor(); switch (b->get_button_index()) { case BUTTON_WHEEL_UP: { if (is_freelook_active()) { @@ -2207,34 +2210,28 @@ void Node3DEditorViewport::set_freelook_active(bool active_now) { } void Node3DEditorViewport::scale_cursor_distance(real_t scale) { - // Prevents zero distance which would short-circuit any scaling - if (cursor.distance < ZOOM_MIN_DISTANCE) { - cursor.distance = ZOOM_MIN_DISTANCE; - } - - cursor.distance *= scale; - - if (cursor.distance < ZOOM_MIN_DISTANCE) { - cursor.distance = ZOOM_MIN_DISTANCE; + real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); + real_t max_distance = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); + if (unlikely(min_distance > max_distance)) { + cursor.distance = (min_distance + max_distance) / 2; + } else { + cursor.distance = CLAMP(cursor.distance * scale, min_distance, max_distance); } - zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S; + zoom_indicator_delay = ZOOM_FREELOOK_INDICATOR_DELAY_S; surface->update(); } void Node3DEditorViewport::scale_freelook_speed(real_t scale) { - // Prevents zero distance which would short-circuit any scaling - if (freelook_speed < FREELOOK_MIN_SPEED) { - freelook_speed = FREELOOK_MIN_SPEED; - } - - freelook_speed *= scale; - - if (freelook_speed < FREELOOK_MIN_SPEED) { - freelook_speed = FREELOOK_MIN_SPEED; + real_t min_speed = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); + real_t max_speed = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); + if (unlikely(min_speed > max_speed)) { + freelook_speed = (min_speed + max_speed) / 2; + } else { + freelook_speed = CLAMP(freelook_speed * scale, min_speed, max_speed); } - zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S; + zoom_indicator_delay = ZOOM_FREELOOK_INDICATOR_DELAY_S; surface->update(); } @@ -2698,19 +2695,13 @@ void Node3DEditorViewport::_draw() { if (is_freelook_active()) { // Show speed - real_t min_speed = FREELOOK_MIN_SPEED; - real_t max_speed = camera->get_zfar(); + real_t min_speed = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); + real_t max_speed = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); real_t scale_length = (max_speed - min_speed); if (!Math::is_zero_approx(scale_length)) { real_t logscale_t = 1.0 - Math::log(1 + freelook_speed - min_speed) / Math::log(1 + scale_length); - // There is no real maximum speed so that factor can become negative, - // Let's make it look asymptotic instead (will decrease slower and slower). - if (logscale_t < 0.25) { - logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0); - } - // Display the freelook speed to help the user get a better sense of scale. const int precision = freelook_speed < 1.0 ? 2 : 1; draw_indicator_bar( @@ -2725,19 +2716,13 @@ void Node3DEditorViewport::_draw() { } else { // Show zoom - real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom? - real_t max_distance = camera->get_zfar(); + real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN); + real_t max_distance = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX); real_t scale_length = (max_distance - min_distance); if (!Math::is_zero_approx(scale_length)) { real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length); - // There is no real maximum distance so that factor can become negative, - // Let's make it look asymptotic instead (will decrease slower and slower). - if (logscale_t < 0.25) { - logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0); - } - // Display the zoom center distance to help the user get a better sense of scale. const int precision = cursor.distance < 1.0 ? 2 : 1; draw_indicator_bar( @@ -5360,7 +5345,7 @@ void Node3DEditor::_init_indicators() { Vector2 ofs = Vector2(Math::cos((Math_PI * 2.0 * k) / m), Math::sin((Math_PI * 2.0 * k) / m)); Vector3 normal = ivec * ofs.x + ivec2 * ofs.y; - surftool->add_normal(basis.xform(normal)); + surftool->set_normal(basis.xform(normal)); surftool->add_vertex(vertex); } } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 6ee8193291..12790a6746 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1249,13 +1249,35 @@ void ScriptEditor::_menu_option(int p_option) { RES resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; + Ref<Script> script = resource; + if (text_file != nullptr) { current->apply_code(); _save_text_file(text_file, text_file->get_path()); break; } + + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + if (EditorHelp::get_doc_data()->has_doc(doc.name)) { + EditorHelp::get_doc_data()->remove_doc(doc.name); + } + } + } + editor->save_resource(resource); + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + EditorHelp::get_doc_data()->add_doc(doc); + update_doc(doc.name); + } + } + } break; case FILE_SAVE_AS: { if (trim_trailing_whitespace_on_save) { @@ -1274,6 +1296,8 @@ void ScriptEditor::_menu_option(int p_option) { RES resource = current->get_edited_resource(); Ref<TextFile> text_file = resource; + Ref<Script> script = resource; + if (text_file != nullptr) { file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE); file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); @@ -1289,9 +1313,27 @@ void ScriptEditor::_menu_option(int p_option) { break; } + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + if (EditorHelp::get_doc_data()->has_doc(doc.name)) { + EditorHelp::get_doc_data()->remove_doc(doc.name); + } + } + } + editor->push_item(resource.ptr()); editor->save_resource_as(resource); + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + EditorHelp::get_doc_data()->add_doc(doc); + update_doc(doc.name); + } + } } break; case FILE_TOOL_RELOAD: @@ -2318,11 +2360,33 @@ void ScriptEditor::save_all_scripts() { if (edited_res->get_path() != "" && edited_res->get_path().find("local://") == -1 && edited_res->get_path().find("::") == -1) { Ref<TextFile> text_file = edited_res; + Ref<Script> script = edited_res; + if (text_file != nullptr) { _save_text_file(text_file, text_file->get_path()); continue; } + + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + if (EditorHelp::get_doc_data()->has_doc(doc.name)) { + EditorHelp::get_doc_data()->remove_doc(doc.name); + } + } + } + editor->save_resource(edited_res); //external script, save it + + if (script != nullptr) { + const Vector<DocData::ClassDoc> &documentations = script->get_documentation(); + for (int j = 0; j < documentations.size(); j++) { + const DocData::ClassDoc &doc = documentations.get(j); + EditorHelp::get_doc_data()->add_doc(doc); + update_doc(doc.name); + } + } } } @@ -2900,6 +2964,18 @@ void ScriptEditor::_help_class_goto(const String &p_desc) { _save_layout(); } +void ScriptEditor::update_doc(const String &p_name) { + ERR_FAIL_COND(!EditorHelp::get_doc_data()->has_doc(p_name)); + + for (int i = 0; i < tab_container->get_child_count(); i++) { + EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i)); + if (eh && eh->get_class() == p_name) { + eh->update_doc(); + return; + } + } +} + void ScriptEditor::_update_selected_editor_menu() { for (int i = 0; i < tab_container->get_child_count(); i++) { bool current = tab_container->get_current_tab() == i; diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index f1453c3d20..cc02a1ccbe 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -482,6 +482,7 @@ public: void close_builtin_scripts_from_scene(const String &p_scene); void goto_help(const String &p_desc) { _help_class_goto(p_desc); } + void update_doc(const String &p_name); bool can_take_away_focus() const; diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 14598237d8..6112e69299 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -499,16 +499,32 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (group_node->is_editable()) { HBoxContainer *hb2 = memnew(HBoxContainer); + String input_port_name = "input" + itos(group_node->get_free_input_port_id()); + String output_port_name = "output" + itos(group_node->get_free_output_port_id()); + + for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) { + if (i < vsnode->get_input_port_count()) { + if (input_port_name == vsnode->get_input_port_name(i)) { + input_port_name = "_" + input_port_name; + } + } + if (i < vsnode->get_output_port_count()) { + if (output_port_name == vsnode->get_output_port_name(i)) { + output_port_name = "_" + output_port_name; + } + } + } + Button *add_input_btn = memnew(Button); add_input_btn->set_text(TTR("Add Input")); - add_input_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_add_input_port), varray(p_id, group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "input" + itos(group_node->get_free_input_port_id())), CONNECT_DEFERRED); + add_input_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_add_input_port), varray(p_id, group_node->get_free_input_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, input_port_name), CONNECT_DEFERRED); hb2->add_child(add_input_btn); hb2->add_spacer(); Button *add_output_btn = memnew(Button); add_output_btn->set_text(TTR("Add Output")); - add_output_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_add_output_port), varray(p_id, group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, "output" + itos(group_node->get_free_output_port_id())), CONNECT_DEFERRED); + add_output_btn->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_add_output_port), varray(p_id, group_node->get_free_output_port_id(), VisualShaderNode::PORT_TYPE_VECTOR, output_port_name), CONNECT_DEFERRED); hb2->add_child(add_output_btn); node->add_child(hb2); @@ -585,8 +601,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0)); name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); name_box->set_text(name_left); - name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_input_port_name), varray(name_box, p_id, i)); - name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, false)); + name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_input_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED); + name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, false), CONNECT_DEFERRED); Button *remove_btn = memnew(Button); remove_btn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons")); @@ -626,8 +642,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { name_box->set_custom_minimum_size(Size2(65 * EDSCALE, 0)); name_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); name_box->set_text(name_right); - name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_output_port_name), varray(name_box, p_id, i)); - name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, true)); + name_box->connect("text_entered", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_change_output_port_name), varray(name_box, p_id, i), CONNECT_DEFERRED); + name_box->connect("focus_exited", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_port_name_focus_out), varray(name_box, p_id, i, true), CONNECT_DEFERRED); OptionButton *type_box = memnew(OptionButton); hb->add_child(type_box); @@ -1337,29 +1353,57 @@ void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_ undo_redo->commit_action(); } -void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *line_edit, int p_node_id, int p_port_id) { +void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *p_line_edit, int p_node_id, int p_port_id) { VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); + String prev_name = node->get_input_port_name(p_port_id); + if (prev_name == p_text) { + return; + } + + LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit); + ERR_FAIL_COND(!line_edit); + + String validated_name = visual_shader->validate_port_name(p_text, node.ptr(), p_port_id, false); + if (validated_name == String() || prev_name == validated_name) { + line_edit->set_text(node->get_input_port_name(p_port_id)); + return; + } + undo_redo->create_action(TTR("Change Input Port Name")); - undo_redo->add_do_method(node.ptr(), "set_input_port_name", p_port_id, p_text); + undo_redo->add_do_method(node.ptr(), "set_input_port_name", p_port_id, validated_name); undo_redo->add_undo_method(node.ptr(), "set_input_port_name", p_port_id, node->get_input_port_name(p_port_id)); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node_id); undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node_id); undo_redo->commit_action(); } -void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *line_edit, int p_node_id, int p_port_id) { +void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *p_line_edit, int p_node_id, int p_port_id) { VisualShader::Type type = get_current_shader_type(); Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); + String prev_name = node->get_output_port_name(p_port_id); + if (prev_name == p_text) { + return; + } + + LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit); + ERR_FAIL_COND(!line_edit); + + String validated_name = visual_shader->validate_port_name(p_text, node.ptr(), p_port_id, true); + if (validated_name == String() || prev_name == validated_name) { + line_edit->set_text(node->get_output_port_name(p_port_id)); + return; + } + undo_redo->create_action(TTR("Change Output Port Name")); - undo_redo->add_do_method(node.ptr(), "set_output_port_name", p_port_id, p_text); - undo_redo->add_undo_method(node.ptr(), "set_output_port_name", p_port_id, node->get_output_port_name(p_port_id)); + undo_redo->add_do_method(node.ptr(), "set_output_port_name", p_port_id, validated_name); + undo_redo->add_undo_method(node.ptr(), "set_output_port_name", p_port_id, prev_name); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node_id); undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", type, p_node_id); undo_redo->commit_action(); @@ -1609,53 +1653,10 @@ void VisualShaderEditor::_uniform_line_edit_focus_out(Object *line_edit, int p_n } void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output) { - VisualShader::Type type = get_current_shader_type(); - - Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); - ERR_FAIL_COND(!node.is_valid()); - - String text = Object::cast_to<LineEdit>(line_edit)->get_text(); - - if (!p_output) { - if (node->get_input_port_name(p_port_id) == text) { - return; - } - } else { - if (node->get_output_port_name(p_port_id) == text) { - return; - } - } - - List<String> input_names; - List<String> output_names; - - for (int i = 0; i < node->get_input_port_count(); i++) { - if (!p_output && i == p_port_id) { - continue; - } - input_names.push_back(node->get_input_port_name(i)); - } - for (int i = 0; i < node->get_output_port_count(); i++) { - if (p_output && i == p_port_id) { - continue; - } - output_names.push_back(node->get_output_port_name(i)); - } - - String validated_name = visual_shader->validate_port_name(text, input_names, output_names); - if (validated_name == "") { - if (!p_output) { - Object::cast_to<LineEdit>(line_edit)->set_text(node->get_input_port_name(p_port_id)); - } else { - Object::cast_to<LineEdit>(line_edit)->set_text(node->get_output_port_name(p_port_id)); - } - return; - } - if (!p_output) { - _change_input_port_name(validated_name, line_edit, p_node_id, p_port_id); + _change_input_port_name(Object::cast_to<LineEdit>(line_edit)->get_text(), line_edit, p_node_id, p_port_id); } else { - _change_output_port_name(validated_name, line_edit, p_node_id, p_port_id); + _change_output_port_name(Object::cast_to<LineEdit>(line_edit)->get_text(), line_edit, p_node_id, p_port_id); } } diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 73bebcd192..2e7e9a8898 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -354,12 +354,12 @@ class VisualShaderEditor : public VBoxContainer { void _add_input_port(int p_node, int p_port, int p_port_type, const String &p_name); void _remove_input_port(int p_node, int p_port); void _change_input_port_type(int p_type, int p_node, int p_port); - void _change_input_port_name(const String &p_text, Object *line_edit, int p_node, int p_port); + void _change_input_port_name(const String &p_text, Object *p_line_edit, int p_node, int p_port); void _add_output_port(int p_node, int p_port, int p_port_type, const String &p_name); void _remove_output_port(int p_node, int p_port); void _change_output_port_type(int p_type, int p_node, int p_port); - void _change_output_port_name(const String &p_text, Object *line_edit, int p_node, int p_port); + void _change_output_port_name(const String &p_text, Object *p_line_edit, int p_node, int p_port); void _expression_focus_out(Object *code_edit, int p_node); diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index 75420a1ef4..1ff73f25c5 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -31,6 +31,7 @@ #include "property_selector.h" #include "core/os/keyboard.h" +#include "editor/doc_tools.h" #include "editor/editor_node.h" #include "editor_scale.h" @@ -349,7 +350,7 @@ void PropertySelector::_item_selected() { class_type = base_type; } - DocData *dd = EditorHelp::get_doc_data(); + DocTools *dd = EditorHelp::get_doc_data(); String text; if (properties) { |