diff options
author | Ray Koopa <raykoopa@users.noreply.github.com> | 2017-12-02 01:37:32 +0100 |
---|---|---|
committer | Ray Koopa <raykoopa@users.noreply.github.com> | 2017-12-05 21:05:58 +0100 |
commit | 5fbd71af1781b0b808af78ef6ff330086222cd37 (patch) | |
tree | 9252ea95f1b8598777043ee2e1088b8f3c02c9c2 /editor/editor_file_dialog.cpp | |
parent | 581ee23a15c0316aec539a8ff5c282e8d37aa191 (diff) |
Add context menu to editor file dialogs.
Diffstat (limited to 'editor/editor_file_dialog.cpp')
-rw-r--r-- | editor/editor_file_dialog.cpp | 177 |
1 files changed, 162 insertions, 15 deletions
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index eb5af2eaeb..a1da0f0fcb 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -28,12 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "editor_file_dialog.h" - +#include "dependency_editor.h" #include "editor_resource_preview.h" #include "editor_scale.h" #include "editor_settings.h" #include "os/file_access.h" #include "os/keyboard.h" +#include "os/os.h" #include "print_string.h" #include "scene/gui/center_container.h" #include "scene/gui/label.h" @@ -159,6 +160,10 @@ void EditorFileDialog::_unhandled_input(const Ref<InputEvent> &p_event) { _make_dir(); handled = true; } + if (ED_IS_SHORTCUT("file_dialog/delete", p_event)) { + _delete_items(); + handled = true; + } if (ED_IS_SHORTCUT("file_dialog/focus_path", p_event)) { dir->grab_focus(); handled = true; @@ -512,6 +517,106 @@ void EditorFileDialog::_item_dc_selected(int p_item) { } } +void EditorFileDialog::_item_list_item_rmb_selected(int p_item, const Vector2 &p_pos) { + + // Right click on specific file(s) or folder(s). + item_menu->clear(); + item_menu->set_size(Size2(1, 1)); + + // Allow specific actions only on one item. + bool single_item_selected = item_list->get_selected_items().size() == 1; + + // Disallow deleting the .import folder, Godot kills a cat if you do and it is possibly a senseless novice action. + bool allow_delete = true; + for (int i = 0; i < item_list->get_item_count(); i++) { + if (!item_list->is_selected(i)) { + continue; + } + Dictionary item_meta = item_list->get_item_metadata(i); + if (item_meta["path"] == "res://.import") { + allow_delete = false; + break; + } + } + + if (single_item_selected) { + item_menu->add_icon_item(get_icon("CopyNodePath", "EditorIcons"), TTR("Copy Path"), ITEM_MENU_COPY_PATH); + } + if (allow_delete) { + item_menu->add_icon_item(get_icon("Remove", "EditorIcons"), TTR("Delete"), ITEM_MENU_DELETE, KEY_DELETE); + } + if (single_item_selected) { + item_menu->add_separator(); + item_menu->add_icon_item(get_icon("Filesystem", "EditorIcons"), TTR("Show In File Manager"), ITEM_MENU_SHOW_IN_EXPLORER); + } + + if (item_menu->get_item_count() > 0) { + item_menu->set_position(item_list->get_global_position() + p_pos); + item_menu->popup(); + } +} + +void EditorFileDialog::_item_list_rmb_clicked(const Vector2 &p_pos) { + + // Right click on folder background. Deselect all files so that actions are applied on the current folder. + for (int i = 0; i < item_list->get_item_count(); i++) { + item_list->unselect(i); + } + + item_menu->clear(); + item_menu->set_size(Size2(1, 1)); + + if (can_create_dir) { + item_menu->add_icon_item(get_icon("folder", "FileDialog"), TTR("New Folder.."), ITEM_MENU_NEW_FOLDER, KEY_MASK_CMD | KEY_N); + } + item_menu->add_icon_item(get_icon("Reload", "EditorIcons"), TTR("Refresh"), ITEM_MENU_REFRESH, KEY_F5); + item_menu->add_separator(); + item_menu->add_icon_item(get_icon("Filesystem", "EditorIcons"), TTR("Show In File Manager"), ITEM_MENU_SHOW_IN_EXPLORER); + + item_menu->set_position(item_list->get_global_position() + p_pos); + item_menu->popup(); +} + +void EditorFileDialog::_item_menu_id_pressed(int p_option) { + + switch (p_option) { + + case ITEM_MENU_COPY_PATH: { + Dictionary item_meta = item_list->get_item_metadata(item_list->get_current()); + OS::get_singleton()->set_clipboard(item_meta["path"]); + } break; + + case ITEM_MENU_DELETE: { + _delete_items(); + } break; + + case ITEM_MENU_REFRESH: { + invalidate(); + } break; + + case ITEM_MENU_NEW_FOLDER: { + _make_dir(); + } break; + + case ITEM_MENU_SHOW_IN_EXPLORER: { + String path; + int idx = item_list->get_current(); + if (idx == -1 || item_list->get_selected_items().size() == 0) { + // Folder background was clicked. Open this folder. + path = ProjectSettings::get_singleton()->globalize_path(dir_access->get_current_dir()); + } else { + // Specific item was clicked. Open folders directly, or the folder containing a selected file. + Dictionary item_meta = item_list->get_item_metadata(idx); + path = ProjectSettings::get_singleton()->globalize_path(item_meta["path"]); + if (!item_meta["dir"]) { + path = path.get_base_dir(); + } + } + OS::get_singleton()->shell_open(String("file://") + path); + } break; + } +} + bool EditorFileDialog::_is_open_should_be_disabled() { if (mode == MODE_OPEN_ANY || mode == MODE_SAVE_FILE) @@ -617,7 +722,7 @@ void EditorFileDialog::update_file_list() { Dictionary d; d["name"] = dir_name; - d["path"] = String(); + d["path"] = cdir.plus_file(dir_name); d["dir"] = true; item_list->set_item_metadata(item_list->get_item_count() - 1, d); @@ -657,8 +762,6 @@ void EditorFileDialog::update_file_list() { } } - String base_dir = dir_access->get_current_dir(); - while (!files.empty()) { bool match = patterns.empty(); @@ -679,7 +782,7 @@ void EditorFileDialog::update_file_list() { if (get_icon_func) { - Ref<Texture> icon = get_icon_func(base_dir.plus_file(files.front()->get())); + Ref<Texture> icon = get_icon_func(cdir.plus_file(files.front()->get())); //ti->set_icon(0,icon); if (display_mode == DISPLAY_THUMBNAILS) { @@ -698,12 +801,11 @@ void EditorFileDialog::update_file_list() { Dictionary d; d["name"] = files.front()->get(); d["dir"] = false; - String fullpath = base_dir.plus_file(files.front()->get()); - + String fullpath = cdir.plus_file(files.front()->get()); if (display_mode == DISPLAY_THUMBNAILS) { EditorResourcePreview::get_singleton()->queue_resource_preview(fullpath, this, "_thumbnail_result", fullpath); } - d["path"] = base_dir.plus_file(files.front()->get()); + d["path"] = fullpath; //ti->set_metadata(0,d); item_list->set_item_metadata(item_list->get_item_count() - 1, d); @@ -723,7 +825,7 @@ void EditorFileDialog::update_file_list() { 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) { + if (favorites->get_item_metadata(i) == cdir) { favorites->select(i); favorite->set_pressed(true); if (i > 0) { @@ -854,27 +956,27 @@ void EditorFileDialog::set_mode(Mode p_mode) { case MODE_OPEN_FILE: get_ok()->set_text(TTR("Open")); set_title(TTR("Open a File")); - makedir->hide(); + can_create_dir = false; break; case MODE_OPEN_FILES: get_ok()->set_text(TTR("Open")); set_title(TTR("Open File(s)")); - makedir->hide(); + can_create_dir = false; break; case MODE_OPEN_DIR: get_ok()->set_text(TTR("Open")); set_title(TTR("Open a Directory")); - makedir->show(); + can_create_dir = true; break; case MODE_OPEN_ANY: get_ok()->set_text(TTR("Open")); set_title(TTR("Open a File or Directory")); - makedir->show(); + can_create_dir = true; break; case MODE_SAVE_FILE: get_ok()->set_text(TTR("Save")); set_title(TTR("Save a File")); - makedir->show(); + can_create_dir = true; break; } @@ -883,6 +985,12 @@ void EditorFileDialog::set_mode(Mode p_mode) { } else { item_list->set_select_mode(ItemList::SELECT_SINGLE); } + + if (can_create_dir) { + makedir->show(); + } else { + makedir->hide(); + } } EditorFileDialog::Mode EditorFileDialog::get_mode() const { @@ -954,6 +1062,28 @@ void EditorFileDialog::_make_dir() { makedirname->grab_focus(); } +void EditorFileDialog::_delete_items() { + + // Collect the selected folders and files to delete and check them in the deletion dependency dialog. + Vector<String> folders; + Vector<String> files; + for (int i = 0; i < item_list->get_item_count(); i++) { + if (!item_list->is_selected(i)) { + continue; + } + Dictionary item_meta = item_list->get_item_metadata(i); + if (item_meta["dir"]) { + folders.push_back(item_meta["path"]); + } else { + files.push_back(item_meta["path"]); + } + } + if (folders.size() + files.size() > 0) { + remove_dialog->set_size(Size2(1, 1)); + remove_dialog->show(folders, files); + } +} + void EditorFileDialog::_select_drive(int p_idx) { String d = drives->get_item_text(p_idx); @@ -1181,6 +1311,9 @@ void EditorFileDialog::_bind_methods() { 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_list_item_rmb_selected"), &EditorFileDialog::_item_list_item_rmb_selected); + ClassDB::bind_method(D_METHOD("_item_list_rmb_clicked"), &EditorFileDialog::_item_list_rmb_clicked); + ClassDB::bind_method(D_METHOD("_item_menu_id_pressed"), &EditorFileDialog::_item_menu_id_pressed); 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); @@ -1317,6 +1450,7 @@ EditorFileDialog::EditorFileDialog() { ED_SHORTCUT("file_dialog/toggle_favorite", TTR("Toggle Favorite"), KEY_MASK_ALT | KEY_F); ED_SHORTCUT("file_dialog/toggle_mode", TTR("Toggle Mode"), KEY_MASK_ALT | KEY_V); ED_SHORTCUT("file_dialog/create_folder", TTR("Create Folder"), KEY_MASK_CMD | KEY_N); + ED_SHORTCUT("file_dialog/delete", TTR("Delete"), KEY_DELETE); ED_SHORTCUT("file_dialog/focus_path", TTR("Focus Path"), KEY_MASK_CMD | KEY_D); ED_SHORTCUT("file_dialog/move_favorite_up", TTR("Move Favorite Up"), KEY_MASK_CMD | KEY_UP); ED_SHORTCUT("file_dialog/move_favorite_down", TTR("Move Favorite Down"), KEY_MASK_CMD | KEY_DOWN); @@ -1423,10 +1557,21 @@ EditorFileDialog::EditorFileDialog() { list_vb->add_child(memnew(Label(TTR("Directories & Files:")))); preview_hb->add_child(list_vb); + // Item (files and folders) list with context menu + item_list = memnew(ItemList); item_list->set_v_size_flags(SIZE_EXPAND_FILL); + item_list->connect("item_rmb_selected", this, "_item_list_item_rmb_selected"); + item_list->connect("rmb_clicked", this, "_item_list_rmb_clicked"); + item_list->set_allow_rmb_select(true); list_vb->add_child(item_list); + item_menu = memnew(PopupMenu); + item_menu->connect("id_pressed", this, "_item_menu_id_pressed"); + add_child(item_menu); + + // Other stuff + preview_vb = memnew(VBoxContainer); preview_hb->add_child(preview_vb); CenterContainer *prev_cc = memnew(CenterContainer); @@ -1465,9 +1610,11 @@ EditorFileDialog::EditorFileDialog() { confirm_save = memnew(ConfirmationDialog); confirm_save->set_as_toplevel(true); add_child(confirm_save); - confirm_save->connect("confirmed", this, "_save_confirm_pressed"); + remove_dialog = memnew(DependencyRemoveDialog); + add_child(remove_dialog); + makedialog = memnew(ConfirmationDialog); makedialog->set_title(TTR("Create Folder")); VBoxContainer *makevb = memnew(VBoxContainer); |