From 0542bccee0a4804bc79fda4515e30161ab227d48 Mon Sep 17 00:00:00 2001 From: vPumpking Date: Wed, 9 Oct 2024 15:57:30 +0200 Subject: [PATCH] Improve space management for EditorFileDialog Move buttons related to the file view on the container above so that they take less horizontal space and make search bar similar to the one in FileDialog --- doc/classes/EditorFileDialog.xml | 25 +++++ editor/gui/editor_file_dialog.cpp | 166 +++++++++++++++++++++++------- editor/gui/editor_file_dialog.h | 10 ++ editor/icons/FilenameFilter.svg | 1 + 4 files changed, 163 insertions(+), 39 deletions(-) create mode 100644 editor/icons/FilenameFilter.svg diff --git a/doc/classes/EditorFileDialog.xml b/doc/classes/EditorFileDialog.xml index d5c2ed55d7..1ac79d0e0e 100644 --- a/doc/classes/EditorFileDialog.xml +++ b/doc/classes/EditorFileDialog.xml @@ -37,12 +37,24 @@ Adds the given [param menu] to the side of the file dialog with the given [param title] text on top. Only one side menu is allowed. + + + + Clear the filter for file names. + + Removes all filters except for "All Files (*)". + + + + Returns the value of the filter for file names. + + @@ -96,6 +108,13 @@ Shows the [EditorFileDialog] at the default size and position for file dialogs in the editor, and selects the file name if there is a current file. + + + + + Sets the value of the filter for file names. + + @@ -168,6 +187,12 @@ Emitted when a file is selected. + + + + Emitted when the filter for file names changes. + + diff --git a/editor/gui/editor_file_dialog.cpp b/editor/gui/editor_file_dialog.cpp index ceff62723f..4d8653c60c 100644 --- a/editor/gui/editor_file_dialog.cpp +++ b/editor/gui/editor_file_dialog.cpp @@ -175,6 +175,7 @@ void EditorFileDialog::_update_theme_item_cache() { theme_cache.back_folder = get_editor_theme_icon(SNAME("Back")); theme_cache.reload = get_editor_theme_icon(SNAME("Reload")); theme_cache.toggle_hidden = get_editor_theme_icon(SNAME("GuiVisibilityVisible")); + theme_cache.toggle_filename_filter = get_editor_theme_icon(SNAME("FilenameFilter")); theme_cache.favorite = get_editor_theme_icon(SNAME("Favorites")); theme_cache.mode_thumbnails = get_editor_theme_icon(SNAME("FileThumbnail")); theme_cache.mode_list = get_editor_theme_icon(SNAME("FileList")); @@ -329,6 +330,7 @@ void EditorFileDialog::shortcut_input(const Ref &p_event) { handled = true; } if (ED_IS_SHORTCUT("file_dialog/focus_filter", p_event)) { + show_search_filter_button->set_pressed(!show_search_filter_button->is_pressed()); _focus_filter_box(); handled = true; } @@ -1146,6 +1148,15 @@ void EditorFileDialog::_filter_selected(int) { update_file_list(); } +void EditorFileDialog::_search_filter_selected() { + Vector items = item_list->get_selected_items(); + if (!items.is_empty()) { + int index = items[0]; + file->set_text(item_list->get_item_text(index)); + file->emit_signal(SceneStringName(text_submitted), file->get_text()); + } +} + void EditorFileDialog::update_filters() { filter->clear(); @@ -1187,6 +1198,23 @@ void EditorFileDialog::clear_filters() { invalidate(); } +void EditorFileDialog::clear_search_filter() { + set_search_filter(""); + update_search_filter_gui(); + invalidate(); +} + +void EditorFileDialog::update_search_filter_gui() { + filter_hb->set_visible(show_search_filter); + if (!show_search_filter) { + search_string.clear(); + } + if (filter_box->get_text() == search_string) { + return; + } + filter_box->set_text(search_string); +} + void EditorFileDialog::add_filter(const String &p_filter, const String &p_description) { if (p_description.is_empty()) { filters.push_back(p_filter); @@ -1206,10 +1234,24 @@ void EditorFileDialog::set_filters(const Vector &p_filters) { invalidate(); } +void EditorFileDialog::set_search_filter(const String &p_search_filter) { + if (search_string == p_search_filter) { + return; + } + search_string = p_search_filter; + update_search_filter_gui(); + emit_signal(SNAME("filename_filter_changed"), filter); + invalidate(); +} + Vector EditorFileDialog::get_filters() const { return filters; } +String EditorFileDialog::get_search_filter() const { + return search_string; +} + String EditorFileDialog::get_current_dir() const { return dir_access->get_current_dir(); } @@ -1399,6 +1441,11 @@ void EditorFileDialog::_focus_filter_box() { void EditorFileDialog::_filter_changed(const String &p_text) { search_string = p_text; invalidate(); + + item_list->deselect_all(); + if (item_list->get_item_count() > 0) { + item_list->call_deferred("select", 0); + } } void EditorFileDialog::_file_sort_popup(int p_id) { @@ -1502,6 +1549,7 @@ void EditorFileDialog::_update_icons() { filter_box->set_right_icon(theme_cache.filter_box); file_sort_button->set_button_icon(theme_cache.file_sort_button); + show_search_filter_button->set_button_icon(theme_cache.toggle_filename_filter); filter_box->set_clear_button_enabled(true); fav_up->set_button_icon(theme_cache.favorites_up); @@ -1981,6 +2029,9 @@ void EditorFileDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("get_option_count"), &EditorFileDialog::get_option_count); ClassDB::bind_method(D_METHOD("add_option", "name", "values", "default_value_index"), &EditorFileDialog::add_option); ClassDB::bind_method(D_METHOD("get_selected_options"), &EditorFileDialog::get_selected_options); + ClassDB::bind_method(D_METHOD("clear_filename_filter"), &EditorFileDialog::clear_search_filter); + ClassDB::bind_method(D_METHOD("set_filename_filter", "filter"), &EditorFileDialog::set_search_filter); + ClassDB::bind_method(D_METHOD("get_filename_filter"), &EditorFileDialog::get_search_filter); ClassDB::bind_method(D_METHOD("get_current_dir"), &EditorFileDialog::get_current_dir); ClassDB::bind_method(D_METHOD("get_current_file"), &EditorFileDialog::get_current_file); ClassDB::bind_method(D_METHOD("get_current_path"), &EditorFileDialog::get_current_path); @@ -2009,6 +2060,7 @@ void EditorFileDialog::_bind_methods() { ADD_SIGNAL(MethodInfo("file_selected", PropertyInfo(Variant::STRING, "path"))); ADD_SIGNAL(MethodInfo("files_selected", PropertyInfo(Variant::PACKED_STRING_ARRAY, "paths"))); ADD_SIGNAL(MethodInfo("dir_selected", PropertyInfo(Variant::STRING, "dir"))); + ADD_SIGNAL(MethodInfo("filename_filter_changed", PropertyInfo(Variant::STRING, "filter"))); ADD_PROPERTY(PropertyInfo(Variant::INT, "access", PROPERTY_HINT_ENUM, "Resources,User data,File system"), "set_access", "get_access"); ADD_PROPERTY(PropertyInfo(Variant::INT, "display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List"), "set_display_mode", "get_display_mode"); @@ -2055,6 +2107,24 @@ void EditorFileDialog::set_show_hidden_files(bool p_show) { invalidate(); } +void EditorFileDialog::set_show_search_filter(bool p_show) { + if (p_show == show_search_filter) { + return; + } + if (p_show) { + filter_box->grab_focus(); + } else { + search_string.clear(); + filter_box->clear(); + if (filter_box->has_focus()) { + item_list->call_deferred("grab_focus"); + } + } + show_search_filter = p_show; + update_search_filter_gui(); + invalidate(); +} + bool EditorFileDialog::is_showing_hidden_files() const { return show_hidden_files; } @@ -2198,7 +2268,6 @@ EditorFileDialog::EditorFileDialog() { dir = memnew(LineEdit); dir->set_structured_text_bidi_override(TextServer::STRUCTURED_TEXT_FILE); pathhb->add_child(dir); - dir->set_h_size_flags(Control::SIZE_EXPAND_FILL); refresh = memnew(Button); refresh->set_theme_type_variation("FlatButton"); @@ -2213,37 +2282,6 @@ EditorFileDialog::EditorFileDialog() { favorite->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::_favorite_pressed)); pathhb->add_child(favorite); - show_hidden = memnew(Button); - show_hidden->set_theme_type_variation("FlatButton"); - show_hidden->set_toggle_mode(true); - show_hidden->set_pressed(is_showing_hidden_files()); - show_hidden->set_tooltip_text(TTR("Toggle the visibility of hidden files.")); - show_hidden->connect(SceneStringName(toggled), callable_mp(this, &EditorFileDialog::set_show_hidden_files)); - pathhb->add_child(show_hidden); - - pathhb->add_child(memnew(VSeparator)); - - Ref view_mode_group; - view_mode_group.instantiate(); - - mode_thumbnails = memnew(Button); - mode_thumbnails->set_theme_type_variation("FlatButton"); - mode_thumbnails->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::set_display_mode).bind(DISPLAY_THUMBNAILS)); - mode_thumbnails->set_toggle_mode(true); - mode_thumbnails->set_pressed(display_mode == DISPLAY_THUMBNAILS); - mode_thumbnails->set_button_group(view_mode_group); - mode_thumbnails->set_tooltip_text(TTR("View items as a grid of thumbnails.")); - pathhb->add_child(mode_thumbnails); - - mode_list = memnew(Button); - mode_list->set_theme_type_variation("FlatButton"); - mode_list->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::set_display_mode).bind(DISPLAY_LIST)); - mode_list->set_toggle_mode(true); - mode_list->set_pressed(display_mode == DISPLAY_LIST); - mode_list->set_button_group(view_mode_group); - mode_list->set_tooltip_text(TTR("View items as a list.")); - pathhb->add_child(mode_list); - shortcuts_container = memnew(HBoxContainer); pathhb->add_child(shortcuts_container); @@ -2259,6 +2297,8 @@ EditorFileDialog::EditorFileDialog() { makedir->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::_make_dir)); pathhb->add_child(makedir); + dir->set_h_size_flags(Control::SIZE_EXPAND_FILL); + body_hsplit = memnew(HSplitContainer); body_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL); vbc->add_child(body_hsplit); @@ -2328,21 +2368,55 @@ EditorFileDialog::EditorFileDialog() { l = memnew(Label(TTR("Directories & Files:"))); l->set_theme_type_variation("HeaderSmall"); + l->set_h_size_flags(Control::SIZE_EXPAND_FILL); + lower_hb->add_child(l); - list_vb->add_child(lower_hb); - preview_hb->add_child(list_vb); + show_hidden = memnew(Button); + show_hidden->set_theme_type_variation("FlatButton"); + show_hidden->set_toggle_mode(true); + show_hidden->set_pressed(is_showing_hidden_files()); + show_hidden->set_tooltip_text(TTR("Toggle the visibility of hidden files.")); + show_hidden->connect(SceneStringName(toggled), callable_mp(this, &EditorFileDialog::set_show_hidden_files)); + lower_hb->add_child(show_hidden); - filter_box = memnew(LineEdit); - filter_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); - filter_box->set_placeholder(TTR("Filter")); - filter_box->connect(SceneStringName(text_changed), callable_mp(this, &EditorFileDialog::_filter_changed)); - lower_hb->add_child(filter_box); + lower_hb->add_child(memnew(VSeparator)); + + Ref view_mode_group; + view_mode_group.instantiate(); + + mode_thumbnails = memnew(Button); + mode_thumbnails->set_theme_type_variation("FlatButton"); + mode_thumbnails->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::set_display_mode).bind(DISPLAY_THUMBNAILS)); + mode_thumbnails->set_toggle_mode(true); + mode_thumbnails->set_pressed(display_mode == DISPLAY_THUMBNAILS); + mode_thumbnails->set_button_group(view_mode_group); + mode_thumbnails->set_tooltip_text(TTR("View items as a grid of thumbnails.")); + lower_hb->add_child(mode_thumbnails); + + mode_list = memnew(Button); + mode_list->set_theme_type_variation("FlatButton"); + mode_list->connect(SceneStringName(pressed), callable_mp(this, &EditorFileDialog::set_display_mode).bind(DISPLAY_LIST)); + mode_list->set_toggle_mode(true); + mode_list->set_pressed(display_mode == DISPLAY_LIST); + mode_list->set_button_group(view_mode_group); + mode_list->set_tooltip_text(TTR("View items as a list.")); + lower_hb->add_child(mode_list); + + lower_hb->add_child(memnew(VSeparator)); file_sort_button = memnew(MenuButton); file_sort_button->set_flat(true); file_sort_button->set_tooltip_text(TTR("Sort files")); + show_search_filter_button = memnew(Button); + show_search_filter_button->set_theme_type_variation("FlatButton"); + show_search_filter_button->set_toggle_mode(true); + show_search_filter_button->set_pressed(false); + show_search_filter_button->set_tooltip_text(TTR("Toggle the visibility of the filter for file names.")); + show_search_filter_button->connect(SceneStringName(toggled), callable_mp(this, &EditorFileDialog::set_show_search_filter)); + lower_hb->add_child(show_search_filter_button); + PopupMenu *p = file_sort_button->get_popup(); p->connect(SceneStringName(id_pressed), callable_mp(this, &EditorFileDialog::_file_sort_popup)); p->add_radio_check_item(TTR("Sort by Name (Ascending)"), static_cast(FileSortOption::FILE_SORT_NAME)); @@ -2354,6 +2428,9 @@ EditorFileDialog::EditorFileDialog() { p->set_item_checked(0, true); lower_hb->add_child(file_sort_button); + list_vb->add_child(lower_hb); + preview_hb->add_child(list_vb); + // Item (files and folders) list with context menu. item_list = memnew(ItemList); @@ -2379,6 +2456,15 @@ EditorFileDialog::EditorFileDialog() { prev_cc->add_child(preview); preview_vb->hide(); + filter_hb = memnew(HBoxContainer); + filter_hb->add_child(memnew(Label(RTR("Filter:")))); + filter_box = memnew(LineEdit); + filter_box->set_h_size_flags(Control::SIZE_EXPAND_FILL); + filter_box->set_placeholder(TTR("Filter")); + filter_hb->add_child(filter_box); + filter_hb->set_visible(false); + item_vb->add_child(filter_hb); + file_box = memnew(HBoxContainer); l = memnew(Label(TTR("File:"))); @@ -2407,6 +2493,8 @@ EditorFileDialog::EditorFileDialog() { item_list->connect("item_activated", callable_mp(this, &EditorFileDialog::_item_dc_selected).bind()); item_list->connect("empty_clicked", callable_mp(this, &EditorFileDialog::_items_clear_selection)); dir->connect("text_submitted", callable_mp(this, &EditorFileDialog::_dir_submitted)); + filter_box->connect(SceneStringName(text_changed), callable_mp(this, &EditorFileDialog::_filter_changed)); + filter_box->connect(SceneStringName(text_submitted), callable_mp(this, &EditorFileDialog::_search_filter_selected).unbind(1)); file->connect("text_submitted", callable_mp(this, &EditorFileDialog::_file_submitted)); filter->connect(SceneStringName(item_selected), callable_mp(this, &EditorFileDialog::_filter_selected)); diff --git a/editor/gui/editor_file_dialog.h b/editor/gui/editor_file_dialog.h index 1922155133..a803267660 100644 --- a/editor/gui/editor_file_dialog.h +++ b/editor/gui/editor_file_dialog.h @@ -128,8 +128,11 @@ private: Button *refresh = nullptr; Button *favorite = nullptr; Button *show_hidden = nullptr; + Button *show_search_filter_button = nullptr; String search_string; + bool show_search_filter = false; + HBoxContainer *filter_hb = nullptr; LineEdit *filter_box = nullptr; FileSortOption file_sort = FileSortOption::FILE_SORT_NAME; MenuButton *file_sort_button = nullptr; @@ -165,6 +168,7 @@ private: Ref back_folder; Ref reload; Ref toggle_hidden; + Ref toggle_filename_filter; Ref favorite; Ref mode_thumbnails; Ref mode_list; @@ -206,6 +210,7 @@ private: void update_dir(); void update_file_name(); void update_file_list(); + void update_search_filter_gui(); void update_filters(); void _focus_file_text(); @@ -239,6 +244,7 @@ private: void _focus_filter_box(); void _filter_changed(const String &p_text); + void _search_filter_selected(); void _file_sort_popup(int p_id); void _delete_items(); @@ -301,6 +307,9 @@ public: void add_filter(const String &p_filter, const String &p_description = ""); void set_filters(const Vector &p_filters); Vector get_filters() const; + void clear_search_filter(); + void set_search_filter(const String &p_search_filter); + String get_search_filter() const; void set_enable_multiple_selection(bool p_enable); Vector get_selected_files() const; @@ -341,6 +350,7 @@ public: static void set_default_show_hidden_files(bool p_show); static void set_default_display_mode(DisplayMode p_mode); void set_show_hidden_files(bool p_show); + void set_show_search_filter(bool p_show); bool is_showing_hidden_files() const; void invalidate(); diff --git a/editor/icons/FilenameFilter.svg b/editor/icons/FilenameFilter.svg new file mode 100644 index 0000000000..351cc44ced --- /dev/null +++ b/editor/icons/FilenameFilter.svg @@ -0,0 +1 @@ + \ No newline at end of file