diff options
Diffstat (limited to 'editor/editor_help.cpp')
-rw-r--r-- | editor/editor_help.cpp | 230 |
1 files changed, 136 insertions, 94 deletions
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 03cd2c9b6b..8f427582ae 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -78,50 +78,40 @@ void EditorHelpSearch::_sbox_input(const Ref<InputEvent> &p_ie) { } } -void EditorHelpSearch::_update_search() { +class EditorHelpSearch::IncrementalSearch : public Reference { + String term; + TreeItem *root; - search_options->clear(); - search_options->set_hide_root(true); - - /* - TreeItem *root = search_options->create_item(); - _parse_fs(EditorFileSystem::get_singleton()->get_filesystem()); -*/ + EditorHelpSearch *search; + Tree *search_options; - List<StringName> type_list; - ClassDB::get_class_list(&type_list); - - DocData *doc = EditorHelp::get_doc_data(); - String term = search_box->get_text(); - if (term.length() < 2) - return; + DocData *doc; + Ref<Texture> def_icon; - TreeItem *root = search_options->create_item(); + int phase; + Map<String, DocData::ClassDoc>::Element *iterator; - Ref<Texture> def_icon = get_icon("Node", "EditorIcons"); - //classes first - for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { + void phase1(Map<String, DocData::ClassDoc>::Element *E) { if (E->key().findn(term) != -1) { TreeItem *item = search_options->create_item(root); item->set_metadata(0, "class_name:" + E->key()); item->set_text(0, E->key() + " (Class)"); - if (has_icon(E->key(), "EditorIcons")) - item->set_icon(0, get_icon(E->key(), "EditorIcons")); + if (search->has_icon(E->key(), "EditorIcons")) + item->set_icon(0, search->get_icon(E->key(), "EditorIcons")); else item->set_icon(0, def_icon); } } - //class methods, etc second - for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { + void phase2(Map<String, DocData::ClassDoc>::Element *E) { DocData::ClassDoc &c = E->get(); Ref<Texture> cicon; - if (has_icon(E->key(), "EditorIcons")) - cicon = get_icon(E->key(), "EditorIcons"); + if (search->has_icon(E->key(), "EditorIcons")) + cicon = search->get_icon(E->key(), "EditorIcons"); else cicon = def_icon; @@ -180,72 +170,80 @@ void EditorHelpSearch::_update_search() { } } - //same but descriptions + bool slice() { - for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) { + if (phase > 2) + return true; - DocData::ClassDoc &c = E->get(); + if (iterator) { - Ref<Texture> cicon; - if (has_icon(E->key(), "EditorIcons")) - cicon = get_icon(E->key(), "EditorIcons"); - else - cicon = def_icon; + switch (phase) { - if (c.description.findn(term) != -1) { + case 1: { + phase1(iterator); + } break; + case 2: { + phase2(iterator); + } break; + default: { + WARN_PRINT("illegal phase in IncrementalSearch"); + return true; + } + } - TreeItem *item = search_options->create_item(root); - item->set_metadata(0, "class_desc:" + E->key()); - item->set_text(0, E->key() + " (Class Description)"); - item->set_icon(0, cicon); + iterator = iterator->next(); + } else { + + phase += 1; + iterator = doc->class_list.front(); } - for (int i = 0; i < c.methods.size(); i++) { + return false; + } - if (c.methods[i].description.findn(term) != -1) { +public: + IncrementalSearch(EditorHelpSearch *p_search, Tree *p_search_options, const String &p_term) + : search(p_search), search_options(p_search_options) { - TreeItem *item = search_options->create_item(root); - item->set_metadata(0, "class_method_desc:" + E->key() + ":" + c.methods[i].name); - item->set_text(0, E->key() + "." + c.methods[i].name + " (Method Description)"); - item->set_icon(0, cicon); - } - } + def_icon = search->get_icon("Node", "EditorIcons"); + doc = EditorHelp::get_doc_data(); - for (int i = 0; i < c.signals.size(); i++) { + term = p_term; - if (c.signals[i].description.findn(term) != -1) { + root = search_options->create_item(); + phase = 0; + iterator = 0; + } - TreeItem *item = search_options->create_item(root); - item->set_metadata(0, "class_signal:" + E->key() + ":" + c.signals[i].name); - item->set_text(0, E->key() + "." + c.signals[i].name + " (Signal Description)"); - item->set_icon(0, cicon); - } - } + bool empty() const { - for (int i = 0; i < c.constants.size(); i++) { + return root->get_children() == NULL; + } - if (c.constants[i].description.findn(term) != -1) { + bool work(uint64_t slot = 1000000 / 10) { - TreeItem *item = search_options->create_item(root); - item->set_metadata(0, "class_constant:" + E->key() + ":" + c.constants[i].name); - item->set_text(0, E->key() + "." + c.constants[i].name + " (Constant Description)"); - item->set_icon(0, cicon); - } - } - - for (int i = 0; i < c.properties.size(); i++) { + const uint64_t until = OS::get_singleton()->get_ticks_usec() + slot; - if (c.properties[i].description.findn(term) != -1) { + while (!slice()) { - TreeItem *item = search_options->create_item(root); - item->set_metadata(0, "class_property_desc:" + E->key() + ":" + c.properties[i].name); - item->set_text(0, E->key() + "." + c.properties[i].name + " (Property Description)"); - item->set_icon(0, cicon); - } + if (OS::get_singleton()->get_ticks_usec() > until) + return false; } + + return true; } +}; - get_ok()->set_disabled(root->get_children() == NULL); +void EditorHelpSearch::_update_search() { + search_options->clear(); + search_options->set_hide_root(true); + + String term = search_box->get_text(); + if (term.length() < 2) + return; + + search = Ref<IncrementalSearch>(memnew(IncrementalSearch(this, search_options, term))); + set_process(true); } void EditorHelpSearch::_confirmed() { @@ -281,6 +279,20 @@ void EditorHelpSearch::_notification(int p_what) { //_update_icons search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons")); + } else if (p_what == NOTIFICATION_PROCESS) { + + if (search.is_valid()) { + + if (search->work()) { + + get_ok()->set_disabled(search->empty()); + search = Ref<IncrementalSearch>(); + set_process(false); + } + } else { + + set_process(false); + } } } @@ -433,12 +445,11 @@ void EditorHelpIndex::_update_class_list() { while (type != "") { if (filter.is_subsequence_ofi(type)) { - if (to_select.empty()) { + if (to_select.empty() || type.length() < to_select.length()) { to_select = type; } found = true; - break; } type = EditorHelp::get_doc_data()->class_list[type].inherits; @@ -555,7 +566,7 @@ void EditorHelp::_class_desc_select(const String &p_select) { if (select.find(".") != -1) { class_name = select.get_slice(".", 0); } else { - class_name = "@Global Scope"; + class_name = "@GlobalScope"; } emit_signal("go_to_help", "class_enum:" + class_name + ":" + select); return; @@ -564,18 +575,37 @@ void EditorHelp::_class_desc_select(const String &p_select) { emit_signal("go_to_help", "class_name:" + p_select.substr(1, p_select.length())); return; } else if (p_select.begins_with("@")) { + String tag = p_select.substr(1, 6); + String link = p_select.substr(7, p_select.length()); + + String topic; + Map<String, int> *table = NULL; + + if (tag == "method") { + topic = "class_method"; + table = &this->method_line; + } else if (tag == "member") { + topic = "class_property"; + table = &this->property_line; + } else if (tag == "enum ") { + topic = "class_enum"; + table = &this->enum_line; + } else if (tag == "signal") { + topic = "class_signal"; + table = &this->signal_line; + } else { + return; + } - String m = p_select.substr(1, p_select.length()); - - if (m.find(".") != -1) { + if (link.find(".") != -1) { //must go somewhere else - emit_signal("go_to_help", "class_method:" + m.get_slice(".", 0) + ":" + m.get_slice(".", 0)); + emit_signal("go_to_help", topic + ":" + link.get_slice(".", 0) + ":" + link.get_slice(".", 1)); } else { - if (!method_line.has(m)) + if (!table->has(link)) return; - class_desc->scroll_to_line(method_line[m]); + class_desc->scroll_to_line((*table)[link]); } } else if (p_select.begins_with("http")) { OS::get_singleton()->shell_open(p_select); @@ -808,7 +838,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) { } class_desc->push_cell(); if (describe) { - class_desc->push_meta("@" + cd.properties[i].name); + class_desc->push_meta("@member" + cd.properties[i].name); } class_desc->push_font(doc_code_font); @@ -881,7 +911,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) { if (methods[i].description != "") { method_descr = true; - class_desc->push_meta("@" + methods[i].name); + class_desc->push_meta("@method" + methods[i].name); } class_desc->push_color(headline_color); _add_text(methods[i].name); @@ -1240,7 +1270,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) { for (int i = 0; i < cd.properties.size(); i++) { - method_line[cd.properties[i].name] = class_desc->get_line_count() - 2; + property_line[cd.properties[i].name] = class_desc->get_line_count() - 2; class_desc->push_table(2); class_desc->set_table_column_expand(1, 1); @@ -1452,7 +1482,6 @@ void EditorHelp::_help_callback(const String &p_topic) { line = property_line[name]; } else if (what == "class_enum") { - print_line("go to enum:"); if (enum_line.has(name)) line = enum_line[name]; } else if (what == "class_theme_item") { @@ -1478,9 +1507,10 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { Color font_color_hl = p_rt->get_color("headline_color", "EditorHelp"); Color link_color = p_rt->get_color("accent_color", "Editor").linear_interpolate(font_color_hl, 0.8); - String bbcode = p_bbcode.replace("\t", " ").replace("\r", " ").strip_edges(); + String bbcode = p_bbcode.dedent().replace("\t", "").replace("\r", "").strip_edges(); List<String> tag_stack; + bool code_tag = false; int pos = 0; while (pos < bbcode.length()) { @@ -1491,7 +1521,10 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { brk_pos = bbcode.length(); if (brk_pos > pos) { - p_rt->add_text(bbcode.substr(pos, brk_pos - pos)); + String text = bbcode.substr(pos, brk_pos - pos); + if (!code_tag) + text = text.replace("\n", "\n\n"); + p_rt->add_text(text); } if (brk_pos == bbcode.length()) @@ -1500,7 +1533,11 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { int brk_end = bbcode.find("]", brk_pos + 1); if (brk_end == -1) { - p_rt->add_text(bbcode.substr(brk_pos, bbcode.length() - brk_pos)); + + String text = bbcode.substr(brk_pos, bbcode.length() - brk_pos); + if (!code_tag) + text = text.replace("\n", "\n\n"); + p_rt->add_text(text); break; } @@ -1509,27 +1546,31 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { if (tag.begins_with("/")) { bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length()); - if (tag_stack.size()) { - } if (!tag_ok) { p_rt->add_text("["); - pos++; + pos = brk_pos + 1; continue; } tag_stack.pop_front(); pos = brk_end + 1; + code_tag = false; if (tag != "/img") p_rt->pop(); + } else if (code_tag) { + + p_rt->add_text("["); + pos = brk_pos + 1; - } else if (tag.begins_with("method ")) { + } else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ")) { - String m = tag.substr(7, tag.length()); + String link_target = tag.substr(tag.find(" ") + 1, tag.length()); + String link_tag = tag.substr(0, tag.find(" ")).rpad(6); p_rt->push_color(link_color); - p_rt->push_meta("@" + m); - p_rt->add_text(m + "()"); + p_rt->push_meta("@" + link_tag + link_target); + p_rt->add_text(link_target + (tag.begins_with("method ") ? "()" : "")); p_rt->pop(); p_rt->pop(); pos = brk_end + 1; @@ -1559,6 +1600,7 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { //use monospace font p_rt->push_font(doc_code_font); + code_tag = true; pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "center") { |