From ad351a29db8328c82838a8aaf070eb111116d632 Mon Sep 17 00:00:00 2001 From: Dmitry Koteroff Date: Mon, 27 Nov 2017 18:58:28 +0300 Subject: [PATCH] Some improvements to file/dir open/save dialogs: 1. Removed "..", instead you now will see "Select Current Folder" and "Select this Folder" buttons. 2. Added "go to parent folder" (^) button to Save a File dialog. 3. Tree.cpp: "nothing_selected" signal has been re-made (previous implementation, merged in #13308, wasn't optimal in context of performance) 4. Fixed issue in Project Export dialog: MODE_SAVE_FILE wasn't set when you click "Export". 5. Now you can deselect items by clicking on empty space in Open a Directory dialog. --- editor/editor_file_dialog.cpp | 7 +---- editor/project_export.cpp | 1 + scene/gui/file_dialog.cpp | 57 +++++++++++++++++++++++++++++++---- scene/gui/file_dialog.h | 5 +++ scene/gui/tree.cpp | 27 +++++++++++++++-- scene/gui/tree.h | 2 ++ 6 files changed, 84 insertions(+), 15 deletions(-) diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index c78b11737eb..eb5af2eaeb1 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -586,7 +586,7 @@ void EditorFileDialog::update_file_list() { while ((item = dir_access->get_next(&isdir)) != "") { - if (item == ".") + if (item == "." || item == "..") continue; ishidden = dir_access->current_is_hidden(); @@ -599,11 +599,6 @@ void EditorFileDialog::update_file_list() { } } - if (dirs.find("..") == NULL) { - //may happen if lacking permissions - dirs.push_back(".."); - } - dirs.sort_custom(); files.sort_custom(); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 6500b10a3ad..767dbcc27b2 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -723,6 +723,7 @@ void ProjectExportDialog::_export_project() { export_project->add_filter("*." + extension + " ; " + platform->get_name() + " Export"); } + export_project->set_mode(FileDialog::MODE_SAVE_FILE); export_project->popup_centered_ratio(); } diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 663a2b390e2..9bfb70bf428 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -47,6 +47,7 @@ void FileDialog::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { refresh->set_icon(get_icon("reload")); + dir_up->set_icon(get_icon("ArrowUp", "EditorIcons")); } if (p_what == NOTIFICATION_DRAW) { @@ -122,6 +123,9 @@ void FileDialog::update_dir() { if (drives->is_visible()) { drives->select(dir_access->get_current_drive()); } + + // Deselect any item, to make "Select Current Folder" button text by default. + deselect_items(); } void FileDialog::_dir_entered(String p_dir) { @@ -156,6 +160,10 @@ void FileDialog::_post_popup() { tree->grab_focus(); set_process_unhandled_input(true); + + // For open dir mode, deselect all items on file dialog open. + if (mode == MODE_OPEN_DIR) + deselect_items(); } void FileDialog::_action_pressed() { @@ -296,6 +304,37 @@ bool FileDialog::_is_open_should_be_disabled() { return false; } +void FileDialog::_go_up() { + + dir_access->change_dir(".."); + update_file_list(); + update_dir(); +} + +void FileDialog::deselect_items() { + + // Clear currently selected items in file manager. + tree->deselect_all(); + + // And change get_ok title. + if (!tree->is_anything_selected()) { + get_ok()->set_disabled(_is_open_should_be_disabled()); + + switch (mode) { + + case MODE_OPEN_FILE: + case MODE_OPEN_FILES: + get_ok()->set_text(TTR("Open")); + get_ok()->set_disabled(false); + break; + + case MODE_OPEN_DIR: + get_ok()->set_text(TTR("Select Current Folder")); + get_ok()->set_disabled(false); + break; + } + } +} void FileDialog::_tree_selected() { TreeItem *ti = tree->get_selected(); @@ -306,6 +345,8 @@ void FileDialog::_tree_selected() { if (!d["dir"]) { file->set_text(d["name"]); + } else if (mode == MODE_OPEN_DIR) { + get_ok()->set_text(TTR("Select this Folder")); } get_ok()->set_disabled(_is_open_should_be_disabled()); @@ -349,7 +390,7 @@ void FileDialog::update_file_list() { while ((item = dir_access->get_next(&isdir)) != "") { - if (item == ".") + if (item == "." || item == "..") continue; ishidden = dir_access->current_is_hidden(); @@ -362,11 +403,6 @@ void FileDialog::update_file_list() { } } - if (dirs.find("..") == NULL) { - //may happen if lacking permissions - dirs.push_back(".."); - } - dirs.sort_custom(); files.sort_custom(); @@ -742,6 +778,8 @@ void FileDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileDialog::_make_dir_confirm); ClassDB::bind_method(D_METHOD("_update_file_list"), &FileDialog::update_file_list); ClassDB::bind_method(D_METHOD("_update_dir"), &FileDialog::update_dir); + ClassDB::bind_method(D_METHOD("_go_up"), &FileDialog::_go_up); + ClassDB::bind_method(D_METHOD("deselect_items"), &FileDialog::deselect_items); ClassDB::bind_method(D_METHOD("invalidate"), &FileDialog::invalidate); @@ -789,6 +827,12 @@ FileDialog::FileDialog() { set_title(RTR("Save a File")); HBoxContainer *hbc = memnew(HBoxContainer); + + dir_up = memnew(ToolButton); + dir_up->set_tooltip(TTR("Go to parent folder")); + hbc->add_child(dir_up); + dir_up->connect("pressed", this, "_go_up"); + hbc->add_child(memnew(Label(RTR("Path:")))); dir = memnew(LineEdit); hbc->add_child(dir); @@ -833,6 +877,7 @@ FileDialog::FileDialog() { //cancel->connect("pressed", this,"_cancel_pressed"); tree->connect("cell_selected", this, "_tree_selected", varray(), CONNECT_DEFERRED); tree->connect("item_activated", this, "_tree_db_selected", varray()); + tree->connect("nothing_selected", this, "deselect_items"); dir->connect("text_entered", this, "_dir_entered"); file->connect("text_entered", this, "_file_entered"); filter->connect("item_selected", this, "_filter_selected"); diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 6281e887313..ca3d9f54b2f 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -86,6 +86,8 @@ private: DirAccess *dir_access; ConfirmationDialog *confirm_save; + ToolButton *dir_up; + ToolButton *refresh; Vector filters; @@ -111,6 +113,7 @@ private: void _filter_selected(int); void _make_dir(); void _make_dir_confirm(); + void _go_up(); void _update_drives(); @@ -156,6 +159,8 @@ public: void invalidate(); + void deselect_items(); + FileDialog(); ~FileDialog(); }; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 57c67378483..ab12d123baa 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1923,9 +1923,6 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool c = c->next; item_h += child_h; } - - if (!c && !p_mod->get_shift() && !p_mod->get_control() && !p_mod->get_command() && !click_handled && p_button != BUTTON_RIGHT) - emit_signal("nothing_selected"); } } @@ -2602,6 +2599,11 @@ void Tree::_gui_input(Ref p_event) { if (drag_touching) { set_physics_process(true); } + + if (b->get_button_index() == BUTTON_LEFT) { + if (get_item_at_position(b->get_position()) == NULL && !b->get_shift() && !b->get_control() && !b->get_command()) + emit_signal("nothing_selected"); + } } } break; @@ -3046,6 +3048,25 @@ void Tree::set_select_mode(SelectMode p_mode) { select_mode = p_mode; } +void Tree::deselect_all() { + + TreeItem *item = get_next_selected(get_root()); + while (item) { + item->deselect(selected_col); + item = get_next_selected(get_root()); + } + + selected_item = NULL; + selected_col = -1; + + update(); +} + +bool Tree::is_anything_selected() { + + return (selected_item != NULL); +} + void Tree::clear() { if (blocked > 0) { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 64d60169429..112de3165f8 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -546,6 +546,8 @@ public: int get_selected_column() const; int get_pressed_button() const; void set_select_mode(SelectMode p_mode); + void deselect_all(); + bool is_anything_selected(); void set_columns(int p_columns); int get_columns() const;