diff options
author | Danil Alexeev <danil@alexeev.xyz> | 2023-08-08 12:45:59 +0300 |
---|---|---|
committer | Danil Alexeev <danil@alexeev.xyz> | 2023-08-16 13:05:10 +0300 |
commit | 1d5539cf776a8228a801fba4dcf70c9a72370487 (patch) | |
tree | e24f8e73b151aa0223e555913e1c41bc7102548c /editor/connections_dialog.cpp | |
parent | 90f90cbcb0cf2c44a3114048accfd5b407c4ac98 (diff) | |
download | redot-engine-1d5539cf776a8228a801fba4dcf70c9a72370487.tar.gz |
Editor: Improve Signal Dock for script classes
* Add signal documentation for script classes.
* Use separate sections for script class inheritance.
Diffstat (limited to 'editor/connections_dialog.cpp')
-rw-r--r-- | editor/connections_dialog.cpp | 134 |
1 files changed, 82 insertions, 52 deletions
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 3965dcd198..d4aebfc7a6 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -31,6 +31,7 @@ #include "connections_dialog.h" #include "core/config/project_settings.h" +#include "core/templates/hash_set.h" #include "editor/doc_tools.h" #include "editor/editor_help.h" #include "editor/editor_inspector.h" @@ -1239,60 +1240,102 @@ void ConnectionsDock::update_tree() { } TreeItem *root = tree->create_item(); + DocTools *doc_data = EditorHelp::get_doc_data(); + EditorData &editor_data = EditorNode::get_editor_data(); + StringName native_base = selected_node->get_class(); + Ref<Script> script_base = selected_node->get_script(); + + while (native_base != StringName()) { + String class_name; + String doc_class_name; + Ref<Texture2D> class_icon; + List<MethodInfo> class_signals; + const DocData::ClassDoc *class_doc = nullptr; + + if (script_base.is_valid()) { + // Try script global name. + class_name = script_base->get_global_name(); + if (!class_name.is_empty()) { + HashMap<String, DocData::ClassDoc>::ConstIterator F = doc_data->class_list.find(class_name); + if (F) { + class_doc = &F->value; + doc_class_name = class_name; + } + } - List<MethodInfo> node_signals; - - selected_node->get_signal_list(&node_signals); + // Try script path. + if (class_name.is_empty()) { + class_name = script_base->get_path().get_file(); + } + if (!class_doc) { + doc_class_name = script_base->get_path().trim_prefix("res://").quote(); + HashMap<String, DocData::ClassDoc>::ConstIterator F = doc_data->class_list.find(doc_class_name); + if (F) { + class_doc = &F->value; + } + } - bool did_script = false; - StringName base = selected_node->get_class(); + class_icon = editor_data.get_script_icon(script_base); + if (class_icon.is_null() && has_theme_icon(native_base, SNAME("EditorIcons"))) { + class_icon = get_theme_icon(native_base, SNAME("EditorIcons")); + } - while (base) { - List<MethodInfo> node_signals2; - Ref<Texture2D> icon; - String name; + script_base->get_script_signal_list(&class_signals); - if (!did_script) { - // Get script signals (including signals from any base scripts). - Ref<Script> scr = selected_node->get_script(); - if (scr.is_valid()) { - scr->get_script_signal_list(&node_signals2); - if (scr->get_path().is_resource_file()) { - name = scr->get_path().get_file(); - } else { - name = scr->get_class(); + // TODO: Core: Add optional parameter to ignore base classes (no_inheritance like in ClassDB). + Ref<Script> base = script_base->get_base_script(); + if (base.is_valid()) { + List<MethodInfo> base_signals; + base->get_script_signal_list(&base_signals); + HashSet<String> base_signal_names; + for (List<MethodInfo>::Element *F = base_signals.front(); F; F = F->next()) { + base_signal_names.insert(F->get().name); } - - if (has_theme_icon(scr->get_class(), SNAME("EditorIcons"))) { - icon = get_theme_icon(scr->get_class(), SNAME("EditorIcons")); + for (List<MethodInfo>::Element *F = class_signals.front(); F; F = F->next()) { + if (base_signal_names.has(F->get().name)) { + class_signals.erase(F); + } } } + + script_base = base; } else { - ClassDB::get_signal_list(base, &node_signals2, true); - if (has_theme_icon(base, SNAME("EditorIcons"))) { - icon = get_theme_icon(base, SNAME("EditorIcons")); + class_name = native_base; + + if (has_theme_icon(native_base, SNAME("EditorIcons"))) { + class_icon = get_theme_icon(native_base, SNAME("EditorIcons")); } - name = base; + + ClassDB::get_signal_list(native_base, &class_signals, true); + + HashMap<String, DocData::ClassDoc>::ConstIterator F = doc_data->class_list.find(class_name); + if (F) { + class_doc = &F->value; + doc_class_name = class_name; + } + + native_base = ClassDB::get_parent_class(native_base); } - if (icon.is_null()) { - icon = get_theme_icon(SNAME("Object"), SNAME("EditorIcons")); + if (class_icon.is_null()) { + class_icon = get_theme_icon(SNAME("Object"), SNAME("EditorIcons")); } TreeItem *section_item = nullptr; // Create subsections. - if (node_signals2.size()) { + if (!class_signals.is_empty()) { + class_signals.sort(); + section_item = tree->create_item(root); - section_item->set_text(0, name); - section_item->set_icon(0, icon); + section_item->set_text(0, class_name); + section_item->set_icon(0, class_icon); section_item->set_selectable(0, false); section_item->set_editable(0, false); section_item->set_custom_bg_color(0, get_theme_color(SNAME("prop_subsection"), SNAME("Editor"))); - node_signals2.sort(); } - for (MethodInfo &mi : node_signals2) { + for (MethodInfo &mi : class_signals) { const StringName signal_name = mi.name; if (!search_box->get_text().is_subsequence_ofn(signal_name)) { continue; @@ -1320,9 +1363,9 @@ void ConnectionsDock::update_tree() { String descr; bool found = false; - HashMap<StringName, HashMap<StringName, String>>::Iterator G = descr_cache.find(base); + HashMap<StringName, HashMap<StringName, String>>::ConstIterator G = descr_cache.find(doc_class_name); if (G) { - HashMap<StringName, String>::Iterator F = G->value.find(signal_name); + HashMap<StringName, String>::ConstIterator F = G->value.find(signal_name); if (F) { found = true; descr = F->value; @@ -1330,22 +1373,15 @@ void ConnectionsDock::update_tree() { } if (!found) { - DocTools *dd = EditorHelp::get_doc_data(); - HashMap<String, DocData::ClassDoc>::Iterator F = dd->class_list.find(base); - while (F && descr.is_empty()) { - for (int i = 0; i < F->value.signals.size(); i++) { - if (F->value.signals[i].name == signal_name.operator String()) { - descr = DTR(F->value.signals[i].description); + if (class_doc) { + for (int i = 0; i < class_doc->signals.size(); i++) { + if (class_doc->signals[i].name == signal_name.operator String()) { + descr = DTR(class_doc->signals[i].description); break; } } - if (!F->value.inherits.is_empty()) { - F = dd->class_list.find(F->value.inherits); - } else { - break; - } } - descr_cache[base][signal_name] = descr; + descr_cache[doc_class_name][signal_name] = descr; } // "::" separators used in make_custom_tooltip for formatting. @@ -1400,12 +1436,6 @@ void ConnectionsDock::update_tree() { } } } - - if (!did_script) { - did_script = true; - } else { - base = ClassDB::get_parent_class(base); - } } connect_button->set_text(TTR("Connect...")); |