diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/code_editor.cpp | 2 | ||||
-rw-r--r-- | editor/editor_settings.cpp | 4 | ||||
-rw-r--r-- | editor/filesystem_dock.cpp | 300 | ||||
-rw-r--r-- | editor/filesystem_dock.h | 3 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 223 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.h | 36 |
6 files changed, 308 insertions, 260 deletions
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 33af5927b3..61adff7c9c 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -908,6 +908,8 @@ void CodeTextEditor::update_editor_settings() { text_editor->set_hiding_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding")); text_editor->set_draw_fold_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding")); text_editor->set_wrap_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/word_wrap")); + text_editor->set_draw_minimap(EditorSettings::get_singleton()->get("text_editor/line_numbers/draw_minimap")); + text_editor->set_minimap_width(EditorSettings::get_singleton()->get("text_editor/line_numbers/minimap_width")); text_editor->set_draw_info_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_info_gutter")); text_editor->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret")); text_editor->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling")); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index e342b784c9..61668d55be 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -448,6 +448,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("text_editor/line_numbers/show_info_gutter", true); _initial_set("text_editor/line_numbers/code_folding", true); _initial_set("text_editor/line_numbers/word_wrap", false); + _initial_set("text_editor/line_numbers/draw_minimap", false); + _initial_set("text_editor/line_numbers/minimap_width", 80); + hints["text_editor/line_numbers/minimap_width"] = PropertyInfo(Variant::INT, "text_editor/line_numbers/minimap_width", PROPERTY_HINT_RANGE, "50,250,1"); _initial_set("text_editor/line_numbers/show_line_length_guideline", false); _initial_set("text_editor/line_numbers/line_length_guideline_column", 80); hints["text_editor/line_numbers/line_length_guideline_column"] = PropertyInfo(Variant::INT, "text_editor/line_numbers/line_length_guideline_column", PROPERTY_HINT_RANGE, "20, 160, 1"); @@ -561,6 +564,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { // 2D _initial_set("editors/2d/grid_color", Color(1.0, 1.0, 1.0, 0.07)); _initial_set("editors/2d/guides_color", Color(0.6, 0.0, 0.8)); + _initial_set("editors/2d/smart_snapping_line_color", Color(0.9, 0.1, 0.1)); _initial_set("editors/2d/bone_width", 5); _initial_set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9)); _initial_set("editors/2d/bone_color2", Color(0.6, 0.6, 0.6, 0.9)); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 0d6f463862..84631f3e38 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -53,10 +53,9 @@ Ref<Texture> FileSystemDock::_get_tree_item_icon(EditorFileSystemDirectory *p_di } bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites) { - bool parent_should_expand = false; - // Create a tree item for the subdirectory + // Create a tree item for the subdirectory. TreeItem *subdirectory_item = tree->create_item(p_parent); String dname = p_dir->get_name(); if (dname == "") @@ -81,28 +80,28 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory parent_should_expand = true; } - // Create items for all subdirectories + // Create items for all subdirectories. for (int i = 0; i < p_dir->get_subdir_count(); i++) parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths, p_select_in_favorites) || parent_should_expand); - // Create all items for the files in the subdirectory + // Create all items for the files in the subdirectory. if (display_mode == DISPLAY_MODE_TREE_ONLY) { for (int i = 0; i < p_dir->get_file_count(); i++) { String file_type = p_dir->get_file_type(i); if (_is_file_type_disabled_by_feature_profile(file_type)) { - //if type is disabled, file won't be displayed. + // If type is disabled, file won't be displayed. continue; } String file_name = p_dir->get_file(i); if (searched_string.length() > 0) { if (file_name.to_lower().find(searched_string) < 0) { - // The searched string is not in the file name, we skip it + // The searched string is not in the file name, we skip it. continue; } else { - // We expand all parents + // We expand all parents. parent_should_expand = true; } } @@ -135,7 +134,7 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory } Vector<String> FileSystemDock::_compute_uncollapsed_paths() { - // Register currently collapsed paths + // Register currently collapsed paths. Vector<String> uncollapsed_paths; TreeItem *root = tree->get_root(); if (root) { @@ -166,14 +165,13 @@ Vector<String> FileSystemDock::_compute_uncollapsed_paths() { } void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, bool p_uncollapse_root, bool p_select_in_favorites) { - - // Recreate the tree + // Recreate the tree. tree->clear(); tree_update_id++; updating_tree = true; TreeItem *root = tree->create_item(); - // Handles the favorites + // Handles the favorites. TreeItem *favorites = tree->create_item(root); favorites->set_icon(0, get_icon("Favorites", "EditorIcons")); favorites->set_text(0, TTR("Favorites:")); @@ -238,7 +236,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo uncollapsed_paths.push_back("res://"); } - // Create the remaining of the tree + // Create the remaining of the tree. _create_tree(root, EditorFileSystem::get_singleton()->get_filesystem(), uncollapsed_paths, p_select_in_favorites); tree->ensure_cursor_is_visible(); updating_tree = false; @@ -250,7 +248,7 @@ void FileSystemDock::set_display_mode(DisplayMode p_display_mode) { } void FileSystemDock::_update_display_mode(bool p_force) { - // Compute the new display mode + // Compute the new display mode. if (p_force || old_display_mode != display_mode) { button_toggle_display_mode->set_pressed(display_mode == DISPLAY_MODE_SPLIT); switch (display_mode) { @@ -283,11 +281,8 @@ void FileSystemDock::_update_display_mode(bool p_force) { } void FileSystemDock::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_ENTER_TREE: { - if (initialized) return; initialized = true; @@ -327,18 +322,15 @@ void FileSystemDock::_notification(int p_what) { } else { _update_tree(Vector<String>(), true); } - } break; + case NOTIFICATION_PROCESS: { if (EditorFileSystem::get_singleton()->is_scanning()) { scanning_progress->set_value(EditorFileSystem::get_singleton()->get_scanning_progress() * 100); } } break; - case NOTIFICATION_EXIT_TREE: { - } break; case NOTIFICATION_DRAG_BEGIN: { - Dictionary dd = get_viewport()->gui_get_drag_data(); if (tree->is_visible_in_tree() && dd.has("type")) { if ((String(dd["type"]) == "files") || (String(dd["type"]) == "files_and_dirs") || (String(dd["type"]) == "resource")) { @@ -347,20 +339,20 @@ void FileSystemDock::_notification(int p_what) { tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN); } } - } break; - case NOTIFICATION_DRAG_END: { + case NOTIFICATION_DRAG_END: { tree->set_drop_mode_flags(0); - } break; + case NOTIFICATION_THEME_CHANGED: { if (is_visible_in_tree()) { _update_display_mode(true); } } break; + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - // Update icons + // Update icons. String ei = "EditorIcons"; button_reload->set_icon(get_icon("Reload", ei)); button_toggle_display_mode->set_icon(get_icon("Panels2", ei)); @@ -377,48 +369,47 @@ void FileSystemDock::_notification(int p_what) { file_list_search_box->set_right_icon(get_icon("Search", ei)); file_list_search_box->set_clear_button_enabled(true); - // Update always showfolders + // Update always show folders. bool new_always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); if (new_always_show_folders != always_show_folders) { always_show_folders = new_always_show_folders; _update_file_list(true); } - // Change full tree mode + // Change full tree mode. _update_display_mode(); - } break; } } void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_selected) { - // Update the import dock + // Update the import dock. import_dock_needs_update = true; call_deferred("_update_import_dock"); - // Return if we don't select something new + // Return if we don't select something new. if (!p_selected) return; - // Tree item selected + // Tree item selected. TreeItem *selected = tree->get_selected(); if (!selected) return; TreeItem *favorites_item = tree->get_root()->get_children(); if (selected->get_parent() == favorites_item && !String(selected->get_metadata(0)).ends_with("/")) { - // Go to the favorites if we click in the favorites and the path has changed + // Go to the favorites if we click in the favorites and the path has changed. path = "Favorites"; } else { path = selected->get_metadata(0); - // Note: the "Favorites" item also leads to this path + // Note: the "Favorites" item also leads to this path. } - // Set the current path + // Set the current path. _set_current_path_text(path); _push_to_history(); - // Update the file list + // Update the file list. if (!updating_tree && display_mode == DISPLAY_MODE_SPLIT) { _update_file_list(false); } @@ -432,7 +423,6 @@ String FileSystemDock::get_selected_path() const { } String FileSystemDock::get_current_path() const { - return path; } @@ -491,7 +481,6 @@ void FileSystemDock::navigate_to_path(const String &p_path) { } void FileSystemDock::_file_list_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata) { - if ((file_list_vb->is_visible_in_tree() || path == p_path.get_base_dir()) && p_preview.is_valid()) { Array uarr = p_udata; int idx = uarr[0]; @@ -539,7 +528,6 @@ void FileSystemDock::_set_file_display(bool p_active) { } bool FileSystemDock::_is_file_type_disabled_by_feature_profile(const StringName &p_class) { - Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile(); if (profile.is_null()) { return false; @@ -559,7 +547,6 @@ bool FileSystemDock::_is_file_type_disabled_by_feature_profile(const StringName } void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> *matches, int p_max_items) { - if (matches->size() > p_max_items) return; @@ -577,10 +564,9 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> * fi.type = p_path->get_file_type(i); fi.path = p_path->get_file_path(i); fi.import_broken = !p_path->get_file_import_is_valid(i); - fi.import_status = 0; if (_is_file_type_disabled_by_feature_profile(fi.type)) { - //this type is disabled, will not appear here + // This type is disabled, will not appear here. continue; } @@ -592,8 +578,7 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> * } void FileSystemDock::_update_file_list(bool p_keep_selection) { - - // Register the previously selected items + // Register the previously selected items. Set<String> cselection; if (p_keep_selection) { for (int i = 0; i < files->get_item_count(); i++) { @@ -619,7 +604,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { bool use_thumbnails = (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS); if (use_thumbnails) { - // Thumbnails mode + // Thumbnails mode. files->set_max_columns(0); files->set_icon_mode(ItemList::ICON_MODE_TOP); files->set_fixed_column_width(thumbnail_size * 3 / 2); @@ -636,8 +621,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { file_thumbnail_broken = get_icon("FileDeadBigThumb", ei); } } else { - - // No thumbnails + // No thumbnails. files->set_icon_mode(ItemList::ICON_MODE_LEFT); files->set_max_columns(1); files->set_max_text_lines(1); @@ -648,10 +632,10 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { Ref<Texture> folder_icon = (use_thumbnails) ? folder_thumbnail : get_icon("folder", "FileDialog"); const Color folder_color = get_color("folder_icon_modulate", "FileDialog"); - // Build the FileInfo list + // Build the FileInfo list. List<FileInfo> filelist; if (path == "Favorites") { - // Display the favorites + // Display the favorites. Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < favorites.size(); i++) { String favorite = favorites[i]; @@ -685,7 +669,6 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { fi.type = ""; fi.import_broken = true; } - fi.import_status = 0; if (searched_string.length() == 0 || fi.name.to_lower().find(searched_string) >= 0) { filelist.push_back(fi); @@ -693,8 +676,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } } } else { - - // Get infos on the directory + file + // Get infos on the directory + file. if (directory.ends_with("/") && directory != "res://") { directory = directory.substr(0, directory.length() - 1); } @@ -708,13 +690,11 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { return; if (searched_string.length() > 0) { - // Display the search results + // Display the search results. _search(EditorFileSystem::get_singleton()->get_filesystem(), &filelist, 128); } else { - if (display_mode == DISPLAY_MODE_TREE_ONLY || always_show_folders) { - // Display folders in the list - + // Display folders in the list. if (directory != "res://") { files->add_item("..", folder_icon, true); @@ -728,7 +708,6 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } for (int i = 0; i < efd->get_subdir_count(); i++) { - String dname = efd->get_subdir(i)->get_name(); files->add_item(dname, folder_icon, true); @@ -741,15 +720,13 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } } - // Display the folder content + // Display the folder content. for (int i = 0; i < efd->get_file_count(); i++) { - FileInfo fi; fi.name = efd->get_file(i); fi.path = directory.plus_file(fi.name); fi.type = efd->get_file_type(i); fi.import_broken = !efd->get_file_import_is_valid(i); - fi.import_status = 0; filelist.push_back(fi); } @@ -757,7 +734,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { filelist.sort(); } - // Fills the ItemList control node from the FileInfos + // Fills the ItemList control node from the FileInfos. String oi = "Object"; for (List<FileInfo>::Element *E = filelist.front(); E; E = E->next()) { FileInfo *finfo = &(E->get()); @@ -770,7 +747,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { String tooltip = fpath; - // Select the icons + // Select the icons. if (!finfo->import_broken) { type_icon = (has_icon(ftype, ei)) ? get_icon(ftype, ei) : get_icon(oi, ei); big_icon = file_thumbnail; @@ -780,7 +757,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { tooltip += "\n" + TTR("Status: Import of file failed. Please fix file and reimport manually."); } - // Add the item to the ItemList + // Add the item to the ItemList. int item_index; if (use_thumbnails) { files->add_item(fname, big_icon, true); @@ -794,7 +771,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->set_item_metadata(item_index, fpath); } - // Generate the preview + // Generate the preview. if (!finfo->import_broken) { Array udata; udata.resize(2); @@ -803,7 +780,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { EditorResourcePreview::get_singleton()->queue_resource_preview(fpath, this, "_file_list_thumbnail_done", udata); } - // Select the items + // Select the items. if (cselection.has(fname)) files->select(item_index, false); @@ -812,7 +789,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->ensure_current_is_visible(); } - // Tooltip + // Tooltip. if (finfo->sources.size()) { for (int j = 0; j < finfo->sources.size(); j++) { tooltip += "\nSource: " + finfo->sources[j]; @@ -859,13 +836,12 @@ void FileSystemDock::_file_list_activate_file(int p_idx) { } void FileSystemDock::_preview_invalidated(const String &p_path) { - if (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS && p_path.get_base_dir() == path && searched_string.length() == 0 && file_list_vb->is_visible_in_tree()) { for (int i = 0; i < files->get_item_count(); i++) { if (files->get_item_metadata(i) == p_path) { - //re-request preview + // Re-request preview. Array udata; udata.resize(2); udata[0] = i; @@ -878,7 +854,6 @@ void FileSystemDock::_preview_invalidated(const String &p_path) { } void FileSystemDock::_fs_changed() { - button_hist_prev->set_disabled(history_pos == 0); button_hist_next->set_disabled(history_pos == history.size() - 1); scanning_vb->hide(); @@ -896,7 +871,6 @@ void FileSystemDock::_fs_changed() { } void FileSystemDock::_set_scanning_mode() { - button_hist_prev->set_disabled(true); button_hist_next->set_disabled(true); split_box->hide(); @@ -910,7 +884,6 @@ void FileSystemDock::_set_scanning_mode() { } void FileSystemDock::_fw_history() { - if (history_pos < history.size() - 1) history_pos++; @@ -988,7 +961,7 @@ void FileSystemDock::_find_remaps(EditorFileSystemDirectory *efsd, const Map<Str void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_new_path, Map<String, String> &p_file_renames, Map<String, String> &p_folder_renames) { - //Ensure folder paths end with "/" + // Ensure folder paths end with "/". String old_path = (p_item.is_file || p_item.path.ends_with("/")) ? p_item.path : (p_item.path + "/"); String new_path = (p_item.is_file || p_new_path.ends_with("/")) ? p_new_path : (p_new_path + "/"); @@ -998,12 +971,12 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ EditorNode::get_singleton()->add_io_error(TTR("Cannot move/rename resources root.")); return; } else if (!p_item.is_file && new_path.begins_with(old_path)) { - //This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/" + // This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/". EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.") + "\n" + old_path + "\n"); return; } - //Build a list of files which will have new paths as a result of this operation + // Build a list of files which will have new paths as a result of this operation. Vector<String> file_changed_paths; Vector<String> folder_changed_paths; if (p_item.is_file) { @@ -1017,8 +990,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ print_verbose("Moving " + old_path + " -> " + new_path); Error err = da->rename(old_path, new_path); if (err == OK) { - - //Move/Rename any corresponding import settings too + // Move/Rename any corresponding import settings too. if (p_item.is_file && FileAccess::exists(old_path + ".import")) { err = da->rename(old_path + ".import", new_path + ".import"); if (err != OK) { @@ -1026,7 +998,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ } } - // update scene if it is open + // Update scene if it is open. for (int i = 0; i < file_changed_paths.size(); ++i) { String new_item_path = p_item.is_file ? new_path : file_changed_paths[i].replace_first(old_path, new_path); if (ResourceLoader::get_resource_type(new_item_path) == "PackedScene" && editor->is_scene_open(file_changed_paths[i])) { @@ -1041,7 +1013,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ } } - //Only treat as a changed dependency if it was successfully moved + // Only treat as a changed dependency if it was successfully moved. for (int i = 0; i < file_changed_paths.size(); ++i) { p_file_renames[file_changed_paths[i]] = file_changed_paths[i].replace_first(old_path, new_path); print_verbose(" Remap: " + file_changed_paths[i] + " -> " + p_file_renames[file_changed_paths[i]]); @@ -1058,7 +1030,7 @@ void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_ } void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const { - //Ensure folder paths end with "/" + // Ensure folder paths end with "/". String old_path = (p_item.is_file || p_item.path.ends_with("/")) ? p_item.path : (p_item.path + "/"); String new_path = (p_item.is_file || p_new_path.ends_with("/")) ? p_new_path : (p_new_path + "/"); @@ -1068,7 +1040,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin EditorNode::get_singleton()->add_io_error(TTR("Cannot move/rename resources root.")); return; } else if (!p_item.is_file && new_path.begins_with(old_path)) { - //This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/" + // This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/". EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.") + "\n" + old_path + "\n"); return; } @@ -1077,7 +1049,7 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin print_verbose("Duplicating " + old_path + " -> " + new_path); Error err = p_item.is_file ? da->copy(old_path, new_path) : da->copy_dir(old_path, new_path); if (err == OK) { - //Move/Rename any corresponding import settings too + // Move/Rename any corresponding import settings too. if (p_item.is_file && FileAccess::exists(old_path + ".import")) { err = da->copy(old_path + ".import", new_path + ".import"); if (err != OK) { @@ -1091,13 +1063,11 @@ void FileSystemDock::_try_duplicate_item(const FileOrFolder &p_item, const Strin } void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> &p_renames) const { - - //Rename all resources loaded, be it subresources or actual resources + // Rename all resources loaded, be it subresources or actual resources. List<Ref<Resource> > cached; ResourceCache::get_cached_resources(&cached); for (List<Ref<Resource> >::Element *E = cached.front(); E; E = E->next()) { - Ref<Resource> r = E->get(); String base_path = r->get_path(); @@ -1116,7 +1086,6 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> } for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) { - String path; if (i == EditorNode::get_editor_data().get_edited_scene()) { if (!get_tree()->get_edited_scene_root()) @@ -1124,7 +1093,6 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> path = get_tree()->get_edited_scene_root()->get_filename(); } else { - path = EditorNode::get_editor_data().get_scene_path(i); } @@ -1133,23 +1101,21 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String> } if (i == EditorNode::get_editor_data().get_edited_scene()) { - get_tree()->get_edited_scene_root()->set_filename(path); } else { - EditorNode::get_editor_data().set_scene_path(i, path); } } } void FileSystemDock::_update_dependencies_after_move(const Map<String, String> &p_renames) const { - //The following code assumes that the following holds: + // The following code assumes that the following holds: // 1) EditorFileSystem contains the old paths/folder structure from before the rename/move. // 2) ResourceLoader can use the new paths without needing to call rescan. Vector<String> remaps; _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), p_renames, remaps); for (int i = 0; i < remaps.size(); ++i) { - //Because we haven't called a rescan yet the found remap might still be an old path itself. + // Because we haven't called a rescan yet the found remap might still be an old path itself. String file = p_renames.has(remaps[i]) ? p_renames[remaps[i]] : remaps[i]; print_verbose("Remapping dependencies for: " + file); Error err = ResourceLoader::rename_dependencies(file, p_renames); @@ -1163,8 +1129,7 @@ void FileSystemDock::_update_dependencies_after_move(const Map<String, String> & } void FileSystemDock::_update_project_settings_after_move(const Map<String, String> &p_renames) const { - - // Find all project settings of type FILE and replace them if needed + // Find all project settings of type FILE and replace them if needed. const Map<StringName, PropertyInfo> prop_info = ProjectSettings::get_singleton()->get_custom_property_info(); for (const Map<StringName, PropertyInfo>::Element *E = prop_info.front(); E; E = E->next()) { if (E->get().hint == PROPERTY_HINT_FILE) { @@ -1195,7 +1160,6 @@ void FileSystemDock::_update_project_settings_after_move(const Map<String, Strin } void FileSystemDock::_update_favorites_list_after_move(const Map<String, String> &p_files_renames, const Map<String, String> &p_folders_renames) const { - Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); Vector<String> new_favorites; @@ -1311,7 +1275,6 @@ void FileSystemDock::_folder_deleted(String p_folder) { } void FileSystemDock::_rename_operation_confirm() { - String new_name = rename_dialog_text->get_text().strip_edges(); if (new_name.length() == 0) { EditorNode::get_singleton()->show_warning(TTR("No name provided.")); @@ -1331,10 +1294,10 @@ void FileSystemDock::_rename_operation_confirm() { EditorFileSystem::get_singleton()->move_group_file(old_path, new_path); } - //Present a more user friendly warning for name conflict + // Present a more user friendly warning for name conflict. DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); #if defined(WINDOWS_ENABLED) || defined(UWP_ENABLED) - // Workaround case insensitivity on Windows + // Workaround case insensitivity on Windows. if ((da->file_exists(new_path) || da->dir_exists(new_path)) && new_path.to_lower() != old_path.to_lower()) { #else if (da->file_exists(new_path) || da->dir_exists(new_path)) { @@ -1366,7 +1329,6 @@ void FileSystemDock::_rename_operation_confirm() { } void FileSystemDock::_duplicate_operation_confirm() { - String new_name = duplicate_dialog_text->get_text().strip_edges(); if (new_name.length() == 0) { EditorNode::get_singleton()->show_warning(TTR("No name provided.")); @@ -1384,7 +1346,7 @@ void FileSystemDock::_duplicate_operation_confirm() { String new_path = base_dir.plus_file(new_name); - //Present a more user friendly warning for name conflict + // Present a more user friendly warning for name conflict DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (da->file_exists(new_path) || da->dir_exists(new_path)) { EditorNode::get_singleton()->show_warning(TTR("A file or folder with this name already exists.")); @@ -1395,7 +1357,7 @@ void FileSystemDock::_duplicate_operation_confirm() { _try_duplicate_item(to_duplicate, new_path); - //Rescan everything + // Rescan everything. print_verbose("FileSystem: calling rescan."); _rescan(); } @@ -1428,14 +1390,14 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw to_move_path = p_to_path; bool can_move = _check_existing(); if (!can_move) { - //ask to do something + // Ask to do something. overwrite_dialog->popup_centered_minsize(); overwrite_dialog->grab_focus(); return; } } - //check groups + // Check groups. for (int i = 0; i < to_move.size(); i++) { print_line("is group: " + to_move[i].path + ": " + itos(EditorFileSystem::get_singleton()->is_group_file(to_move[i].path))); @@ -1476,7 +1438,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw } Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) { - // Build a list of selected items with the active one at the first position + // Build a list of selected items with the active one at the first position. Vector<String> selected_strings; TreeItem *favorites_item = tree->get_root()->get_children(); @@ -1501,7 +1463,7 @@ Vector<String> FileSystemDock::_tree_get_selected(bool remove_self_inclusion) { } Vector<String> FileSystemDock::_remove_self_included_paths(Vector<String> selected_strings) { - // Remove paths or files that are included into another + // Remove paths or files that are included into another. if (selected_strings.size() > 1) { selected_strings.sort_custom<NaturalNoCaseComparator>(); String last_path = ""; @@ -1519,10 +1481,9 @@ Vector<String> FileSystemDock::_remove_self_included_paths(Vector<String> select } void FileSystemDock::_tree_rmb_option(int p_option) { - Vector<String> selected_strings = _tree_get_selected(false); - // Execute the current option + // Execute the current option. switch (p_option) { case FOLDER_EXPAND_ALL: case FOLDER_COLLAPSE_ALL: { @@ -1562,11 +1523,11 @@ void FileSystemDock::_file_list_rmb_option(int p_option) { } void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected) { - // The first one should be the active item + // The first one should be the active item. switch (p_option) { case FILE_SHOW_IN_EXPLORER: { - // Show the file / folder in the OS explorer + // Show the file/folder in the OS explorer. String fpath = path; if (path == "Favorites") { fpath = p_selected[0]; @@ -1580,7 +1541,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_OPEN: { - // Open folders + // Open folders. TreeItem *selected = tree->get_root(); selected = tree->get_next_selected(selected); while (selected) { @@ -1589,21 +1550,21 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } selected = tree->get_next_selected(selected); } - // Open the file + // Open the file. for (int i = 0; i < p_selected.size(); i++) { _select_file(p_selected[i]); } } break; case FILE_INHERIT: { - // Create a new scene inherited from the selected one + // Create a new scene inherited from the selected one. if (p_selected.size() == 1) { emit_signal("inherit", p_selected[0]); } } break; case FILE_INSTANCE: { - // Instance all selected scenes + // Instance all selected scenes. Vector<String> paths; for (int i = 0; i < p_selected.size(); i++) { String fpath = p_selected[i]; @@ -1617,7 +1578,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_ADD_FAVORITE: { - // Add the files from favorites + // Add the files from favorites. Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < p_selected.size(); i++) { if (favorites.find(p_selected[i]) == -1) { @@ -1629,7 +1590,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_REMOVE_FAVORITE: { - // Remove the files from favorites + // Remove the files from favorites. Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); for (int i = 0; i < p_selected.size(); i++) { favorites.erase(p_selected[i]); @@ -1641,7 +1602,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_DEPENDENCIES: { - // Checkout the file dependencies + // Checkout the file dependencies. if (!p_selected.empty()) { String fpath = p_selected[0]; deps_editor->edit(fpath); @@ -1649,7 +1610,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_OWNERS: { - // Checkout the file owners + // Checkout the file owners. if (!p_selected.empty()) { String fpath = p_selected[0]; owners_editor->show(fpath); @@ -1657,7 +1618,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_MOVE: { - // Move the files to a given location + // Move the files to a given location. to_move.clear(); Vector<String> collapsed_paths = _remove_self_included_paths(p_selected); for (int i = collapsed_paths.size() - 1; i >= 0; i--) { @@ -1672,7 +1633,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_RENAME: { - // Rename the active file + // Rename the active file. if (!p_selected.empty()) { to_rename.path = p_selected[0]; if (to_rename.path != "res://") { @@ -1695,7 +1656,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_REMOVE: { - // Remove the selected files + // Remove the selected files. Vector<String> remove_files; Vector<String> remove_folders; Vector<String> collapsed_paths = _remove_self_included_paths(p_selected); @@ -1717,7 +1678,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_DUPLICATE: { - // Duplicate the selected files + // Duplicate the selected files. for (int i = 0; i < p_selected.size(); i++) { to_duplicate.path = p_selected[i]; to_duplicate.is_file = !to_duplicate.path.ends_with("/"); @@ -1742,7 +1703,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_REIMPORT: { - // Reimport all selected files + // Reimport all selected files. Vector<String> reimport; for (int i = 0; i < p_selected.size(); i++) { reimport.push_back(p_selected[i]); @@ -1752,7 +1713,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_NEW_FOLDER: { - // Create a new folder make_dir_dialog_text->set_text("new folder"); make_dir_dialog_text->select_all(); make_dir_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); @@ -1767,7 +1727,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_NEW_SCRIPT: { - // Create a new script String fpath = path; if (!fpath.ends_with("/")) { fpath = fpath.get_base_dir(); @@ -1777,7 +1736,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_COPY_PATH: { - // Copy the file path if (!p_selected.empty()) { String fpath = p_selected[0]; OS::get_singleton()->set_clipboard(fpath); @@ -1785,7 +1743,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } break; case FILE_NEW_RESOURCE: { - // Create a new resource new_resource_dialog->popup_create(true); } break; } @@ -1813,7 +1770,7 @@ void FileSystemDock::_resource_created() const { void FileSystemDock::_search_changed(const String &p_text, const Control *p_from) { if (searched_string.length() == 0 && p_text.length() > 0) { - // Register the uncollapsed paths before they change + // Register the uncollapsed paths before they change. uncollapsed_paths_before_search = _compute_uncollapsed_paths(); } @@ -1821,7 +1778,7 @@ void FileSystemDock::_search_changed(const String &p_text, const Control *p_from if (p_from == tree_search_box) file_list_search_box->set_text(searched_string); - else // file_list_search_box + else // File_list_search_box. tree_search_box->set_text(searched_string); switch (display_mode) { @@ -1836,7 +1793,6 @@ void FileSystemDock::_search_changed(const String &p_text, const Control *p_from } void FileSystemDock::_rescan() { - _set_scanning_mode(); EditorFileSystem::get_singleton()->scan(); } @@ -1851,12 +1807,10 @@ void FileSystemDock::fix_dependencies(const String &p_for_file) { } void FileSystemDock::focus_on_filter() { - file_list_search_box->grab_focus(); } void FileSystemDock::set_file_list_display_mode(FileListDisplayMode p_mode) { - if (p_mode == file_list_display_mode) return; @@ -1870,12 +1824,12 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from) Vector<String> paths; if (p_from == tree) { - // Check if the first selected is in favorite + // Check if the first selected is in favorite. TreeItem *selected = tree->get_next_selected(tree->get_root()); while (selected) { TreeItem *favorites_item = tree->get_root()->get_children(); if (selected == favorites_item) { - // The "Favorites" item is not draggable + // The "Favorites" item is not draggable. return Variant(); } @@ -1913,12 +1867,11 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from) } bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { - Dictionary drag_data = p_data; if (drag_data.has("type") && String(drag_data["type"]) == "favorite") { - // Moving favorite around + // Moving favorite around. TreeItem *ti = tree->get_item_at_position(p_point); if (!ti) return false; @@ -1929,20 +1882,20 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da TreeItem *resources_item = favorites_item->get_next(); if (ti == favorites_item) { - return (drop_section == 1); // The parent, first fav + return (drop_section == 1); // The parent, first fav. } if (ti->get_parent() && favorites_item == ti->get_parent()) { return true; // A favorite } if (ti == resources_item) { - return (drop_section == -1); // The tree, last fav + return (drop_section == -1); // The tree, last fav. } return false; } if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - // Move resources + // Move resources. String to_dir; bool favorite; _get_drag_target_folder(to_dir, favorite, p_point, p_from); @@ -1950,7 +1903,7 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da } if (drag_data.has("type") && (String(drag_data["type"]) == "files" || String(drag_data["type"]) == "files_and_dirs")) { - // Move files or dir + // Move files or dir. String to_dir; bool favorite; _get_drag_target_folder(to_dir, favorite, p_point, p_from); @@ -1961,8 +1914,8 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da if (to_dir.empty()) return false; - //Attempting to move a folder into itself will fail later - //Rather than bring up a message don't try to do it in the first place + // Attempting to move a folder into itself will fail later, + // rather than bring up a message don't try to do it in the first place to_dir = to_dir.ends_with("/") ? to_dir : (to_dir + "/"); Vector<String> fnames = drag_data["files"]; for (int i = 0; i < fnames.size(); ++i) { @@ -1977,7 +1930,6 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da } void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { - if (!can_drop_data_fw(p_point, p_data, p_from)) return; Dictionary drag_data = p_data; @@ -1985,7 +1937,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, Vector<String> dirs = EditorSettings::get_singleton()->get_favorites(); if (drag_data.has("type") && String(drag_data["type"]) == "favorite") { - // Moving favorite around + // Moving favorite around. TreeItem *ti = tree->get_item_at_position(p_point); if (!ti) return; @@ -1997,20 +1949,20 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, TreeItem *resources_item = favorites_item->get_next(); if (ti == favorites_item) { - // Drop on the favorite folder + // Drop on the favorite folder. drop_position = 0; } else if (ti == resources_item) { - // Drop on the resource item + // Drop on the resource item. drop_position = dirs.size(); } else { - // Drop in the list + // Drop in the list. drop_position = dirs.find(ti->get_metadata(0)); if (drop_section == 1) { drop_position++; } } - // Remove dragged favorites + // Remove dragged favorites. Vector<int> to_remove; int offset = 0; for (int i = 0; i < files.size(); i++) { @@ -2026,7 +1978,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, dirs.remove(to_remove[i] - i); } - // Re-add them at the right position + // Re-add them at the right position. for (int i = 0; i < files.size(); i++) { dirs.insert(drop_position, files[i]); drop_position++; @@ -2041,7 +1993,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } if (drag_data.has("type") && String(drag_data["type"]) == "resource") { - // Moving resource + // Moving resource. Ref<Resource> res = drag_data["resource"]; String to_dir; bool favorite; @@ -2053,7 +2005,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } if (drag_data.has("type") && (String(drag_data["type"]) == "files" || String(drag_data["type"]) == "files_and_dirs")) { - // Move files or add to favorites + // Move files or add to favorites. String to_dir; bool favorite; _get_drag_target_folder(to_dir, favorite, p_point, p_from); @@ -2083,7 +2035,7 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori target = String(); target_favorites = false; - // In the file list + // In the file list. if (p_from == files) { int pos = files->get_item_at_position(p_point, true); if (pos == -1) { @@ -2095,12 +2047,12 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori return; } - // In the tree + // In the tree. if (p_from == tree) { TreeItem *ti = tree->get_item_at_position(p_point); int section = tree->get_drop_section_at_position(p_point); if (ti) { - // Check the favorites first + // Check the favorites first. if (ti == tree->get_root()->get_children() && section >= 0) { target_favorites = true; return; @@ -2111,13 +2063,13 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori String fpath = ti->get_metadata(0); if (section == 0) { if (fpath.ends_with("/")) { - // We drop on a folder + // We drop on a folder. target = fpath; return; } } else { if (ti->get_parent() != tree->get_root()->get_children()) { - // Not in the favorite section + // Not in the favorite section. if (fpath != "res://") { // We drop between two files if (fpath.ends_with("/")) { @@ -2134,7 +2086,7 @@ void FileSystemDock::_get_drag_target_folder(String &target, bool &target_favori } void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<String> p_paths, bool p_display_path_dependent_options) { - // Add options for files and folders + // Add options for files and folders. ERR_FAIL_COND(p_paths.empty()); Vector<String> filenames; @@ -2158,7 +2110,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str all_files_scenes &= (EditorFileSystem::get_singleton()->get_file_type(fpath) == "PackedScene"); } - // Check if in favorites + // Check if in favorites. bool found = false; for (int j = 0; j < favorites.size(); j++) { if (favorites[j] == fpath) { @@ -2174,7 +2126,6 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str } if (all_files) { - if (all_files_scenes) { if (filenames.size() == 1) { p_popup->add_item(TTR("Open Scene"), FILE_OPEN); @@ -2232,6 +2183,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str p_popup->add_item(TTR("New Scene..."), FILE_NEW_SCENE); p_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT); p_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE); + p_popup->add_separator(); } String fpath = p_paths[0]; @@ -2241,7 +2193,7 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str } void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) { - // Right click is pressed in the tree + // Right click is pressed in the tree. Vector<String> paths = _tree_get_selected(false); if (paths.size() == 1) { @@ -2252,7 +2204,7 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) { } } - // Popup + // Popup. if (!paths.empty()) { tree_popup->clear(); tree_popup->set_size(Size2(1, 1)); @@ -2263,7 +2215,7 @@ void FileSystemDock::_tree_rmb_select(const Vector2 &p_pos) { } void FileSystemDock::_tree_rmb_empty(const Vector2 &p_pos) { - // Right click is pressed in the empty space of the tree + // Right click is pressed in the empty space of the tree. path = "res://"; tree_popup->clear(); tree_popup->set_size(Size2(1, 1)); @@ -2280,7 +2232,7 @@ void FileSystemDock::_tree_empty_selected() { } void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) { - // Right click is pressed in the file list + // Right click is pressed in the file list. Vector<String> paths; for (int i = 0; i < files->get_item_count(); i++) { if (!files->is_selected(i)) @@ -2292,7 +2244,7 @@ void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) { paths.push_back(files->get_item_metadata(i)); } - // Popup + // Popup. if (!paths.empty()) { file_list_popup->clear(); file_list_popup->set_size(Size2(1, 1)); @@ -2303,7 +2255,7 @@ void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) { } void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) { - // Right click on empty space for file list + // Right click on empty space for file list. if (searched_string.length() > 0) return; @@ -2314,19 +2266,18 @@ void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) { file_list_popup->add_item(TTR("New Scene..."), FILE_NEW_SCENE); file_list_popup->add_item(TTR("New Script..."), FILE_NEW_SCRIPT); file_list_popup->add_item(TTR("New Resource..."), FILE_NEW_RESOURCE); - file_list_popup->add_item(TTR("Show in File Manager"), FILE_SHOW_IN_EXPLORER); + file_list_popup->add_separator(); + file_list_popup->add_item(TTR("Open in File Manager"), FILE_SHOW_IN_EXPLORER); file_list_popup->set_position(files->get_global_position() + p_pos); file_list_popup->popup(); } void FileSystemDock::select_file(const String &p_file) { - _navigate_to_path(p_file); } void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) { - - // Set the path to the current focused item + // Set the path to the current focused item. int current = files->get_current(); if (current == p_index) { String fpath = files->get_item_metadata(current); @@ -2338,15 +2289,14 @@ void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) { } } - // Update the import dock + // Update the import dock. import_dock_needs_update = true; call_deferred("_update_import_dock"); } void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) { - if (get_viewport()->get_modal_stack_top()) - return; //ignore because of modal window + return; // Ignore because of modal window. Ref<InputEventKey> key = p_event; if (key.is_valid() && key->is_pressed() && !key->is_echo()) { @@ -2363,9 +2313,8 @@ void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) { } void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) { - if (get_viewport()->get_modal_stack_top()) - return; //ignore because of modal window + return; // Ignore because of modal window. Ref<InputEventKey> key = p_event; if (key.is_valid() && key->is_pressed() && !key->is_echo()) { @@ -2382,18 +2331,17 @@ void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) { } void FileSystemDock::_update_import_dock() { - if (!import_dock_needs_update) return; - // List selected + // List selected. Vector<String> selected; if (display_mode == DISPLAY_MODE_TREE_ONLY) { // Use the tree selected = _tree_get_selected(); } else { - // Use the file list + // Use the file list. for (int i = 0; i < files->get_item_count(); i++) { if (!files->is_selected(i)) continue; @@ -2402,7 +2350,7 @@ void FileSystemDock::_update_import_dock() { } } - // Check import + // Check import. Vector<String> imports; String import_type; for (int i = 0; i < selected.size(); i++) { @@ -2429,7 +2377,7 @@ void FileSystemDock::_update_import_dock() { if (import_type == "") { import_type = type; } else if (import_type != type) { - //all should be the same type + // All should be the same type. imports.clear(); break; } @@ -2448,12 +2396,10 @@ void FileSystemDock::_update_import_dock() { } void FileSystemDock::_feature_profile_changed() { - _update_display_mode(true); } void FileSystemDock::_bind_methods() { - ClassDB::bind_method(D_METHOD("_file_list_gui_input"), &FileSystemDock::_file_list_gui_input); ClassDB::bind_method(D_METHOD("_tree_gui_input"), &FileSystemDock::_tree_gui_input); @@ -2518,7 +2464,6 @@ void FileSystemDock::_bind_methods() { } FileSystemDock::FileSystemDock(EditorNode *p_editor) { - set_name("FileSystem"); editor = p_editor; path = "res://"; @@ -2599,7 +2544,6 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { tree->set_custom_minimum_size(Size2(0, 15 * EDSCALE)); split_box->add_child(tree); - tree->connect("item_edited", this, "_favorite_toggled"); tree->connect("item_activated", this, "_tree_activate_file"); tree->connect("multi_selected", this, "_tree_multi_selected"); tree->connect("item_rmb_selected", this, "_tree_rmb_select"); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 561a4eba81..49eb31e330 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -171,7 +171,7 @@ private: bool updating_tree; int tree_update_id; - Tree *tree; //directories + Tree *tree; ItemList *files; bool import_dock_needs_update; @@ -250,7 +250,6 @@ private: String name; String path; StringName type; - int import_status; //0 not imported, 1 - ok, 2- must reimport, 3- broken Vector<String> sources; bool import_broken; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 5942e8e5f2..785a1c107a 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -174,15 +174,6 @@ public: } }; -void CanvasItemEditor::_snap_if_closer_float(float p_value, float p_target_snap, float &r_current_snap, bool &r_snapped, float p_radius) { - float radius = p_radius / zoom; - float dist = Math::abs(p_value - p_target_snap); - if ((p_radius < 0 || dist < radius) && (!r_snapped || dist < Math::abs(r_current_snap - p_value))) { - r_current_snap = p_target_snap; - r_snapped = true; - } -} - bool CanvasItemEditor::_is_node_locked(const Node *p_node) { return p_node->has_meta("_edit_lock_") && p_node->get_meta("_edit_lock_"); } @@ -200,108 +191,174 @@ bool CanvasItemEditor::_is_node_movable(const Node *p_node, bool p_popup_warning return true; } -void CanvasItemEditor::_snap_if_closer_point(Point2 p_value, Point2 p_target_snap, Point2 &r_current_snap, bool (&r_snapped)[2], real_t rotation, float p_radius) { +void CanvasItemEditor::_snap_if_closer_float( + float p_value, + float &r_current_snap, SnapTarget &r_current_snap_target, + float p_target_value, SnapTarget p_snap_target, + float p_radius) { + + float radius = p_radius / zoom; + float dist = Math::abs(p_value - p_target_value); + if ((p_radius < 0 || dist < radius) && (r_current_snap_target == SNAP_TARGET_NONE || dist < Math::abs(r_current_snap - p_value))) { + r_current_snap = p_target_value; + r_current_snap_target = p_snap_target; + } +} + +void CanvasItemEditor::_snap_if_closer_point( + Point2 p_value, + Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2], + Point2 p_target_value, SnapTarget p_snap_target, + real_t rotation, + float p_radius) { + Transform2D rot_trans = Transform2D(rotation, Point2()); p_value = rot_trans.inverse().xform(p_value); - p_target_snap = rot_trans.inverse().xform(p_target_snap); + p_target_value = rot_trans.inverse().xform(p_target_value); r_current_snap = rot_trans.inverse().xform(r_current_snap); - _snap_if_closer_float(p_value.x, p_target_snap.x, r_current_snap.x, r_snapped[0], p_radius); - _snap_if_closer_float(p_value.y, p_target_snap.y, r_current_snap.y, r_snapped[1], p_radius); + _snap_if_closer_float( + p_value.x, + r_current_snap.x, + r_current_snap_target[0], + p_target_value.x, + p_snap_target, + p_radius); + + _snap_if_closer_float( + p_value.y, + r_current_snap.y, + r_current_snap_target[1], + p_target_value.y, + p_snap_target, + p_radius); r_current_snap = rot_trans.xform(r_current_snap); } -void CanvasItemEditor::_snap_other_nodes(Point2 p_value, Point2 &r_current_snap, bool (&r_snapped)[2], const Node *p_current, const CanvasItem *p_to_snap) { +void CanvasItemEditor::_snap_other_nodes( + const Point2 p_value, + const Transform2D p_transform_to_snap, + Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2], + const SnapTarget p_snap_target, List<const CanvasItem *> p_exceptions, + const Node *p_current) { const CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_current); - if (canvas_item && (!p_to_snap || p_current != p_to_snap)) { + + // Check if the element is in the exception + bool exception = false; + for (List<const CanvasItem *>::Element *E = p_exceptions.front(); E; E = E->next()) { + if (E->get() == p_current) { + exception = true; + break; + } + }; + + if (canvas_item && !exception) { Transform2D ci_transform = canvas_item->get_global_transform_with_canvas(); - Transform2D to_snap_transform = p_to_snap ? p_to_snap->get_global_transform_with_canvas() : Transform2D(); - if (fmod(ci_transform.get_rotation() - to_snap_transform.get_rotation(), (real_t)360.0) == 0.0) { + if (fmod(ci_transform.get_rotation() - p_transform_to_snap.get_rotation(), (real_t)360.0) == 0.0) { if (canvas_item->_edit_use_rect()) { Point2 begin = ci_transform.xform(canvas_item->_edit_get_rect().get_position()); Point2 end = ci_transform.xform(canvas_item->_edit_get_rect().get_position() + canvas_item->_edit_get_rect().get_size()); - _snap_if_closer_point(p_value, begin, r_current_snap, r_snapped, ci_transform.get_rotation()); - _snap_if_closer_point(p_value, end, r_current_snap, r_snapped, ci_transform.get_rotation()); + + _snap_if_closer_point(p_value, r_current_snap, r_current_snap_target, begin, p_snap_target, ci_transform.get_rotation()); + _snap_if_closer_point(p_value, r_current_snap, r_current_snap_target, end, p_snap_target, ci_transform.get_rotation()); } else { Point2 position = ci_transform.xform(Point2()); - _snap_if_closer_point(p_value, position, r_current_snap, r_snapped, ci_transform.get_rotation()); + _snap_if_closer_point(p_value, r_current_snap, r_current_snap_target, position, p_snap_target, ci_transform.get_rotation()); } } } for (int i = 0; i < p_current->get_child_count(); i++) { - _snap_other_nodes(p_value, r_current_snap, r_snapped, p_current->get_child(i), p_to_snap); + _snap_other_nodes(p_value, p_transform_to_snap, r_current_snap, r_current_snap_target, p_snap_target, p_exceptions, p_current->get_child(i)); } } -Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const CanvasItem *p_canvas_item, unsigned int p_forced_modes) { - bool snapped[2] = { false, false }; +Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsigned int p_forced_modes, const CanvasItem *p_self_canvas_item, List<CanvasItem *> p_other_nodes_exceptions) { + + snap_target[0] = SNAP_TARGET_NONE; + snap_target[1] = SNAP_TARGET_NONE; + bool is_snap_active = snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL); // Smart snap using the canvas position Vector2 output = p_target; real_t rotation = 0.0; - if (p_canvas_item) { - rotation = p_canvas_item->get_global_transform_with_canvas().get_rotation(); + if (p_self_canvas_item) { + rotation = p_self_canvas_item->get_global_transform_with_canvas().get_rotation(); // Parent sides and center if ((is_snap_active && snap_node_parent && (p_modes & SNAP_NODE_PARENT)) || (p_forced_modes & SNAP_NODE_PARENT)) { - if (const Control *c = Object::cast_to<Control>(p_canvas_item)) { - Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(0, 0))); - Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(1, 1))); - _snap_if_closer_point(p_target, begin, output, snapped, rotation); - _snap_if_closer_point(p_target, (begin + end) / 2.0, output, snapped, rotation); - _snap_if_closer_point(p_target, end, output, snapped, rotation); - } else if (const CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_canvas_item->get_parent())) { + if (const Control *c = Object::cast_to<Control>(p_self_canvas_item)) { + Point2 begin = p_self_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(0, 0))); + Point2 end = p_self_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(1, 1))); + _snap_if_closer_point(p_target, output, snap_target, begin, SNAP_TARGET_PARENT, rotation); + _snap_if_closer_point(p_target, output, snap_target, (begin + end) / 2.0, SNAP_TARGET_PARENT, rotation); + _snap_if_closer_point(p_target, output, snap_target, end, SNAP_TARGET_PARENT, rotation); + } else if (const CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_self_canvas_item->get_parent())) { if (parent_ci->_edit_use_rect()) { - Point2 begin = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position()); - Point2 end = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position() + parent_ci->_edit_get_rect().get_size()); - _snap_if_closer_point(p_target, begin, output, snapped, rotation); - _snap_if_closer_point(p_target, (begin + end) / 2.0, output, snapped, rotation); - _snap_if_closer_point(p_target, end, output, snapped, rotation); + Point2 begin = p_self_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position()); + Point2 end = p_self_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position() + parent_ci->_edit_get_rect().get_size()); + _snap_if_closer_point(p_target, output, snap_target, begin, SNAP_TARGET_PARENT, rotation); + _snap_if_closer_point(p_target, output, snap_target, (begin + end) / 2.0, SNAP_TARGET_PARENT, rotation); + _snap_if_closer_point(p_target, output, snap_target, end, SNAP_TARGET_PARENT, rotation); } else { - Point2 position = p_canvas_item->get_transform().affine_inverse().xform(Point2()); - _snap_if_closer_point(p_target, position, output, snapped, rotation); + Point2 position = p_self_canvas_item->get_transform().affine_inverse().xform(Point2()); + _snap_if_closer_point(p_target, output, snap_target, position, SNAP_TARGET_PARENT, rotation); } } } // Self anchors if ((is_snap_active && snap_node_anchors && (p_modes & SNAP_NODE_ANCHORS)) || (p_forced_modes & SNAP_NODE_ANCHORS)) { - if (const Control *c = Object::cast_to<Control>(p_canvas_item)) { - Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_LEFT), c->get_anchor(MARGIN_TOP)))); - Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_RIGHT), c->get_anchor(MARGIN_BOTTOM)))); - _snap_if_closer_point(p_target, begin, output, snapped, rotation); - _snap_if_closer_point(p_target, end, output, snapped, rotation); + if (const Control *c = Object::cast_to<Control>(p_self_canvas_item)) { + Point2 begin = p_self_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_LEFT), c->get_anchor(MARGIN_TOP)))); + Point2 end = p_self_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(c->get_anchor(MARGIN_RIGHT), c->get_anchor(MARGIN_BOTTOM)))); + _snap_if_closer_point(p_target, output, snap_target, begin, SNAP_TARGET_SELF_ANCHORS, rotation); + _snap_if_closer_point(p_target, output, snap_target, end, SNAP_TARGET_SELF_ANCHORS, rotation); } } // Self sides if ((is_snap_active && snap_node_sides && (p_modes & SNAP_NODE_SIDES)) || (p_forced_modes & SNAP_NODE_SIDES)) { - if (p_canvas_item->_edit_use_rect()) { - Point2 begin = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position()); - Point2 end = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size()); - _snap_if_closer_point(p_target, begin, output, snapped, rotation); - _snap_if_closer_point(p_target, end, output, snapped, rotation); + if (p_self_canvas_item->_edit_use_rect()) { + Point2 begin = p_self_canvas_item->get_global_transform_with_canvas().xform(p_self_canvas_item->_edit_get_rect().get_position()); + Point2 end = p_self_canvas_item->get_global_transform_with_canvas().xform(p_self_canvas_item->_edit_get_rect().get_position() + p_self_canvas_item->_edit_get_rect().get_size()); + _snap_if_closer_point(p_target, output, snap_target, begin, SNAP_TARGET_SELF, rotation); + _snap_if_closer_point(p_target, output, snap_target, end, SNAP_TARGET_SELF, rotation); } } // Self center if ((is_snap_active && snap_node_center && (p_modes & SNAP_NODE_CENTER)) || (p_forced_modes & SNAP_NODE_CENTER)) { - if (p_canvas_item->_edit_use_rect()) { - Point2 center = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size() / 2.0); - _snap_if_closer_point(p_target, center, output, snapped, rotation); + if (p_self_canvas_item->_edit_use_rect()) { + Point2 center = p_self_canvas_item->get_global_transform_with_canvas().xform(p_self_canvas_item->_edit_get_rect().get_position() + p_self_canvas_item->_edit_get_rect().get_size() / 2.0); + _snap_if_closer_point(p_target, output, snap_target, center, SNAP_TARGET_SELF, rotation); } else { - Point2 position = p_canvas_item->get_global_transform_with_canvas().xform(Point2()); - _snap_if_closer_point(p_target, position, output, snapped, rotation); + Point2 position = p_self_canvas_item->get_global_transform_with_canvas().xform(Point2()); + _snap_if_closer_point(p_target, output, snap_target, position, SNAP_TARGET_SELF, rotation); } } } // Other nodes sides if ((is_snap_active && snap_other_nodes && (p_modes & SNAP_OTHER_NODES)) || (p_forced_modes & SNAP_OTHER_NODES)) { - _snap_other_nodes(p_target, output, snapped, get_tree()->get_edited_scene_root(), p_canvas_item); + Transform2D to_snap_transform = Transform2D(); + List<const CanvasItem *> exceptions = List<const CanvasItem *>(); + for (List<CanvasItem *>::Element *E = p_other_nodes_exceptions.front(); E; E = E->next()) { + exceptions.push_back(E->get()); + } + if (p_self_canvas_item) { + exceptions.push_back(p_self_canvas_item); + to_snap_transform = p_self_canvas_item->get_global_transform_with_canvas(); + } + + _snap_other_nodes( + p_target, to_snap_transform, + output, snap_target, + SNAP_TARGET_OTHER_NODE, + exceptions, + get_tree()->get_edited_scene_root()); } if (((is_snap_active && snap_guides && (p_modes & SNAP_GUIDES)) || (p_forced_modes & SNAP_GUIDES)) && fmod(rotation, (real_t)360.0) == 0.0) { @@ -309,14 +366,14 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) { Array vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_"); for (int i = 0; i < vguides.size(); i++) { - _snap_if_closer_float(p_target.x, vguides[i], output.x, snapped[0]); + _snap_if_closer_float(p_target.x, output.x, snap_target[0], vguides[i], SNAP_TARGET_GUIDE); } } if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) { Array hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_"); for (int i = 0; i < hguides.size(); i++) { - _snap_if_closer_float(p_target.y, hguides[i], output.y, snapped[1]); + _snap_if_closer_float(p_target.y, output.y, snap_target[1], hguides[i], SNAP_TARGET_GUIDE); } } } @@ -335,7 +392,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const Point2 grid_output; grid_output.x = Math::stepify(p_target.x - offset.x, grid_step.x * Math::pow(2.0, grid_step_multiplier)) + offset.x; grid_output.y = Math::stepify(p_target.y - offset.y, grid_step.y * Math::pow(2.0, grid_step_multiplier)) + offset.y; - _snap_if_closer_point(p_target, grid_output, output, snapped, 0.0, -1.0); + _snap_if_closer_point(p_target, output, snap_target, grid_output, SNAP_TARGET_GRID, 0.0, -1.0); } if (((snap_pixel && (p_modes & SNAP_PIXEL)) || (p_forced_modes & SNAP_PIXEL)) && rotation == 0.0) { @@ -343,6 +400,8 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const output = output.snapped(Size2(1, 1)); } + snap_transform = Transform2D(rotation, output); + return output; } @@ -1205,10 +1264,11 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { if (drag_selection.size() > 0) { drag_from = transform.affine_inverse().xform((b.is_valid()) ? b->get_position() : viewport->get_local_mouse_position()); Vector2 new_pos; - if (drag_selection.size() == 1) - new_pos = snap_point(drag_from, SNAP_NODE_SIDES | SNAP_NODE_CENTER | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, drag_selection[0]); - else - new_pos = snap_point(drag_from, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL); + if (drag_selection.size() == 1) { + new_pos = snap_point(drag_from, SNAP_NODE_SIDES | SNAP_NODE_CENTER | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, drag_selection[0]); + } else { + new_pos = snap_point(drag_from, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, NULL, drag_selection); + } for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { CanvasItem *canvas_item = E->get(); canvas_item->_edit_set_pivot(canvas_item->get_global_transform_with_canvas().affine_inverse().xform(new_pos)); @@ -1228,7 +1288,7 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { _restore_canvas_item_state(drag_selection); Vector2 new_pos; if (drag_selection.size() == 1) - new_pos = snap_point(drag_to, SNAP_NODE_SIDES | SNAP_NODE_CENTER | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, drag_selection[0]); + new_pos = snap_point(drag_to, SNAP_NODE_SIDES | SNAP_NODE_CENTER | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, drag_selection[0]); else new_pos = snap_point(drag_to, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL); for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) { @@ -1478,7 +1538,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) { previous_anchor.y = (drag_type == DRAG_ANCHOR_TOP_LEFT || drag_type == DRAG_ANCHOR_TOP_RIGHT) ? control->get_anchor(MARGIN_TOP) : control->get_anchor(MARGIN_BOTTOM); previous_anchor = xform.affine_inverse().xform(_anchor_to_position(control, previous_anchor)); - Vector2 new_anchor = xform.xform(snap_point(previous_anchor + (drag_to - drag_from), SNAP_GRID | SNAP_OTHER_NODES, control, SNAP_NODE_PARENT | SNAP_NODE_SIDES | SNAP_NODE_CENTER)); + Vector2 new_anchor = xform.xform(snap_point(previous_anchor + (drag_to - drag_from), SNAP_GRID | SNAP_OTHER_NODES, SNAP_NODE_PARENT | SNAP_NODE_SIDES | SNAP_NODE_CENTER, control)); new_anchor = _position_to_anchor(control, new_anchor).snapped(Vector2(0.001, 0.001)); bool use_single_axis = m->get_shift(); @@ -1624,8 +1684,8 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { Transform2D xform = canvas_item->get_global_transform_with_canvas().affine_inverse(); - Point2 drag_to_snapped_begin = snap_point(xform.affine_inverse().xform(current_begin) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, canvas_item); - Point2 drag_to_snapped_end = snap_point(xform.affine_inverse().xform(current_end) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, canvas_item); + Point2 drag_to_snapped_begin = snap_point(xform.affine_inverse().xform(current_begin) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); + Point2 drag_to_snapped_end = snap_point(xform.affine_inverse().xform(current_end) + (drag_to - drag_from), SNAP_NODE_ANCHORS | SNAP_NODE_PARENT | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, canvas_item); Point2 drag_begin = xform.xform(drag_to_snapped_begin); Point2 drag_end = xform.xform(drag_to_snapped_end); @@ -1866,7 +1926,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } else { previous_pos = _get_encompassing_rect_from_list(drag_selection).position; } - Point2 new_pos = snap_point(previous_pos + (drag_to - drag_from), SNAP_GRID | SNAP_GUIDES | SNAP_PIXEL | SNAP_NODE_PARENT | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES); + Point2 new_pos = snap_point(previous_pos + (drag_to - drag_from), SNAP_GRID | SNAP_GUIDES | SNAP_PIXEL | SNAP_NODE_PARENT | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES, 0, NULL, drag_selection); bool single_axis = m->get_shift(); if (single_axis) { if (ABS(new_pos.x - previous_pos.x) > ABS(new_pos.y - previous_pos.y)) { @@ -2421,6 +2481,20 @@ void CanvasItemEditor::_draw_guides() { } } +void CanvasItemEditor::_draw_smart_snapping() { + Color line_color = EditorSettings::get_singleton()->get("editors/2d/smart_snapping_line_color"); + if (snap_target[0] != SNAP_TARGET_NONE && snap_target[0] != SNAP_TARGET_GRID) { + viewport->draw_set_transform_matrix(viewport->get_transform() * transform * snap_transform); + viewport->draw_line(Point2(0, -1.0e+10F), Point2(0, 1.0e+10F), line_color); + viewport->draw_set_transform_matrix(viewport->get_transform()); + } + if (snap_target[1] != SNAP_TARGET_NONE && snap_target[1] != SNAP_TARGET_GRID) { + viewport->draw_set_transform_matrix(viewport->get_transform() * transform * snap_transform); + viewport->draw_line(Point2(-1.0e+10F, 0), Point2(1.0e+10F, 0), line_color); + viewport->draw_set_transform_matrix(viewport->get_transform()); + } +} + void CanvasItemEditor::_draw_rulers() { Color bg_color = get_color("dark_color_2", "Editor"); Color graduation_color = get_color("font_color", "Editor").linear_interpolate(bg_color, 0.5); @@ -2505,6 +2579,8 @@ void CanvasItemEditor::_draw_rulers() { } } } + + // Draw the top left corner viewport->draw_rect(Rect2(Point2(), Size2(RULER_WIDTH, RULER_WIDTH)), graduation_color); } @@ -2623,7 +2699,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) { if (dragged_anchor >= 0) { // Draw the 4 lines when dragged - bool snapped; + bool anchor_snapped; Color color_snapped = Color(0.64, 0.93, 0.67, 0.5); Vector2 corners_pos[4]; @@ -2637,14 +2713,8 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) { float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i]; line_starts[i] = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val); line_ends[i] = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val); - snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0; - int line_width; - if (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) { - line_width = 2; - } else { - line_width = 1; - } - viewport->draw_line(line_starts[i], line_ends[i], snapped ? color_snapped : color_base, Math::round(line_width * EDSCALE)); + anchor_snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0; + viewport->draw_line(line_starts[i], line_ends[i], anchor_snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1); } // Display the percentages next to the lines @@ -3312,6 +3382,7 @@ void CanvasItemEditor::_draw_viewport() { _draw_rulers(); if (show_guides) _draw_guides(); + _draw_smart_snapping(); _draw_focus(); _draw_hover(); } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 08c71c94f4..a16d07599a 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -86,6 +86,17 @@ public: private: EditorNode *editor; + enum SnapTarget { + SNAP_TARGET_NONE = 0, + SNAP_TARGET_PARENT, + SNAP_TARGET_SELF_ANCHORS, + SNAP_TARGET_SELF, + SNAP_TARGET_OTHER_NODE, + SNAP_TARGET_GUIDE, + SNAP_TARGET_GRID, + SNAP_TARGET_PIXEL + }; + enum MenuOption { SNAP_USE, SNAP_USE_NODE_PARENT, @@ -440,6 +451,7 @@ private: void _draw_percentage_at_position(float p_value, Point2 p_position, Margin p_side); void _draw_straight_line(Point2 p_from, Point2 p_to, Color p_color); + void _draw_smart_snapping(); void _draw_rulers(); void _draw_guides(); void _draw_focus(); @@ -475,9 +487,25 @@ private: void _solve_IK(Node2D *leaf_node, Point2 target_position); - void _snap_if_closer_float(float p_value, float p_target_snap, float &r_current_snap, bool &r_snapped, float p_radius = 10.0); - void _snap_if_closer_point(Point2 p_value, Point2 p_target_snap, Point2 &r_current_snap, bool (&r_snapped)[2], real_t rotation = 0.0, float p_radius = 10.0); - void _snap_other_nodes(Point2 p_value, Point2 &r_current_snap, bool (&r_snapped)[2], const Node *p_current, const CanvasItem *p_to_snap = NULL); + SnapTarget snap_target[2]; + Transform2D snap_transform; + void _snap_if_closer_float( + float p_value, + float &r_current_snap, SnapTarget &r_current_snap_target, + float p_target_value, SnapTarget p_snap_target, + float p_radius = 10.0); + void _snap_if_closer_point( + Point2 p_value, + Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2], + Point2 p_target_value, SnapTarget p_snap_target, + real_t rotation = 0.0, + float p_radius = 10.0); + void _snap_other_nodes( + const Point2 p_value, + const Transform2D p_transform_to_snap, + Point2 &r_current_snap, SnapTarget (&r_current_snap_target)[2], + const SnapTarget p_snap_target, List<const CanvasItem *> p_exceptions, + const Node *p_current); void _set_anchors_preset(Control::LayoutPreset p_preset); void _set_margins_preset(Control::LayoutPreset p_preset); @@ -558,7 +586,7 @@ public: SNAP_DEFAULT = SNAP_GRID | SNAP_GUIDES | SNAP_PIXEL, }; - Point2 snap_point(Point2 p_target, unsigned int p_modes = SNAP_DEFAULT, const CanvasItem *p_canvas_item = NULL, unsigned int p_forced_modes = 0); + Point2 snap_point(Point2 p_target, unsigned int p_modes = SNAP_DEFAULT, unsigned int p_forced_modes = 0, const CanvasItem *p_self_canvas_item = NULL, List<CanvasItem *> p_other_nodes_exceptions = List<CanvasItem *>()); float snap_angle(float p_target, float p_start = 0) const; Transform2D get_canvas_transform() const { return transform; } |