You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-07 12:30:27 +00:00
Unify editor class and reference search
Co-authored-by: Michael Alexsander Silva Dias <michaelalexsander@protonmail.com>
This commit is contained in:
committed by
Michael Alexsander Silva Dias
parent
f2cc969843
commit
fddffa9eb8
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user