diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/animation_track_editor.cpp | 18 | ||||
-rw-r--r-- | editor/editor_file_dialog.cpp | 154 | ||||
-rw-r--r-- | editor/editor_file_dialog.h | 24 | ||||
-rw-r--r-- | editor/editor_paths.cpp | 2 | ||||
-rw-r--r-- | editor/editor_settings.cpp | 33 | ||||
-rw-r--r-- | editor/editor_settings.h | 2 | ||||
-rw-r--r-- | editor/icons/GuiToggleOffDisabled.svg | 1 | ||||
-rw-r--r-- | editor/icons/GuiToggleOffDisabledMirrored.svg | 1 | ||||
-rw-r--r-- | editor/icons/GuiToggleOffMirrored.svg | 2 | ||||
-rw-r--r-- | editor/icons/GuiToggleOnDisabled.svg | 1 | ||||
-rw-r--r-- | editor/icons/GuiToggleOnMirrored.svg | 2 | ||||
-rw-r--r-- | editor/icons/GuiToggleOnMirroredDisabled.svg | 1 | ||||
-rw-r--r-- | editor/plugins/animation_player_editor_plugin.cpp | 108 | ||||
-rw-r--r-- | editor/plugins/animation_player_editor_plugin.h | 2 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 18 | ||||
-rw-r--r-- | editor/project_manager.cpp | 78 | ||||
-rw-r--r-- | editor/project_manager.h | 11 |
17 files changed, 302 insertions, 156 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 961eb907bb..fdeee32849 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1844,11 +1844,14 @@ void AnimationTimelineEdit::_pan_callback(Vector2 p_scroll_vec) { } void AnimationTimelineEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { - if (p_scroll_vec.y < 0) { - get_zoom()->set_value(get_zoom()->get_value() * 1.05); + double new_zoom_value; + double current_zoom_value = get_zoom()->get_value(); + if (current_zoom_value <= 0.1) { + new_zoom_value = MAX(0.01, current_zoom_value - 0.01 * SIGN(p_scroll_vec.y)); } else { - get_zoom()->set_value(get_zoom()->get_value() / 1.05); + new_zoom_value = p_scroll_vec.y > 0 ? MAX(0.01, current_zoom_value / 1.05) : current_zoom_value * 1.05; } + get_zoom()->set_value(new_zoom_value); } void AnimationTimelineEdit::set_use_fps(bool p_use_fps) { @@ -5332,11 +5335,14 @@ void AnimationTrackEditor::_pan_callback(Vector2 p_scroll_vec) { } void AnimationTrackEditor::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin, bool p_alt) { - if (p_scroll_vec.y < 0) { - timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05); + double new_zoom_value; + double current_zoom_value = timeline->get_zoom()->get_value(); + if (current_zoom_value <= 0.1) { + new_zoom_value = MAX(0.01, current_zoom_value - 0.01 * SIGN(p_scroll_vec.y)); } else { - timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05); + new_zoom_value = p_scroll_vec.y > 0 ? MAX(0.01, current_zoom_value / 1.05) : current_zoom_value * 1.05; } + timeline->get_zoom()->set_value(new_zoom_value); } void AnimationTrackEditor::_cancel_bezier_edit() { diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 74e02609f9..bda026e16c 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -70,24 +70,7 @@ VBoxContainer *EditorFileDialog::get_vbox() { void EditorFileDialog::_notification(int p_what) { if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_THEME_CHANGED || p_what == Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED || p_what == NOTIFICATION_TRANSLATION_CHANGED) { - // Update icons. - mode_thumbnails->set_icon(item_list->get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons"))); - mode_list->set_icon(item_list->get_theme_icon(SNAME("FileList"), SNAME("EditorIcons"))); - if (is_layout_rtl()) { - dir_prev->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - dir_next->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - } else { - dir_prev->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - dir_next->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - } - dir_up->set_icon(item_list->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); - refresh->set_icon(item_list->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); - favorite->set_icon(item_list->get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"))); - show_hidden->set_icon(item_list->get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); - - fav_up->set_icon(item_list->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); - fav_down->set_icon(item_list->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); - + _update_icons(); } else if (p_what == NOTIFICATION_PROCESS) { if (preview_waiting) { preview_wheel_timeout -= get_process_delta_time(); @@ -109,22 +92,7 @@ void EditorFileDialog::_notification(int p_what) { } set_display_mode((DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int()); - // Update icons. - mode_thumbnails->set_icon(item_list->get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons"))); - mode_list->set_icon(item_list->get_theme_icon(SNAME("FileList"), SNAME("EditorIcons"))); - if (is_layout_rtl()) { - dir_prev->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - dir_next->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - } else { - dir_prev->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); - dir_next->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); - } - dir_up->set_icon(item_list->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); - refresh->set_icon(item_list->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); - favorite->set_icon(item_list->get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"))); - - fav_up->set_icon(item_list->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); - fav_down->set_icon(item_list->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); + _update_icons(); // DO NOT CALL UPDATE FILE LIST HERE, ALL HUNDREDS OF HIDDEN DIALOGS WILL RESPOND, CALL INVALIDATE INSTEAD invalidate(); } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { @@ -312,7 +280,7 @@ void EditorFileDialog::_post_popup() { const Color folder_color = item_list->get_theme_color(SNAME("folder_icon_modulate"), SNAME("FileDialog")); recent->clear(); - bool res = access == ACCESS_RESOURCES; + bool res = (access == ACCESS_RESOURCES); Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs(); for (int i = 0; i < recentd.size(); i++) { bool cres = recentd[i].begins_with("res://"); @@ -384,7 +352,7 @@ void EditorFileDialog::_thumbnail_done(const String &p_path, const Ref<Texture2D } void EditorFileDialog::_request_single_thumbnail(const String &p_path) { - if (!FileAccess::exists(p_path)) { + if (!FileAccess::exists(p_path) || !previews_enabled) { return; } @@ -891,7 +859,7 @@ void EditorFileDialog::update_file_list() { d["path"] = fullpath; item_list->set_item_metadata(item_list->get_item_count() - 1, d); - if (display_mode == DISPLAY_THUMBNAILS) { + if (display_mode == DISPLAY_THUMBNAILS && previews_enabled) { EditorResourcePreview::get_singleton()->queue_resource_preview(fullpath, this, "_thumbnail_result", fullpath); } @@ -1118,9 +1086,12 @@ void EditorFileDialog::_make_dir_confirm() { update_filters(); update_dir(); _push_history(); - EditorFileSystem::get_singleton()->scan_changes(); //we created a dir, so rescan changes + if (access != ACCESS_FILESYSTEM) { + EditorFileSystem::get_singleton()->scan_changes(); //we created a dir, so rescan changes + } } else { - mkdirerr->popup_centered(Size2(250, 50) * EDSCALE); + error_dialog->set_text(TTR("Could not create folder.")); + error_dialog->popup_centered(Size2(250, 50) * EDSCALE); } makedirname->set_text(""); // reset label } @@ -1146,11 +1117,28 @@ void EditorFileDialog::_delete_items() { } } if (folders.size() + files.size() > 0) { - remove_dialog->reset_size(); - remove_dialog->show(folders, files); + if (access == ACCESS_FILESYSTEM) { + global_remove_dialog->popup_centered(); + } else { + dep_remove_dialog->reset_size(); + dep_remove_dialog->show(folders, files); + } } } +void EditorFileDialog::_delete_files_global() { + // Delete files outside of the project directory without dependency checks. + 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); + // Only delete empty directories for safety. + dir_access->remove(item_meta["path"]); + } + update_file_list(); +} + void EditorFileDialog::_select_drive(int p_idx) { String d = drives->get_item_text(p_idx); dir_access->change_dir(d); @@ -1184,11 +1172,60 @@ void EditorFileDialog::_update_drives(bool p_select) { } } +void EditorFileDialog::_update_icons() { + // Update icons. + mode_thumbnails->set_icon(item_list->get_theme_icon(SNAME("FileThumbnail"), SNAME("EditorIcons"))); + mode_list->set_icon(item_list->get_theme_icon(SNAME("FileList"), SNAME("EditorIcons"))); + if (is_layout_rtl()) { + dir_prev->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); + dir_next->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); + } else { + dir_prev->set_icon(item_list->get_theme_icon(SNAME("Back"), SNAME("EditorIcons"))); + dir_next->set_icon(item_list->get_theme_icon(SNAME("Forward"), SNAME("EditorIcons"))); + } + dir_up->set_icon(item_list->get_theme_icon(SNAME("ArrowUp"), SNAME("EditorIcons"))); + refresh->set_icon(item_list->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); + favorite->set_icon(item_list->get_theme_icon(SNAME("Favorites"), SNAME("EditorIcons"))); + show_hidden->set_icon(item_list->get_theme_icon(SNAME("GuiVisibilityVisible"), SNAME("EditorIcons"))); + + fav_up->set_icon(item_list->get_theme_icon(SNAME("MoveUp"), SNAME("EditorIcons"))); + fav_down->set_icon(item_list->get_theme_icon(SNAME("MoveDown"), SNAME("EditorIcons"))); +} + void EditorFileDialog::_favorite_selected(int p_idx) { - dir_access->change_dir(favorites->get_item_metadata(p_idx)); - update_dir(); - invalidate(); - _push_history(); + Error change_dir_result = dir_access->change_dir(favorites->get_item_metadata(p_idx)); + if (change_dir_result != OK) { + error_dialog->set_text(TTR("Favorited folder does not exist anymore and will be removed.")); + error_dialog->popup_centered(Size2(250, 50) * EDSCALE); + + bool res = (access == ACCESS_RESOURCES); + + Vector<String> favorited = EditorSettings::get_singleton()->get_favorites(); + String dir_to_remove = favorites->get_item_metadata(p_idx); + + bool found = false; + for (int i = 0; i < favorited.size(); i++) { + bool cres = favorited[i].begins_with("res://"); + if (cres != res) { + continue; + } + + if (favorited[i] == dir_to_remove) { + found = true; + break; + } + } + + if (found) { + favorited.erase(favorites->get_item_metadata(p_idx)); + favorites->remove_item(p_idx); + EditorSettings::get_singleton()->set_favorites(favorited); + } + } else { + update_dir(); + invalidate(); + _push_history(); + } } void EditorFileDialog::_favorite_move_up() { @@ -1234,7 +1271,7 @@ void EditorFileDialog::_favorite_move_down() { } void EditorFileDialog::_update_favorites() { - bool res = access == ACCESS_RESOURCES; + bool res = (access == ACCESS_RESOURCES); String current = get_current_dir(); Ref<Texture2D> folder_icon = item_list->get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")); @@ -1283,7 +1320,7 @@ void EditorFileDialog::_update_favorites() { } void EditorFileDialog::_favorite_pressed() { - bool res = access == ACCESS_RESOURCES; + bool res = (access == ACCESS_RESOURCES); String cd = get_current_dir(); if (!cd.ends_with("/")) { @@ -1495,6 +1532,14 @@ bool EditorFileDialog::is_overwrite_warning_disabled() const { return disable_overwrite_warning; } +void EditorFileDialog::set_previews_enabled(bool p_enabled) { + previews_enabled = p_enabled; +} + +bool EditorFileDialog::are_previews_enabled() { + return previews_enabled; +} + EditorFileDialog::EditorFileDialog() { show_hidden_files = default_show_hidden_files; display_mode = default_display_mode; @@ -1728,8 +1773,13 @@ EditorFileDialog::EditorFileDialog() { add_child(confirm_save); confirm_save->connect("confirmed", callable_mp(this, &EditorFileDialog::_save_confirm_pressed)); - remove_dialog = memnew(DependencyRemoveDialog); - add_child(remove_dialog); + dep_remove_dialog = memnew(DependencyRemoveDialog); + add_child(dep_remove_dialog); + + global_remove_dialog = memnew(ConfirmationDialog); + global_remove_dialog->set_text(TTR("Remove the selected files? For safety only files and empty directories can be deleted from here. (Cannot be undone.)\nDepending on your filesystem configuration, the files will either be moved to the system trash or deleted permanently.")); + global_remove_dialog->connect("confirmed", callable_mp(this, &EditorFileDialog::_delete_files_global)); + add_child(global_remove_dialog); makedialog = memnew(ConfirmationDialog); makedialog->set_title(TTR("Create Folder")); @@ -1742,9 +1792,8 @@ EditorFileDialog::EditorFileDialog() { add_child(makedialog); makedialog->register_text_enter(makedirname); makedialog->connect("confirmed", callable_mp(this, &EditorFileDialog::_make_dir_confirm)); - mkdirerr = memnew(AcceptDialog); - mkdirerr->set_text(TTR("Could not create folder.")); - add_child(mkdirerr); + error_dialog = memnew(AcceptDialog); + add_child(error_dialog); update_filters(); update_dir(); @@ -1757,6 +1806,7 @@ EditorFileDialog::EditorFileDialog() { register_func(this); } + previews_enabled = true; preview_wheel_timeout = 0; preview_wheel_index = 0; preview_waiting = false; diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h index 6cfdf53780..65a4c9e544 100644 --- a/editor/editor_file_dialog.h +++ b/editor/editor_file_dialog.h @@ -32,6 +32,7 @@ #define EDITORFILEDIALOG_H #include "core/io/dir_access.h" +#include "editor/plugins/editor_preview_plugins.h" #include "scene/gui/box_container.h" #include "scene/gui/dialogs.h" #include "scene/gui/item_list.h" @@ -88,7 +89,7 @@ private: Button *makedir; Access access; - //Button *action; + VBoxContainer *vbox; FileMode mode; bool can_create_dir; @@ -109,10 +110,11 @@ private: HBoxContainer *file_box; LineEdit *file; OptionButton *filter; - AcceptDialog *mkdirerr; + AcceptDialog *error_dialog; DirAccess *dir_access; ConfirmationDialog *confirm_save; - DependencyRemoveDialog *remove_dialog; + DependencyRemoveDialog *dep_remove_dialog; + ConfirmationDialog *global_remove_dialog; Button *mode_thumbnails; Button *mode_list; @@ -133,9 +135,11 @@ private: Vector<String> filters; + bool previews_enabled; bool preview_waiting; int preview_wheel_index; float preview_wheel_timeout; + static bool default_show_hidden_files; static DisplayMode default_display_mode; bool show_hidden_files; @@ -179,8 +183,10 @@ private: void _make_dir_confirm(); void _delete_items(); + void _delete_files_global(); void _update_drives(bool p_select = true); + void _update_icons(); void _go_up(); void _go_back(); @@ -189,7 +195,7 @@ private: virtual void _post_popup() override; void _save_to_recent(); - //callback function is callback(String p_path,Ref<Texture2D> preview,Variant udata) preview null if could not load + // Callback function is callback(String p_path,Ref<Texture2D> preview,Variant udata) preview null if could not load. void _thumbnail_result(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, const Variant &p_udata); void _thumbnail_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, const Variant &p_udata); @@ -202,7 +208,7 @@ private: protected: void _notification(int p_what); static void _bind_methods(); - //bind helpers + public: void popup_file_dialog(); void clear_filters(); @@ -230,17 +236,19 @@ public: void set_access(Access p_access); Access get_access() const; - void set_show_hidden_files(bool p_show); - bool is_showing_hidden_files() const; - 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); + bool is_showing_hidden_files() const; void invalidate(); void set_disable_overwrite_warning(bool p_disable); bool is_overwrite_warning_disabled() const; + void set_previews_enabled(bool p_enabled); + bool are_previews_enabled(); + EditorFileDialog(); ~EditorFileDialog(); }; diff --git a/editor/editor_paths.cpp b/editor/editor_paths.cpp index d4e40db406..c209238447 100644 --- a/editor/editor_paths.cpp +++ b/editor/editor_paths.cpp @@ -193,7 +193,7 @@ EditorPaths::EditorPaths() { // Validate or create project-specific editor data dir, // including shader cache subdir. - if (Main::is_project_manager() || Main::is_cmdline_tool()) { + if (Engine::get_singleton()->is_project_manager_hint() || Main::is_cmdline_tool()) { // Nothing to create, use shared editor data dir for shader cache. Engine::get_singleton()->set_shader_cache_path(data_dir); } else { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index f230a9b435..0c3f7287a5 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -845,7 +845,7 @@ void EditorSettings::create() { singleton->setup_language(); singleton->setup_network(); - singleton->load_favorites(); + singleton->load_favorites_and_recent_dirs(); singleton->list_text_editor_themes(); return; @@ -1103,7 +1103,13 @@ Variant EditorSettings::get_project_metadata(const String &p_section, const Stri void EditorSettings::set_favorites(const Vector<String> &p_favorites) { favorites = p_favorites; - FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::WRITE); + String favorites_file; + if (Engine::get_singleton()->is_project_manager_hint()) { + favorites_file = EditorPaths::get_singleton()->get_config_dir().plus_file("favorite_dirs"); + } else { + favorites_file = get_project_settings_dir().plus_file("favorites"); + } + FileAccess *f = FileAccess::open(favorites_file, FileAccess::WRITE); if (f) { for (int i = 0; i < favorites.size(); i++) { f->store_line(favorites[i]); @@ -1118,7 +1124,13 @@ Vector<String> EditorSettings::get_favorites() const { void EditorSettings::set_recent_dirs(const Vector<String> &p_recent_dirs) { recent_dirs = p_recent_dirs; - FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("recent_dirs"), FileAccess::WRITE); + String recent_dirs_file; + if (Engine::get_singleton()->is_project_manager_hint()) { + recent_dirs_file = EditorPaths::get_singleton()->get_config_dir().plus_file("recent_dirs"); + } else { + recent_dirs_file = get_project_settings_dir().plus_file("recent_dirs"); + } + FileAccess *f = FileAccess::open(recent_dirs_file, FileAccess::WRITE); if (f) { for (int i = 0; i < recent_dirs.size(); i++) { f->store_line(recent_dirs[i]); @@ -1131,8 +1143,17 @@ Vector<String> EditorSettings::get_recent_dirs() const { return recent_dirs; } -void EditorSettings::load_favorites() { - FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::READ); +void EditorSettings::load_favorites_and_recent_dirs() { + String favorites_file; + String recent_dirs_file; + if (Engine::get_singleton()->is_project_manager_hint()) { + favorites_file = EditorPaths::get_singleton()->get_config_dir().plus_file("favorite_dirs"); + recent_dirs_file = EditorPaths::get_singleton()->get_config_dir().plus_file("recent_dirs"); + } else { + favorites_file = get_project_settings_dir().plus_file("favorites"); + recent_dirs_file = get_project_settings_dir().plus_file("recent_dirs"); + } + FileAccess *f = FileAccess::open(favorites_file, FileAccess::READ); if (f) { String line = f->get_line().strip_edges(); while (!line.is_empty()) { @@ -1142,7 +1163,7 @@ void EditorSettings::load_favorites() { memdelete(f); } - f = FileAccess::open(get_project_settings_dir().plus_file("recent_dirs"), FileAccess::READ); + f = FileAccess::open(recent_dirs_file, FileAccess::READ); if (f) { String line = f->get_line().strip_edges(); while (!line.is_empty()) { diff --git a/editor/editor_settings.h b/editor/editor_settings.h index f1a0329d65..078abcb4d9 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -161,7 +161,7 @@ public: Vector<String> get_favorites() const; void set_recent_dirs(const Vector<String> &p_recent_dirs); Vector<String> get_recent_dirs() const; - void load_favorites(); + void load_favorites_and_recent_dirs(); bool is_dark_theme(); diff --git a/editor/icons/GuiToggleOffDisabled.svg b/editor/icons/GuiToggleOffDisabled.svg new file mode 100644 index 0000000000..020ebdc3a8 --- /dev/null +++ b/editor/icons/GuiToggleOffDisabled.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 38 15.999999" width="38" xmlns="http://www.w3.org/2000/svg"><g fill="#808080"><rect fill-opacity=".188235" height="14" rx="7" stroke-width="55.8958" width="36" x="1" y="1"/><circle cx="8" cy="8" r="5" stroke-width="97.3613"/></g></svg> diff --git a/editor/icons/GuiToggleOffDisabledMirrored.svg b/editor/icons/GuiToggleOffDisabledMirrored.svg new file mode 100644 index 0000000000..79ab79a20f --- /dev/null +++ b/editor/icons/GuiToggleOffDisabledMirrored.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 38 16" xmlns="http://www.w3.org/2000/svg"><g fill="#808080"><path d="m1 8c0-3.863 3.137-7 7-7h22c3.863 0 7 3.137 7 7s-3.137 7-7 7h-22c-3.863 0-7-3.137-7-7z" fill-opacity=".18"/><circle cx="30" cy="8" r="5"/></g></svg> diff --git a/editor/icons/GuiToggleOffMirrored.svg b/editor/icons/GuiToggleOffMirrored.svg index d650de9cda..58122b9d1f 100644 --- a/editor/icons/GuiToggleOffMirrored.svg +++ b/editor/icons/GuiToggleOffMirrored.svg @@ -1 +1 @@ -<svg height="26" width="42" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="matrix(-1 0 0 1 42 0)"><rect fill-opacity=".188" height="16" rx="9" width="38" x="2" y="5"/><circle cx="10" cy="13" r="5"/></g></svg> +<svg viewBox="0 0 38 16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0"><path d="m1 8c0-3.863 3.137-7 7-7h22c3.863 0 7 3.137 7 7s-3.137 7-7 7h-22c-3.863 0-7-3.137-7-7z" fill-opacity=".18"/><circle cx="30" cy="8" r="5"/></g></svg> diff --git a/editor/icons/GuiToggleOnDisabled.svg b/editor/icons/GuiToggleOnDisabled.svg new file mode 100644 index 0000000000..df6b27c71e --- /dev/null +++ b/editor/icons/GuiToggleOnDisabled.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 38 15.999999" width="38" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-4 0-7 3.0000002-7 7.0000002 0 3.9999998 3 6.9999998 7 6.9999998h22c4 0 7-3 7-6.9999998 0-4-3-7.0000002-7-7.0000002-7.333334 0-14.55609 0-22 0z" fill="#808080"/><circle cx="30" cy="8" fill="#b3b3b3" r="5"/></svg> diff --git a/editor/icons/GuiToggleOnMirrored.svg b/editor/icons/GuiToggleOnMirrored.svg index affbb5c7a8..e4706b82eb 100644 --- a/editor/icons/GuiToggleOnMirrored.svg +++ b/editor/icons/GuiToggleOnMirrored.svg @@ -1 +1 @@ -<svg height="26" width="42" xmlns="http://www.w3.org/2000/svg"><path d="m31 5c4.986 0 9 3.568 9 8s-4.014 8-9 8h-20c-4.986 0-9-3.568-9-8s4.014-8 9-8z" fill="#699ce8"/><circle cx="10" cy="13" fill="#ffffff" r="5"/></svg> +<svg viewBox="0 0 38 16" xmlns="http://www.w3.org/2000/svg"><path d="m30 1c4 0 7 3 7 7s-3 7-7 7h-22c-4 0-7-3-7-7s3-7 7-7z" fill="#699ce8" fill-rule="nonzero"/><circle cx="8" cy="8" fill="#fff" r="5"/></svg> diff --git a/editor/icons/GuiToggleOnMirroredDisabled.svg b/editor/icons/GuiToggleOnMirroredDisabled.svg new file mode 100644 index 0000000000..3541221e29 --- /dev/null +++ b/editor/icons/GuiToggleOnMirroredDisabled.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 38 16" xmlns="http://www.w3.org/2000/svg"><path d="m30 1c4 0 7 3 7 7s-3 7-7 7h-22c-4 0-7-3-7-7s3-7 7-7z" fill="#808080" fill-rule="nonzero"/><circle cx="8" cy="8" fill="#b3b3b3" r="5"/></svg> diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 1d9a2422da..c3f62bcfd8 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -308,7 +308,7 @@ void AnimationPlayerEditor::_animation_selected(int p_which) { } void AnimationPlayerEditor::_animation_new() { - renaming = false; + name_dialog_op = TOOL_NEW_ANIM; name_title->set_text(TTR("New Animation Name:")); int count = 1; @@ -341,7 +341,7 @@ void AnimationPlayerEditor::_animation_rename() { name_title->set_text(TTR("Change Animation Name:")); name->set_text(selected_name); - renaming = true; + name_dialog_op = TOOL_RENAME_ANIM; name_dialog->popup_centered(Size2(300, 90)); name->select_all(); name->grab_focus(); @@ -494,7 +494,7 @@ void AnimationPlayerEditor::_animation_name_edited() { return; } - if (renaming && animation->get_item_count() > 0 && animation->get_item_text(animation->get_selected()) == new_name) { + if (name_dialog_op == TOOL_RENAME_ANIM && animation->get_item_count() > 0 && animation->get_item_text(animation->get_selected()) == new_name) { name_dialog->hide(); return; } @@ -505,37 +505,57 @@ void AnimationPlayerEditor::_animation_name_edited() { return; } - if (renaming) { - String current = animation->get_item_text(animation->get_selected()); - Ref<Animation> anim = player->get_animation(current); + switch (name_dialog_op) { + case TOOL_RENAME_ANIM: { + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); + + undo_redo->create_action(TTR("Rename Animation")); + undo_redo->add_do_method(player, "rename_animation", current, new_name); + undo_redo->add_do_method(anim.ptr(), "set_name", new_name); + undo_redo->add_undo_method(player, "rename_animation", new_name, current); + undo_redo->add_undo_method(anim.ptr(), "set_name", current); + undo_redo->add_do_method(this, "_animation_player_changed", player); + undo_redo->add_undo_method(this, "_animation_player_changed", player); + undo_redo->commit_action(); + + _select_anim_by_name(new_name); + } break; - undo_redo->create_action(TTR("Rename Animation")); - undo_redo->add_do_method(player, "rename_animation", current, new_name); - undo_redo->add_do_method(anim.ptr(), "set_name", new_name); - undo_redo->add_undo_method(player, "rename_animation", new_name, current); - undo_redo->add_undo_method(anim.ptr(), "set_name", current); - undo_redo->add_do_method(this, "_animation_player_changed", player); - undo_redo->add_undo_method(this, "_animation_player_changed", player); - undo_redo->commit_action(); + case TOOL_NEW_ANIM: { + Ref<Animation> new_anim = Ref<Animation>(memnew(Animation)); + new_anim->set_name(new_name); + + undo_redo->create_action(TTR("Add Animation")); + undo_redo->add_do_method(player, "add_animation", new_name, new_anim); + undo_redo->add_undo_method(player, "remove_animation", new_name); + undo_redo->add_do_method(this, "_animation_player_changed", player); + undo_redo->add_undo_method(this, "_animation_player_changed", player); + if (animation->get_item_count() == 0) { + undo_redo->add_do_method(this, "_start_onion_skinning"); + undo_redo->add_undo_method(this, "_stop_onion_skinning"); + } + undo_redo->commit_action(); - _select_anim_by_name(new_name); + _select_anim_by_name(new_name); + } break; - } else { - Ref<Animation> new_anim = Ref<Animation>(memnew(Animation)); - new_anim->set_name(new_name); + case TOOL_DUPLICATE_ANIM: { + String current = animation->get_item_text(animation->get_selected()); + Ref<Animation> anim = player->get_animation(current); - undo_redo->create_action(TTR("Add Animation")); - undo_redo->add_do_method(player, "add_animation", new_name, new_anim); - undo_redo->add_undo_method(player, "remove_animation", new_name); - undo_redo->add_do_method(this, "_animation_player_changed", player); - undo_redo->add_undo_method(this, "_animation_player_changed", player); - if (animation->get_item_count() == 0) { - undo_redo->add_do_method(this, "_start_onion_skinning"); - undo_redo->add_undo_method(this, "_stop_onion_skinning"); - } - undo_redo->commit_action(); + Ref<Animation> new_anim = _animation_clone(anim); + + undo_redo->create_action(TTR("Duplicate Animation")); + undo_redo->add_do_method(player, "add_animation", new_name, new_anim); + undo_redo->add_undo_method(player, "remove_animation", new_name); + undo_redo->add_do_method(player, "animation_set_next", new_name, player->animation_get_next(current)); + undo_redo->add_do_method(this, "_animation_player_changed", player); + undo_redo->add_undo_method(this, "_animation_player_changed", player); + undo_redo->commit_action(); - _select_anim_by_name(new_name); + _select_anim_by_name(new_name); + } break; } name_dialog->hide(); @@ -968,28 +988,17 @@ void AnimationPlayerEditor::_animation_duplicate() { return; } - Ref<Animation> new_anim = _animation_clone(anim); String new_name = current; while (player->has_animation(new_name)) { new_name = new_name + " (copy)"; } - new_anim->set_name(new_name); - - undo_redo->create_action(TTR("Duplicate Animation")); - undo_redo->add_do_method(player, "add_animation", new_name, new_anim); - undo_redo->add_undo_method(player, "remove_animation", new_name); - undo_redo->add_do_method(player, "animation_set_next", new_name, player->animation_get_next(current)); - undo_redo->add_do_method(this, "_animation_player_changed", player); - undo_redo->add_undo_method(this, "_animation_player_changed", player); - undo_redo->commit_action(); - for (int i = 0; i < animation->get_item_count(); i++) { - if (animation->get_item_text(i) == new_name) { - animation->select(i); - _animation_selected(i); - return; - } - } + name_title->set_text(TTR("New Animation Name:")); + name->set_text(new_name); + name_dialog_op = TOOL_DUPLICATE_ANIM; + name_dialog->popup_centered(Size2(300, 90)); + name->select_all(); + name->grab_focus(); } Ref<Animation> AnimationPlayerEditor::_animation_clone(Ref<Animation> p_anim) { @@ -1139,9 +1148,7 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) { } break; case TOOL_DUPLICATE_ANIM: { _animation_duplicate(); - - [[fallthrough]]; // Allow immediate rename after animation is duplicated - } + } break; case TOOL_RENAME_ANIM: { _animation_rename(); } break; @@ -1610,7 +1617,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/paste_animation", TTR("Paste")), TOOL_PASTE_ANIM); tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/paste_animation_as_reference", TTR("Paste As Reference")), TOOL_PASTE_ANIM_REF); tool_anim->get_popup()->add_separator(); - tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/duplicate_animation", TTR("Duplicate")), TOOL_DUPLICATE_ANIM); + tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/duplicate_animation", TTR("Duplicate...")), TOOL_DUPLICATE_ANIM); tool_anim->get_popup()->add_separator(); tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/rename_animation", TTR("Rename...")), TOOL_RENAME_ANIM); tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/edit_transitions", TTR("Edit Transitions...")), TOOL_EDIT_TRANSITIONS); @@ -1726,7 +1733,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay frame->connect("value_changed", callable_mp(this, &AnimationPlayerEditor::_seek_value_changed), make_binds(true, false)); scale->connect("text_submitted", callable_mp(this, &AnimationPlayerEditor::_scale_changed)); - renaming = false; last_active = false; timeline_position = 0; diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h index cfd18f39fd..cf6ba292fc 100644 --- a/editor/plugins/animation_player_editor_plugin.h +++ b/editor/plugins/animation_player_editor_plugin.h @@ -125,7 +125,7 @@ class AnimationPlayerEditor : public VBoxContainer { ConfirmationDialog *name_dialog; ConfirmationDialog *error_dialog; - bool renaming; + int name_dialog_op = TOOL_NEW_ANIM; bool updating; bool updating_blends; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index d62bb3814f..8bcc220c8f 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -1889,7 +1889,12 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } - if (_edit.mode != TRANSFORM_NONE) { + if (_edit.mode == TRANSFORM_NONE) { + if (k->get_keycode() == Key::ESCAPE && !cursor.region_select) { + _clear_selected(); + return; + } + } else { // We're actively transforming, handle keys specially TransformPlane new_plane = TRANSFORM_VIEW; String new_message; @@ -6308,14 +6313,15 @@ void fragment() { // Lines to visualize transforms locked to an axis/plane { Ref<SurfaceTool> surftool = memnew(SurfaceTool); - surftool->begin(Mesh::PRIMITIVE_LINES); + surftool->begin(Mesh::PRIMITIVE_LINE_STRIP); Vector3 vec; vec[i] = 1; // line extending through infinity(ish) - surftool->add_vertex(vec * -99999); - surftool->add_vertex(vec * 99999); + surftool->add_vertex(vec * -1048576); + surftool->add_vertex(Vector3()); + surftool->add_vertex(vec * 1048576); surftool->set_material(mat_hl); surftool->commit(axis_gizmo[i]); } @@ -7354,8 +7360,8 @@ void Node3DEditor::_load_default_preview_settings() { sun_angle_altitude->set_value(-Math::rad2deg(sun_rotation.x)); sun_angle_azimuth->set_value(180.0 - Math::rad2deg(sun_rotation.y)); sun_direction->update(); - environ_sky_color->set_pick_color(Color::hex(0x91b2ceff)); - environ_ground_color->set_pick_color(Color::hex(0x1f1f21ff)); + environ_sky_color->set_pick_color(Color(0.385, 0.454, 0.55)); + environ_ground_color->set_pick_color(Color(0.2, 0.169, 0.133)); environ_energy->set_value(1.0); environ_glow_button->set_pressed(true); environ_tonemap_button->set_pressed(true); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 4dfa310e08..2a9f699ee6 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -41,6 +41,7 @@ #include "core/os/os.h" #include "core/string/translation.h" #include "core/version.h" +#include "editor/editor_file_dialog.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_themes.h" @@ -100,8 +101,8 @@ private: LineEdit *install_path; TextureRect *status_rect; TextureRect *install_status_rect; - FileDialog *fdialog; - FileDialog *fdialog_install; + EditorFileDialog *fdialog; + EditorFileDialog *fdialog_install; OptionButton *vcs_metadata_selection; String zip_path; String zip_title; @@ -365,19 +366,19 @@ private: fdialog->set_current_dir(project_path->get_text()); if (mode == MODE_IMPORT) { - fdialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE); + fdialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); fdialog->clear_filters(); fdialog->add_filter(vformat("project.godot ; %s %s", VERSION_NAME, TTR("Project"))); fdialog->add_filter("*.zip ; " + TTR("ZIP File")); } else { - fdialog->set_file_mode(FileDialog::FILE_MODE_OPEN_DIR); + fdialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR); } fdialog->popup_file_dialog(); } void _browse_install_path() { fdialog_install->set_current_dir(install_path->get_text()); - fdialog_install->set_file_mode(FileDialog::FILE_MODE_OPEN_DIR); + fdialog_install->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR); fdialog_install->popup_file_dialog(); } @@ -925,12 +926,15 @@ public: spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL); default_files_container->add_child(spacer); - fdialog = memnew(FileDialog); - fdialog->set_access(FileDialog::ACCESS_FILESYSTEM); - fdialog_install = memnew(FileDialog); - fdialog_install->set_access(FileDialog::ACCESS_FILESYSTEM); + fdialog = memnew(EditorFileDialog); + fdialog->set_previews_enabled(false); //Crucial, otherwise the engine crashes. + fdialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + fdialog_install = memnew(EditorFileDialog); + fdialog_install->set_previews_enabled(false); //Crucial, otherwise the engine crashes. + fdialog_install->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(fdialog); add_child(fdialog_install); + project_name->connect("text_changed", callable_mp(this, &ProjectDialog::_text_changed)); project_path->connect("text_changed", callable_mp(this, &ProjectDialog::_path_text_changed)); install_path->connect("text_changed", callable_mp(this, &ProjectDialog::_path_text_changed)); @@ -1859,6 +1863,8 @@ void ProjectList::_bind_methods() { ADD_SIGNAL(MethodInfo(SIGNAL_PROJECT_ASK_OPEN)); } +ProjectManager *ProjectManager::singleton = nullptr; + void ProjectManager::_notification(int p_what) { switch (p_what) { case NOTIFICATION_TRANSLATION_CHANGED: @@ -1904,6 +1910,21 @@ void ProjectManager::_notification(int p_what) { } } +Ref<Texture2D> ProjectManager::_file_dialog_get_icon(const String &p_path) { + return singleton->icon_type_cache["ObjectHR"]; +} + +void ProjectManager::_build_icon_type_cache(Ref<Theme> p_theme) { + List<StringName> tl; + p_theme->get_icon_list(SNAME("EditorIcons"), &tl); + for (List<StringName>::Element *E = tl.front(); E; E = E->next()) { + if (!ClassDB::class_exists(E->get())) { + continue; + } + icon_type_cache[E->get()] = p_theme->get_icon(E->get(), SNAME("EditorIcons")); + } +} + void ProjectManager::_dim_window() { // This method must be called before calling `get_tree()->quit()`. // Otherwise, its effect won't be visible @@ -2460,6 +2481,8 @@ void ProjectManager::_version_button_pressed() { } ProjectManager::ProjectManager() { + singleton = this; + // load settings if (!EditorSettings::get_singleton()) { EditorSettings::create(); @@ -2502,20 +2525,13 @@ ProjectManager::ProjectManager() { editor_set_scale(EditorSettings::get_singleton()->get("interface/editor/custom_display_scale")); break; } - - // Define a minimum window size to prevent UI elements from overlapping or being cut off - DisplayServer::get_singleton()->window_set_min_size(Size2(750, 420) * EDSCALE); - - // TODO: Resize windows on hiDPI displays on Windows and Linux and remove the lines below - float scale_factor = MAX(1, EDSCALE); - Vector2i window_size = DisplayServer::get_singleton()->window_get_size(); - DisplayServer::get_singleton()->window_set_size(Vector2i(window_size.x * scale_factor, window_size.y * scale_factor)); + EditorFileDialog::get_icon_func = &ProjectManager::_file_dialog_get_icon; } // TRANSLATORS: This refers to the application where users manage their Godot projects. DisplayServer::get_singleton()->window_set_title(VERSION_NAME + String(" - ") + TTR("Project Manager")); - FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); + EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files")); set_anchors_and_offsets_preset(Control::PRESET_WIDE); set_theme(create_custom_theme()); @@ -2746,9 +2762,10 @@ ProjectManager::ProjectManager() { language_restart_ask->get_cancel_button()->set_text(TTR("Continue")); add_child(language_restart_ask); - scan_dir = memnew(FileDialog); - scan_dir->set_access(FileDialog::ACCESS_FILESYSTEM); - scan_dir->set_file_mode(FileDialog::FILE_MODE_OPEN_DIR); + scan_dir = memnew(EditorFileDialog); + scan_dir->set_previews_enabled(false); + scan_dir->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + scan_dir->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR); scan_dir->set_title(TTR("Select a Folder to Scan")); // must be after mode or it's overridden scan_dir->set_current_dir(EditorSettings::get_singleton()->get("filesystem/directories/default_project_path")); add_child(scan_dir); @@ -2812,6 +2829,8 @@ ProjectManager::ProjectManager() { about = memnew(EditorAbout); add_child(about); + + _build_icon_type_cache(get_theme()); } _load_recent_projects(); @@ -2840,10 +2859,27 @@ ProjectManager::ProjectManager() { SceneTree::get_singleton()->get_root()->connect("files_dropped", callable_mp(this, &ProjectManager::_files_dropped)); + // Define a minimum window size to prevent UI elements from overlapping or being cut off + DisplayServer::get_singleton()->window_set_min_size(Size2(750, 420) * EDSCALE); + + // Resize the bootsplash window based on Editor display scale EDSCALE. + float scale_factor = MAX(1, EDSCALE); + if (scale_factor > 1.0) { + Vector2i window_size = DisplayServer::get_singleton()->window_get_size(); + Vector2i screen_size = DisplayServer::get_singleton()->screen_get_size(); + window_size *= scale_factor; + Vector2i window_position; + window_position.x = (screen_size.x - window_size.x) / 2; + window_position.y = (screen_size.y - window_size.y) / 2; + DisplayServer::get_singleton()->window_set_size(window_size); + DisplayServer::get_singleton()->window_set_position(window_position); + } + OS::get_singleton()->set_low_processor_usage_mode(true); } ProjectManager::~ProjectManager() { + singleton = nullptr; if (EditorSettings::get_singleton()) { EditorSettings::destroy(); } diff --git a/editor/project_manager.h b/editor/project_manager.h index f99e879664..2965dc7d2e 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -50,6 +50,11 @@ enum FilterOption { class ProjectManager : public Control { GDCLASS(ProjectManager, Control); + Map<String, Ref<Texture2D>> icon_type_cache; + void _build_icon_type_cache(Ref<Theme> p_theme); + + static ProjectManager *singleton; + TabContainer *tabs; ProjectList *_project_list; @@ -67,7 +72,7 @@ class ProjectManager : public Control { EditorAssetLibrary *asset_library; - FileDialog *scan_dir; + EditorFileDialog *scan_dir; ConfirmationDialog *language_restart_ask; ConfirmationDialog *erase_ask; @@ -129,11 +134,15 @@ class ProjectManager : public Control { void _on_tab_changed(int p_tab); void _on_search_term_changed(const String &p_term); + static Ref<Texture2D> _file_dialog_get_icon(const String &p_path); + protected: void _notification(int p_what); static void _bind_methods(); public: + static ProjectManager *get_singleton() { return singleton; } + ProjectManager(); ~ProjectManager(); }; |