diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index f8b9425a4e2..c78b11737eb 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -197,6 +197,9 @@ Vector EditorFileDialog::get_selected_files() const { void EditorFileDialog::update_dir() { dir->set_text(dir_access->get_current_dir()); + + // Disable "Open" button only when we in selecting file(s) mode or open dir mode. + get_ok()->set_disabled(_is_open_should_be_disabled()); } void EditorFileDialog::_dir_entered(String p_dir) { @@ -452,6 +455,28 @@ void EditorFileDialog::_item_selected(int p_item) { file->set_text(d["name"]); _request_single_thumbnail(get_current_dir().plus_file(get_current_file())); } + + get_ok()->set_disabled(_is_open_should_be_disabled()); +} + +void EditorFileDialog::_items_clear_selection() { + + item_list->unselect_all(); + + // If nothing is selected, then block Open button. + switch (mode) { + + case MODE_OPEN_FILE: + case MODE_OPEN_FILES: + get_ok()->set_text(TTR("Open")); + get_ok()->set_disabled(item_list->is_anything_selected() == false); + break; + + case MODE_OPEN_DIR: + get_ok()->set_disabled(false); + get_ok()->set_text(TTR("Select Current Folder")); + break; + } } void EditorFileDialog::_push_history() { @@ -487,6 +512,26 @@ void EditorFileDialog::_item_dc_selected(int p_item) { } } +bool EditorFileDialog::_is_open_should_be_disabled() { + + if (mode == MODE_OPEN_ANY || mode == MODE_SAVE_FILE) + return false; + + Vector items = item_list->get_selected_items(); + if (items.size() == 0) + return true; + + for (int i = 0; i < items.size(); i++) { + + Dictionary d = item_list->get_item_metadata(items.get(i)); + + if (((mode == MODE_OPEN_FILE || mode == MODE_OPEN_FILES) && d["dir"]) || (mode == MODE_OPEN_DIR && !d["dir"])) + return true; + } + + return false; +} + void EditorFileDialog::update_file_list() { int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); @@ -681,6 +726,7 @@ void EditorFileDialog::update_file_list() { favorite->set_pressed(false); fav_up->set_disabled(true); fav_down->set_disabled(true); + get_ok()->set_disabled(_is_open_should_be_disabled()); for (int i = 0; i < favorites->get_item_count(); i++) { if (favorites->get_item_metadata(i) == base_dir) { favorites->select(i); @@ -1139,6 +1185,7 @@ void EditorFileDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_unhandled_input"), &EditorFileDialog::_unhandled_input); ClassDB::bind_method(D_METHOD("_item_selected"), &EditorFileDialog::_item_selected); + ClassDB::bind_method(D_METHOD("_items_clear_selection"), &EditorFileDialog::_items_clear_selection); ClassDB::bind_method(D_METHOD("_item_db_selected"), &EditorFileDialog::_item_dc_selected); ClassDB::bind_method(D_METHOD("_dir_entered"), &EditorFileDialog::_dir_entered); ClassDB::bind_method(D_METHOD("_file_entered"), &EditorFileDialog::_file_entered); @@ -1415,6 +1462,7 @@ EditorFileDialog::EditorFileDialog() { //cancel->connect("pressed", this,"_cancel_pressed"); item_list->connect("item_selected", this, "_item_selected", varray(), CONNECT_DEFERRED); item_list->connect("item_activated", this, "_item_db_selected", varray()); + item_list->connect("nothing_selected", this, "_items_clear_selection"); dir->connect("text_entered", this, "_dir_entered"); file->connect("text_entered", this, "_file_entered"); filter->connect("item_selected", this, "_filter_selected"); diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h index 4dc2947292d..0599d222f35 100644 --- a/editor/editor_file_dialog.h +++ b/editor/editor_file_dialog.h @@ -143,6 +143,7 @@ private: void _recent_selected(int p_idx); void _item_selected(int p_item); + void _items_clear_selection(); void _item_dc_selected(int p_item); void _select_drive(int p_idx); @@ -172,6 +173,8 @@ private: void _unhandled_input(const Ref &p_event); + bool _is_open_should_be_disabled(); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 6aba535572a..663a2b390e2 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -85,6 +85,10 @@ void FileDialog::_unhandled_input(const Ref &p_event) { invalidate(); } break; + case KEY_BACKSPACE: { + + _dir_entered(".."); + } break; default: { handled = false; } } @@ -189,7 +193,7 @@ void FileDialog::_action_pressed() { TreeItem *item = tree->get_selected(); if (item) { Dictionary d = item->get_metadata(0); - if (d["dir"]) { + if (d["dir"] && d["name"] != "..") { path = path.plus_file(d["name"]); } } @@ -272,6 +276,26 @@ void FileDialog::_cancel_pressed() { hide(); } +bool FileDialog::_is_open_should_be_disabled() { + + if (mode == MODE_OPEN_ANY || mode == MODE_SAVE_FILE) + return false; + + TreeItem *ti = tree->get_selected(); + // We have something that we can't select? + if (!ti) + return true; + + Dictionary d = ti->get_metadata(0); + + // Opening a file, but selected a folder? Forbidden. + if (((mode == MODE_OPEN_FILE || mode == MODE_OPEN_FILES) && d["dir"]) || // Flipped case, also forbidden. + (mode == MODE_OPEN_DIR && !d["dir"])) + return true; + + return false; +} + void FileDialog::_tree_selected() { TreeItem *ti = tree->get_selected(); @@ -283,6 +307,8 @@ void FileDialog::_tree_selected() { file->set_text(d["name"]); } + + get_ok()->set_disabled(_is_open_should_be_disabled()); } void FileDialog::_tree_dc_selected() { @@ -563,7 +589,7 @@ void FileDialog::set_mode(Mode p_mode) { makedir->hide(); break; case MODE_OPEN_DIR: - get_ok()->set_text(RTR("Open")); + get_ok()->set_text(RTR("Select Current Folder")); set_title(RTR("Open a Directory")); makedir->show(); break; diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 34cecfe4d00..6281e887313 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -33,7 +33,6 @@ #include "box_container.h" #include "os/dir_access.h" #include "scene/gui/dialogs.h" -#include "scene/gui/dialogs.h" #include "scene/gui/line_edit.h" #include "scene/gui/option_button.h" #include "scene/gui/tool_button.h" @@ -117,6 +116,8 @@ private: void _unhandled_input(const Ref &p_event); + bool _is_open_should_be_disabled(); + virtual void _post_popup(); protected: