summaryrefslogtreecommitdiff
path: root/editor/editor_help.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/editor_help.cpp')
-rw-r--r--editor/editor_help.cpp230
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") {