diff options
-rw-r--r-- | editor/editor_help.cpp | 478 | ||||
-rw-r--r-- | editor/editor_help.h | 89 | ||||
-rw-r--r-- | editor/editor_help_search.cpp | 591 | ||||
-rw-r--r-- | editor/editor_help_search.h | 156 | ||||
-rw-r--r-- | editor/editor_node.cpp | 8 | ||||
-rw-r--r-- | editor/editor_node.h | 1 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 33 | ||||
-rw-r--r-- | editor/plugins/script_editor_plugin.h | 5 | ||||
-rw-r--r-- | editor/plugins/script_text_editor.cpp | 2 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 2 |
10 files changed, 757 insertions, 608 deletions
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index de1f856608..f502f918df 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -40,482 +40,6 @@ #define CONTRIBUTE2_URL "https://github.com/godotengine/godot-docs" #define REQUEST_URL "https://github.com/godotengine/godot-docs/issues/new" -void EditorHelpSearch::popup_dialog() { - - popup_centered(Size2(700, 600) * EDSCALE); - if (search_box->get_text() != "") { - search_box->select_all(); - _update_search(); - } - search_box->grab_focus(); -} - -void EditorHelpSearch::popup_dialog(const String &p_term) { - - popup_centered(Size2(700, 600) * EDSCALE); - if (p_term != "") { - search_box->set_text(p_term); - search_box->select_all(); - _update_search(); - } else { - search_box->clear(); - } - search_box->grab_focus(); -} - -void EditorHelpSearch::_text_changed(const String &p_newtext) { - - _update_search(); -} - -void EditorHelpSearch::_sbox_input(const Ref<InputEvent> &p_ie) { - - Ref<InputEventKey> k = p_ie; - - if (k.is_valid() && (k->get_scancode() == KEY_UP || - k->get_scancode() == KEY_DOWN || - k->get_scancode() == KEY_PAGEUP || - k->get_scancode() == KEY_PAGEDOWN)) { - - search_options->call("_gui_input", k); - search_box->accept_event(); - } -} - -void EditorHelpSearch::IncrementalSearch::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)"); - Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(E->key(), "Node"); - item->set_icon(0, icon); - } -} - -void EditorHelpSearch::IncrementalSearch::phase2(Map<String, DocData::ClassDoc>::Element *E) { - - DocData::ClassDoc &c = E->get(); - - Ref<Texture> cicon = EditorNode::get_singleton()->get_class_icon(E->key(), "Node"); - - for (int i = 0; i < c.methods.size(); i++) { - if ((term.begins_with(".") && c.methods[i].name.begins_with(term.right(1))) || (term.ends_with("(") && c.methods[i].name.ends_with(term.left(term.length() - 1).strip_edges())) || (term.begins_with(".") && term.ends_with("(") && c.methods[i].name == term.substr(1, term.length() - 2).strip_edges()) || c.methods[i].name.findn(term) != -1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0, "class_method:" + E->key() + ":" + c.methods[i].name); - item->set_text(0, E->key() + "." + c.methods[i].name + " (Method)"); - item->set_icon(0, cicon); - } - } - - for (int i = 0; i < c.signals.size(); i++) { - - if (c.signals[i].name.findn(term) != -1) { - - 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)"); - item->set_icon(0, cicon); - } - } - - for (int i = 0; i < c.constants.size(); i++) { - - if (c.constants[i].name.findn(term) != -1) { - - 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)"); - item->set_icon(0, cicon); - } - } - - for (int i = 0; i < c.properties.size(); i++) { - - if (c.properties[i].name.findn(term) != -1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0, "class_property:" + E->key() + ":" + c.properties[i].name); - item->set_text(0, E->key() + "." + c.properties[i].name + " (Property)"); - item->set_icon(0, cicon); - } - } - - for (int i = 0; i < c.theme_properties.size(); i++) { - - if (c.theme_properties[i].name.findn(term) != -1) { - - TreeItem *item = search_options->create_item(root); - item->set_metadata(0, "class_theme_item:" + E->key() + ":" + c.theme_properties[i].name); - item->set_text(0, E->key() + "." + c.theme_properties[i].name + " (Theme Item)"); - item->set_icon(0, cicon); - } - } -} - -bool EditorHelpSearch::IncrementalSearch::slice() { - - if (phase > 2) - return true; - - if (iterator) { - - switch (phase) { - - case 1: { - phase1(iterator); - } break; - case 2: { - phase2(iterator); - } break; - default: { - WARN_PRINT("illegal phase in IncrementalSearch"); - return true; - } - } - - iterator = iterator->next(); - } else { - - phase += 1; - iterator = doc->class_list.front(); - } - - return false; -} - -EditorHelpSearch::IncrementalSearch::IncrementalSearch(EditorHelpSearch *p_search, Tree *p_search_options, const String &p_term) : - search(p_search), - search_options(p_search_options) { - - def_icon = search->get_icon("Node", "EditorIcons"); - doc = EditorHelp::get_doc_data(); - - term = p_term; - - root = search_options->create_item(); - phase = 0; - iterator = 0; -} - -bool EditorHelpSearch::IncrementalSearch::empty() const { - - return root->get_children() == NULL; -} - -bool EditorHelpSearch::IncrementalSearch::work(uint64_t slot) { - - const uint64_t until = OS::get_singleton()->get_ticks_usec() + slot; - - while (!slice()) { - - if (OS::get_singleton()->get_ticks_usec() > until) - return false; - } - - return true; -} - -void EditorHelpSearch::_update_search() { - search_options->clear(); - - 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() { - - TreeItem *ti = search_options->get_selected(); - if (!ti) - return; - - String mdata = ti->get_metadata(0); - EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT); - emit_signal("go_to_help", mdata); - // go to that - hide(); -} - -void EditorHelpSearch::_notification(int p_what) { - - if (p_what == NOTIFICATION_ENTER_TREE) { - - //_update_icons - search_box->set_right_icon(get_icon("Search", "EditorIcons")); - search_box->set_clear_button_enabled(true); - - connect("confirmed", this, "_confirmed"); - _update_search(); - } else if (p_what == NOTIFICATION_EXIT_TREE) { - disconnect("confirmed", this, "_confirmed"); - } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { - - if (is_visible_in_tree()) { - - search_box->call_deferred("grab_focus"); // still not visible - search_box->select_all(); - } - } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - - //_update_icons - search_box->set_right_icon(get_icon("Search", "EditorIcons")); - search_box->set_clear_button_enabled(true); - } 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); - } - } -} - -void EditorHelpSearch::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_text_changed"), &EditorHelpSearch::_text_changed); - ClassDB::bind_method(D_METHOD("_confirmed"), &EditorHelpSearch::_confirmed); - ClassDB::bind_method(D_METHOD("_sbox_input"), &EditorHelpSearch::_sbox_input); - ClassDB::bind_method(D_METHOD("_update_search"), &EditorHelpSearch::_update_search); - - ADD_SIGNAL(MethodInfo("go_to_help")); -} - -EditorHelpSearch::EditorHelpSearch() { - - VBoxContainer *vbc = memnew(VBoxContainer); - add_child(vbc); - - search_box = memnew(LineEdit); - vbc->add_child(search_box); - search_box->connect("text_changed", this, "_text_changed"); - search_box->connect("gui_input", this, "_sbox_input"); - search_options = memnew(Tree); - search_options->set_hide_root(true); - vbc->add_margin_child(TTR("Matches:"), search_options, true); - get_ok()->set_text(TTR("Open")); - get_ok()->set_disabled(true); - register_text_enter(search_box); - set_hide_on_ok(false); - search_options->connect("item_activated", this, "_confirmed"); - set_title(TTR("Search Help")); -} - -///////////////////////////////// - -void EditorHelpIndex::add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root) { - - if (p_types.has(p_type)) - return; - - String inherits = EditorHelp::get_doc_data()->class_list[p_type].inherits; - - TreeItem *parent = p_root; - - if (inherits.length()) { - - if (!p_types.has(inherits)) { - - add_type(inherits, p_types, p_root); - } - - if (p_types.has(inherits)) - parent = p_types[inherits]; - } - - TreeItem *item = class_list->create_item(parent); - item->set_metadata(0, p_type); - item->set_tooltip(0, EditorHelp::get_doc_data()->class_list[p_type].brief_description); - item->set_text(0, p_type); - - Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(p_type); - item->set_icon(0, icon); - - p_types[p_type] = item; -} - -void EditorHelpIndex::_tree_item_selected() { - - TreeItem *s = class_list->get_selected(); - if (!s) - return; - - EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT); - emit_signal("open_class", s->get_text(0)); - hide(); -} - -void EditorHelpIndex::select_class(const String &p_class) { - - if (!tree_item_map.has(p_class)) - return; - tree_item_map[p_class]->select(0); - class_list->ensure_cursor_is_visible(); -} - -void EditorHelpIndex::popup_dialog() { - - popup_centered(Size2(500, 600) * EDSCALE); - - search_box->set_text(""); - _update_class_list(); -} - -void EditorHelpIndex::_notification(int p_what) { - - if (p_what == NOTIFICATION_ENTER_TREE) { - - //_update_icons - search_box->set_right_icon(get_icon("Search", "EditorIcons")); - search_box->set_clear_button_enabled(true); - _update_class_list(); - - connect("confirmed", this, "_tree_item_selected"); - - } else if (p_what == NOTIFICATION_POST_POPUP) { - - search_box->call_deferred("grab_focus"); - } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - - //_update_icons - search_box->set_right_icon(get_icon("Search", "EditorIcons")); - search_box->set_clear_button_enabled(true); - - bool enable_rl = EditorSettings::get_singleton()->get("docks/scene_tree/draw_relationship_lines"); - Color rl_color = EditorSettings::get_singleton()->get("docks/scene_tree/relationship_line_color"); - - if (enable_rl) { - class_list->add_constant_override("draw_relationship_lines", 1); - class_list->add_color_override("relationship_line_color", rl_color); - class_list->add_constant_override("draw_guides", 0); - } else { - class_list->add_constant_override("draw_relationship_lines", 0); - class_list->add_constant_override("draw_guides", 1); - } - } -} - -void EditorHelpIndex::_text_changed(const String &p_text) { - - _update_class_list(); -} - -void EditorHelpIndex::_update_class_list() { - - class_list->clear(); - tree_item_map.clear(); - TreeItem *root = class_list->create_item(); - - String filter = search_box->get_text().strip_edges(); - String to_select = ""; - - for (Map<String, DocData::ClassDoc>::Element *E = EditorHelp::get_doc_data()->class_list.front(); E; E = E->next()) { - - if (filter == "") { - add_type(E->key(), tree_item_map, root); - } else { - - bool found = false; - String type = E->key(); - - while (type != "") { - if (filter.is_subsequence_ofi(type)) { - - if (to_select.empty() || type.length() < to_select.length()) { - to_select = type; - } - - found = true; - } - - type = EditorHelp::get_doc_data()->class_list[type].inherits; - } - - if (found) { - add_type(E->key(), tree_item_map, root); - } - } - } - - if (tree_item_map.has(filter)) { - select_class(filter); - } else if (to_select != "") { - select_class(to_select); - } -} - -void EditorHelpIndex::_sbox_input(const Ref<InputEvent> &p_ie) { - - Ref<InputEventKey> k = p_ie; - - if (k.is_valid() && (k->get_scancode() == KEY_UP || - k->get_scancode() == KEY_DOWN || - k->get_scancode() == KEY_PAGEUP || - k->get_scancode() == KEY_PAGEDOWN)) { - - class_list->call("_gui_input", k); - search_box->accept_event(); - } -} - -void EditorHelpIndex::_bind_methods() { - - ClassDB::bind_method("_tree_item_selected", &EditorHelpIndex::_tree_item_selected); - ClassDB::bind_method("_text_changed", &EditorHelpIndex::_text_changed); - ClassDB::bind_method("_sbox_input", &EditorHelpIndex::_sbox_input); - ClassDB::bind_method("select_class", &EditorHelpIndex::select_class); - ADD_SIGNAL(MethodInfo("open_class")); -} - -EditorHelpIndex::EditorHelpIndex() { - - VBoxContainer *vbc = memnew(VBoxContainer); - add_child(vbc); - - search_box = memnew(LineEdit); - vbc->add_child(search_box); - search_box->set_h_size_flags(SIZE_EXPAND_FILL); - - register_text_enter(search_box); - - search_box->connect("text_changed", this, "_text_changed"); - search_box->connect("gui_input", this, "_sbox_input"); - - class_list = memnew(Tree); - vbc->add_margin_child(TTR("Class List:") + " ", class_list, true); - class_list->set_hide_root(true); - class_list->set_v_size_flags(SIZE_EXPAND_FILL); - - class_list->connect("item_activated", this, "_tree_item_selected"); - - bool enable_rl = EditorSettings::get_singleton()->get("docks/scene_tree/draw_relationship_lines"); - Color rl_color = EditorSettings::get_singleton()->get("docks/scene_tree/relationship_line_color"); - - if (enable_rl) { - class_list->add_constant_override("draw_relationship_lines", 1); - class_list->add_color_override("relationship_line_color", rl_color); - } else { - class_list->add_constant_override("draw_relationship_lines", 0); - } - - get_ok()->set_text(TTR("Open")); - set_title(TTR("Search Classes")); -} - -///////////////////////////////// - DocData *EditorHelp::doc = NULL; void EditorHelp::_init_colors() { @@ -1923,8 +1447,6 @@ EditorHelp::EditorHelp() { EditorHelp::~EditorHelp() { } -///////////// - void EditorHelpBit::_go_to_help(String p_what) { EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT); diff --git a/editor/editor_help.h b/editor/editor_help.h index 25db68b42d..205778ec11 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -31,6 +31,8 @@ #ifndef EDITOR_HELP_H #define EDITOR_HELP_H +#include "editor/code_editor.h" +#include "editor/doc/doc_data.h" #include "editor/editor_plugin.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel_container.h" @@ -38,95 +40,9 @@ #include "scene/gui/split_container.h" #include "scene/gui/tab_container.h" #include "scene/gui/text_edit.h" -#include "scene/gui/tree.h" - -#include "editor/code_editor.h" -#include "editor/doc/doc_data.h" #include "scene/main/timer.h" -class EditorNode; - -class EditorHelpSearch : public ConfirmationDialog { - - GDCLASS(EditorHelpSearch, ConfirmationDialog) - - LineEdit *search_box; - Tree *search_options; - String base_type; - - class IncrementalSearch : public Reference { - String term; - TreeItem *root; - - EditorHelpSearch *search; - Tree *search_options; - - DocData *doc; - Ref<Texture> def_icon; - - int phase; - Map<String, DocData::ClassDoc>::Element *iterator; - - void phase1(Map<String, DocData::ClassDoc>::Element *E); - void phase2(Map<String, DocData::ClassDoc>::Element *E); - bool slice(); - - public: - IncrementalSearch(EditorHelpSearch *p_search, Tree *p_search_options, const String &p_term); - - bool empty() const; - bool work(uint64_t slot = 1000000 / 10); - }; - - Ref<IncrementalSearch> search; - - void _update_search(); - - void _sbox_input(const Ref<InputEvent> &p_ie); - - void _confirmed(); - void _text_changed(const String &p_newtext); - -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - void popup_dialog(); - void popup_dialog(const String &p_term); - - EditorHelpSearch(); -}; - -class EditorHelpIndex : public ConfirmationDialog { - GDCLASS(EditorHelpIndex, ConfirmationDialog); - - LineEdit *search_box; - Tree *class_list; - HashMap<String, TreeItem *> tree_item_map; - - void _tree_item_selected(); - void _text_changed(const String &p_text); - void _sbox_input(const Ref<InputEvent> &p_ie); - - void _update_class_list(); - - void add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root); - -protected: - void _notification(int p_what); - static void _bind_methods(); - -public: - void select_class(const String &p_class); - - void popup_dialog(); - - EditorHelpIndex(); -}; - class FindBar : public HBoxContainer { - GDCLASS(FindBar, HBoxContainer); LineEdit *search_text; @@ -172,6 +88,7 @@ public: }; class EditorHelp : public VBoxContainer { + GDCLASS(EditorHelp, VBoxContainer); enum Page { diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp new file mode 100644 index 0000000000..f5717ddf2a --- /dev/null +++ b/editor/editor_help_search.cpp @@ -0,0 +1,591 @@ +/*************************************************************************/ +/* editor_help_search.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_help_search.h" + +#include "core/os/keyboard.h" +#include "editor_node.h" + +void EditorHelpSearch::_update_icons() { + + search_box->set_right_icon(get_icon("Search", "EditorIcons")); + search_box->set_clear_button_enabled(true); + search_box->add_icon_override("right_icon", get_icon("Search", "EditorIcons")); + case_sensitive_button->set_icon(get_icon("MatchCase", "EditorIcons")); + hierarchy_button->set_icon(get_icon("ClassList", "EditorIcons")); + + if (is_visible_in_tree()) + _update_results(); +} + +void EditorHelpSearch::_load_settings() { + + bool enable_rl = EditorSettings::get_singleton()->get("docks/scene_tree/draw_relationship_lines"); + Color rl_color = EditorSettings::get_singleton()->get("docks/scene_tree/relationship_line_color"); + + if (enable_rl) { + results_tree->add_constant_override("draw_relationship_lines", 1); + results_tree->add_color_override("relationship_line_color", rl_color); + } else { + results_tree->add_constant_override("draw_relationship_lines", 0); + results_tree->add_constant_override("draw_guides", 1); + } +} + +void EditorHelpSearch::_update_results() { + + String term = search_box->get_text(); + + int search_flags = filter_combo->get_selected_id(); + if (case_sensitive_button->is_pressed()) + search_flags |= SEARCH_CASE_SENSITIVE; + if (hierarchy_button->is_pressed()) + search_flags |= SEARCH_SHOW_HIERARCHY; + + search = Ref<Runner>(memnew(Runner(this, results_tree, term, search_flags))); + set_process(true); +} + +void EditorHelpSearch::_search_box_gui_input(const Ref<InputEvent> &p_ie) { + + // Redirect up and down navigational key events to the results list. + Ref<InputEventKey> k = p_ie; + if (k.is_valid()) { + switch (k->get_scancode()) { + case KEY_UP: + case KEY_DOWN: + case KEY_PAGEUP: + case KEY_PAGEDOWN: { + results_tree->call("_gui_input", k); + search_box->accept_event(); + } break; + } + } +} + +void EditorHelpSearch::_search_box_text_changed(const String &p_text) { + + _update_results(); +} + +void EditorHelpSearch::_case_sensitive_button_pressed() { + + search_box->grab_focus(); + _update_results(); +} + +void EditorHelpSearch::_hierarchy_button_pressed() { + + search_box->grab_focus(); + _update_results(); +} + +void EditorHelpSearch::_filter_combo_item_selected(int p_option) { + + _update_results(); +} + +void EditorHelpSearch::_confirmed() { + + // Activate the script editor and emit the signal with the documentation link to display. + EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT); + + TreeItem *item = results_tree->get_selected(); + emit_signal("go_to_help", item->get_metadata(0)); + + hide(); +} + +void EditorHelpSearch::_notification(int p_what) { + + switch (p_what) { + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + _load_settings(); + _update_icons(); + } break; + case NOTIFICATION_ENTER_TREE: { + + connect("confirmed", this, "_confirmed"); + _update_icons(); + } break; + case NOTIFICATION_POPUP_HIDE: { + + results_tree->clear(); + EditorSettings::get_singleton()->set("interface/dialogs/search_help_bounds", get_rect()); + } break; + case NOTIFICATION_PROCESS: { + + // Update background search. + if (search.is_valid()) { + if (search->work()) { + // Search done. + get_ok()->set_disabled(results_tree->get_root()->get_children() == NULL); + search = Ref<Runner>(); + set_process(false); + } + } else { + set_process(false); + } + } break; + } +} + +void EditorHelpSearch::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_search_box_gui_input"), &EditorHelpSearch::_search_box_gui_input); + ClassDB::bind_method(D_METHOD("_search_box_text_changed"), &EditorHelpSearch::_search_box_text_changed); + ClassDB::bind_method(D_METHOD("_case_sensitive_button_pressed"), &EditorHelpSearch::_case_sensitive_button_pressed); + ClassDB::bind_method(D_METHOD("_hierarchy_button_pressed"), &EditorHelpSearch::_hierarchy_button_pressed); + ClassDB::bind_method(D_METHOD("_filter_combo_item_selected"), &EditorHelpSearch::_filter_combo_item_selected); + ClassDB::bind_method(D_METHOD("_confirmed"), &EditorHelpSearch::_confirmed); + ADD_SIGNAL(MethodInfo("go_to_help")); +} + +void EditorHelpSearch::popup_dialog() { + + popup_dialog(search_box->get_text()); +} + +void EditorHelpSearch::popup_dialog(const String &p_term) { + + // Restore valid window bounds or pop up at default size. + if (EditorSettings::get_singleton()->has_setting("interface/dialogs/search_help_bounds")) + popup(EditorSettings::get_singleton()->get("interface/dialogs/search_help_bounds")); + else + popup_centered_ratio(0.5F); + + if (p_term == "") { + search_box->clear(); + } else { + search_box->set_text(p_term); + search_box->select_all(); + } + search_box->grab_focus(); + _update_results(); +} + +EditorHelpSearch::EditorHelpSearch() { + + set_hide_on_ok(false); + set_resizable(true); + set_title(TTR("Search Help")); + + get_ok()->set_disabled(true); + get_ok()->set_text(TTR("Open")); + + // Split search and results area. + VBoxContainer *vbox = memnew(VBoxContainer); + add_child(vbox); + + // Create the search box and filter controls (at the top). + HBoxContainer *hbox = memnew(HBoxContainer); + vbox->add_child(hbox); + + search_box = memnew(LineEdit); + search_box->set_custom_minimum_size(Size2(200, 0)); + search_box->set_h_size_flags(SIZE_EXPAND_FILL); + search_box->connect("gui_input", this, "_search_box_gui_input"); + search_box->connect("text_changed", this, "_search_box_text_changed"); + register_text_enter(search_box); + hbox->add_child(search_box); + + case_sensitive_button = memnew(ToolButton); + case_sensitive_button->set_tooltip("Case Sensitive"); + case_sensitive_button->connect("pressed", this, "_case_sensitive_button_pressed"); + case_sensitive_button->set_toggle_mode(true); + hbox->add_child(case_sensitive_button); + + hierarchy_button = memnew(ToolButton); + hierarchy_button->set_tooltip("Show Hierarchy"); + hierarchy_button->connect("pressed", this, "_hierarchy_button_pressed"); + hierarchy_button->set_toggle_mode(true); + hierarchy_button->set_pressed(true); + hbox->add_child(hierarchy_button); + + filter_combo = memnew(OptionButton); + filter_combo->set_custom_minimum_size(Size2(200, 0)); + filter_combo->set_stretch_ratio(0); // Fixed width. + filter_combo->add_item(TTR("Display All"), SEARCH_ALL); + filter_combo->add_separator(); + filter_combo->add_item(TTR("Classes Only"), SEARCH_CLASSES); + filter_combo->add_item(TTR("Methods Only"), SEARCH_METHODS); + filter_combo->add_item(TTR("Signals Only"), SEARCH_SIGNALS); + filter_combo->add_item(TTR("Constants Only"), SEARCH_CONSTANTS); + filter_combo->add_item(TTR("Properties Only"), SEARCH_PROPERTIES); + filter_combo->add_item(TTR("Theme Properties Only"), SEARCH_THEME_ITEMS); + filter_combo->connect("item_selected", this, "_filter_combo_item_selected"); + hbox->add_child(filter_combo); + + // Create the results tree. + results_tree = memnew(Tree); + results_tree->set_v_size_flags(SIZE_EXPAND_FILL); + results_tree->set_columns(2); + results_tree->set_column_title(0, TTR("Name")); + results_tree->set_column_title(1, TTR("Member Type")); + results_tree->set_column_expand(1, false); + results_tree->set_column_min_width(1, 150); + results_tree->set_custom_minimum_size(Size2(0, 100)); + results_tree->set_hide_root(true); + results_tree->set_select_mode(Tree::SELECT_ROW); + results_tree->connect("item_activated", this, "_confirmed"); + vbox->add_child(results_tree, true); + + _load_settings(); +} + +bool EditorHelpSearch::Runner::_slice() { + + bool phase_done = false; + switch (phase) { + case PHASE_MATCH_CLASSES_INIT: + phase_done = _phase_match_classes_init(); + break; + case PHASE_MATCH_CLASSES: + phase_done = _phase_match_classes(); + break; + case PHASE_CLASS_ITEMS_INIT: + phase_done = _phase_class_items_init(); + break; + case PHASE_CLASS_ITEMS: + phase_done = _phase_class_items(); + break; + case PHASE_MEMBER_ITEMS_INIT: + phase_done = _phase_member_items_init(); + break; + case PHASE_MEMBER_ITEMS: + phase_done = _phase_member_items(); + break; + case PHASE_SELECT_MATCH: + phase_done = _phase_select_match(); + break; + case PHASE_MAX: + return true; + default: + WARN_PRINTS("Invalid or unhandled phase in EditorHelpSearch::Runner, aborting search."); + return true; + }; + + if (phase_done) + phase++; + return false; +} + +bool EditorHelpSearch::Runner::_phase_match_classes_init() { + + iterator_doc = EditorHelp::get_doc_data()->class_list.front(); + matches.clear(); + matched_item = NULL; + + return true; +} + +bool EditorHelpSearch::Runner::_phase_match_classes() { + + DocData::ClassDoc &class_doc = iterator_doc->value(); + + matches[class_doc.name] = ClassMatch(); + ClassMatch &match = matches[class_doc.name]; + + match.doc = &class_doc; + + // Match class name. + if (search_flags & SEARCH_CLASSES) + match.name = term == "" || _match_string(term, class_doc.name); + + // Match members if the term is long enough. + if (term.length() > 1) { + if (search_flags & SEARCH_METHODS) + for (int i = 0; i < class_doc.methods.size(); i++) { + String method_name = search_flags & SEARCH_CASE_SENSITIVE ? class_doc.methods[i].name : class_doc.methods[i].name.to_lower(); + if (method_name.find(term) > -1 || + (term.begins_with(".") && method_name.begins_with(term.right(1))) || + (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || + (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) + match.methods.push_back(const_cast<DocData::MethodDoc *>(&class_doc.methods[i])); + } + if (search_flags & SEARCH_SIGNALS) + for (int i = 0; i < class_doc.signals.size(); i++) + if (_match_string(term, class_doc.signals[i].name)) + match.signals.push_back(const_cast<DocData::MethodDoc *>(&class_doc.signals[i])); + if (search_flags & SEARCH_CONSTANTS) + for (int i = 0; i < class_doc.constants.size(); i++) + if (_match_string(term, class_doc.constants[i].name)) + match.constants.push_back(const_cast<DocData::ConstantDoc *>(&class_doc.constants[i])); + if (search_flags & SEARCH_PROPERTIES) + for (int i = 0; i < class_doc.properties.size(); i++) + if (_match_string(term, class_doc.properties[i].name)) + match.properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc.properties[i])); + if (search_flags & SEARCH_THEME_ITEMS) + for (int i = 0; i < class_doc.theme_properties.size(); i++) + if (_match_string(term, class_doc.theme_properties[i].name)) + match.theme_properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc.theme_properties[i])); + } + + iterator_doc = iterator_doc->next(); + return !iterator_doc; +} + +bool EditorHelpSearch::Runner::_phase_class_items_init() { + + iterator_match = matches.front(); + + results_tree->clear(); + root_item = results_tree->create_item(); + class_items.clear(); + + return true; +} + +bool EditorHelpSearch::Runner::_phase_class_items() { + + ClassMatch &match = iterator_match->value(); + + if (search_flags & SEARCH_SHOW_HIERARCHY) { + if (match.required()) + _create_class_hierarchy(match); + } else { + if (match.name) + _create_class_item(root_item, match.doc, false); + } + + iterator_match = iterator_match->next(); + return !iterator_match; +} + +bool EditorHelpSearch::Runner::_phase_member_items_init() { + + iterator_match = matches.front(); + + return true; +} + +bool EditorHelpSearch::Runner::_phase_member_items() { + + ClassMatch &match = iterator_match->value(); + + TreeItem *parent = search_flags & SEARCH_SHOW_HIERARCHY ? class_items[match.doc->name] : root_item; + for (int i = 0; i < match.methods.size(); i++) + _create_method_item(parent, match.doc, match.methods[i]); + for (int i = 0; i < match.signals.size(); i++) + _create_signal_item(parent, match.doc, match.signals[i]); + for (int i = 0; i < match.constants.size(); i++) + _create_constant_item(parent, match.doc, match.constants[i]); + for (int i = 0; i < match.properties.size(); i++) + _create_property_item(parent, match.doc, match.properties[i]); + for (int i = 0; i < match.theme_properties.size(); i++) + _create_theme_property_item(parent, match.doc, match.theme_properties[i]); + + iterator_match = iterator_match->next(); + return !iterator_match; +} + +bool EditorHelpSearch::Runner::_phase_select_match() { + + if (matched_item) + matched_item->select(0); + results_tree->ensure_cursor_is_visible(); + + return true; +} + +bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String &p_string) const { + + if (search_flags & SEARCH_CASE_SENSITIVE) + return p_string.find(p_term) > -1; + else + return p_string.findn(p_term) > -1; +} + +void EditorHelpSearch::Runner::_match_item(TreeItem *p_item, const String &p_text) { + + if (!matched_item) { + if (search_flags & SEARCH_CASE_SENSITIVE) { + if (p_text.casecmp_to(term) == 0) + matched_item = p_item; + } else { + if (p_text.nocasecmp_to(term) == 0) + matched_item = p_item; + } + } +} + +TreeItem *EditorHelpSearch::Runner::_create_class_hierarchy(const ClassMatch &p_match) { + + if (class_items.has(p_match.doc->name)) + return class_items[p_match.doc->name]; + + // Ensure parent nodes are created first. + TreeItem *parent = root_item; + if (p_match.doc->inherits != "") { + if (class_items.has(p_match.doc->inherits)) { + parent = class_items[p_match.doc->inherits]; + } else { + ClassMatch &base_match = matches[p_match.doc->inherits]; + parent = _create_class_hierarchy(base_match); + } + } + + TreeItem *class_item = _create_class_item(parent, p_match.doc, !p_match.name); + class_items[p_match.doc->name] = class_item; + return class_item; +} + +TreeItem *EditorHelpSearch::Runner::_create_class_item(TreeItem *p_parent, const DocData::ClassDoc *p_doc, bool p_gray) { + + Ref<Texture> icon = empty_icon; + if (ui_service->has_icon(p_doc->name, "EditorIcons")) + icon = ui_service->get_icon(p_doc->name, "EditorIcons"); + else if (ClassDB::is_parent_class(p_doc->name, "Object")) + icon = ui_service->get_icon("Object", "EditorIcons"); + String tooltip = p_doc->brief_description.strip_edges(); + + TreeItem *item = results_tree->create_item(p_parent); + item->set_icon(0, icon); + item->set_text(0, p_doc->name); + item->set_text(1, TTR("Class")); + item->set_tooltip(0, tooltip); + item->set_tooltip(1, tooltip); + item->set_metadata(0, "class_name:" + p_doc->name); + if (p_gray) { + item->set_custom_color(0, disabled_color); + item->set_custom_color(1, disabled_color); + } + + _match_item(item, p_doc->name); + + return item; +} + +TreeItem *EditorHelpSearch::Runner::_create_method_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc) { + + String tooltip = p_doc->return_type + " " + p_class_doc->name + "." + p_doc->name + "("; + for (int i = 0; i < p_doc->arguments.size(); i++) { + const DocData::ArgumentDoc &arg = p_doc->arguments[i]; + tooltip += arg.type + " " + arg.name; + if (arg.default_value != "") + tooltip += " = " + arg.default_value; + if (i < p_doc->arguments.size() - 1) + tooltip += ", "; + } + tooltip += ")"; + return _create_member_item(p_parent, p_class_doc->name, "MemberMethod", p_doc->name, "Method", "method", tooltip); +} + +TreeItem *EditorHelpSearch::Runner::_create_signal_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc) { + + String tooltip = p_doc->return_type + " " + p_class_doc->name + "." + p_doc->name + "("; + for (int i = 0; i < p_doc->arguments.size(); i++) { + const DocData::ArgumentDoc &arg = p_doc->arguments[i]; + tooltip += arg.type + " " + arg.name; + if (arg.default_value != "") + tooltip += " = " + arg.default_value; + if (i < p_doc->arguments.size() - 1) + tooltip += ", "; + } + tooltip += ")"; + return _create_member_item(p_parent, p_class_doc->name, "MemberSignal", p_doc->name, "Signal", "signal", tooltip); +} + +TreeItem *EditorHelpSearch::Runner::_create_constant_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ConstantDoc *p_doc) { + + String tooltip = p_class_doc->name + "." + p_doc->name; + return _create_member_item(p_parent, p_class_doc->name, "MemberConstant", p_doc->name, "Constant", "constant", tooltip); +} + +TreeItem *EditorHelpSearch::Runner::_create_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::PropertyDoc *p_doc) { + + String tooltip = p_doc->type + " " + p_class_doc->name + "." + p_doc->name; + tooltip += "\n " + p_class_doc->name + "." + p_doc->setter + "(value) setter"; + tooltip += "\n " + p_class_doc->name + "." + p_doc->getter + "() getter"; + return _create_member_item(p_parent, p_class_doc->name, "MemberProperty", p_doc->name, "Property", "property", tooltip); +} + +TreeItem *EditorHelpSearch::Runner::_create_theme_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::PropertyDoc *p_doc) { + + String tooltip = p_doc->type + " " + p_class_doc->name + "." + p_doc->name; + return _create_member_item(p_parent, p_class_doc->name, "MemberTheme", p_doc->name, "Theme Property", "theme_item", tooltip); +} + +TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, const String &p_class_name, const String &p_icon, const String &p_name, const String &p_type, const String &p_metatype, const String &p_tooltip) { + + Ref<Texture> icon; + String text; + if (search_flags & SEARCH_SHOW_HIERARCHY) { + icon = ui_service->get_icon(p_icon, "EditorIcons"); + text = p_name; + } else { + icon = ui_service->get_icon(p_icon, "EditorIcons"); + /*// In flat mode, show the class icon. + if (ui_service->has_icon(p_class_name, "EditorIcons")) + icon = ui_service->get_icon(p_class_name, "EditorIcons"); + else if (ClassDB::is_parent_class(p_class_name, "Object")) + icon = ui_service->get_icon("Object", "EditorIcons");*/ + text = p_class_name + "." + p_name; + } + + TreeItem *item = results_tree->create_item(p_parent); + item->set_icon(0, icon); + item->set_text(0, text); + item->set_text(1, TTR(p_type)); + item->set_tooltip(0, p_tooltip); + item->set_tooltip(1, p_tooltip); + item->set_metadata(0, "class_" + p_metatype + ":" + p_class_name + ":" + p_name); + + _match_item(item, p_name); + + return item; +} + +bool EditorHelpSearch::Runner::work(uint64_t slot) { + + // Return true when the search has been completed, otherwise false. + const uint64_t until = OS::get_singleton()->get_ticks_usec() + slot; + while (!_slice()) + if (OS::get_singleton()->get_ticks_usec() > until) + return false; + return true; +} + +EditorHelpSearch::Runner::Runner(Control *p_icon_service, Tree *p_results_tree, const String &p_term, int p_search_flags) { + + ui_service = p_icon_service; + results_tree = p_results_tree; + term = p_term.strip_edges(); + search_flags = p_search_flags; + + if ((search_flags & SEARCH_CASE_SENSITIVE) == 0) + term = term.to_lower(); + + empty_icon = ui_service->get_icon("ArrowRight", "EditorIcons"); + disabled_color = ui_service->get_color("disabled_font_color", "Editor"); + + phase = 0; +} diff --git a/editor/editor_help_search.h b/editor/editor_help_search.h new file mode 100644 index 0000000000..1016675dd2 --- /dev/null +++ b/editor/editor_help_search.h @@ -0,0 +1,156 @@ +/*************************************************************************/ +/* editor_help_search.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef EDITOR_HELP_SEARCH_H +#define EDITOR_HELP_SEARCH_H + +#include "core/ordered_hash_map.h" +#include "editor/code_editor.h" +#include "editor/editor_help.h" +#include "editor/editor_plugin.h" +#include "scene/gui/option_button.h" +#include "scene/gui/tree.h" + +class EditorHelpSearch : public ConfirmationDialog { + GDCLASS(EditorHelpSearch, ConfirmationDialog); + + enum SearchFlags { + SEARCH_CLASSES = 1 << 0, + SEARCH_METHODS = 1 << 1, + SEARCH_SIGNALS = 1 << 2, + SEARCH_CONSTANTS = 1 << 3, + SEARCH_PROPERTIES = 1 << 4, + SEARCH_THEME_ITEMS = 1 << 5, + SEARCH_ALL = SEARCH_CLASSES | SEARCH_METHODS | SEARCH_SIGNALS | SEARCH_CONSTANTS | SEARCH_PROPERTIES | SEARCH_THEME_ITEMS, + SEARCH_CASE_SENSITIVE = 1 << 29, + SEARCH_SHOW_HIERARCHY = 1 << 30 + }; + + LineEdit *search_box; + ToolButton *case_sensitive_button; + ToolButton *hierarchy_button; + OptionButton *filter_combo; + Tree *results_tree; + + class Runner; + Ref<Runner> search; + + void _update_icons(); + void _load_settings(); + void _update_results(); + + void _search_box_gui_input(const Ref<InputEvent> &p_ie); + void _search_box_text_changed(const String &p_text); + void _case_sensitive_button_pressed(); + void _hierarchy_button_pressed(); + void _filter_combo_item_selected(int p_option); + void _confirmed(); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + void popup_dialog(); + void popup_dialog(const String &p_term); + + EditorHelpSearch(); +}; + +class EditorHelpSearch::Runner : public Reference { + + enum Phase { + PHASE_MATCH_CLASSES_INIT, + PHASE_MATCH_CLASSES, + PHASE_CLASS_ITEMS_INIT, + PHASE_CLASS_ITEMS, + PHASE_MEMBER_ITEMS_INIT, + PHASE_MEMBER_ITEMS, + PHASE_SELECT_MATCH, + PHASE_MAX + }; + int phase; + + struct ClassMatch { + DocData::ClassDoc *doc; + bool name; + Vector<DocData::MethodDoc *> methods; + Vector<DocData::MethodDoc *> signals; + Vector<DocData::ConstantDoc *> constants; + Vector<DocData::PropertyDoc *> properties; + Vector<DocData::PropertyDoc *> theme_properties; + + bool required() { + return name || methods.size() || signals.size() || constants.size() || properties.size() || theme_properties.size(); + } + }; + + Control *ui_service; + Tree *results_tree; + String term; + int search_flags; + + Ref<Texture> empty_icon; + Color disabled_color; + + Map<String, DocData::ClassDoc>::Element *iterator_doc; + Map<String, ClassMatch> matches; + Map<String, ClassMatch>::Element *iterator_match; + TreeItem *root_item; + Map<String, TreeItem *> class_items; + TreeItem *matched_item; + + bool _slice(); + bool _phase_match_classes_init(); + bool _phase_match_classes(); + bool _phase_class_items_init(); + bool _phase_class_items(); + bool _phase_member_items_init(); + bool _phase_member_items(); + bool _phase_select_match(); + + bool _match_string(const String &p_term, const String &p_string) const; + void _match_item(TreeItem *p_item, const String &p_text); + TreeItem *_create_class_hierarchy(const ClassMatch &p_match); + TreeItem *_create_class_item(TreeItem *p_parent, const DocData::ClassDoc *p_doc, bool p_gray); + TreeItem *_create_method_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc); + TreeItem *_create_signal_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc); + TreeItem *_create_constant_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ConstantDoc *p_doc); + TreeItem *_create_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::PropertyDoc *p_doc); + TreeItem *_create_theme_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::PropertyDoc *p_doc); + TreeItem *_create_member_item(TreeItem *p_parent, const String &p_class_name, const String &p_icon, const String &p_name, const String &p_type, const String &p_metatype, const String &p_tooltip); + +public: + bool work(uint64_t slot = 100000); + + Runner(Control *p_icon_service, Tree *p_results_tree, const String &p_term, int p_search_flags); +}; + +#endif // EDITOR_HELP_SEARCH_H diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index b8d5ba5acb..a6f94ab363 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -384,7 +384,6 @@ void EditorNode::_notification(int p_what) { update_menu->set_icon(gui_base->get_icon("Progress1", "EditorIcons")); PopupMenu *p = help_menu->get_popup(); - p->set_item_icon(p->get_item_index(HELP_CLASSES), gui_base->get_icon("ClassList", "EditorIcons")); p->set_item_icon(p->get_item_index(HELP_SEARCH), gui_base->get_icon("HelpSearch", "EditorIcons")); p->set_item_icon(p->get_item_index(HELP_DOCS), gui_base->get_icon("Instance", "EditorIcons")); p->set_item_icon(p->get_item_index(HELP_QA), gui_base->get_icon("Instance", "EditorIcons")); @@ -2262,9 +2261,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { file->popup_centered_ratio(); } break; - case HELP_CLASSES: { - emit_signal("request_help_index", ""); - } break; case HELP_SEARCH: { emit_signal("request_help_search", ""); } break; @@ -4654,7 +4650,6 @@ void EditorNode::_bind_methods() { ADD_SIGNAL(MethodInfo("pause_pressed")); ADD_SIGNAL(MethodInfo("stop_pressed")); ADD_SIGNAL(MethodInfo("request_help_search")); - ADD_SIGNAL(MethodInfo("request_help_index")); ADD_SIGNAL(MethodInfo("script_add_function_request", PropertyInfo(Variant::OBJECT, "obj"), PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::POOL_STRING_ARRAY, "args"))); ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj"))); } @@ -5340,8 +5335,7 @@ EditorNode::EditorNode() { p = help_menu->get_popup(); p->set_hide_on_window_lose_focus(true); p->connect("id_pressed", this, "_menu_option"); - p->add_icon_item(gui_base->get_icon("ClassList", "EditorIcons"), TTR("Classes"), HELP_CLASSES); - p->add_icon_item(gui_base->get_icon("HelpSearch", "EditorIcons"), TTR("Search"), HELP_SEARCH); + p->add_icon_shortcut(gui_base->get_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("editor/editor_help", TTR("Search"), KEY_F4), HELP_SEARCH); p->add_separator(); p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Online Docs"), HELP_DOCS); p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Q&A"), HELP_QA); diff --git a/editor/editor_node.h b/editor/editor_node.h index be6bacd0d1..ebf0b9de7c 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -180,7 +180,6 @@ private: SETTINGS_HELP, SCENE_TAB_CLOSE, - HELP_CLASSES, HELP_SEARCH, HELP_DOCS, HELP_QA, diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 085660b79e..ae6fa8e6bb 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -50,8 +50,7 @@ void ScriptEditorBase::_bind_methods() { ADD_SIGNAL(MethodInfo("name_changed")); ADD_SIGNAL(MethodInfo("edited_script_changed")); - ADD_SIGNAL(MethodInfo("request_help_search", PropertyInfo(Variant::STRING, "topic"))); - ADD_SIGNAL(MethodInfo("request_help_index")); + ADD_SIGNAL(MethodInfo("request_help", PropertyInfo(Variant::STRING, "topic"))); ADD_SIGNAL(MethodInfo("request_open_script_at_line", PropertyInfo(Variant::OBJECT, "script"), PropertyInfo(Variant::INT, "line"))); ADD_SIGNAL(MethodInfo("request_save_history")); ADD_SIGNAL(MethodInfo("go_to_help", PropertyInfo(Variant::STRING, "what"))); @@ -975,10 +974,6 @@ void ScriptEditor::_menu_option(int p_option) { help_search_dialog->popup_dialog(); } break; - case SEARCH_CLASSES: { - - help_index->popup_dialog(); - } break; case SEARCH_WEBSITE: { OS::get_singleton()->shell_open("https://docs.godotengine.org/"); @@ -1206,12 +1201,6 @@ void ScriptEditor::_menu_option(int p_option) { if (help) { switch (p_option) { - - case SEARCH_CLASSES: { - - help_index->popup_dialog(); - help_index->call_deferred("select_class", help->get_class()); - } break; case HELP_SEARCH_FIND: { help->popup_search(); } break; @@ -1318,7 +1307,6 @@ void ScriptEditor::_notification(int p_what) { EditorSettings::get_singleton()->connect("settings_changed", this, "_editor_settings_changed"); help_search->set_icon(get_icon("HelpSearch", "EditorIcons")); site_search->set_icon(get_icon("Instance", "EditorIcons")); - class_search->set_icon(get_icon("ClassList", "EditorIcons")); script_forward->set_icon(get_icon("Forward", "EditorIcons")); script_back->set_icon(get_icon("Back", "EditorIcons")); @@ -1330,7 +1318,6 @@ void ScriptEditor::_notification(int p_what) { get_tree()->connect("tree_changed", this, "_tree_changed"); editor->get_inspector_dock()->connect("request_help", this, "_request_help"); editor->connect("request_help_search", this, "_help_search"); - editor->connect("request_help_index", this, "_help_index"); } break; case NOTIFICATION_EXIT_TREE: { @@ -1350,7 +1337,6 @@ void ScriptEditor::_notification(int p_what) { help_search->set_icon(get_icon("HelpSearch", "EditorIcons")); site_search->set_icon(get_icon("Instance", "EditorIcons")); - class_search->set_icon(get_icon("ClassList", "EditorIcons")); script_forward->set_icon(get_icon("Forward", "EditorIcons")); script_back->set_icon(get_icon("Back", "EditorIcons")); @@ -2006,7 +1992,7 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra _save_layout(); se->connect("name_changed", this, "_update_script_names"); se->connect("edited_script_changed", this, "_script_changed"); - se->connect("request_help_search", this, "_help_search"); + se->connect("request_help", this, "_help_search"); se->connect("request_open_script_at_line", this, "_goto_script_line"); se->connect("go_to_help", this, "_help_class_goto"); se->connect("request_save_history", this, "_save_history"); @@ -2733,10 +2719,6 @@ void ScriptEditor::set_live_auto_reload_running_scripts(bool p_enabled) { auto_reload_running_scripts = p_enabled; } -void ScriptEditor::_help_index(String p_text) { - help_index->popup_dialog(); -} - void ScriptEditor::_help_search(String p_text) { help_search_dialog->popup_dialog(p_text); } @@ -2842,7 +2824,6 @@ void ScriptEditor::_bind_methods() { ClassDB::bind_method("_goto_script_line", &ScriptEditor::_goto_script_line); ClassDB::bind_method("_goto_script_line2", &ScriptEditor::_goto_script_line2); ClassDB::bind_method("_help_search", &ScriptEditor::_help_search); - ClassDB::bind_method("_help_index", &ScriptEditor::_help_index); ClassDB::bind_method("_save_history", &ScriptEditor::_save_history); ClassDB::bind_method("_copy_script_path", &ScriptEditor::_copy_script_path); @@ -3077,12 +3058,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { menu_hb->add_child(site_search); site_search->set_tooltip(TTR("Open Godot online documentation")); - class_search = memnew(ToolButton); - class_search->set_text(TTR("Classes")); - class_search->connect("pressed", this, "_menu_option", varray(SEARCH_CLASSES)); - menu_hb->add_child(class_search); - class_search->set_tooltip(TTR("Search the class hierarchy.")); - help_search = memnew(ToolButton); help_search->set_text(TTR("Search Help")); help_search->connect("pressed", this, "_menu_option", varray(SEARCH_HELP)); @@ -3168,10 +3143,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { add_child(help_search_dialog); help_search_dialog->connect("go_to_help", this, "_help_class_goto"); - help_index = memnew(EditorHelpIndex); - add_child(help_index); - help_index->connect("open_class", this, "_help_class_open"); - find_in_files_dialog = memnew(FindInFilesDialog); find_in_files_dialog->connect(FindInFilesDialog::SIGNAL_FIND_REQUESTED, this, "_start_find_in_files", varray(false)); find_in_files_dialog->connect(FindInFilesDialog::SIGNAL_REPLACE_REQUESTED, this, "_start_find_in_files", varray(true)); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index 28c07393f7..4be5345aaa 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -34,6 +34,7 @@ #include "core/script_language.h" #include "editor/code_editor.h" #include "editor/editor_help.h" +#include "editor/editor_help_search.h" #include "editor/editor_plugin.h" #include "editor/script_create_dialog.h" #include "scene/gui/item_list.h" @@ -155,7 +156,6 @@ class ScriptEditor : public PanelContainer { DEBUG_SHOW_KEEP_OPEN, DEBUG_WITH_EXTERNAL_EDITOR, SEARCH_HELP, - SEARCH_CLASSES, SEARCH_WEBSITE, HELP_SEARCH_FIND, HELP_SEARCH_FIND_NEXT, @@ -200,7 +200,6 @@ class ScriptEditor : public PanelContainer { Button *help_search; Button *site_search; - Button *class_search; EditorHelpSearch *help_search_dialog; ItemList *script_list; @@ -254,7 +253,7 @@ class ScriptEditor : public PanelContainer { Vector<ScriptHistory> history; int history_pos; - EditorHelpIndex *help_index; + Vector<String> previous_scripts; void _tab_changed(int p_which); void _menu_option(int p_option); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index c3e2aa86f0..cbd5d629d3 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1049,7 +1049,7 @@ void ScriptTextEditor::_edit_option(int p_op) { if (text == "") text = tx->get_word_under_cursor(); if (text != "") { - emit_signal("request_help_search", text); + emit_signal("request_help", text); } } break; case LOOKUP_SYMBOL: { diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index c083e727d1..f441364c44 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1419,7 +1419,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 while (c) { - if (cache.draw_relationship_lines == 1 && (c->get_parent() != root || !hide_root)) { + if (cache.draw_relationship_lines == 1 && (!hide_root || c->parent != root)) { int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); int parent_ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - cache.offset + p_draw_ofs; |