diff options
Diffstat (limited to 'editor')
56 files changed, 898 insertions, 588 deletions
diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp index b832b993bb..54eb695178 100644 --- a/editor/animation_editor.cpp +++ b/editor/animation_editor.cpp @@ -64,6 +64,8 @@ private: float transition; Mode mode; + LineEdit *value_edit; + void _notification(int p_what) { if (p_what == NOTIFICATION_DRAW) { @@ -144,14 +146,11 @@ private: } } - String txt = String::num(exp, 2); if (mode == MODE_DISABLED) { - txt = TTR("Disabled"); + f->draw(ci, Point2(5, 5 + f->get_ascent()), TTR("Disabled"), color); } else if (mode == MODE_MULTIPLE) { - txt += " - " + TTR("All Selection"); + f->draw(ci, Point2(5, 5 + f->get_ascent() + value_edit->get_size().height), TTR("All Selection"), color); } - - f->draw(ci, Point2(10, 10 + f->get_ascent()), txt, color); } } @@ -163,6 +162,8 @@ private: if (mode == MODE_DISABLED) return; + value_edit->release_focus(); + float rel = mm->get_relative().x; if (rel == 0) return; @@ -187,24 +188,28 @@ private: if (sg) val = -val; - transition = val; - update(); - //emit_signal("variant_changed"); - emit_signal("transition_changed", transition); + force_transition(val); } } + void _edit_value_changed(const String &p_value_str) { + + force_transition(p_value_str.to_float()); + } + public: static void _bind_methods() { //ClassDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj); ClassDB::bind_method("_gui_input", &AnimationCurveEdit::_gui_input); + ClassDB::bind_method("_edit_value_changed", &AnimationCurveEdit::_edit_value_changed); ADD_SIGNAL(MethodInfo("transition_changed")); } void set_mode(Mode p_mode) { mode = p_mode; + value_edit->set_visible(mode != MODE_DISABLED); update(); } @@ -218,7 +223,8 @@ public: } void set_transition(float p_transition) { - transition = p_transition; + transition = Math::stepify(p_transition, 0.01); + value_edit->set_text(String::num(transition)); update(); } @@ -229,9 +235,8 @@ public: void force_transition(float p_value) { if (mode == MODE_DISABLED) return; - transition = p_value; + set_transition(p_value); emit_signal("transition_changed", p_value); - update(); } AnimationCurveEdit() { @@ -239,6 +244,11 @@ public: transition = 1.0; set_default_cursor_shape(CURSOR_HSPLIT); mode = MODE_DISABLED; + + value_edit = memnew(LineEdit); + value_edit->hide(); + value_edit->connect("text_entered", this, "_edit_value_changed"); + add_child(value_edit); } }; @@ -1101,7 +1111,7 @@ void AnimationKeyEditor::_track_editor_draw() { Color select_color = color; select_color.a = 0.1; Color invalid_path_color = get_color("error_color", "Editor"); - Color track_select_color = get_color("accent", "Editor"); + Color track_select_color = get_color("highlighted_font_color", "Editor"); Ref<Texture> remove_icon = get_icon("Remove", "EditorIcons"); Ref<Texture> move_up_icon = get_icon("MoveUp", "EditorIcons"); diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 5305c4f256..64f1c4ccb2 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -337,92 +337,142 @@ DependencyEditorOwners::DependencyEditorOwners() { /////////////////////// -void DependencyRemoveDialog::_fill_owners(EditorFileSystemDirectory *efsd) { +void DependencyRemoveDialog::_find_files_in_removed_folder(EditorFileSystemDirectory *efsd, const String &p_folder) { + if (!efsd) + return; + + for (int i = 0; i < efsd->get_subdir_count(); ++i) { + _find_files_in_removed_folder(efsd->get_subdir(i), p_folder); + } + for (int i = 0; i < efsd->get_file_count(); i++) { + String file = efsd->get_file_path(i); + ERR_FAIL_COND(all_remove_files.has(file)); //We are deleting a directory which is contained in a directory we are deleting... + all_remove_files[file] = p_folder; //Point the file to the ancestor directory we are deleting so we know what to parent it under in the tree. + } +} +void DependencyRemoveDialog::_find_all_removed_dependencies(EditorFileSystemDirectory *efsd, Vector<RemovedDependency> &p_removed) { if (!efsd) return; for (int i = 0; i < efsd->get_subdir_count(); i++) { - _fill_owners(efsd->get_subdir(i)); + _find_all_removed_dependencies(efsd->get_subdir(i), p_removed); } for (int i = 0; i < efsd->get_file_count(); i++) { + const String path = efsd->get_file_path(i); - Vector<String> deps = efsd->get_file_deps(i); - //print_line(":::"+efsd->get_file_path(i)); - Set<String> met; - for (int j = 0; j < deps.size(); j++) { - if (files.has(deps[j])) { - met.insert(deps[j]); - } - } - if (!met.size()) + //It doesn't matter if a file we are about to delete will have some of its dependencies removed too + if (all_remove_files.has(path)) continue; - exist = true; - - Ref<Texture> icon; - String type = efsd->get_file_type(i); - if (!has_icon(type, "EditorIcons")) { - icon = get_icon("Object", "EditorIcons"); - } else { - icon = get_icon(type, "EditorIcons"); + Vector<String> all_deps = efsd->get_file_deps(i); + for (int j = 0; j < all_deps.size(); ++j) { + if (all_remove_files.has(all_deps[j])) { + RemovedDependency dep; + dep.file = path; + dep.file_type = efsd->get_file_type(i); + dep.dependency = all_deps[j]; + dep.dependency_folder = all_remove_files[all_deps[j]]; + p_removed.push_back(dep); + } } + } +} - for (Set<String>::Element *E = met.front(); E; E = E->next()) { +void DependencyRemoveDialog::_build_removed_dependency_tree(const Vector<RemovedDependency> &p_removed) { + owners->clear(); + owners->create_item(); // root - String which = E->get(); - if (!files[which]) { - TreeItem *ti = owners->create_item(owners->get_root()); - ti->set_text(0, which.get_file()); - files[which] = ti; + Map<String, TreeItem *> tree_items; + for (int i = 0; i < p_removed.size(); i++) { + RemovedDependency rd = p_removed[i]; + + //Ensure that the dependency is already in the tree + if (!tree_items.has(rd.dependency)) { + if (rd.dependency_folder.length() > 0) { + //Ensure the ancestor folder is already in the tree + if (!tree_items.has(rd.dependency_folder)) { + TreeItem *folder_item = owners->create_item(owners->get_root()); + folder_item->set_text(0, rd.dependency_folder); + folder_item->set_icon(0, get_icon("Folder", "EditorIcons")); + tree_items[rd.dependency_folder] = folder_item; + } + TreeItem *dependency_item = owners->create_item(tree_items[rd.dependency_folder]); + dependency_item->set_text(0, rd.dependency); + dependency_item->set_icon(0, get_icon("Warning", "EditorIcons")); + tree_items[rd.dependency] = dependency_item; + } else { + TreeItem *dependency_item = owners->create_item(owners->get_root()); + dependency_item->set_text(0, rd.dependency); + dependency_item->set_icon(0, get_icon("Warning", "EditorIcons")); + tree_items[rd.dependency] = dependency_item; } - TreeItem *ti = owners->create_item(files[which]); - ti->set_text(0, efsd->get_file_path(i)); - ti->set_icon(0, icon); } + + //List this file under this dependency + Ref<Texture> icon = has_icon(rd.file_type, "EditorIcons") ? get_icon(rd.file_type, "EditorIcons") : get_icon("Object", "EditorIcons"); + TreeItem *file_item = owners->create_item(tree_items[rd.dependency]); + file_item->set_text(0, rd.file); + file_item->set_icon(0, icon); } } -void DependencyRemoveDialog::show(const Vector<String> &to_erase) { - - exist = false; +void DependencyRemoveDialog::show(const Vector<String> &p_folders, const Vector<String> &p_files) { + all_remove_files.clear(); + to_delete.clear(); owners->clear(); - files.clear(); - owners->create_item(); // root - for (int i = 0; i < to_erase.size(); i++) { - files[to_erase[i]] = NULL; + + for (int i = 0; i < p_folders.size(); ++i) { + String folder = p_folders[i].ends_with("/") ? p_folders[i] : (p_folders[i] + "/"); + _find_files_in_removed_folder(EditorFileSystem::get_singleton()->get_filesystem_path(folder), folder); + to_delete.push_back(folder); + } + for (int i = 0; i < p_files.size(); ++i) { + all_remove_files[p_files[i]] = String(); + to_delete.push_back(p_files[i]); } - _fill_owners(EditorFileSystem::get_singleton()->get_filesystem()); + Vector<RemovedDependency> removed_deps; + _find_all_removed_dependencies(EditorFileSystem::get_singleton()->get_filesystem(), removed_deps); + removed_deps.sort(); - if (exist) { - owners->show(); - text->set_text(TTR("The files being removed are required by other resources in order for them to work.\nRemove them anyway? (no undo)")); - popup_centered_minsize(Size2(500, 220)); - } else { + if (removed_deps.empty()) { owners->hide(); text->set_text(TTR("Remove selected files from the project? (no undo)")); popup_centered_minsize(Size2(400, 100)); + } else { + _build_removed_dependency_tree(removed_deps); + owners->show(); + text->set_text(TTR("The files being removed are required by other resources in order for them to work.\nRemove them anyway? (no undo)")); + popup_centered_minsize(Size2(500, 350)); } } void DependencyRemoveDialog::ok_pressed() { - - bool changed = false; - - for (Map<String, TreeItem *>::Element *E = files.front(); E; E = E->next()) { - - if (ResourceCache::has(E->key())) { - Resource *res = ResourceCache::get(E->key()); + bool files_only = true; + for (int i = 0; i < to_delete.size(); ++i) { + if (to_delete[i].ends_with("/")) { + files_only = false; + } else if (ResourceCache::has(to_delete[i])) { + Resource *res = ResourceCache::get(to_delete[i]); res->set_path(""); //clear reference to path } - String fpath = OS::get_singleton()->get_resource_dir() + E->key().replace_first("res://", "/"); - OS::get_singleton()->move_to_trash(fpath); - changed = true; + + String path = OS::get_singleton()->get_resource_dir() + to_delete[i].replace_first("res://", "/"); + print_line("Moving to trash: " + path); + Error err = OS::get_singleton()->move_to_trash(path); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:\n") + to_delete[i] + "\n"); + } } - if (changed) { + if (files_only) { + //If we only deleted files we should only need to tell the file system about the files we touched. + for (int i = 0; i < to_delete.size(); ++i) { + EditorFileSystem::get_singleton()->update_file(to_delete[i]); + } + } else { EditorFileSystem::get_singleton()->scan_changes(); } } diff --git a/editor/dependency_editor.h b/editor/dependency_editor.h index 4dfb9de268..c7e9baa5c2 100644 --- a/editor/dependency_editor.h +++ b/editor/dependency_editor.h @@ -84,14 +84,33 @@ class DependencyRemoveDialog : public ConfirmationDialog { Label *text; Tree *owners; - bool exist; - Map<String, TreeItem *> files; - void _fill_owners(EditorFileSystemDirectory *efsd); + + Map<String, String> all_remove_files; + Vector<String> to_delete; + + struct RemovedDependency { + String file; + String file_type; + String dependency; + String dependency_folder; + + bool operator<(const RemovedDependency &p_other) const { + if (dependency_folder.empty() != p_other.dependency_folder.empty()) { + return p_other.dependency_folder.empty(); + } else { + return dependency < p_other.dependency; + } + } + }; + + void _find_files_in_removed_folder(EditorFileSystemDirectory *efsd, const String &p_folder); + void _find_all_removed_dependencies(EditorFileSystemDirectory *efsd, Vector<RemovedDependency> &p_removed); + void _build_removed_dependency_tree(const Vector<RemovedDependency> &p_removed); void ok_pressed(); public: - void show(const Vector<String> &to_erase); + void show(const Vector<String> &p_folders, const Vector<String> &p_files); DependencyRemoveDialog(); }; diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index cb94ea72d1..2c4d3035a4 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -694,7 +694,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) { inherits = doc->class_list[inherits].inherits; if (inherits != "") { - class_desc->add_text(" , "); + class_desc->add_text(" < "); } } @@ -1699,7 +1699,7 @@ void EditorHelp::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); + class_desc->add_color_override("selection_color", get_color("text_editor/theme/selection_color", "Editor")); } break; @@ -1788,7 +1788,7 @@ EditorHelp::EditorHelp() { class_desc = memnew(RichTextLabel); vbc->add_child(class_desc); class_desc->set_v_size_flags(SIZE_EXPAND_FILL); - class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); + class_desc->add_color_override("selection_color", get_color("text_editor/theme/selection_color", "Editor")); class_desc->connect("meta_clicked", this, "_class_desc_select"); class_desc->connect("gui_input", this, "_class_desc_input"); } @@ -1879,7 +1879,7 @@ void EditorHelpBit::_notification(int p_what) { switch (p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); + rich_text->add_color_override("selection_color", get_color("text_editor/theme/selection_color", "Editor")); } break; default: break; @@ -1898,6 +1898,7 @@ EditorHelpBit::EditorHelpBit() { add_child(rich_text); rich_text->set_anchors_and_margins_preset(Control::PRESET_WIDE); rich_text->connect("meta_clicked", this, "_meta_clicked"); - rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); + rich_text->add_color_override("selection_color", get_color("text_editor/theme/selection_color", "Editor")); + rich_text->set_override_selected_font_color(false); set_custom_minimum_size(Size2(0, 70 * EDSCALE)); } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 1ca88133b8..aca2f59134 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -3156,12 +3156,19 @@ void EditorNode::_add_to_recent_scenes(const String &p_scene) { void EditorNode::_open_recent_scene(int p_idx) { String base = "_" + ProjectSettings::get_singleton()->get_resource_path().replace("\\", "::").replace("/", "::"); - Vector<String> rc = EDITOR_DEF(base + "/_recent_scenes", Array()); - ERR_FAIL_INDEX(p_idx, rc.size()); + if (p_idx == recent_scenes->get_item_count() - 1) { + + EditorSettings::get_singleton()->erase(base + "/_recent_scenes"); + call_deferred("_update_recent_scenes"); + } else { + + Vector<String> rc = EDITOR_DEF(base + "/_recent_scenes", Array()); + ERR_FAIL_INDEX(p_idx, rc.size()); - String path = "res://" + rc[p_idx]; - load_scene(path); + String path = "res://" + rc[p_idx]; + load_scene(path); + } } void EditorNode::_update_recent_scenes() { @@ -3169,10 +3176,15 @@ void EditorNode::_update_recent_scenes() { String base = "_" + ProjectSettings::get_singleton()->get_resource_path().replace("\\", "::").replace("/", "::"); Vector<String> rc = EDITOR_DEF(base + "/_recent_scenes", Array()); recent_scenes->clear(); + for (int i = 0; i < rc.size(); i++) { recent_scenes->add_item(rc[i], i); } + + recent_scenes->add_separator(); + recent_scenes->add_shortcut(ED_SHORTCUT("editor/clear_recent", TTR("Clear Recent Scenes"))); + recent_scenes->set_as_minsize(); } void EditorNode::_quick_opened() { @@ -4513,6 +4525,7 @@ void EditorNode::_bind_methods() { ClassDB::bind_method("_set_main_scene_state", &EditorNode::_set_main_scene_state); ClassDB::bind_method("_update_scene_tabs", &EditorNode::_update_scene_tabs); ClassDB::bind_method("_discard_changes", &EditorNode::_discard_changes); + ClassDB::bind_method("_update_recent_scenes", &EditorNode::_update_recent_scenes); ClassDB::bind_method("_prepare_history", &EditorNode::_prepare_history); ClassDB::bind_method("_select_history", &EditorNode::_select_history); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index b532bb793a..7c45e19f5f 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -719,12 +719,13 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { // freelook _initial_set("editors/3d/freelook/freelook_inertia", 0.1); hints["editors/3d/freelook/freelook_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); - _initial_set("editors/3d/freelook/freelook_base_speed", 0.1); + _initial_set("editors/3d/freelook/freelook_base_speed", 5.0); hints["editors/3d/freelook/freelook_base_speed"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_base_speed", PROPERTY_HINT_RANGE, "0.0, 10, 0.01"); _initial_set("editors/3d/freelook/freelook_activation_modifier", 0); hints["editors/3d/freelook/freelook_activation_modifier"] = PropertyInfo(Variant::INT, "editors/3d/freelook/freelook_activation_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); _initial_set("editors/3d/freelook/freelook_modifier_speed_factor", 3.0); hints["editors/3d/freelook/freelook_modifier_speed_factor"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_modifier_speed_factor", PROPERTY_HINT_RANGE, "0.0, 10.0, 0.1"); + _initial_set("editors/3d/freelook/freelook_speed_zoom_link", false); _initial_set("editors/2d/bone_width", 5); _initial_set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9)); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 0436ac78df..13ed7a7f30 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -350,6 +350,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("contrast_color_2", "Editor", contrast_color_2); theme->set_color("font_color", "Editor", font_color); + theme->set_color("highlighted_font_color", "Editor", font_color_hl); theme->set_color("disabled_font_color", "Editor", font_color_disabled); theme->set_color("mono_color", "Editor", mono_color); @@ -971,8 +972,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color dim_color = Color(font_color.r, font_color.g, font_color.b, 0.5); const float mono_value = mono_color.r; - const Color alpha1 = Color(mono_value, mono_value, mono_value, 0.1); - const Color alpha2 = Color(mono_value, mono_value, mono_value, 0.3); + const Color alpha1 = Color(mono_value, mono_value, mono_value, 0.07); + const Color alpha2 = Color(mono_value, mono_value, mono_value, 0.14); const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.5); const Color alpha4 = Color(mono_value, mono_value, mono_value, 0.7); @@ -997,7 +998,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color caret_color = mono_color; const Color caret_background_color = mono_color.inverted(); const Color text_selected_color = dark_color_3; - const Color selection_color = alpha3; + const Color selection_color = alpha2; const Color brace_mismatch_color = error_color; const Color current_line_color = alpha1; const Color line_length_guideline_color = warning_color; diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index a9d72607b4..dfd35fdd96 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -458,9 +458,9 @@ void FileSystemDock::_update_files(bool p_keep_selection) { if (path != "res://") { if (use_thumbnails) { - files->add_item("..", folder_thumbnail, true); + files->add_item("..", folder_thumbnail, false); } else { - files->add_item("..", get_icon("folder", "FileDialog"), true); + files->add_item("..", get_icon("folder", "FileDialog"), false); } String bd = path.get_base_dir(); @@ -567,9 +567,22 @@ void FileSystemDock::_update_files(bool p_keep_selection) { } void FileSystemDock::_select_file(int p_idx) { - - files->select(p_idx, true); - _file_option(FILE_OPEN); + String path = files->get_item_metadata(p_idx); + if (path.ends_with("/")) { + if (path != "res://") { + path = path.substr(0, path.length() - 1); + } + this->path = path; + _update_files(false); + current_path->set_text(path); + _push_to_history(); + } else { + if (ResourceLoader::get_resource_type(path) == "PackedScene") { + editor->open_request(path); + } else { + editor->load_resource(path); + } + } } void FileSystemDock::_go_to_tree() { @@ -704,18 +717,19 @@ void FileSystemDock::_push_to_history() { button_hist_next->set_disabled(history_pos + 1 == history.size()); } -void FileSystemDock::_find_inside_move_files(EditorFileSystemDirectory *efsd, Vector<String> &files) { +void FileSystemDock::_get_all_files_in_dir(EditorFileSystemDirectory *efsd, Vector<String> &files) const { + if (efsd == NULL) + return; for (int i = 0; i < efsd->get_subdir_count(); i++) { - _find_inside_move_files(efsd->get_subdir(i), files); + _get_all_files_in_dir(efsd->get_subdir(i), files); } for (int i = 0; i < efsd->get_file_count(); i++) { files.push_back(efsd->get_file_path(i)); } } -void FileSystemDock::_find_remaps(EditorFileSystemDirectory *efsd, Map<String, String> &renames, List<String> &to_remaps) { - +void FileSystemDock::_find_remaps(EditorFileSystemDirectory *efsd, const Map<String, String> &renames, Vector<String> &to_remaps) const { for (int i = 0; i < efsd->get_subdir_count(); i++) { _find_remaps(efsd->get_subdir(i), renames, to_remaps); } @@ -730,199 +744,157 @@ void FileSystemDock::_find_remaps(EditorFileSystemDirectory *efsd, Map<String, S } } -void FileSystemDock::_rename_operation(const String &p_to_path) { +void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_new_path, Map<String, String> &p_renames) const { + //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 + "/"); - if (move_files[0] == p_to_path) { - EditorNode::get_singleton()->show_warning(TTR("Same source and destination files, doing nothing.")); + if (new_path == old_path) { return; - } - if (FileAccess::exists(p_to_path)) { - EditorNode::get_singleton()->show_warning(TTR("Target file exists, can't overwrite. Delete first.")); + } else if (old_path == "res://") { + 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 "/" + EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.\n") + old_path + "\n"); return; } - Map<String, String> renames; - renames[move_files[0]] = p_to_path; - - List<String> remap; - - _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), renames, remap); - print_line("found files to remap: " + itos(remap.size())); - - //perform remaps - for (List<String>::Element *E = remap.front(); E; E = E->next()) { - - Error err = ResourceLoader::rename_dependencies(E->get(), renames); - print_line("remapping: " + E->get()); - - if (err != OK) { - EditorNode::get_singleton()->add_io_error("Can't rename deps for:\n" + E->get() + "\n"); - } + //Build a list of files which will have new paths as a result of this operation + Vector<String> changed_paths; + if (p_item.is_file) { + changed_paths.push_back(old_path); + } else { + _get_all_files_in_dir(EditorFileSystem::get_singleton()->get_filesystem_path(old_path), changed_paths); } - //finally, perform moves - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + print_line("Moving " + old_path + " -> " + new_path); + Error err = da->rename(old_path, new_path); + if (err == OK) { + //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) { + EditorNode::get_singleton()->add_io_error(TTR("Error moving:\n") + old_path + ".import\n"); + } + } - Error err = da->rename(move_files[0], p_to_path); - print_line("moving file " + move_files[0] + " to " + p_to_path); - if (err != OK) { - EditorNode::get_singleton()->add_io_error("Error moving file:\n" + move_files[0] + "\n"); + //Only treat as a changed dependency if it was successfully moved + for (int i = 0; i < changed_paths.size(); ++i) { + p_renames[changed_paths[i]] = changed_paths[i].replace_first(old_path, new_path); + print_line(" Remap: " + changed_paths[i] + " -> " + p_renames[changed_paths[i]]); + } + } else { + EditorNode::get_singleton()->add_io_error(TTR("Error moving:\n") + old_path + "\n"); } - - //rescan everything memdelete(da); - print_line("call rescan!"); - _rescan(); } -void FileSystemDock::_move_operation(const String &p_to_path) { - - if (p_to_path == path) { - EditorNode::get_singleton()->show_warning(TTR("Same source and destination paths, doing nothing.")); - return; +void FileSystemDock::_update_dependencies_after_move(const Map<String, String> &p_renames) const { + //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. + String file = p_renames.has(remaps[i]) ? p_renames[remaps[i]] : remaps[i]; + print_line("Remapping dependencies for: " + file); + Error err = ResourceLoader::rename_dependencies(file, p_renames); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies:\n") + remaps[i] + "\n"); + } } +} - //find files inside dirs to be moved - - Vector<String> inside_files; - - for (int i = 0; i < move_dirs.size(); i++) { - if (p_to_path.begins_with(move_dirs[i])) { - EditorNode::get_singleton()->show_warning(TTR("Can't move directories to within themselves.")); - return; - } +void FileSystemDock::_make_dir_confirm() { + String dir_name = make_dir_dialog_text->get_text().strip_edges(); - EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->get_filesystem_path(move_dirs[i]); - if (!efsd) - continue; - _find_inside_move_files(efsd, inside_files); + if (dir_name.length() == 0) { + EditorNode::get_singleton()->show_warning(TTR("No name provided")); + return; + } else if (dir_name.find("/") != -1 || dir_name.find("\\") != -1 || dir_name.find(":") != -1) { + EditorNode::get_singleton()->show_warning(TTR("Provided name contains invalid characters")); + return; } - //make list of remaps - Map<String, String> renames; - String repfrom = path == "res://" ? path : String(path + "/"); - String repto = p_to_path; - if (!repto.ends_with("/")) { - repto += "/"; + print_line("Making folder " + dir_name + " in " + path); + DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + Error err = da->change_dir(path); + if (err == OK) { + err = da->make_dir(dir_name); } + memdelete(da); - print_line("reprfrom: " + repfrom + " repto " + repto); - - for (int i = 0; i < move_files.size(); i++) { - renames[move_files[i]] = move_files[i].replace_first(repfrom, repto); - print_line("move file " + move_files[i] + " -> " + renames[move_files[i]]); - } - for (int i = 0; i < inside_files.size(); i++) { - renames[inside_files[i]] = inside_files[i].replace_first(repfrom, repto); - print_line("inside file " + inside_files[i] + " -> " + renames[inside_files[i]]); + if (err == OK) { + print_line("call rescan!"); + _rescan(); + } else { + EditorNode::get_singleton()->show_warning(TTR("Could not create folder.")); } +} - //make list of files that will be run the remapping - List<String> remap; - - _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), renames, remap); - print_line("found files to remap: " + itos(remap.size())); - - //perform remaps - for (List<String>::Element *E = remap.front(); E; E = E->next()) { - - Error err = ResourceLoader::rename_dependencies(E->get(), renames); - print_line("remapping: " + E->get()); +void FileSystemDock::_rename_operation_confirm() { - if (err != OK) { - EditorNode::get_singleton()->add_io_error(TTR("Can't rename deps for:\n") + E->get() + "\n"); - } + String new_name = rename_dialog_text->get_text().strip_edges(); + if (new_name.length() == 0) { + EditorNode::get_singleton()->show_warning(TTR("No name provided.")); + return; + } else if (new_name.find("/") != -1 || new_name.find("\\") != -1 || new_name.find(":") != -1) { + EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters.")); + return; } - //finally, perform moves + String old_path = to_rename.path.ends_with("/") ? to_rename.path.substr(0, to_rename.path.length() - 1) : to_rename.path; + String new_path = old_path.get_base_dir().plus_file(new_name); + if (old_path == new_path) { + return; + } + //Present a more user friendly warning for name conflict DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - - for (int i = 0; i < move_files.size(); i++) { - - String to = move_files[i].replace_first(repfrom, repto); - Error err = da->rename(move_files[i], to); - print_line("moving file " + move_files[i] + " to " + to); - if (err != OK) { - EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + "\n"); - } - if (FileAccess::exists(move_files[i] + ".import")) { //move imported files too - //@todo should remove the files in .import folder - err = da->rename(move_files[i] + ".import", to + ".import"); - if (err != OK) { - EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + ".import\n"); - } - } + 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.")); + memdelete(da); + return; } + memdelete(da); - for (int i = 0; i < move_dirs.size(); i++) { + Map<String, String> renames; + _try_move_item(to_rename, new_path, renames); + _update_dependencies_after_move(renames); - String mdir = move_dirs[i]; - if (mdir == "res://") - continue; + //Rescan everything + print_line("call rescan!"); + _rescan(); +} - if (mdir.ends_with("/")) { - mdir = mdir.substr(0, mdir.length() - 1); - } +void FileSystemDock::_move_operation_confirm(const String &p_to_path) { - String to = p_to_path.plus_file(mdir.get_file()); - Error err = da->rename(mdir, to); - print_line("moving dir " + mdir + " to " + to); - if (err != OK) { - EditorNode::get_singleton()->add_io_error(TTR("Error moving dir:\n") + move_dirs[i] + "\n"); - } + Map<String, String> renames; + for (int i = 0; i < to_move.size(); i++) { + String old_path = to_move[i].path.ends_with("/") ? to_move[i].path.substr(0, to_move[i].path.length() - 1) : to_move[i].path; + String new_path = p_to_path.plus_file(old_path.get_file()); + _try_move_item(to_move[i], new_path, renames); } - memdelete(da); - //rescan everything + _update_dependencies_after_move(renames); print_line("call rescan!"); _rescan(); } void FileSystemDock::_file_option(int p_option) { - switch (p_option) { - - case FILE_SHOW_IN_EXPLORER: + case FILE_SHOW_IN_EXPLORER: { + String dir = ProjectSettings::get_singleton()->globalize_path(this->path); + OS::get_singleton()->shell_open(String("file://") + dir); + } break; case FILE_OPEN: { - int idx = -1; - for (int i = 0; i < files->get_item_count(); i++) { - if (files->is_selected(i)) { - idx = i; - break; - } - } - - if (idx < 0) - return; - - String path = files->get_item_metadata(idx); - if (p_option == FILE_SHOW_IN_EXPLORER) { - String dir = ProjectSettings::get_singleton()->globalize_path(path); - dir = dir.substr(0, dir.find_last("/")); - OS::get_singleton()->shell_open(String("file://") + dir); - return; - } - - if (path.ends_with("/")) { - if (path != "res://") { - path = path.substr(0, path.length() - 1); - } - this->path = path; - _update_files(false); - current_path->set_text(path); - _push_to_history(); - } else { - - if (ResourceLoader::get_resource_type(path) == "PackedScene") { - - editor->open_request(path); - } else { - - editor->load_resource(path); - } - } + int idx = files->get_current(); + if (idx < 0 || idx >= files->get_item_count()) + break; + _select_file(idx); } break; case FILE_INSTANCE: { @@ -958,64 +930,59 @@ void FileSystemDock::_file_option(int p_option) { owners_editor->show(path); } break; case FILE_MOVE: { - - move_dirs.clear(); - move_files.clear(); - + to_move.clear(); for (int i = 0; i < files->get_item_count(); i++) { - - String path = files->get_item_metadata(i); if (!files->is_selected(i)) continue; - if (files->get_item_text(i) == "..") { - EditorNode::get_singleton()->show_warning(TTR("Can't operate on '..'")); - return; - } - - if (path.ends_with("/")) { - move_dirs.push_back(path.substr(0, path.length() - 1)); - } else { - move_files.push_back(path); - } + String path = files->get_item_metadata(i); + to_move.push_back(FileOrFolder(path, !path.ends_with("/"))); } - - if (move_dirs.empty() && move_files.size() == 1) { - - rename_dialog->clear_filters(); - rename_dialog->add_filter("*." + move_files[0].get_extension()); - rename_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); - rename_dialog->set_current_path(move_files[0]); - rename_dialog->popup_centered_ratio(); - rename_dialog->set_title(TTR("Pick New Name and Location For:") + " " + move_files[0].get_file()); - - } else { - //just move + if (to_move.size() > 0) { move_dialog->popup_centered_ratio(); } + } break; + case FILE_RENAME: { + int idx = files->get_current(); + if (idx < 0 || idx >= files->get_item_count()) + break; + to_rename.path = files->get_item_metadata(idx); + to_rename.is_file = !to_rename.path.ends_with("/"); + if (to_rename.is_file) { + String name = to_rename.path.get_file(); + rename_dialog->set_title(TTR("Renaming file:") + " " + name); + rename_dialog_text->set_text(name); + rename_dialog_text->select(0, name.find_last(".")); + } else { + String name = to_rename.path.substr(0, to_rename.path.length() - 1).get_file(); + rename_dialog->set_title(TTR("Renaming folder:") + " " + name); + rename_dialog_text->set_text(name); + rename_dialog_text->select(0, name.length()); + } + rename_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); + rename_dialog_text->grab_focus(); } break; case FILE_REMOVE: { - - Vector<String> torem; + Vector<String> remove_files; + Vector<String> remove_folders; for (int i = 0; i < files->get_item_count(); i++) { - String path = files->get_item_metadata(i); - if (!files->is_selected(i)) - continue; - torem.push_back(path); + if (files->is_selected(i) && path != "res://") { + if (path.ends_with("/")) { + remove_folders.push_back(path); + } else { + remove_files.push_back(path); + } + } } - if (torem.empty()) { - EditorNode::get_singleton()->show_warning(TTR("No files selected!")); - break; + if (remove_files.size() + remove_folders.size() > 0) { + remove_dialog->show(remove_folders, remove_files); + //1) find if used + //2) warn } - - remove_dialog->show(torem); - //1) find if used - //2) warn - } break; case FILE_INFO: { @@ -1052,15 +1019,20 @@ void FileSystemDock::_file_option(int p_option) { } */ - } break; - case FILE_COPY_PATH: - + case FILE_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); + make_dir_dialog_text->grab_focus(); + } break; + case FILE_COPY_PATH: { int idx = files->get_current(); if (idx < 0 || idx >= files->get_item_count()) break; String path = files->get_item_metadata(idx); OS::get_singleton()->set_clipboard(path); + } break; } } @@ -1070,26 +1042,64 @@ void FileSystemDock::_folder_option(int p_option) { TreeItem *child = item->get_children(); switch (p_option) { - - case FOLDER_EXPAND_ALL: + case FOLDER_EXPAND_ALL: { item->set_collapsed(false); while (child) { child->set_collapsed(false); child = child->get_next(); } - break; - - case FOLDER_COLLAPSE_ALL: + } break; + case FOLDER_COLLAPSE_ALL: { while (child) { child->set_collapsed(true); child = child->get_next(); } - break; - case FOLDER_SHOW_IN_EXPLORER: + } break; + case FOLDER_MOVE: { + to_move.clear(); + String fpath = item->get_metadata(tree->get_selected_column()); + if (fpath != "res://") { + fpath = fpath.ends_with("/") ? fpath.substr(0, fpath.length() - 1) : fpath; + to_move.push_back(FileOrFolder(fpath, false)); + move_dialog->popup_centered_ratio(); + } + } break; + case FOLDER_RENAME: { + to_rename.path = item->get_metadata(tree->get_selected_column()); + to_rename.is_file = false; + if (to_rename.path != "res://") { + String name = to_rename.path.ends_with("/") ? to_rename.path.substr(0, to_rename.path.length() - 1).get_file() : to_rename.path.get_file(); + rename_dialog->set_title(TTR("Renaming folder:") + " " + name); + rename_dialog_text->set_text(name); + rename_dialog_text->select(0, name.length()); + rename_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE); + rename_dialog_text->grab_focus(); + } + } break; + case FOLDER_REMOVE: { + Vector<String> remove_folders; + Vector<String> remove_files; + String path = item->get_metadata(tree->get_selected_column()); + if (path != "res://") { + remove_folders.push_back(path); + remove_dialog->show(remove_folders, remove_files); + } + } break; + case FOLDER_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); + make_dir_dialog_text->grab_focus(); + } break; + case FOLDER_COPY_PATH: { + String path = item->get_metadata(tree->get_selected_column()); + OS::get_singleton()->set_clipboard(path); + } break; + case FOLDER_SHOW_IN_EXPLORER: { String path = item->get_metadata(tree->get_selected_column()); String dir = ProjectSettings::get_singleton()->globalize_path(path); OS::get_singleton()->shell_open(String("file://") + dir); - return; + } break; } } @@ -1128,9 +1138,20 @@ void FileSystemDock::_dir_rmb_pressed(const Vector2 &p_pos) { folder_options->add_item(TTR("Expand all"), FOLDER_EXPAND_ALL); folder_options->add_item(TTR("Collapse all"), FOLDER_COLLAPSE_ALL); - folder_options->add_separator(); - folder_options->add_item(TTR("Show In File Manager"), FOLDER_SHOW_IN_EXPLORER); - + TreeItem *item = tree->get_selected(); + if (item) { + String fpath = item->get_metadata(tree->get_selected_column()); + folder_options->add_separator(); + folder_options->add_item(TTR("Copy Path"), FOLDER_COPY_PATH); + if (fpath != "res://") { + folder_options->add_item(TTR("Rename.."), FOLDER_RENAME); + folder_options->add_item(TTR("Move To.."), FOLDER_MOVE); + folder_options->add_item(TTR("Delete"), FOLDER_REMOVE); + } + folder_options->add_separator(); + folder_options->add_item(TTR("New Folder.."), FOLDER_NEW_FOLDER); + folder_options->add_item(TTR("Show In File Manager"), FOLDER_SHOW_IN_EXPLORER); + } folder_options->set_position(tree->get_global_position() + p_pos); folder_options->popup(); } @@ -1445,117 +1466,79 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, } Vector<String> fnames = drag_data["files"]; - move_files.clear(); - move_dirs.clear(); - + to_move.clear(); for (int i = 0; i < fnames.size(); i++) { - if (fnames[i].ends_with("/")) - move_dirs.push_back(fnames[i]); - else - move_files.push_back(fnames[i]); + to_move.push_back(FileOrFolder(fnames[i], !fnames[i].ends_with("/"))); } - - _move_operation(to_dir); + _move_operation_confirm(to_dir); } } } void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) { - Vector<String> filenames; + //Right clicking ".." should clear current selection + if (files->get_item_text(p_item) == "..") { + for (int i = 0; i < files->get_item_count(); i++) { + files->unselect(i); + } + } - bool all_scenes = true; - bool all_can_reimport = true; - bool is_dir = false; - Set<String> types; + Vector<String> filenames; + Vector<String> foldernames; + bool all_files = true; + bool all_files_scenes = true; + bool all_folders = true; for (int i = 0; i < files->get_item_count(); i++) { - - if (!files->is_selected(i)) + if (!files->is_selected(i)) { continue; - - String path = files->get_item_metadata(i); - - if (files->get_item_text(i) == "..") { - // no operate on .. - return; } + String path = files->get_item_metadata(i); if (path.ends_with("/")) { - is_dir = true; - } - - int pos; - - EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(path, &pos); - - if (efsd) { - + foldernames.push_back(path); + all_files = false; } else { - all_can_reimport = false; + filenames.push_back(path); + all_folders = false; + all_files_scenes &= (EditorFileSystem::get_singleton()->get_file_type(path) == "PackedScene"); } - - filenames.push_back(path); - if (EditorFileSystem::get_singleton()->get_file_type(path) != "PackedScene") - all_scenes = false; } - if (filenames.size() == 0) - return; - file_options->clear(); file_options->set_size(Size2(1, 1)); + if (all_files && filenames.size() > 0) { + file_options->add_item(TTR("Open"), FILE_OPEN); + if (all_files_scenes) { + file_options->add_item(TTR("Instance"), FILE_INSTANCE); + } + file_options->add_separator(); - file_options->add_item(TTR("Open"), FILE_OPEN); - if (all_scenes) { - file_options->add_item(TTR("Instance"), FILE_INSTANCE); - } - - file_options->add_separator(); - - if (filenames.size() == 1 && !is_dir) { - file_options->add_item(TTR("Edit Dependencies.."), FILE_DEPENDENCIES); - file_options->add_item(TTR("View Owners.."), FILE_OWNERS); + if (filenames.size() == 1) { + file_options->add_item(TTR("Edit Dependencies.."), FILE_DEPENDENCIES); + file_options->add_item(TTR("View Owners.."), FILE_OWNERS); + file_options->add_separator(); + } + } else if (all_folders && foldernames.size() > 0) { + file_options->add_item(TTR("Open"), FILE_OPEN); file_options->add_separator(); } - if (!is_dir) { - if (filenames.size() == 1) { + int num_items = filenames.size() + foldernames.size(); + if (num_items >= 1) { + if (num_items == 1) { file_options->add_item(TTR("Copy Path"), FILE_COPY_PATH); - file_options->add_item(TTR("Rename or Move.."), FILE_MOVE); - } else { - file_options->add_item(TTR("Move To.."), FILE_MOVE); + file_options->add_item(TTR("Rename.."), FILE_RENAME); } + file_options->add_item(TTR("Move To.."), FILE_MOVE); + file_options->add_item(TTR("Delete"), FILE_REMOVE); + file_options->add_separator(); } - file_options->add_item(TTR("Delete"), FILE_REMOVE); - - //file_options->add_item(TTR("Info"),FILE_INFO); - - file_options->add_separator(); + file_options->add_item(TTR("New Folder.."), FILE_NEW_FOLDER); file_options->add_item(TTR("Show In File Manager"), FILE_SHOW_IN_EXPLORER); - if (all_can_reimport && types.size() == 1) { //all can reimport and are of the same type - - /* - bool valid=true; - Ref<EditorImportPlugin> rimp = EditorImportExport::get_singleton()->get_import_plugin_by_name(types.front()->get()); - if (rimp.is_valid()) { - - if (filenames.size()>1 && !rimp->can_reimport_multiple_files()) { - valid=false; - } - } else { - valid=false; - } - - if (valid) { - file_options->add_separator(); - file_options->add_item(TTR("Re-Import.."),FILE_REIMPORT); - } - */ - } - file_options->set_position(files->get_global_position() + p_pos); file_options->popup(); } @@ -1640,8 +1623,9 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_dir_selected"), &FileSystemDock::_dir_selected); ClassDB::bind_method(D_METHOD("_file_option"), &FileSystemDock::_file_option); ClassDB::bind_method(D_METHOD("_folder_option"), &FileSystemDock::_folder_option); - ClassDB::bind_method(D_METHOD("_move_operation"), &FileSystemDock::_move_operation); - ClassDB::bind_method(D_METHOD("_rename_operation"), &FileSystemDock::_rename_operation); + ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileSystemDock::_make_dir_confirm); + ClassDB::bind_method(D_METHOD("_move_operation_confirm"), &FileSystemDock::_move_operation_confirm); + ClassDB::bind_method(D_METHOD("_rename_operation_confirm"), &FileSystemDock::_rename_operation_confirm); ClassDB::bind_method(D_METHOD("_search_changed"), &FileSystemDock::_search_changed); @@ -1796,13 +1780,30 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { move_dialog = memnew(EditorDirDialog); add_child(move_dialog); - move_dialog->connect("dir_selected", this, "_move_operation"); + move_dialog->connect("dir_selected", this, "_move_operation_confirm"); move_dialog->get_ok()->set_text(TTR("Move")); - rename_dialog = memnew(EditorFileDialog); - rename_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE); - rename_dialog->connect("file_selected", this, "_rename_operation"); + rename_dialog = memnew(ConfirmationDialog); + VBoxContainer *rename_dialog_vb = memnew(VBoxContainer); + rename_dialog->add_child(rename_dialog_vb); + + rename_dialog_text = memnew(LineEdit); + rename_dialog_vb->add_margin_child(TTR("Name:"), rename_dialog_text); + rename_dialog->get_ok()->set_text(TTR("Rename")); add_child(rename_dialog); + rename_dialog->register_text_enter(rename_dialog_text); + rename_dialog->connect("confirmed", this, "_rename_operation_confirm"); + + make_dir_dialog = memnew(ConfirmationDialog); + make_dir_dialog->set_title(TTR("Create Folder")); + VBoxContainer *make_folder_dialog_vb = memnew(VBoxContainer); + make_dir_dialog->add_child(make_folder_dialog_vb); + + make_dir_dialog_text = memnew(LineEdit); + make_folder_dialog_vb->add_margin_child(TTR("Name:"), make_dir_dialog_text); + add_child(make_dir_dialog); + make_dir_dialog->register_text_enter(make_dir_dialog_text); + make_dir_dialog->connect("confirmed", this, "_make_dir_confirm"); updating_tree = false; initialized = false; diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index aec049ba43..89b250e295 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -32,6 +32,7 @@ #include "scene/gui/box_container.h" #include "scene/gui/control.h" +#include "scene/gui/dialogs.h" #include "scene/gui/item_list.h" #include "scene/gui/label.h" #include "scene/gui/menu_button.h" @@ -67,9 +68,11 @@ private: FILE_DEPENDENCIES, FILE_OWNERS, FILE_MOVE, + FILE_RENAME, FILE_REMOVE, FILE_REIMPORT, FILE_INFO, + FILE_NEW_FOLDER, FILE_SHOW_IN_EXPLORER, FILE_COPY_PATH }; @@ -77,7 +80,12 @@ private: enum FolderMenu { FOLDER_EXPAND_ALL, FOLDER_COLLAPSE_ALL, - FOLDER_SHOW_IN_EXPLORER + FOLDER_MOVE, + FOLDER_RENAME, + FOLDER_REMOVE, + FOLDER_NEW_FOLDER, + FOLDER_SHOW_IN_EXPLORER, + FOLDER_COPY_PATH }; VBoxContainer *scanning_vb; @@ -110,10 +118,23 @@ private: DependencyRemoveDialog *remove_dialog; EditorDirDialog *move_dialog; - EditorFileDialog *rename_dialog; + ConfirmationDialog *rename_dialog; + LineEdit *rename_dialog_text; + ConfirmationDialog *make_dir_dialog; + LineEdit *make_dir_dialog_text; - Vector<String> move_dirs; - Vector<String> move_files; + class FileOrFolder { + public: + String path; + bool is_file; + + FileOrFolder() + : path(""), is_file(false) {} + FileOrFolder(const String &p_path, bool p_is_file) + : path(p_path), is_file(p_is_file) {} + }; + FileOrFolder to_rename; + Vector<FileOrFolder> to_move; Vector<String> history; int history_pos; @@ -135,11 +156,15 @@ private: bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir); void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata); - void _find_inside_move_files(EditorFileSystemDirectory *efsd, Vector<String> &files); - void _find_remaps(EditorFileSystemDirectory *efsd, Map<String, String> &renames, List<String> &to_remaps); - void _rename_operation(const String &p_to_path); - void _move_operation(const String &p_to_path); + void _get_all_files_in_dir(EditorFileSystemDirectory *efsd, Vector<String> &files) const; + void _find_remaps(EditorFileSystemDirectory *efsd, const Map<String, String> &renames, Vector<String> &to_remaps) const; + void _try_move_item(const FileOrFolder &p_item, const String &p_new_path, Map<String, String> &p_renames) const; + void _update_dependencies_after_move(const Map<String, String> &p_renames) const; + + void _make_dir_confirm(); + void _rename_operation_confirm(); + void _move_operation_confirm(const String &p_to_path); void _file_option(int p_option); void _folder_option(int p_option); diff --git a/editor/icons/icon_GUI_unchecked.svg b/editor/icons/icon_GUI_unchecked.svg index 4adf3dd61e..59df40954f 100644 --- a/editor/icons/icon_GUI_unchecked.svg +++ b/editor/icons/icon_GUI_unchecked.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m4 2a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2v-8a2 2 0 0 0 -2 -2h-8zm0.80078 2h6.3984a0.8 0.8 0 0 1 0.80078 0.80078v6.3984a0.8 0.8 0 0 1 -0.80078 0.80078h-6.3984a0.8 0.8 0 0 1 -0.80078 -0.80078v-6.3984a0.8 0.8 0 0 1 0.80078 -0.80078z" fill="#e0e0e0" fill-opacity=".78431"/> -</g> +<path d="m4 2a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2v-8a2 2 0 0 0 -2 -2h-8zm0.80078 2h6.3984a0.8 0.8 0 0 1 0.80078 0.80078v6.3984a0.8 0.8 0 0 1 -0.80078 0.80078h-6.3984a0.8 0.8 0 0 1 -0.80078 -0.80078v-6.3984a0.8 0.8 0 0 1 0.80078 -0.80078z" fill="#e0e0e0" fill-opacity=".78431"/> </svg> diff --git a/editor/icons/icon_a_r_v_r_anchor.svg b/editor/icons/icon_a_r_v_r_anchor.svg new file mode 100644 index 0000000000..1a8398a1be --- /dev/null +++ b/editor/icons/icon_a_r_v_r_anchor.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m7 1v2h-2v2h2v3.2656l-2.5527-1.2773c-0.15005-0.075253-0.31662-0.11152-0.48438-0.10547-0.36536 0.013648-0.69415 0.2256-0.85742 0.55273-0.24709 0.49403-0.046823 1.0948 0.44727 1.3418l4.4473 2.2227 4.4473-2.2227c0.49409-0.24697 0.69435-0.84777 0.44726-1.3418-0.24697-0.49409-0.84777-0.69435-1.3418-0.44727l-2.5527 1.2773v-3.2656h2v-2h-2v-2zm-3 11v1c0 0.55228 0.44772 1 1 1-0.55228 0-1 0.44772-1 1v1h1v-1h1v1h1v-1c0-0.55228-0.44772-1-1-1 0.55228 0 1-0.44772 1-1v-1h-1v1h-1v-1zm5 0v4h1v-1h1v1h1v-1c-8.34e-4 -0.17579-0.047991-0.34825-0.13672-0.5 0.088728-0.15175 0.13588-0.32421 0.13672-0.5v-1c0-0.55228-0.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc9c9c"/> +</svg> diff --git a/editor/icons/icon_a_r_v_r_camera.svg b/editor/icons/icon_a_r_v_r_camera.svg index a02b4d983c..5bf815bcef 100644 --- a/editor/icons/icon_a_r_v_r_camera.svg +++ b/editor/icons/icon_a_r_v_r_camera.svg @@ -1,3 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<path d="m2 1c-0.55401 0-1 0.446-1 1v7c0 0.554 0.44599 1 1 1h4l1-2c0.24699-0.494 0.44772-1 1-1s0.75301 0.506 1 1l1 2h4c0.55401 0 1-0.446 1-1v-7c0-0.554-0.44599-1-1-1h-12zm2 3a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm8 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm-8 7v4h2c0.502 4e-4 0.9265-0.37144 0.99219-0.86914 0.0059-0.047 0.0085325-0.094025 0.0078125-0.14062v-2.9902h-1v3h-1v-3h-1zm5 0v4h1v-1h1v1h1v-1c-7.73e-4 -0.1811-0.05073-0.35867-0.14453-0.51367 0.08369-0.1462 0.14453-0.30573 0.14453-0.48633v-1c0-0.5523-0.4485-1.0293-1-1h-2zm1 1h1v1h-1v-1z" fill="#fc9c9c"/> +<path d="m9.5 0a3 3 0 0 0 -2.9883 2.7773 3 3 0 0 0 -2.0117 -0.77734 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8242v2.1758c0 0.554 0.44599 1 1 1h6c0.55401 0 1-0.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1 -2.2305 3 3 0 0 0 -3 -3zm-5.5 12v1c0 0.55228 0.44772 1 1 1-0.55228 0-1 0.44772-1 1v1h1v-1h1v1h1v-1c0-0.55228-0.44772-1-1-1 0.55228 0 1-0.44772 1-1v-1h-1v1h-1v-1h-1zm5 0v1 3h1v-1h1v1h1v-1c-8.34e-4 -0.17579-0.047991-0.34825-0.13672-0.5 0.088728-0.15175 0.13588-0.32421 0.13672-0.5v-1c0-0.55228-0.44772-1-1-1h-1-1zm1 1h1v1h-1v-1z" fill="#fc9c9c"/> </svg> diff --git a/editor/icons/icon_a_r_v_r_controller.svg b/editor/icons/icon_a_r_v_r_controller.svg new file mode 100644 index 0000000000..a61f99ffdf --- /dev/null +++ b/editor/icons/icon_a_r_v_r_controller.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m2 1c-0.554 0-1 0.446-1 1v6c0 0.554 0.446 1 1 1h12c0.554 0 1-0.446 1-1v-6c0-0.554-0.446-1-1-1h-12zm2 1h2v2h2v2h-2v2h-2v-2h-2v-2h2v-2zm9 1c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1-1-0.44772-1-1 0.44772-1 1-1zm-2 2c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1-1-0.44772-1-1 0.44772-1 1-1zm-7 7v1c0 0.55228 0.44772 1 1 1-0.55228 0-1 0.44772-1 1v1h1v-1h1v1h1v-1c0-0.55228-0.44772-1-1-1 0.55228 0 1-0.44772 1-1v-1h-1v1h-1v-1h-1zm5 0v1 3h1v-1h1v1h1v-1c-8.34e-4 -0.17579-0.047991-0.34825-0.13672-0.5 0.088728-0.15175 0.13588-0.32421 0.13672-0.5v-1c0-0.55228-0.44772-1-1-1h-1-1zm1 1h1v1h-1v-1z" fill="#fc9c9c"/> +</svg> diff --git a/editor/icons/icon_a_r_v_r_origin.svg b/editor/icons/icon_a_r_v_r_origin.svg new file mode 100644 index 0000000000..53a149cec6 --- /dev/null +++ b/editor/icons/icon_a_r_v_r_origin.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m7 1v3h2v-3h-2zm-4 4v2h3v-2h-3zm5 0c-0.55228 0-1 0.44772-1 1s0.44772 1 1 1 1-0.44772 1-1-0.44772-1-1-1zm2 0v2h3v-2h-3zm-3 3v3h2v-3h-2zm-3 4v1c0 0.55228 0.44772 1 1 1-0.55228 0-1 0.44772-1 1v1h1v-1h1v1h1v-1c0-0.55228-0.44772-1-1-1 0.55228 0 1-0.44772 1-1v-1h-1v1h-1v-1h-1zm5 0v1 3h1v-1h1v1h1v-1c-8.34e-4 -0.17579-0.047991-0.34825-0.13672-0.5 0.088728-0.15175 0.13588-0.32421 0.13672-0.5v-1c0-0.55228-0.44772-1-1-1h-1-1zm1 1h1v1h-1v-1z" fill="#fc9c9c"/> +</svg> diff --git a/editor/icons/icon_animated_sprite.svg b/editor/icons/icon_animated_sprite.svg index fe7fde5a39..6fdf8a7a40 100644 --- a/editor/icons/icon_animated_sprite.svg +++ b/editor/icons/icon_animated_sprite.svg @@ -1,7 +1,7 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" fill="#a5b7f3"> -<path transform="translate(0 1036.4)" d="m10.5 0a5.5 5.5 0 0 0 -5.3301 4.1699 5.5 5.5 0 0 1 1.3301 -0.16992 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.16992 1.3301 5.5 5.5 0 0 0 4.1699 -5.3301 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".39216"/> -<path transform="translate(0 1036.4)" d="m8.5 2a5.5 5.5 0 0 0 -4.7559 2.748 5.5 5.5 0 0 1 2.7559 -0.74805 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.74414 2.752 5.5 5.5 0 0 0 2.7441 -4.752 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".58824"/> -<path transform="translate(0 1036.4)" d="m6.5 4a5.5 5.5 0 0 0 -5.5 5.5 5.5 5.5 0 0 0 5.5 5.5 5.5 5.5 0 0 0 5.5 -5.5 5.5 5.5 0 0 0 -5.5 -5.5zm-2.5 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-5 3h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25 -1.7324z"/> +<g fill="#a5b7f3"> +<path d="m7 0c-1.108 0-2 0.89199-2 2h7c1.108 0 2 0.89199 2 2v6c1.108 0 2-0.89199 2-2v-6c0-1.108-0.89199-2-2-2z" fill-opacity=".39216"/> +<path d="m5 2c-1.108 0-2 0.89199-2 2h7c1.108 0 2 0.89199 2 2v7c1.108 0 2-0.89199 2-2v-7c0-1.108-0.89199-2-2-2h-7z" fill-opacity=".58824"/> +<path d="m3 4c-1.108 0-2 0.89199-2 2v7c0 1.108 0.89199 2 2 2h7c1.108 0 2-0.89199 2-2v-7c0-1.108-0.89199-2-2-2h-7zm0 4c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm7 0c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm-6 4h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25 -1.7324z"/> </g> </svg> diff --git a/editor/icons/icon_animated_sprite_3d.svg b/editor/icons/icon_animated_sprite_3d.svg index 658ba3e5c2..ccc836832c 100644 --- a/editor/icons/icon_animated_sprite_3d.svg +++ b/editor/icons/icon_animated_sprite_3d.svg @@ -1,7 +1,7 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" fill="#fc9c9c"> -<path transform="translate(0 1036.4)" d="m10.5 0a5.5 5.5 0 0 0 -5.3301 4.1699 5.5 5.5 0 0 1 1.3301 -0.16992 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.16992 1.3301 5.5 5.5 0 0 0 4.1699 -5.3301 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".39216"/> -<path transform="translate(0 1036.4)" d="m8.5 2a5.5 5.5 0 0 0 -4.7559 2.748 5.5 5.5 0 0 1 2.7559 -0.74805 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.74414 2.752 5.5 5.5 0 0 0 2.7441 -4.752 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".58824"/> -<path transform="translate(0 1036.4)" d="m6.5 4a5.5 5.5 0 0 0 -5.5 5.5 5.5 5.5 0 0 0 5.5 5.5 5.5 5.5 0 0 0 5.5 -5.5 5.5 5.5 0 0 0 -5.5 -5.5zm-2.5 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-5 3h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25 -1.7324z"/> +<g fill="#fc9c9c"> +<path d="m7 0c-1.108 0-2 0.89199-2 2h7c1.108 0 2 0.89199 2 2v6c1.108 0 2-0.89199 2-2v-6c0-1.108-0.89199-2-2-2z" fill-opacity=".39216"/> +<path d="m5 2c-1.108 0-2 0.89199-2 2h7c1.108 0 2 0.89199 2 2v7c1.108 0 2-0.89199 2-2v-7c0-1.108-0.89199-2-2-2h-7z" fill-opacity=".58824"/> +<path d="m3 4c-1.108 0-2 0.89199-2 2v7c0 1.108 0.89199 2 2 2h7c1.108 0 2-0.89199 2-2v-7c0-1.108-0.89199-2-2-2h-7zm0 4c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm7 0c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm-6 4h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25 -1.7324z"/> </g> </svg> diff --git a/editor/icons/icon_center_container.svg b/editor/icons/icon_center_container.svg index 446e9e0f9c..fc0abc5c28 100644 --- a/editor/icons/icon_center_container.svg +++ b/editor/icons/icon_center_container.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm0 2h10v10h-10v-10zm3 1l2 2 2-2h-4zm-2 2v4l2-2-2-2zm8 0l-2 2 2 2v-4zm-4 4l-2 2h4l-2-2z" fill="#a5efac"/> -</g> +<path d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm0 2h10v10h-10v-10zm3 1l2 2 2-2h-4zm-2 2v4l2-2-2-2zm8 0l-2 2 2 2v-4zm-4 4l-2 2h4l-2-2z" fill="#a5efac"/> </svg> diff --git a/editor/icons/icon_color_pick.svg b/editor/icons/icon_color_pick.svg index 893afb4eb4..5c21eeba8b 100644 --- a/editor/icons/icon_color_pick.svg +++ b/editor/icons/icon_color_pick.svg @@ -1,5 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m13.051 0.97852a2 2 0 0 0 -1.4434 0.58594l-1.4141 1.4141-1.416-1.4141-1.4141 1.4141 1.4141 1.4141-7.0703 7.0723-0.35352 1.7676-0.35352 1.7676 1.7676-0.35352 1.7676-0.35352 7.0723-7.0703 1.4141 1.4141 1.4141-1.4141-1.4141-1.416 1.4141-1.4141a2 2 0 0 0 0 -2.8281 2 2 0 0 0 -1.3848 -0.58594zm-3.5664 4.1211l1.416 1.416-7.0723 7.0703-0.70703-0.70703-0.70703-0.70703 7.0703-7.0723z" fill="#e0e0e0" fill-opacity=".99608"/> +<path transform="translate(0 1036.4)" d="m8 1c-1.108 0-2 0.892-2 2v2h-1v2h1v5a2 2 0 0 0 1 1.7285v1.2715h2v-1.2695a2 2 0 0 0 1 -1.7305v-5h1v-2h-1v-2c0-1.108-0.892-2-2-2zm-1 6h2v5a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1v-5z" fill="#e0e0e0"/> </g> </svg> diff --git a/editor/icons/icon_color_picker.svg b/editor/icons/icon_color_picker.svg index 272dfeca48..55c55fe205 100644 --- a/editor/icons/icon_color_picker.svg +++ b/editor/icons/icon_color_picker.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m13.051 0.97852a2 2 0 0 0 -1.4434 0.58594l-1.4141 1.4141-1.416-1.4141-1.4141 1.4141 1.4141 1.4141-7.0703 7.0723-0.35352 1.7676-0.35352 1.7676 1.7676-0.35352 1.7676-0.35352 7.0723-7.0703 1.4141 1.4141 1.4141-1.4141-1.4141-1.416 1.4141-1.4141a2 2 0 0 0 0 -2.8281 2 2 0 0 0 -1.3848 -0.58594zm-3.5664 4.1211l1.416 1.416-7.0723 7.0703-0.70703-0.70703-0.70703-0.70703 7.0703-7.0723z" fill="#a5efac"/> -</g> +<path d="m8 1c-1.108 0-2 0.892-2 2v2h-1v2h1v5a2 2 0 0 0 1 1.7285v1.2715h2v-1.2695a2 2 0 0 0 1 -1.7305v-5h1v-2h-1v-2c0-1.108-0.892-2-2-2zm-1 6h2v5a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1v-5z" fill="#a5efac"/> </svg> diff --git a/editor/icons/icon_color_picker_button.svg b/editor/icons/icon_color_picker_button.svg index 5d734a5b20..d8de02b298 100644 --- a/editor/icons/icon_color_picker_button.svg +++ b/editor/icons/icon_color_picker_button.svg @@ -1,7 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m13.051 0.97852a2 2 0 0 0 -1.4434 0.58594l-1.4141 1.4141-1.416-1.4141-1.4141 1.4141 1.4141 1.4141-7.0703 7.0723-0.35352 1.7676-0.35352 1.7676 1.7676-0.35352 1.7676-0.35352 7.0723-7.0703 1.4141 1.4141 1.4141-1.4141-1.4141-1.416 1.4141-1.4141a2 2 0 0 0 0 -2.8281 2 2 0 0 0 -1.3848 -0.58594zm-3.5664 4.1211 1.416 1.416-7.0723 7.0703-0.70703-0.70703-0.70703-0.70703 7.0703-7.0723z" fill="#a5efac"/> -<path transform="translate(0 1036.4)" d="m1 3v6.3438l4.9492-4.9512-1.3926-1.3926h-3.5566zm14 6.4863l-1.5137 1.5137h-0.92969l-0.94922-0.94922-2.9492 2.9492h6.3418v-3.5137z" fill="#a5efac"/> -<path transform="translate(0 1036.4)" d="m10.658 11l-2 2h6.3418v-2h-1.5137-0.92969-1.8984z" fill-opacity=".078431"/> -</g> +<path d="m13 1c-1.108 0-2 0.892-2 2v2h-1v2h1v5a2 2 0 0 0 1 1.7285v1.2715h2v-1.2695a2 2 0 0 0 1 -1.7305v-5h1v-2h-1v-2c0-1.108-0.892-2-2-2zm-9 1v3.1328l-1.4453-0.96484-1.1094 1.6641 3 2c0.3359 0.2239 0.77347 0.2239 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-3.1328h-2zm8 5h2v5a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1v-5zm-8.5 3c-0.831 0-1.5 0.669-1.5 1.5v0.5 1h-1v2h8v-2h-1v-1-0.5c0-0.831-0.669-1.5-1.5-1.5h-3z" fill="#a5efac"/> </svg> diff --git a/editor/icons/icon_connection_and_groups.svg b/editor/icons/icon_connection_and_groups.svg deleted file mode 100644 index 67a73f02b3..0000000000 --- a/editor/icons/icon_connection_and_groups.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m2 0v1 5 1h12v-1-6h-11-1zm1 1h10v5h-10v-5zm2.5 1a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5zm5 0a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5zm-0.5 7a2 2 0 0 0 -2 2v1h-6v1h6v1a2 2 0 0 0 2 2h2v-1h2v-1h-2v-3h2v-1h-2v-1h-2z" fill="#e0e0e0"/> -</g> -</svg> diff --git a/editor/icons/icon_control_layout.svg b/editor/icons/icon_control_layout.svg new file mode 100644 index 0000000000..4bf60cf751 --- /dev/null +++ b/editor/icons/icon_control_layout.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m1 1v14h14v-14zm2 2h3v3h-3zm5 0h5v3h-5zm-5 5h3v5h-3zm5 0h5v5h-5z" fill="#a5efac"/> +</svg> diff --git a/editor/icons/icon_edit.svg b/editor/icons/icon_edit.svg index b1bce158c4..1805aab54f 100644 --- a/editor/icons/icon_edit.svg +++ b/editor/icons/icon_edit.svg @@ -1,5 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<path d="m1.7071 1047.8-0.70711 3.5356l3.5355-0.7071 7.7782-7.7782-2.8284-2.8284zm9.1924-9.1924 2.8284 2.8285 1.4142-1.4142-2.8284-2.8285z" fill="#e0e0e0"/> +<path transform="translate(0 1036.4)" d="m7 1c-0.554 0-1 0.446-1 1v2h4v-2c0-0.554-0.446-1-1-1h-2zm-1 4v7l2 3 2-3v-7h-4zm1 1h1v5h-1v-5z" fill="#e0e0e0"/> </g> </svg> diff --git a/editor/icons/icon_edit_key.svg b/editor/icons/icon_edit_key.svg index 2959900d04..443a9a0455 100644 --- a/editor/icons/icon_edit_key.svg +++ b/editor/icons/icon_edit_key.svg @@ -1,6 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" fill="#e0e0e0"> -<path d="m1.7071 1047.8-0.70711 3.5356l3.5355-0.7071 7.7782-7.7782-2.8284-2.8284zm9.1924-9.1924 2.8284 2.8285 1.4142-1.4142-2.8284-2.8285z"/> -<ellipse cx="3.5" cy="1039.9" rx="2.5" ry="2.5"/> +<g transform="translate(0 -1036.4)"> +<path transform="translate(0 1036.4)" d="m12 1c-0.554 0-1 0.446-1 1v2h4v-2c0-0.554-0.446-1-1-1h-2zm-7 3c-0.195 0-0.38964 0.07519-0.53906 0.22461l-3.2363 3.2363c-0.29884 0.29884-0.29884 0.77929 0 1.0781l3.2363 3.2363c0.29884 0.29884 0.77929 0.29884 1.0781 0l3.2363-3.2363c0.29884-0.29884 0.29884-0.77929 0-1.0781l-3.2363-3.2363c-0.14942-0.14942-0.34406-0.22461-0.53906-0.22461zm6 1v7l2 3 2-3v-7h-4zm1 1h1v5h-1v-5z" fill="#e0e0e0"/> </g> </svg> diff --git a/editor/icons/icon_groups.svg b/editor/icons/icon_groups.svg index 37e40749b8..55cf3c48eb 100644 --- a/editor/icons/icon_groups.svg +++ b/editor/icons/icon_groups.svg @@ -1,7 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<rect x="1" y="1040.4" width="14" height="8" fill="none" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="2"/> -<ellipse cx="5" cy="1044.4" rx="2" ry="2" fill="#e0e0e0"/> -<ellipse cx="11" cy="1044.4" rx="2" ry="2" fill="#e0e0e0"/> +<path transform="translate(0 1036.4)" d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h12a1.0001 1.0001 0 0 0 1 -1v-12a1.0001 1.0001 0 0 0 -1 -1h-12zm1 2h10v10h-10v-10zm5 2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#e0e0e0" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> </g> </svg> diff --git a/editor/icons/icon_key_move_enabled.svg b/editor/icons/icon_key_position.svg index 203b697ad2..203b697ad2 100644 --- a/editor/icons/icon_key_move_enabled.svg +++ b/editor/icons/icon_key_position.svg diff --git a/editor/icons/icon_key_rotate_enabled.svg b/editor/icons/icon_key_rotation.svg index 0f975631b2..0f975631b2 100644 --- a/editor/icons/icon_key_rotate_enabled.svg +++ b/editor/icons/icon_key_rotation.svg diff --git a/editor/icons/icon_key_scale_enabled.svg b/editor/icons/icon_key_scale.svg index eaa12fdf0e..eaa12fdf0e 100644 --- a/editor/icons/icon_key_scale_enabled.svg +++ b/editor/icons/icon_key_scale.svg diff --git a/editor/icons/icon_kinematic_body.svg b/editor/icons/icon_kinematic_body.svg index 393e21a529..6f8d69fa53 100644 --- a/editor/icons/icon_kinematic_body.svg +++ b/editor/icons/icon_kinematic_body.svg @@ -1,5 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m4 4v1h1v-1h-1zm1 1v1h-1v1h-1v1h-1v1 2h1v-2h1v1 1h1v-1h5v1h1v-2h1v2h1v-2-1h-1v-1h-1v-1h-1v-1h-1v1h-3v-1h-1zm5 0h1v-1h-1v1zm0 6h-2v1h2v-1zm-5 0v1h2v-1h-2zm0-4h1v1h-1v-1zm4 0h1v1h-1v-1z" fill="#fc9c9c" fill-opacity=".99608"/> +<path transform="translate(0 1036.4)" d="m6 1c-0.55401 0-1 0.44599-1 1v3c0 0.55401 0.44599 1 1 1h1v0.99023a1.0001 1.0001 0 0 0 -0.31641 0.0625l-2.0508 0.68359-0.68359-2.0508a1.0001 1.0001 0 0 0 -0.99023 -0.69727 1.0001 1.0001 0 0 0 -0.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656 0.63281l1.6836-0.56055v0.61133c0 0.040884 0.018715 0.075662 0.023438 0.11523l-4.5781 3.0527a1.0001 1.0001 0 1 0 1.1094 1.6641l5.0566-3.3711 1.4941 2.9863a1.0001 1.0001 0 0 0 1.2109 0.50195l3-1a1.0001 1.0001 0 1 0 -0.63281 -1.8965l-2.1777 0.72461-0.97461-1.9512c0.2759-0.17764 0.46875-0.47227 0.46875-0.82617v-1h1.3828l0.72266 1.4473a1.0001 1.0001 0 1 0 1.7891 -0.89453l-1-2a1.0001 1.0001 0 0 0 -0.89453 -0.55273h-3v-1h1c0.55401 0 1-0.44599 1-1v-3c0-0.55401-0.44599-1-1-1h-4zm0 2h1v2h-1v-2z" fill="#fc9c9c" fill-opacity=".99608"/> </g> </svg> diff --git a/editor/icons/icon_kinematic_body_2d.svg b/editor/icons/icon_kinematic_body_2d.svg index e269efd12a..51026e5f28 100644 --- a/editor/icons/icon_kinematic_body_2d.svg +++ b/editor/icons/icon_kinematic_body_2d.svg @@ -1,5 +1,7 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m4 4v1h1v-1h-1zm1 1v1h-1v1h-1v1h-1v1 2h1v-2h1v1 1h1v-1h5v1h1v-2h1v2h1v-2-1h-1v-1h-1v-1h-1v-1h-1v1h-3v-1h-1zm5 0h1v-1h-1v1zm0 6h-2v1h2v-1zm-5 0v1h2v-1h-2zm0-4h1v1h-1v-1zm4 0h1v1h-1v-1z" fill="#a5b7f3" fill-opacity=".98824"/> +<g transform="translate(.49212 -.0044019)" fill="#a5b7f5" fill-opacity=".98824"> +<path transform="translate(0 1036.4)" d="m6 1c-0.55401 0-1 0.44599-1 1v3c0 0.55401 0.44599 1 1 1h1v0.99023a1.0001 1.0001 0 0 0 -0.31641 0.0625l-2.0508 0.68359-0.68359-2.0508a1.0001 1.0001 0 0 0 -0.99023 -0.69727 1.0001 1.0001 0 0 0 -0.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656 0.63281l1.6836-0.56055v0.61133c0 0.04088 0.018715 0.07566 0.023437 0.11523l-4.5781 3.0527a1.0001 1.0001 0 1 0 1.1094 1.6641l5.0566-3.3711 1.4941 2.9863a1.0001 1.0001 0 0 0 1.2109 0.50195l3-1a1.0001 1.0001 0 1 0 -0.63281 -1.8965l-2.1777 0.72461-0.97461-1.9512c0.2759-0.17764 0.46875-0.47227 0.46875-0.82617v-1h1.3828l0.72266 1.4473a1.0001 1.0001 0 1 0 1.7891 -0.89453l-1-2a1.0001 1.0001 0 0 0 -0.89453 -0.55273h-3v-1h1c0.55401 0 1-0.44599 1-1v-3c0-0.55401-0.44599-1-1-1zm0 2h1v2h-1z" fill="#a5b7f5" fill-opacity=".98824"/> +</g> </g> </svg> diff --git a/editor/icons/icon_multi_edit.svg b/editor/icons/icon_multi_edit.svg index 36f62006e0..9a1cfe8e16 100644 --- a/editor/icons/icon_multi_edit.svg +++ b/editor/icons/icon_multi_edit.svg @@ -1,5 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m12.314 0.85742l-1.4141 1.4141 2.8281 2.8281 1.4141-1.4141-2.8281-2.8281zm-11.314 0.14258v2h2v-2h-2zm4 0v2h2v-2h-2zm4.4844 2.6855l-7.7773 7.7793-0.70703 3.5352 3.5352-0.70703 7.7793-7.7773-2.8301-2.8301zm-8.4844 1.3145v2h2v-2h-2z" fill="#e0e0e0"/> +<path transform="translate(0 1036.4)" d="m2 1c-0.554 0-1 0.446-1 1v2h4v-2c0-0.554-0.446-1-1-1h-2zm-1 4v7l2 3 2-3v-7h-4zm1 1h1v5h-1v-5zm8 1v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2z" fill="#e0e0e0"/> </g> </svg> diff --git a/editor/icons/icon_shader.svg b/editor/icons/icon_shader.svg new file mode 100644 index 0000000000..659d81519a --- /dev/null +++ b/editor/icons/icon_shader.svg @@ -0,0 +1,12 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<g> +<path d="m2 1c-0.55226 1e-4 -0.99994 0.4477-1 1v12c5.52e-5 0.5523 0.44774 0.9999 1 1h12c0.55226-1e-4 0.99994-0.4477 1-1v-8l-5-5zm1 2h6v3c0 0.554 0.44599 1 1 1h3v6h-10z" fill="#e0e0e0"/> +<path d="m10 11h2v1h-2z" fill="#9f70ff"/> +<path d="m4 6h2v1h-2z" fill="#ffeb70"/> +<path d="m8 8h4v1h-4z" fill="#9dff70"/> +<path d="m7 6h1v1h-1z" fill="#70deff"/> +<path d="m4 11h5v1h-5z" fill="#ff70ac"/> +<path d="m4 4h3v1h-3z" fill="#ff7070"/> +<path d="m4 8h3v1h-3z" fill="#70ffb9"/> +</g> +</svg> diff --git a/editor/icons/icon_connect.svg b/editor/icons/icon_signals.svg index 97859370b7..97859370b7 100644 --- a/editor/icons/icon_connect.svg +++ b/editor/icons/icon_signals.svg diff --git a/editor/icons/icon_signals_and_groups.svg b/editor/icons/icon_signals_and_groups.svg new file mode 100644 index 0000000000..5dedbaa433 --- /dev/null +++ b/editor/icons/icon_signals_and_groups.svg @@ -0,0 +1,5 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<g transform="translate(0 -1036.4)"> +<path transform="translate(0 1036.4)" d="m6 0c-0.55228 0-1 0.4477-1 1s0.44772 1 1 1c4.4301 0 8 3.5699 8 8 0 0.5523 0.44772 1 1 1s1-0.4477 1-1c0-5.511-4.489-10-10-10zm0 4c-0.55228 0-1 0.4477-1 1s0.44772 1 1 1c2.221 0 4 1.779 4 4 0 0.5523 0.44772 1 1 1s1-0.4477 1-1c0-3.3018-2.6981-6-6-6zm-5 4a1.0001 1.0001 0 0 0 -1 1v6a1.0001 1.0001 0 0 0 1 1h6a1.0001 1.0001 0 0 0 1 -1v-6a1.0001 1.0001 0 0 0 -1 -1h-6zm1 2h4v4h-4v-4z" fill="#e0e0e0"/> +</g> +</svg> diff --git a/editor/icons/icon_sprite.svg b/editor/icons/icon_sprite.svg index 4feea4d265..09fc2f0979 100644 --- a/editor/icons/icon_sprite.svg +++ b/editor/icons/icon_sprite.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-4 5a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm8 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-7 3h6a3 3 0 0 1 -1.5 2.5977 3 3 0 0 1 -3 0 3 3 0 0 1 -1.5 -2.5977z" fill="#a5b7f3"/> -</g> +<path d="m5 1c-2.216 0-4 1.784-4 4v6c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4v-6c0-2.216-1.784-4-4-4h-6zm-1 5c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm8 0c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm-1.8887 5.1074a1.0001 1.0001 0 0 1 0.7168 1.7207c-0.74987 0.74987-1.7676 1.1719-2.8281 1.1719s-2.0783-0.422-2.8281-1.1719a1.0001 1.0001 0 0 1 0.69727 -1.7168 1.0001 1.0001 0 0 1 0.7168 0.30273c0.37534 0.37535 0.88325 0.58594 1.4141 0.58594s1.0387-0.21059 1.4141-0.58594a1.0001 1.0001 0 0 1 0.69727 -0.30664z" fill="#a5b7f6" fill-opacity=".98824"/> </svg> diff --git a/editor/icons/icon_sprite_3d.svg b/editor/icons/icon_sprite_3d.svg index 0d5caae501..eb163e3f43 100644 --- a/editor/icons/icon_sprite_3d.svg +++ b/editor/icons/icon_sprite_3d.svg @@ -1,5 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-4 5a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm8 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-7 3h6a3 3 0 0 1 -1.5 2.5977 3 3 0 0 1 -3 0 3 3 0 0 1 -1.5 -2.5977z" fill="#fc9c9c" fill-opacity=".99608"/> +<g fill="#fc9c9c"> +<path d="m5 1c-2.216 0-4 1.784-4 4v6c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4v-6c0-2.216-1.784-4-4-4zm-1 5c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm8 0c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm-1.8887 5.1074a1.0001 1.0001 0 0 1 0.7168 1.7207c-0.74987 0.74987-1.7676 1.1719-2.8281 1.1719s-2.0783-0.422-2.8281-1.1719a1.0001 1.0001 0 0 1 0.69727 -1.7168 1.0001 1.0001 0 0 1 0.7168 0.30273c0.37534 0.37535 0.88325 0.58594 1.4141 0.58594s1.0387-0.21059 1.4141-0.58594a1.0001 1.0001 0 0 1 0.69727 -0.30664z" fill="#fc9c9c"/> </g> </svg> diff --git a/editor/icons/icon_sprite_frames.svg b/editor/icons/icon_sprite_frames.svg index e797819892..8123cbd6b4 100644 --- a/editor/icons/icon_sprite_frames.svg +++ b/editor/icons/icon_sprite_frames.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 5 -5 5 5 0 0 0 -5 -5zm-3 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm4 2v2h2v-2h-2zm-5.0039 0.49219a0.50005 0.50005 0 0 1 0.35742 0.86133c-0.61785 0.6179-1.4924 0.89648-2.3535 0.89648s-1.7357-0.27858-2.3535-0.89648a0.50005 0.50005 0 0 1 0.34766 -0.85742 0.50005 0.50005 0 0 1 0.35938 0.15039c0.38215 0.3822 1.0076 0.60352 1.6465 0.60352s1.2643-0.22132 1.6465-0.60352a0.50005 0.50005 0 0 1 0.34961 -0.1543zm2.0039 2.5078v2h2v-2h-2zm3 0v2h2v-2h-2zm-6 3v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2z" fill="#e0e0e0"/> -</g> +<path d="m3 1c-1.108 0-2 0.89199-2 2v6c0 1.108 0.89199 2 2 2h6c1.108 0 2-0.89199 2-2v-6c0-1.108-0.89199-2-2-2h-6zm10 0v2h2v-2h-2zm-10 4c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm6 0c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm4 0v2h2v-2h-2zm-9 4h2 2a2 1 0 0 1 -1 0.86523 2 1 0 0 1 -2 0 2 1 0 0 1 -1 -0.86523zm9 0v2h2v-2h-2zm-12 4v2h2v-2h-2zm4 0v2h2v-2h-2zm4 0v2h2v-2h-2zm4 0v2h2v-2h-2z" fill="#e0e0e0"/> </svg> diff --git a/editor/icons/icon_viewport_speed.svg b/editor/icons/icon_viewport_speed.svg new file mode 100644 index 0000000000..e64b5a8059 --- /dev/null +++ b/editor/icons/icon_viewport_speed.svg @@ -0,0 +1,4 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333333 4.2333333" xmlns="http://www.w3.org/2000/svg"> +<path d="m1.5875 0c-0.28858 0-0.52917 0.24059-0.52917 0.52917v0.61132c-0.085589-0.051-0.18113-0.0891-0.28525-0.0853-0.34849 0.0127-0.5952 0.37346-0.48059 0.70278l0.26355 0.79066c0.048664 0.14623 0.15979 0.24805 0.29249 0.30644l-0.60927 0.40669c-0.13121 0.0845-0.22102 0.22389-0.24133 0.3633-0.020312 0.13941 0.017471 0.26985 0.087333 0.37465s0.17614 0.19045 0.31264 0.22532c0.13634 0.0348 0.29946 6e-3 0.42788-0.0827h5.159e-4l1.0852-0.72348 0.26097 0.52192c0.11682 0.23391 0.39274 0.34829 0.64079 0.26561l0.79375-0.26458-0.00775 3e-3c0.15105-0.0454 0.27732-0.15615 0.33486-0.2863 0.057538-0.13015 0.055144-0.26773 0.014986-0.38809-0.03156-0.0946-0.10972-0.1687-0.19275-0.23617 0.069099-0.0546 0.1445-0.10364 0.18035-0.19325 0.051761-0.12941 0.045257-0.29292-0.02377-0.43098l-0.26459-0.52946c-0.089407-0.17933-0.27348-0.29308-0.47335-0.29305h-0.1111c0.052029-0.0817 0.1111-0.16214 0.1111-0.26458v-0.79375c0-0.28858-0.24059-0.52917-0.52917-0.52917z" color="#000000" color-rendering="auto" dominant-baseline="auto" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> +<path d="m1.5875 0.26458c-0.14658 0-0.26458 0.118-0.26458 0.26459v0.79375c0 0.14658 0.118 0.26458 0.26458 0.26458h0.26458v0.262a0.26461 0.26461 0 0 0 -0.083716 0.0165l-0.5426 0.18086-0.18087-0.5426a0.26461 0.26461 0 0 0 -0.262 -0.18448 0.26461 0.26461 0 0 0 -0.2403 0.3514l0.26458 0.79375a0.26461 0.26461 0 0 0 0.33486 0.16743l0.44545-0.14831v0.16174c0 0.0108 0.00495 0.02 0.0062 0.0305l-1.2113 0.80771a0.26461 0.26461 0 1 0 0.29352 0.44028l1.3379-0.89194 0.39532 0.79014a0.26461 0.26461 0 0 0 0.32039 0.1328l0.79375-0.26458a0.26461 0.26461 0 1 0 -0.16743 -0.50175l-0.57619 0.19172-0.25787-0.51625c0.072998-0.047 0.12402-0.12495 0.12402-0.21859v-0.26458h0.36587l0.1912 0.38292a0.26461 0.26461 0 1 0 0.47336 -0.23668l-0.26458-0.52916a0.26461 0.26461 0 0 0 -0.23668 -0.14625h-0.79375v-0.26458h0.26458c0.14658 0 0.26458-0.118 0.26458-0.26458v-0.79375c0-0.14659-0.118-0.26459-0.26458-0.26459zm0 0.52917h0.26458v0.52917h-0.26458z" fill="#fff" fill-opacity=".99608"/> +</svg> diff --git a/editor/icons/icon_viewport_sprite.svg b/editor/icons/icon_viewport_sprite.svg deleted file mode 100644 index 4b8bbeaeba..0000000000 --- a/editor/icons/icon_viewport_sprite.svg +++ /dev/null @@ -1,7 +0,0 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<rect x="20" y="1042.4" width="1" height="1" fill="#fefeff"/> -<rect x="29" y="1042.4" width="1" height="1" fill="#fefeff"/> -<path transform="translate(0 1036.4)" d="m3 2c-0.5304 8.01e-5 -1.0391 0.21085-1.4141 0.58594-0.37509 0.37501-0.58586 0.88366-0.58594 1.4141v8c8.03e-5 0.5304 0.21085 1.0391 0.58594 1.4141 0.37501 0.37509 0.88366 0.58586 1.4141 0.58594h10c1.1046 0 2-0.89543 2-2v-8c0-1.1046-0.89543-2-2-2h-10zm0 1h10c0.55228 9.6e-6 0.99999 0.44772 1 1v8c-1e-5 0.55228-0.44772 0.99999-1 1h-10c-0.55228-1e-5 -0.99999-0.44772-1-1v-8c9.6e-6 -0.55228 0.44772-0.99999 1-1zm1 3v2h2v-2h-2zm6 0v2h2v-2h-2zm-6 3v1h8v-1h-8z" fill="#a5b7f3" fill-opacity=".98824"/> -</g> -</svg> diff --git a/editor/icons/icon_viewport_zoom.svg b/editor/icons/icon_viewport_zoom.svg new file mode 100644 index 0000000000..18d4ec32ce --- /dev/null +++ b/editor/icons/icon_viewport_zoom.svg @@ -0,0 +1,6 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<g> +<path d="m6 0c-3.3019 0-6 2.6981-6 6s2.6981 6 6 6h0.00195c0.88828 0 1.737-0.2588 2.5332-0.6367l3.8281 3.8281c0.39053 0.3904 1.0235 0.3904 1.4141 0l1.4141-1.4141c0.39033-0.3905 0.39033-1.0235 0-1.414l-3.791-3.791c0.02779-0.058 0.06588-0.1109 0.0918-0.17 0.05554-0.1268 0.08414-0.2638 0.08398-0.4023h1.4238c0.55226-1e-4 0.99994-0.4477 1-1v-1h1c0.55226-1e-4 0.99994-0.4477 1-1v-2c-5.5e-5 -0.5523-0.44774-0.9999-1-1h-1v-1c-5.5e-5 -0.5523-0.44774-0.9999-1-1h-2c-0.55226 1e-4 -0.99994 0.4477-1 1v1h-0.00977c1.44e-4 -0.3151-0.14822-0.6118-0.40039-0.8008-1.0353-0.7764-2.2938-1.1967-3.5879-1.1992h-0.00195z" color="#000000" color-rendering="auto" dominant-baseline="auto" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> +<path d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 2.752 -0.83398l4.3184 4.3184 1.4141-1.4141-4.3184-4.3184a5 5 0 0 0 0.41016 -0.75195h-0.57617v-2h-1a3 3 0 0 1 -3 3 3 3 0 0 1 -3 -3 3 3 0 0 1 3 -3 3 3 0 0 1 2 0.76758v-1.7676h0.99023a5 5 0 0 0 -2.9902 -1zm5 0v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#fff"/> +</g> +</svg> diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp index 7edaf0e5af..20392a67a7 100644 --- a/editor/node_dock.cpp +++ b/editor/node_dock.cpp @@ -56,10 +56,10 @@ void NodeDock::_bind_methods() { void NodeDock::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - connections_button->set_icon(get_icon("Connect", "EditorIcons")); + connections_button->set_icon(get_icon("Signals", "EditorIcons")); groups_button->set_icon(get_icon("Groups", "EditorIcons")); } else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - connections_button->set_icon(get_icon("Connect", "EditorIcons")); + connections_button->set_icon(get_icon("Signals", "EditorIcons")); groups_button->set_icon(get_icon("Groups", "EditorIcons")); } } diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index bdfe380211..2b9c625aa4 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -557,7 +557,7 @@ void AnimationPlayerEditor::_animation_blend() { String current = animation->get_item_text(animation->get_selected()); - blend_editor.dialog->popup_centered(Size2(400, 400)); + blend_editor.dialog->popup_centered(Size2(400, 400) * EDSCALE); blend_editor.tree->set_hide_root(true); blend_editor.tree->set_column_min_width(0, 10); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 4b216d63f5..3f64e75bc8 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2806,12 +2806,16 @@ void CanvasItemEditor::_notification(int p_what) { unlock_button->set_icon(get_icon("Unlock", "EditorIcons")); group_button->set_icon(get_icon("Group", "EditorIcons")); ungroup_button->set_icon(get_icon("Ungroup", "EditorIcons")); + key_loc_button->set_icon(get_icon("KeyPosition", "EditorIcons")); + key_rot_button->set_icon(get_icon("KeyRotation", "EditorIcons")); + key_scale_button->set_icon(get_icon("KeyScale", "EditorIcons")); key_insert_button->set_icon(get_icon("Key", "EditorIcons")); zoom_minus->set_icon(get_icon("ZoomLess", "EditorIcons")); zoom_reset->set_icon(get_icon("ZoomReset", "EditorIcons")); zoom_plus->set_icon(get_icon("ZoomMore", "EditorIcons")); + presets_menu->set_icon(get_icon("ControlLayout", "EditorIcons")); PopupMenu *p = presets_menu->get_popup(); p->clear(); @@ -3949,30 +3953,24 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { animation_hb->add_child(memnew(VSeparator)); animation_hb->hide(); - key_loc_button = memnew(Button("loc")); + key_loc_button = memnew(Button); key_loc_button->set_toggle_mode(true); key_loc_button->set_flat(true); key_loc_button->set_pressed(true); key_loc_button->set_focus_mode(FOCUS_NONE); - key_loc_button->add_color_override("font_color", Color(1, 0.6, 0.6)); - key_loc_button->add_color_override("font_color_pressed", Color(0.6, 1, 0.6)); key_loc_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_POS)); animation_hb->add_child(key_loc_button); - key_rot_button = memnew(Button("rot")); + key_rot_button = memnew(Button); key_rot_button->set_toggle_mode(true); key_rot_button->set_flat(true); key_rot_button->set_pressed(true); key_rot_button->set_focus_mode(FOCUS_NONE); - key_rot_button->add_color_override("font_color", Color(1, 0.6, 0.6)); - key_rot_button->add_color_override("font_color_pressed", Color(0.6, 1, 0.6)); key_rot_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_ROT)); animation_hb->add_child(key_rot_button); - key_scale_button = memnew(Button("scl")); + key_scale_button = memnew(Button); key_scale_button->set_toggle_mode(true); key_scale_button->set_flat(true); key_scale_button->set_focus_mode(FOCUS_NONE); - key_scale_button->add_color_override("font_color", Color(1, 0.6, 0.6)); - key_scale_button->add_color_override("font_color_pressed", Color(0.6, 1, 0.6)); key_scale_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_SCALE)); animation_hb->add_child(key_scale_button); key_insert_button = memnew(Button); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index d56756502d..84808cb876 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -1409,8 +1409,10 @@ void ScriptEditor::_update_members_overview() { void ScriptEditor::_update_help_overview_visibility() { int selected = tab_container->get_current_tab(); - if (selected < 0 || selected >= tab_container->get_child_count()) + if (selected < 0 || selected >= tab_container->get_child_count()) { + help_overview->set_visible(false); return; + } Node *current = tab_container->get_child(tab_container->get_current_tab()); EditorHelp *se = Object::cast_to<EditorHelp>(current); @@ -1427,6 +1429,7 @@ void ScriptEditor::_update_help_overview_visibility() { } void ScriptEditor::_update_help_overview() { + help_overview->clear(); int selected = tab_container->get_current_tab(); if (selected < 0 || selected >= tab_container->get_child_count()) @@ -1438,8 +1441,6 @@ void ScriptEditor::_update_help_overview() { return; } - help_overview->clear(); - Vector<Pair<String, int> > sections = se->get_sections(); for (int i = 0; i < sections.size(); i++) { help_overview->add_item(sections[i].first); @@ -1447,9 +1448,6 @@ void ScriptEditor::_update_help_overview() { } } -void _help_overview_selected(int p_idx) { -} - void ScriptEditor::_update_script_colors() { bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_enabled"); @@ -1595,6 +1593,8 @@ void ScriptEditor::_update_script_names() { _update_members_overview(); _update_help_overview(); + _update_members_overview_visibility(); + _update_help_overview_visibility(); _update_script_colors(); } diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 32973db6ec..703c9e96b6 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -63,7 +63,8 @@ #define ZOOM_MULTIPLIER 1.08 #define ZOOM_INDICATOR_DELAY_S 1.5 -#define FREELOOK_MIN_SPEED 0.1 +#define FREELOOK_MIN_SPEED 0.01 +#define FREELOOK_SPEED_MULTIPLIER 1.08 #define MIN_Z 0.01 #define MAX_Z 10000 @@ -75,34 +76,66 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) { bool is_orthogonal = camera->get_projection() == Camera::PROJECTION_ORTHOGONAL; - //when not being manipulated, move softly - float free_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia"); - float free_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/translation_inertia"); - //when being manipulated, move more quickly - float manip_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_orbit_inertia"); - float manip_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_translation_inertia"); + Cursor old_camera_cursor = camera_cursor; + camera_cursor = cursor; - float zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia"); + if (p_interp_delta > 0) { - //determine if being manipulated - bool manipulated = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL); + //------- + // Perform smoothing - float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia); - float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia); + if (is_freelook_active()) { - Cursor old_camera_cursor = camera_cursor; - camera_cursor = cursor; + // Higher inertia should increase "lag" (lerp with factor between 0 and 1) + // Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1. + real_t inertia = EDITOR_GET("editors/3d/freelook/freelook_inertia"); + inertia = MAX(0.001, inertia); + real_t factor = (1.0 / inertia) * p_interp_delta; - camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia))); - camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia))); + // We interpolate a different point here, because in freelook mode the focus point (cursor.pos) orbits around eye_pos + camera_cursor.eye_pos = old_camera_cursor.eye_pos.linear_interpolate(cursor.eye_pos, CLAMP(factor, 0, 1)); + //camera_cursor.pos = camera_cursor.eye_pos + (cursor.pos - cursor.eye_pos); - camera_cursor.pos = old_camera_cursor.pos.linear_interpolate(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia))); - camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / zoom_inertia))); + float orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia"); + orbit_inertia = MAX(0.0001, orbit_inertia); + camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia))); + camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia))); + + Vector3 forward = to_camera_transform(camera_cursor).basis.xform(Vector3(0, 0, -1)); + camera_cursor.pos = camera_cursor.eye_pos + forward * camera_cursor.distance; + + } else { - if (p_interp_delta == 0 || is_freelook_active()) { - camera_cursor = cursor; + //when not being manipulated, move softly + float free_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia"); + float free_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/translation_inertia"); + //when being manipulated, move more quickly + float manip_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_orbit_inertia"); + float manip_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_translation_inertia"); + + float zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia"); + + //determine if being manipulated + bool manipulated = Input::get_singleton()->get_mouse_button_mask() & (2 | 4); + manipulated |= Input::get_singleton()->is_key_pressed(KEY_SHIFT); + manipulated |= Input::get_singleton()->is_key_pressed(KEY_ALT); + manipulated |= Input::get_singleton()->is_key_pressed(KEY_CONTROL); + + float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia); + float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia); + zoom_inertia = MAX(0.0001, zoom_inertia); + + camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia))); + camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia))); + + camera_cursor.pos = old_camera_cursor.pos.linear_interpolate(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia))); + camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / zoom_inertia))); + } } + //------- + // Apply camera transform + float tolerance = 0.001; bool equal = true; if (Math::abs(old_camera_cursor.x_rot - camera_cursor.x_rot) > tolerance || Math::abs(old_camera_cursor.y_rot - camera_cursor.y_rot) > tolerance) { @@ -845,11 +878,17 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { switch (b->get_button_index()) { case BUTTON_WHEEL_UP: { - scale_cursor_distance(is_freelook_active() ? zoom_factor : 1.0 / zoom_factor); + if (is_freelook_active()) + scale_freelook_speed(zoom_factor); + else + scale_cursor_distance(1.0 / zoom_factor); } break; case BUTTON_WHEEL_DOWN: { - scale_cursor_distance(is_freelook_active() ? 1.0 / zoom_factor : zoom_factor); + if (is_freelook_active()) + scale_freelook_speed(1.0 / zoom_factor); + else + scale_cursor_distance(zoom_factor); } break; case BUTTON_RIGHT: { @@ -901,10 +940,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (b->is_pressed()) { int mod = _get_key_modifier(b); if (mod == _get_key_modifier_setting("editors/3d/freelook/freelook_activation_modifier")) { - freelook_active = true; + set_freelook_active(true); } } else { - freelook_active = false; + set_freelook_active(false); } if (freelook_active && !surface->has_focus()) { @@ -1645,6 +1684,9 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity"); real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel); + // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag". + Transform prev_camera_transform = to_camera_transform(cursor); + cursor.x_rot += relative.y * radians_per_pixel; cursor.y_rot += relative.x * radians_per_pixel; if (cursor.x_rot > Math_PI / 2.0) @@ -1652,12 +1694,12 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (cursor.x_rot < -Math_PI / 2.0) cursor.x_rot = -Math_PI / 2.0; - // Look is like Orbit, except the cursor translates, not the camera + // Look is like the opposite of Orbit: the focus point rotates around the camera Transform camera_transform = to_camera_transform(cursor); Vector3 pos = camera_transform.xform(Vector3(0, 0, 0)); - Vector3 diff = camera->get_translation() - pos; + Vector3 prev_pos = prev_camera_transform.xform(Vector3(0, 0, 0)); + Vector3 diff = prev_pos - pos; cursor.pos += diff; - freelook_target_position += diff; name = ""; _update_name(); @@ -1755,23 +1797,57 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } +void SpatialEditorViewport::set_freelook_active(bool active_now) { + + if (!freelook_active && active_now) { + // Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential + cursor = camera_cursor; + + // Make sure eye_pos is synced, because freelook referential is eye pos rather than orbit pos + Vector3 forward = to_camera_transform(cursor).basis.xform(Vector3(0, 0, -1)); + cursor.eye_pos = cursor.pos - cursor.distance * forward; + // Also sync the camera cursor, otherwise switching to freelook will be trippy if inertia is active + camera_cursor.eye_pos = cursor.eye_pos; + + if (EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_speed_zoom_link")) { + // Re-adjust freelook speed from the current zoom level + real_t base_speed = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_base_speed"); + freelook_speed = base_speed * cursor.distance; + } + + } else if (freelook_active && !active_now) { + // Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential + cursor = camera_cursor; + } + + freelook_active = active_now; +} + void SpatialEditorViewport::scale_cursor_distance(real_t scale) { // Prevents zero distance which would short-circuit any scaling if (cursor.distance < ZOOM_MIN_DISTANCE) cursor.distance = ZOOM_MIN_DISTANCE; - real_t prev_distance = cursor.distance; cursor.distance *= scale; if (cursor.distance < ZOOM_MIN_DISTANCE) cursor.distance = ZOOM_MIN_DISTANCE; - if (is_freelook_active()) { - // In freelook mode, cursor reference is reversed so it needs to be adjusted - Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1)); - cursor.pos += (cursor.distance - prev_distance) * forward; - } + zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S; + surface->update(); +} + +void SpatialEditorViewport::scale_freelook_speed(real_t scale) { + + // Prevents zero distance which would short-circuit any scaling + if (freelook_speed < FREELOOK_MIN_SPEED) + freelook_speed = FREELOOK_MIN_SPEED; + + freelook_speed *= scale; + + if (freelook_speed < FREELOOK_MIN_SPEED) + freelook_speed = FREELOOK_MIN_SPEED; zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S; surface->update(); @@ -1790,7 +1866,6 @@ Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMous void SpatialEditorViewport::_update_freelook(real_t delta) { if (!is_freelook_active()) { - freelook_target_position = cursor.pos; return; } @@ -1833,21 +1908,15 @@ void SpatialEditorViewport::_update_freelook(real_t delta) { speed_modifier = true; } - real_t inertia = EDITOR_DEF("editors/3d/freelook/freelook_inertia", 0.1); - inertia = MAX(0, inertia); - const real_t base_speed = EDITOR_DEF("editors/3d/freelook/freelook_base_speed", 0.5); - const real_t modifier_speed_factor = EDITOR_DEF("editors/3d/freelook/freelook_modifier_speed_factor", 3); - - real_t speed = base_speed * cursor.distance; - if (speed_modifier) + real_t speed = freelook_speed; + if (speed_modifier) { + real_t modifier_speed_factor = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_modifier_speed_factor"); speed *= modifier_speed_factor; + } - // Higher inertia should increase "lag" (lerp with factor between 0 and 1) - // Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1. - - freelook_target_position += direction * speed; - real_t factor = (1.0 / (inertia + 0.001)) * delta; - cursor.pos = cursor.pos.linear_interpolate(freelook_target_position, CLAMP(factor, 0, 1)); + Vector3 motion = direction * speed * delta; + cursor.pos += motion; + cursor.eye_pos += motion; } void SpatialEditorViewport::set_message(String p_message, float p_time) { @@ -1886,7 +1955,7 @@ void SpatialEditorViewport::_notification(int p_what) { } */ - real_t delta = get_tree()->get_idle_process_time(); + real_t delta = get_process_delta_time(); if (zoom_indicator_delay > 0) { zoom_indicator_delay -= delta; @@ -1897,7 +1966,7 @@ void SpatialEditorViewport::_notification(int p_what) { _update_freelook(delta); - _update_camera(get_process_delta_time()); + _update_camera(delta); Map<Node *, Object *> &selection = editor_selection->get_selection(); @@ -2026,7 +2095,7 @@ void SpatialEditorViewport::_notification(int p_what) { } // TODO That should be part of the drawing API... -static void stroke_rect(CanvasItem *ci, Rect2 rect, Color color, real_t width = 1.0) { +static void stroke_rect(CanvasItem &ci, Rect2 rect, Color color, real_t width = 1.0) { // a---b // | | @@ -2036,10 +2105,31 @@ static void stroke_rect(CanvasItem *ci, Rect2 rect, Color color, real_t width = Vector2 c(rect.position.x, rect.position.y + rect.size.y); Vector2 d(rect.position + rect.size); - ci->draw_line(a, b, color, width); - ci->draw_line(b, d, color, width); - ci->draw_line(d, c, color, width); - ci->draw_line(c, a, color, width); + ci.draw_line(a, b, color, width); + ci.draw_line(b, d, color, width); + ci.draw_line(d, c, color, width); + ci.draw_line(c, a, color, width); +} + +static void draw_indicator_bar(Control &surface, real_t fill, Ref<Texture> icon) { + + // Adjust bar size from control height + Vector2 surface_size = surface.get_size(); + real_t h = surface_size.y / 2.0; + real_t y = (surface_size.y - h) / 2.0; + + Rect2 r(10, y, 6, h); + real_t sy = r.size.y * fill; + + // Note: because this bar appears over the viewport, it has to stay readable for any background color + // Draw both neutral dark and bright colors to account this + surface.draw_rect(r, Color(1, 1, 1, 0.2)); + surface.draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6)); + stroke_rect(surface, r.grow(1), Color(0, 0, 0, 0.7)); + + Vector2 icon_size = icon->get_size(); + Vector2 icon_pos = Vector2(r.position.x - (icon_size.x - r.size.x) / 2, r.position.y + r.size.y + 2); + surface.draw_texture(icon, icon_pos); } void SpatialEditorViewport::_draw() { @@ -2098,35 +2188,47 @@ void SpatialEditorViewport::_draw() { draw_rect = Rect2(Vector2(), s).clip(draw_rect); - stroke_rect(surface, draw_rect, Color(0.6, 0.6, 0.1, 0.5), 2.0); + stroke_rect(*surface, draw_rect, Color(0.6, 0.6, 0.1, 0.5), 2.0); } else { if (zoom_indicator_delay > 0.0) { - // Show indicative zoom factor - real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom? - real_t max_distance = camera->get_zfar(); - real_t scale_length = (max_distance - min_distance); + if (is_freelook_active()) { + // Show speed + + real_t min_speed = FREELOOK_MIN_SPEED; + real_t max_speed = camera->get_zfar(); + real_t scale_length = (max_speed - min_speed); - if (Math::abs(scale_length) > CMP_EPSILON) { - real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length); + if (Math::abs(scale_length) > CMP_EPSILON) { + real_t logscale_t = 1.0 - Math::log(1 + freelook_speed - min_speed) / Math::log(1 + scale_length); - // There is no real maximum distance so that factor can become negative, - // Let's make it look asymptotic instead (will decrease slower and slower). - if (logscale_t < 0.25) - logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0); + // There is no real maximum speed so that factor can become negative, + // Let's make it look asymptotic instead (will decrease slower and slower). + if (logscale_t < 0.25) + logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0); - Vector2 surface_size = surface->get_size(); - real_t h = surface_size.y / 2.0; - real_t y = (surface_size.y - h) / 2.0; + draw_indicator_bar(*surface, 1.0 - logscale_t, get_icon("ViewportSpeed", "EditorIcons")); + } + + } else { + // Show zoom - Rect2 r(10, y, 6, h); - real_t sy = r.size.y * logscale_t; + real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom? + real_t max_distance = camera->get_zfar(); + real_t scale_length = (max_distance - min_distance); - surface->draw_rect(r, Color(1, 1, 1, 0.2)); - surface->draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6)); - stroke_rect(surface, r.grow(1), Color(0, 0, 0, 0.7)); + if (Math::abs(scale_length) > CMP_EPSILON) { + real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length); + + // There is no real maximum distance so that factor can become negative, + // Let's make it look asymptotic instead (will decrease slower and slower). + if (logscale_t < 0.25) + logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0); + + draw_indicator_bar(*surface, logscale_t, get_icon("ViewportZoom", "EditorIcons")); + } } } } @@ -2576,6 +2678,7 @@ void SpatialEditorViewport::reset() { cursor.y_rot = 0.5; cursor.distance = 4; cursor.region_select = false; + cursor.pos = Vector3(); _update_name(); } @@ -3036,6 +3139,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed accept = NULL; freelook_active = false; + freelook_speed = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_base_speed"); selection_menu = memnew(PopupMenu); add_child(selection_menu); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 4f4c540048..a9dd1f1327 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -131,7 +131,7 @@ private: float gizmo_scale; bool freelook_active; - Vector3 freelook_target_position; + real_t freelook_speed; PanelContainer *info; Label *info_label; @@ -231,6 +231,7 @@ private: Vector3 pos; float x_rot, y_rot, distance; + Vector3 eye_pos; // Used in freelook mode bool region_select; Point2 region_begin, region_end; @@ -239,10 +240,17 @@ private: distance = 4; region_select = false; } - } cursor, camera_cursor; + }; + // Viewport camera supports movement smoothing, + // so one cursor is the real cursor, while the other can be an interpolated version. + Cursor cursor; // Immediate cursor + Cursor camera_cursor; // That one may be interpolated (don't modify this one except for smoothing purposes) void scale_cursor_distance(real_t scale); + void set_freelook_active(bool active_now); + void scale_freelook_speed(real_t scale); + real_t zoom_indicator_delay; RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[3], scale_gizmo_instance[3]; diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index 3b6eeb61d6..dc7acd9fdc 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -43,10 +43,10 @@ void SpriteFramesEditor::_notification(int p_what) { } if (p_what == NOTIFICATION_ENTER_TREE) { - load->set_icon(get_icon("Folder", "EditorIcons")); - _delete->set_icon(get_icon("Del", "EditorIcons")); + load->set_icon(get_icon("Load", "EditorIcons")); + _delete->set_icon(get_icon("Remove", "EditorIcons")); new_anim->set_icon(get_icon("New", "EditorIcons")); - remove_anim->set_icon(get_icon("Del", "EditorIcons")); + remove_anim->set_icon(get_icon("Remove", "EditorIcons")); } if (p_what == NOTIFICATION_READY) { @@ -667,7 +667,7 @@ SpriteFramesEditor::SpriteFramesEditor() { VBoxContainer *vbc_animlist = memnew(VBoxContainer); split->add_child(vbc_animlist); - vbc_animlist->set_custom_minimum_size(Size2(150, 0)); + vbc_animlist->set_custom_minimum_size(Size2(150, 0) * EDSCALE); //vbc_animlist->set_v_size_flags(SIZE_EXPAND_FILL); VBoxContainer *sub_vb = memnew(VBoxContainer); @@ -678,12 +678,13 @@ SpriteFramesEditor::SpriteFramesEditor() { sub_vb->add_child(hbc_animlist); new_anim = memnew(Button); + new_anim->set_flat(true); hbc_animlist->add_child(new_anim); + new_anim->set_h_size_flags(SIZE_EXPAND_FILL); new_anim->connect("pressed", this, "_animation_add"); - hbc_animlist->add_spacer(); - remove_anim = memnew(Button); + remove_anim->set_flat(true); hbc_animlist->add_child(remove_anim); remove_anim->connect("pressed", this, "_animation_remove"); @@ -720,6 +721,7 @@ SpriteFramesEditor::SpriteFramesEditor() { //animations = memnew( ItemList ); load = memnew(Button); + load->set_flat(true); load->set_tooltip(TTR("Load Resource")); hbc->add_child(load); @@ -736,14 +738,15 @@ SpriteFramesEditor::SpriteFramesEditor() { hbc->add_child(empty2); move_up = memnew(Button); - move_up->set_text(TTR("Up")); + move_up->set_text(TTR("Move (Before)")); hbc->add_child(move_up); move_down = memnew(Button); - move_down->set_text(TTR("Down")); + move_down->set_text(TTR("Move (After)")); hbc->add_child(move_down); _delete = memnew(Button); + _delete->set_flat(true); hbc->add_child(_delete); file = memnew(EditorFileDialog); @@ -818,7 +821,7 @@ SpriteFramesEditorPlugin::SpriteFramesEditorPlugin(EditorNode *p_node) { editor = p_node; frames_editor = memnew(SpriteFramesEditor); - frames_editor->set_custom_minimum_size(Size2(0, 300)); + frames_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE); button = editor->add_bottom_panel_item("SpriteFrames", frames_editor); button->hide(); } diff --git a/editor/project_export.cpp b/editor/project_export.cpp index e5b6f8e406..d8a87e738f 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -733,8 +733,12 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) { ERR_FAIL_COND(platform.is_null()); Error err = platform->export_project(current, export_debug->is_pressed(), p_path, 0); - if (err != OK) + if (err != OK) { + error_dialog->set_text(TTR("Export templates for this platform are missing/corrupted: ") + platform->get_name()); + error_dialog->show(); + error_dialog->popup_centered_minsize(Size2(300, 80)); ERR_PRINT("Failed to export project"); + } } void ProjectExportDialog::_bind_methods() { @@ -940,6 +944,12 @@ ProjectExportDialog::ProjectExportDialog() { export_error2->add_color_override("font_color", get_color("error_color", "Editor")); export_error2->set_text(" - " + TTR("Export templates for this platform are missing:") + " "); + error_dialog = memnew(AcceptDialog); + error_dialog->set_title("Error"); + error_dialog->set_text(TTR("Export templates for this platform are missing/corrupted:") + " "); + main_vb->add_child(error_dialog); + error_dialog->hide(); + LinkButton *download_templates = memnew(LinkButton); download_templates->set_text(TTR("Manage Export Templates")); export_templates_error->add_child(download_templates); diff --git a/editor/project_export.h b/editor/project_export.h index 61de0f739a..288b0c290f 100644 --- a/editor/project_export.h +++ b/editor/project_export.h @@ -72,6 +72,7 @@ private: Button *button_export; bool updating; + AcceptDialog *error_dialog; ConfirmationDialog *delete_confirm; OptionButton *export_filter; diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 91ef9e36f3..723d7b14ff 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -1189,7 +1189,7 @@ void ProjectSettingsEditor::_translation_res_option_delete(Object *p_item, int p ERR_FAIL_COND(!remaps.has(key)); PoolStringArray r = remaps[key]; - ERR_FAIL_INDEX(idx, remaps.size()); + ERR_FAIL_INDEX(idx, r.size()); r.remove(idx); remaps[key] = r; diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 658f67d6a4..b7cc9347f2 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -376,7 +376,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: if (hint == PROPERTY_HINT_RANGE) { int c = hint_text.get_slice_count(","); - float min = 0, max = 100, step = 1; + float min = 0, max = 100, step = type == Variant::REAL ? .01 : 1; if (c >= 1) { if (!hint_text.get_slice(",", 0).empty()) @@ -3032,7 +3032,7 @@ void PropertyEditor::update_tree() { if (p.hint == PROPERTY_HINT_SPRITE_FRAME || p.hint == PROPERTY_HINT_RANGE || p.hint == PROPERTY_HINT_EXP_RANGE) { int c = p.hint_string.get_slice_count(","); - float min = 0, max = 100, step = 1; + float min = 0, max = 100, step = p.type == Variant::REAL ? .01 : 1; if (c >= 1) { min = p.hint_string.get_slice(",", 0).to_double(); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index 6dcd5e54ec..a6e0af05b2 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -215,9 +215,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { bool has_groups = p_node->has_persistent_groups(); if (has_connections && has_groups) { - item->add_button(0, get_icon("ConnectionAndGroups", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connection(s) and group(s)\nClick to show signals dock.")); + item->add_button(0, get_icon("SignalsAndGroups", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connection(s) and group(s)\nClick to show signals dock.")); } else if (has_connections) { - item->add_button(0, get_icon("Connect", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connections.\nClick to show signals dock.")); + item->add_button(0, get_icon("Signals", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connections.\nClick to show signals dock.")); } else if (has_groups) { item->add_button(0, get_icon("Groups", "EditorIcons"), BUTTON_GROUPS, false, TTR("Node is in group(s).\nClick to show groups dock.")); } diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h index 64ac2535a9..d0faab5892 100644 --- a/editor/script_editor_debugger.h +++ b/editor/script_editor_debugger.h @@ -166,9 +166,6 @@ class ScriptEditorDebugger : public Control { void _method_changed(Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE); void _property_changed(Object *p_base, const StringName &p_property, const Variant &p_value); - static void _method_changeds(void *p_ud, Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE); - static void _property_changeds(void *p_ud, Object *p_base, const StringName &p_property, const Variant &p_value); - void _error_selected(int p_idx); void _error_stack_selected(int p_idx); @@ -196,6 +193,9 @@ public: void set_live_debugging(bool p_enable); + static void _method_changeds(void *p_ud, Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE); + static void _property_changeds(void *p_ud, Object *p_base, const StringName &p_property, const Variant &p_value); + void live_debug_create_node(const NodePath &p_parent, const String &p_type, const String &p_name); void live_debug_instance_node(const NodePath &p_parent, const String &p_path, const String &p_name); void live_debug_remove_node(const NodePath &p_at); diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 86979a1174..c052845be9 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -35,6 +35,7 @@ #include "os/keyboard.h" #include "project_settings.h" #include "scene/gui/margin_container.h" +#include "script_editor_debugger.h" void EditorSettingsDialog::ok_pressed() { @@ -91,6 +92,7 @@ void EditorSettingsDialog::popup_edit_settings() { search_box->grab_focus(); _update_shortcuts(); + set_process_unhandled_input(true); // Restore valid window bounds or pop up at default size. if (EditorSettings::get_singleton()->has_setting("interface/dialogs/editor_settings_bounds")) { @@ -121,19 +123,62 @@ void EditorSettingsDialog::_filter_shortcuts(const String &p_filter) { _update_shortcuts(); } +void EditorSettingsDialog::_undo_redo_callback(void *p_self, const String &p_name) { + EditorNode::get_log()->add_message(p_name); +} + void EditorSettingsDialog::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_READY: { + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + undo_redo->set_method_notify_callback(sed->_method_changeds, sed); + undo_redo->set_property_notify_callback(sed->_property_changeds, sed); + undo_redo->set_commit_notify_callback(_undo_redo_callback, this); + } break; case NOTIFICATION_ENTER_TREE: { clear_button->set_icon(get_icon("Close", "EditorIcons")); shortcut_clear_button->set_icon(get_icon("Close", "EditorIcons")); } break; case NOTIFICATION_POPUP_HIDE: { EditorSettings::get_singleton()->set("interface/dialogs/editor_settings_bounds", get_rect()); + set_process_unhandled_input(false); } break; } } +void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) { + + Ref<InputEventKey> k = p_event; + + if (k.is_valid() && is_window_modal_on_top()) { + + if (k->is_pressed()) { + + bool handled = false; + + if (ED_IS_SHORTCUT("editor/undo", p_event)) { + String action = undo_redo->get_current_action_name(); + if (action != "") + EditorNode::get_log()->add_message("UNDO: " + action); + undo_redo->undo(); + handled = true; + } + if (ED_IS_SHORTCUT("editor/redo", p_event)) { + undo_redo->redo(); + String action = undo_redo->get_current_action_name(); + if (action != "") + EditorNode::get_log()->add_message("REDO: " + action); + handled = true; + } + + if (handled) { + accept_event(); + } + } + } +} + void EditorSettingsDialog::_update_shortcuts() { shortcuts->clear(); @@ -212,30 +257,28 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column if (!sc.is_valid()) return; //pointless, there is nothing - UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Erase Shortcut"); - ur->add_do_method(sc.ptr(), "set_shortcut", Ref<InputEvent>()); - ur->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); - ur->add_do_method(this, "_update_shortcuts"); - ur->add_undo_method(this, "_update_shortcuts"); - ur->add_do_method(this, "_settings_changed"); - ur->add_undo_method(this, "_settings_changed"); - ur->commit_action(); + undo_redo->create_action("Erase Shortcut"); + undo_redo->add_do_method(sc.ptr(), "set_shortcut", Ref<InputEvent>()); + undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); + undo_redo->add_do_method(this, "_update_shortcuts"); + undo_redo->add_undo_method(this, "_update_shortcuts"); + undo_redo->add_do_method(this, "_settings_changed"); + undo_redo->add_undo_method(this, "_settings_changed"); + undo_redo->commit_action(); } else if (p_idx == 2) { //revert to original if (!sc.is_valid()) return; //pointless, there is nothing Ref<InputEvent> original = sc->get_meta("original"); - UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Restore Shortcut"); - ur->add_do_method(sc.ptr(), "set_shortcut", original); - ur->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); - ur->add_do_method(this, "_update_shortcuts"); - ur->add_undo_method(this, "_update_shortcuts"); - ur->add_do_method(this, "_settings_changed"); - ur->add_undo_method(this, "_settings_changed"); - ur->commit_action(); + undo_redo->create_action("Restore Shortcut"); + undo_redo->add_do_method(sc.ptr(), "set_shortcut", original); + undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); + undo_redo->add_do_method(this, "_update_shortcuts"); + undo_redo->add_undo_method(this, "_update_shortcuts"); + undo_redo->add_do_method(this, "_settings_changed"); + undo_redo->add_undo_method(this, "_settings_changed"); + undo_redo->commit_action(); } } @@ -276,19 +319,19 @@ void EditorSettingsDialog::_press_a_key_confirm() { Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured); - UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Shortcut '" + shortcut_configured + "'"); - ur->add_do_method(sc.ptr(), "set_shortcut", ie); - ur->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); - ur->add_do_method(this, "_update_shortcuts"); - ur->add_undo_method(this, "_update_shortcuts"); - ur->add_do_method(this, "_settings_changed"); - ur->add_undo_method(this, "_settings_changed"); - ur->commit_action(); + undo_redo->create_action("Change Shortcut '" + shortcut_configured + "'"); + undo_redo->add_do_method(sc.ptr(), "set_shortcut", ie); + undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut()); + undo_redo->add_do_method(this, "_update_shortcuts"); + undo_redo->add_undo_method(this, "_update_shortcuts"); + undo_redo->add_do_method(this, "_settings_changed"); + undo_redo->add_undo_method(this, "_settings_changed"); + undo_redo->commit_action(); } void EditorSettingsDialog::_bind_methods() { + ClassDB::bind_method(D_METHOD("_unhandled_input"), &EditorSettingsDialog::_unhandled_input); ClassDB::bind_method(D_METHOD("_settings_save"), &EditorSettingsDialog::_settings_save); ClassDB::bind_method(D_METHOD("_settings_changed"), &EditorSettingsDialog::_settings_changed); ClassDB::bind_method(D_METHOD("_settings_property_edited"), &EditorSettingsDialog::_settings_property_edited); @@ -305,6 +348,7 @@ EditorSettingsDialog::EditorSettingsDialog() { set_title(TTR("Editor Settings")); set_resizable(true); + undo_redo = memnew(UndoRedo); tabs = memnew(TabContainer); tabs->set_tab_align(TabContainer::ALIGN_LEFT); @@ -336,7 +380,7 @@ EditorSettingsDialog::EditorSettingsDialog() { property_editor->get_property_editor()->set_use_filter(true); property_editor->register_search_box(search_box); property_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL); - property_editor->get_property_editor()->set_undo_redo(EditorNode::get_singleton()->get_undo_redo()); + property_editor->get_property_editor()->set_undo_redo(undo_redo); vbc->add_child(property_editor); property_editor->get_property_editor()->connect("property_edited", this, "_settings_property_edited"); @@ -400,3 +444,7 @@ EditorSettingsDialog::EditorSettingsDialog() { updating = false; } + +EditorSettingsDialog::~EditorSettingsDialog() { + memdelete(undo_redo); +} diff --git a/editor/settings_config_dialog.h b/editor/settings_config_dialog.h index 8a66d5098c..a03b15c06d 100644 --- a/editor/settings_config_dialog.h +++ b/editor/settings_config_dialog.h @@ -50,6 +50,7 @@ class EditorSettingsDialog : public AcceptDialog { Timer *timer; + UndoRedo *undo_redo; Tree *shortcuts; ConfirmationDialog *press_a_key; @@ -65,6 +66,7 @@ class EditorSettingsDialog : public AcceptDialog { void _settings_property_edited(const String &p_name); void _settings_save(); + void _unhandled_input(const Ref<InputEvent> &p_event); void _notification(int p_what); void _press_a_key_confirm(); @@ -78,6 +80,8 @@ class EditorSettingsDialog : public AcceptDialog { void _update_shortcuts(); void _shortcut_button_pressed(Object *p_item, int p_column, int p_idx); + static void _undo_redo_callback(void *p_self, const String &p_name); + protected: static void _bind_methods(); @@ -85,6 +89,7 @@ public: void popup_edit_settings(); EditorSettingsDialog(); + ~EditorSettingsDialog(); }; #endif // SETTINGS_CONFIG_DIALOG_H diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 3c1889e829..3f8d93d976 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -298,11 +298,11 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi } } -void EditorSpatialGizmo::add_solid_box(Ref<Material> &p_material, Vector3 size) { +void EditorSpatialGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size) { ERR_FAIL_COND(!spatial_node); CubeMesh cubem; - cubem.set_size(size); + cubem.set_size(p_size); Ref<ArrayMesh> m = memnew(ArrayMesh); m->add_surface_from_arrays(cubem.surface_get_primitive_type(0), cubem.surface_get_arrays(0)); m->surface_set_material(0, p_material); |