diff options
Diffstat (limited to 'editor/create_dialog.cpp')
-rw-r--r-- | editor/create_dialog.cpp | 167 |
1 files changed, 112 insertions, 55 deletions
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 205bdc63b9..d5f0dc01ee 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -38,7 +38,7 @@ #include "editor_settings.h" #include "scene/gui/box_container.h" -void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) { +void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const String &p_select_type) { type_list.clear(); ClassDB::get_class_list(&type_list); @@ -93,14 +93,7 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) { if (saved_size != Rect2()) { popup(saved_size); } else { - - Size2 popup_size = Size2(900, 700) * editor_get_scale(); - Size2 window_size = get_viewport_rect().size; - - popup_size.x = MIN(window_size.x * 0.8, popup_size.x); - popup_size.y = MIN(window_size.y * 0.8, popup_size.y); - - popup_centered(popup_size); + popup_centered_clamped(Size2(900, 700) * EDSCALE, 0.8); } if (p_dont_clear) { @@ -113,21 +106,10 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) { _update_search(); - 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) { - search_options->add_constant_override("draw_relationship_lines", 1); - search_options->add_color_override("relationship_line_color", rl_color); - search_options->add_constant_override("draw_guides", 0); - } else { - search_options->add_constant_override("draw_relationship_lines", 0); - search_options->add_constant_override("draw_guides", 1); - } - is_replace_mode = p_replace_mode; if (p_replace_mode) { + select_type(p_select_type); set_title(vformat(TTR("Change %s Type"), base_type)); get_ok()->set_text(TTR("Change")); } else { @@ -208,25 +190,44 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p if (!can_instance) { item->set_custom_color(0, get_color("disabled_font_color", "Editor")); item->set_selectable(0, false); - } else { - bool is_search_subsequence = search_box->get_text().is_subsequence_ofi(p_type); - String to_select_type = *to_select ? (*to_select)->get_text(0) : ""; - to_select_type = to_select_type.split(" ")[0]; - bool current_item_is_preferred; - if (cpp_type) { - String cpp_to_select_type = to_select_type; - if (ScriptServer::is_global_class(to_select_type)) - cpp_to_select_type = ScriptServer::get_global_class_base(to_select_type); - current_item_is_preferred = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(cpp_to_select_type, preferred_search_result_type); - } else { - current_item_is_preferred = ed.script_class_is_parent(p_type, preferred_search_result_type) && !ed.script_class_is_parent(to_select_type, preferred_search_result_type) && search_box->get_text() != to_select_type; - } - if (*to_select && p_type.length() < (*to_select)->get_text(0).length()) { - current_item_is_preferred = true; - } + } else if (!(*to_select && (*to_select)->get_text(0) == search_box->get_text())) { + String search_term = search_box->get_text().to_lower(); - if (((!*to_select || current_item_is_preferred) && is_search_subsequence) || search_box->get_text() == p_type) { + // if the node name matches exactly as the search, the node should be selected. + // this also fixes when the user clicks on recent nodes. + if (p_type.to_lower() == search_term) { *to_select = item; + } else { + bool current_type_prefered = _is_type_prefered(p_type); + bool selected_type_prefered = *to_select ? _is_type_prefered((*to_select)->get_text(0).split(" ")[0]) : false; + + bool is_subsequence_of_type = search_box->get_text().is_subsequence_ofi(p_type); + bool is_substring_of_type = p_type.to_lower().find(search_term) >= 0; + bool is_substring_of_selected = false; + bool is_subsequence_of_selected = false; + bool is_selected_equal = false; + + if (*to_select) { + String name = (*to_select)->get_text(0).split(" ")[0].to_lower(); + is_substring_of_selected = name.find(search_term) >= 0; + is_subsequence_of_selected = search_term.is_subsequence_of(name); + is_selected_equal = name == search_term; + } + + if (is_subsequence_of_type && !is_selected_equal) { + if (is_substring_of_type) { + if (!is_substring_of_selected || (current_type_prefered && !selected_type_prefered)) { + *to_select = item; + } + } else { + // substring results weigh more than subsequences, so let's make sure we don't override them + if (!is_substring_of_selected) { + if (!is_subsequence_of_selected || (current_type_prefered && !selected_type_prefered)) { + *to_select = item; + } + } + } + } } } @@ -250,18 +251,65 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p p_types[p_type] = item; } -void CreateDialog::_update_search() { +bool CreateDialog::_is_type_prefered(const String &type) { + bool cpp_type = ClassDB::class_exists(type); + EditorData &ed = EditorNode::get_editor_data(); + if (cpp_type) { + return ClassDB::is_parent_class(type, preferred_search_result_type); + } + return ed.script_class_is_parent(type, preferred_search_result_type); +} + +bool CreateDialog::_is_class_disabled_by_feature_profile(const StringName &p_class) { + + Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile(); + if (profile.is_null()) { + return false; + } + + StringName class_name = p_class; + + while (class_name != StringName()) { + + if (profile->is_class_disabled(class_name)) { + return true; + } + class_name = ClassDB::get_parent_class_nocheck(class_name); + } + + return false; +} + +void CreateDialog::select_type(const String &p_type) { + + TreeItem *to_select; + if (search_options_types.has(p_type)) { + to_select = search_options_types[p_type]; + } else { + to_select = search_options->get_root(); + } + + // uncollapse from selected type to top level + // TODO: should this be in tree? + TreeItem *cur = to_select; + while (cur) { + cur->set_collapsed(false); + cur = cur->get_parent(); + } + + to_select->select(0); + + search_options->scroll_to_item(to_select); +} + +void CreateDialog::_update_search() { search_options->clear(); favorite->set_disabled(true); help_bit->set_text(""); - /* - TreeItem *root = search_options->create_item(); - _parse_fs(EditorFileSystem::get_singleton()->get_filesystem()); -*/ - HashMap<String, TreeItem *> types; + search_options_types.clear(); TreeItem *root = search_options->create_item(); EditorData &ed = EditorNode::get_editor_data(); @@ -276,6 +324,10 @@ void CreateDialog::_update_search() { for (List<StringName>::Element *I = type_list.front(); I; I = I->next()) { String type = I->get(); + + if (_is_class_disabled_by_feature_profile(type)) { + continue; + } bool cpp_type = ClassDB::class_exists(type); if (base_type == "Node" && type.begins_with("Editor")) @@ -284,8 +336,9 @@ void CreateDialog::_update_search() { if (cpp_type && !ClassDB::can_instance(type)) continue; // can't create what can't be instanced - bool skip = false; if (cpp_type) { + bool skip = false; + for (Set<StringName>::Element *E = type_blacklist.front(); E && !skip; E = E->next()) { if (ClassDB::is_parent_class(type, E->get())) skip = true; @@ -295,23 +348,23 @@ void CreateDialog::_update_search() { } if (search_box->get_text() == "") { - add_type(type, types, root, &to_select); + add_type(type, search_options_types, root, &to_select); } else { bool found = false; - String type = I->get(); - while (type != "" && (cpp_type ? ClassDB::is_parent_class(type, base_type) : ed.script_class_is_parent(type, base_type)) && type != base_type) { - if (search_box->get_text().is_subsequence_ofi(type)) { + String type2 = I->get(); + while (type2 != "" && (cpp_type ? ClassDB::is_parent_class(type2, base_type) : ed.script_class_is_parent(type2, base_type)) && type2 != base_type) { + if (search_box->get_text().is_subsequence_ofi(type2)) { found = true; break; } - type = cpp_type ? ClassDB::get_parent_class(type) : ed.script_class_get_base(type); + type2 = cpp_type ? ClassDB::get_parent_class(type2) : ed.script_class_get_base(type2); } if (found) - add_type(I->get(), types, root, &to_select); + add_type(I->get(), search_options_types, root, &to_select); } if (EditorNode::get_editor_data().get_custom_types().has(type) && ClassDB::is_parent_class(type, base_type)) { @@ -325,12 +378,12 @@ void CreateDialog::_update_search() { if (!show) continue; - if (!types.has(type)) - add_type(type, types, root, &to_select); + if (!search_options_types.has(type)) + add_type(type, search_options_types, root, &to_select); TreeItem *ti; - if (types.has(type)) - ti = types[type]; + if (search_options_types.has(type)) + ti = search_options_types[type]; else ti = search_options->get_root(); @@ -706,9 +759,11 @@ CreateDialog::CreateDialog() { fav_vb->add_margin_child(TTR("Favorites:"), favorites, true); favorites->set_hide_root(true); favorites->set_hide_folding(true); + favorites->set_allow_reselect(true); favorites->connect("cell_selected", this, "_favorite_selected"); favorites->connect("item_activated", this, "_favorite_activated"); favorites->set_drag_forwarding(this); + favorites->add_constant_override("draw_guides", 1); VBoxContainer *rec_vb = memnew(VBoxContainer); vsc->add_child(rec_vb); @@ -719,8 +774,10 @@ CreateDialog::CreateDialog() { rec_vb->add_margin_child(TTR("Recent:"), recent, true); recent->set_hide_root(true); recent->set_hide_folding(true); + recent->set_allow_reselect(true); recent->connect("cell_selected", this, "_history_selected"); recent->connect("item_activated", this, "_history_activated"); + recent->add_constant_override("draw_guides", 1); VBoxContainer *vbc = memnew(VBoxContainer); hsc->add_child(vbc); |