diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index fdcd4f9b606..a12b8968311 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1263,10 +1263,10 @@ void ProjectSettings::refresh_global_class_list() { Array script_classes = get_global_class_list(); for (int i = 0; i < script_classes.size(); i++) { Dictionary c = script_classes[i]; - if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) { + if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base") || !c.has("is_abstract") || !c.has("is_tool")) { continue; } - ScriptServer::add_global_class(c["class"], c["base"], c["language"], c["path"]); + ScriptServer::add_global_class(c["class"], c["base"], c["language"], c["path"], c["is_abstract"], c["is_tool"]); } } diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 4ef53dba1df..33bf7ab48a0 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -269,10 +269,10 @@ void ScriptServer::init_languages() { for (const Variant &script_class : script_classes) { Dictionary c = script_class; - if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) { + if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base") || !c.has("is_abstract") || !c.has("is_tool")) { continue; } - add_global_class(c["class"], c["base"], c["language"], c["path"]); + add_global_class(c["class"], c["base"], c["language"], c["path"], c["is_abstract"], c["is_tool"]); } ProjectSettings::get_singleton()->clear("_global_script_classes"); } @@ -281,10 +281,10 @@ void ScriptServer::init_languages() { Array script_classes = ProjectSettings::get_singleton()->get_global_class_list(); for (const Variant &script_class : script_classes) { Dictionary c = script_class; - if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) { + if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base") || !c.has("is_abstract") || !c.has("is_tool")) { continue; } - add_global_class(c["class"], c["base"], c["language"], c["path"]); + add_global_class(c["class"], c["base"], c["language"], c["path"], c["is_abstract"], c["is_tool"]); } } @@ -390,7 +390,7 @@ void ScriptServer::global_classes_clear() { inheriters_cache.clear(); } -void ScriptServer::add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path) { +void ScriptServer::add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path, bool p_is_abstract, bool p_is_tool) { ERR_FAIL_COND_MSG(p_class == p_base || (global_classes.has(p_base) && get_global_class_native_base(p_base) == p_class), "Cyclic inheritance in script class."); GlobalScriptClass *existing = global_classes.getptr(p_class); if (existing) { @@ -399,6 +399,8 @@ void ScriptServer::add_global_class(const StringName &p_class, const StringName existing->base = p_base; existing->path = p_path; existing->language = p_language; + existing->is_abstract = p_is_abstract; + existing->is_tool = p_is_tool; inheriters_cache_dirty = true; } } else { @@ -407,6 +409,8 @@ void ScriptServer::add_global_class(const StringName &p_class, const StringName g.language = p_language; g.path = p_path; g.base = p_base; + g.is_abstract = p_is_abstract; + g.is_tool = p_is_tool; global_classes[p_class] = g; inheriters_cache_dirty = true; } @@ -480,6 +484,16 @@ StringName ScriptServer::get_global_class_native_base(const String &p_class) { return base; } +bool ScriptServer::is_global_class_abstract(const String &p_class) { + ERR_FAIL_COND_V(!global_classes.has(p_class), false); + return global_classes[p_class].is_abstract; +} + +bool ScriptServer::is_global_class_tool(const String &p_class) { + ERR_FAIL_COND_V(!global_classes.has(p_class), false); + return global_classes[p_class].is_tool; +} + void ScriptServer::get_global_class_list(List *r_global_classes) { List classes; for (const KeyValue &E : global_classes) { @@ -507,12 +521,15 @@ void ScriptServer::save_global_classes() { get_global_class_list(&gc); Array gcarr; for (const StringName &E : gc) { + const GlobalScriptClass &global_class = global_classes[E]; Dictionary d; d["class"] = E; - d["language"] = global_classes[E].language; - d["path"] = global_classes[E].path; - d["base"] = global_classes[E].base; + d["language"] = global_class.language; + d["path"] = global_class.path; + d["base"] = global_class.base; d["icon"] = class_icons.get(E, ""); + d["is_abstract"] = global_class.is_abstract; + d["is_tool"] = global_class.is_tool; gcarr.push_back(d); } ProjectSettings::get_singleton()->store_global_class_list(gcarr); diff --git a/core/object/script_language.h b/core/object/script_language.h index 6ceeb428751..8158d633ae1 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -62,6 +62,8 @@ class ScriptServer { StringName language; String path; StringName base; + bool is_abstract = false; + bool is_tool = false; }; static HashMap global_classes; @@ -86,7 +88,7 @@ public: static void thread_exit(); static void global_classes_clear(); - static void add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path); + static void add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path, bool p_is_abstract, bool p_is_tool); static void remove_global_class(const StringName &p_class); static void remove_global_class_by_path(const String &p_path); static bool is_global_class(const StringName &p_class); @@ -94,6 +96,8 @@ public: static String get_global_class_path(const String &p_class); static StringName get_global_class_base(const String &p_class); static StringName get_global_class_native_base(const String &p_class); + static bool is_global_class_abstract(const String &p_class); + static bool is_global_class_tool(const String &p_class); static void get_global_class_list(List *r_global_classes); static void get_inheriters_list(const StringName &p_base_type, List *r_classes); static void save_global_classes(); @@ -443,7 +447,7 @@ public: virtual void frame(); virtual bool handles_global_class_type(const String &p_type) const { return false; } - virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const { return String(); } + virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr, bool *r_is_abstract = nullptr, bool *r_is_tool = nullptr) const { return String(); } virtual ~ScriptLanguage() {} }; diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 09c395e71e8..715ec43fb35 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -672,7 +672,7 @@ public: GDVIRTUAL1RC_REQUIRED(Dictionary, _get_global_class_name, const String &) - virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const override { + virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr, bool *r_is_abstract = nullptr, bool *r_is_tool = nullptr) const override { Dictionary ret; GDVIRTUAL_CALL(_get_global_class_name, p_path, ret); if (!ret.has("name")) { @@ -684,6 +684,12 @@ public: if (r_icon_path != nullptr && ret.has("icon_path")) { *r_icon_path = ret["icon_path"]; } + if (r_is_abstract != nullptr && ret.has("is_abstract")) { + *r_is_abstract = ret["is_abstract"]; + } + if (r_is_tool != nullptr && ret.has("is_tool")) { + *r_is_tool = ret["is_tool"]; + } return ret["name"]; } }; diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 429467d3403..dca43411e10 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -1446,7 +1446,7 @@ void ConnectionsDock::update_tree() { doc_class_name = String(); } - class_icon = editor_data.get_script_icon(script_base); + class_icon = editor_data.get_script_icon(script_base->get_path()); if (class_icon.is_null() && has_theme_icon(native_base, EditorStringName(EditorIcons))) { class_icon = get_editor_theme_icon(native_base); } diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 7f1670bcb64..5eebb1c492e 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -257,14 +257,9 @@ void CreateDialog::_add_type(const StringName &p_type, TypeCategory p_type_categ inherits = ClassDB::get_parent_class(p_type); inherited_type = TypeCategory::CPP_TYPE; } else { - if (p_type_category == TypeCategory::PATH_TYPE || ScriptServer::is_global_class(p_type)) { - Ref