diff options
Diffstat (limited to 'editor')
49 files changed, 663 insertions, 720 deletions
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index d3a4dbb6e7..0f86385031 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -185,35 +185,6 @@ bool EditorExportPreset::has_export_file(const String &p_path) { return selected_files.has(p_path); } -void EditorExportPreset::add_patch(const String &p_path, int p_at_pos) { - if (p_at_pos < 0) { - patches.push_back(p_path); - } else { - patches.insert(p_at_pos, p_path); - } - EditorExport::singleton->save_presets(); -} - -void EditorExportPreset::remove_patch(int p_idx) { - patches.remove(p_idx); - EditorExport::singleton->save_presets(); -} - -void EditorExportPreset::set_patch(int p_index, const String &p_path) { - ERR_FAIL_INDEX(p_index, patches.size()); - patches.write[p_index] = p_path; - EditorExport::singleton->save_presets(); -} - -String EditorExportPreset::get_patch(int p_index) { - ERR_FAIL_INDEX_V(p_index, patches.size(), String()); - return patches[p_index]; -} - -Vector<String> EditorExportPreset::get_patches() const { - return patches; -} - void EditorExportPreset::set_custom_features(const String &p_custom_features) { custom_features = p_custom_features; EditorExport::singleton->save_presets(); @@ -1341,7 +1312,6 @@ void EditorExport::_save() { config->set_value(section, "include_filter", preset->get_include_filter()); config->set_value(section, "exclude_filter", preset->get_exclude_filter()); config->set_value(section, "export_path", preset->get_export_path()); - config->set_value(section, "patch_list", preset->get_patches()); config->set_value(section, "encryption_include_filters", preset->get_enc_in_filter()); config->set_value(section, "encryption_exclude_filters", preset->get_enc_ex_filter()); config->set_value(section, "encrypt_pck", preset->get_enc_pck()); @@ -1529,12 +1499,6 @@ void EditorExport::load_config() { preset->set_exclude_filter(config->get_value(section, "exclude_filter")); preset->set_export_path(config->get_value(section, "export_path", "")); - Vector<String> patch_list = config->get_value(section, "patch_list"); - - for (int i = 0; i < patch_list.size(); i++) { - preset->add_patch(patch_list[i]); - } - if (config->has_section_key(section, "encrypt_pck")) { preset->set_enc_pck(config->get_value(section, "encrypt_pck")); } diff --git a/editor/editor_export.h b/editor/editor_export.h index fa6be88302..55728f0c94 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -68,8 +68,6 @@ private: Set<String> selected_files; bool runnable = false; - Vector<String> patches; - friend class EditorExport; friend class EditorExportPlatform; @@ -121,12 +119,6 @@ public: void set_exclude_filter(const String &p_exclude); String get_exclude_filter() const; - void add_patch(const String &p_path, int p_at_pos = -1); - void set_patch(int p_index, const String &p_path); - String get_patch(int p_index); - void remove_patch(int p_idx); - Vector<String> get_patches() const; - void set_custom_features(const String &p_custom_features); String get_custom_features() const; diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 5607bb3f17..3fcc06526b 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -119,6 +119,11 @@ bool EditorFileSystemDirectory::get_file_import_is_valid(int p_idx) const { return files[p_idx]->import_valid; } +uint64_t EditorFileSystemDirectory::get_file_modified_time(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, files.size(), 0); + return files[p_idx]->modified_time; +} + String EditorFileSystemDirectory::get_file_script_class_name(int p_idx) const { return files[p_idx]->script_class_name; } diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h index da27a63c64..02315d76f3 100644 --- a/editor/editor_file_system.h +++ b/editor/editor_file_system.h @@ -89,6 +89,7 @@ public: StringName get_file_type(int p_idx) const; Vector<String> get_file_deps(int p_idx) const; bool get_file_import_is_valid(int p_idx) const; + uint64_t get_file_modified_time(int p_idx) const; String get_file_script_class_name(int p_idx) const; //used for scripts String get_file_script_class_extends(int p_idx) const; //used for scripts String get_file_script_class_icon_path(int p_idx) const; //used for scripts diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 9900e8184d..1837b23a0b 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -358,10 +358,6 @@ bool EditorPropertyRevert::may_node_be_in_instance(Node *p_node) { Node *node = p_node; while (node) { - if (node->get_scene_instance_state().is_valid()) { - might_be = true; - break; - } if (node == edited_scene) { if (node->get_scene_inherited_state().is_valid()) { might_be = true; @@ -370,6 +366,10 @@ bool EditorPropertyRevert::may_node_be_in_instance(Node *p_node) { might_be = false; break; } + if (node->get_scene_instance_state().is_valid()) { + might_be = true; + break; + } node = node->get_owner(); } @@ -414,9 +414,9 @@ bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, co node = node->get_owner(); } - if (!found && node) { + if (!found && p_node) { //if not found, try default class value - Variant attempt = ClassDB::class_get_default_property_value(node->get_class_name(), p_prop); + Variant attempt = ClassDB::class_get_default_property_value(p_node->get_class_name(), p_prop); if (attempt.get_type() != Variant::NIL) { found = true; value = attempt; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 73562e0695..668cce5b67 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -505,6 +505,7 @@ void EditorNode::_notification(int p_what) { RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/volumetric_fog/use_filter"))); RS::get_singleton()->environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink")); RS::get_singleton()->environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink")); + RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/quality/2d_shadow_atlas/size")); } ResourceImporterTexture::get_singleton()->update_imports(); @@ -4225,6 +4226,7 @@ void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String &p p_layout->set_value(p_section, "dock_filesystem_split", filesystem_dock->get_split_offset()); p_layout->set_value(p_section, "dock_filesystem_display_mode", filesystem_dock->get_display_mode()); + p_layout->set_value(p_section, "dock_filesystem_file_sort", filesystem_dock->get_file_sort()); p_layout->set_value(p_section, "dock_filesystem_file_list_display_mode", filesystem_dock->get_file_list_display_mode()); for (int i = 0; i < vsplits.size(); i++) { @@ -4419,6 +4421,11 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String filesystem_dock->set_display_mode(dock_filesystem_display_mode); } + if (p_layout->has_section_key(p_section, "dock_filesystem_file_sort")) { + FileSystemDock::FileSortOption dock_filesystem_file_sort = FileSystemDock::FileSortOption(int(p_layout->get_value(p_section, "dock_filesystem_file_sort"))); + filesystem_dock->set_file_sort(dock_filesystem_file_sort); + } + if (p_layout->has_section_key(p_section, "dock_filesystem_file_list_display_mode")) { FileSystemDock::FileListDisplayMode dock_filesystem_file_list_display_mode = FileSystemDock::FileListDisplayMode(int(p_layout->get_value(p_section, "dock_filesystem_file_list_display_mode"))); filesystem_dock->set_file_list_display_mode(dock_filesystem_file_list_display_mode); @@ -5122,7 +5129,6 @@ void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) { void EditorNode::_add_dropped_files_recursive(const Vector<String> &p_files, String to_path) { DirAccessRef dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - Vector<String> just_copy = String("ttf,otf").split(","); for (int i = 0; i < p_files.size(); i++) { String from = p_files[i]; @@ -5153,9 +5159,6 @@ void EditorNode::_add_dropped_files_recursive(const Vector<String> &p_files, Str continue; } - if (!ResourceFormatImporter::get_singleton()->can_be_imported(from) && (just_copy.find(from.get_extension().to_lower()) == -1)) { - continue; - } dir->copy(from, to); } } diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 082c317655..e330713cfb 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -791,7 +791,7 @@ bool EditorPlugin::build() { return true; } -void EditorPlugin::queue_save_layout() const { +void EditorPlugin::queue_save_layout() { EditorNode::get_singleton()->save_layout(); } diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 40a91cbfb9..dd3bf08678 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -221,7 +221,7 @@ public: int update_overlays() const; - void queue_save_layout() const; + void queue_save_layout(); void make_bottom_panel_item_visible(Control *p_item); void hide_bottom_panel(); diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 9e68ef2f35..9e7ddd9fac 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -614,7 +614,7 @@ public: const Ref<InputEventMouseButton> mb = p_ev; - if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed() && hovered_index > 0) { + if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed() && hovered_index >= 0) { // Toggle the flag. // We base our choice on the hovered flag, so that it always matches the hovered flag. if (value & (1 << hovered_index)) { @@ -1172,7 +1172,7 @@ void EditorPropertyVector2::setup(double p_min, double p_max, double p_step, boo } EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing"); + bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector2_editing")); BoxContainer *bc; @@ -1258,7 +1258,7 @@ void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool } EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) { - bool horizontal = !p_force_wide && bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); + bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); BoxContainer *bc; @@ -1353,7 +1353,7 @@ void EditorPropertyVector3::setup(double p_min, double p_max, double p_step, boo } EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); BoxContainer *bc; @@ -1435,7 +1435,7 @@ void EditorPropertyVector2i::setup(int p_min, int p_max, bool p_no_slider) { } EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector2_editing"); + bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector2_editing")); BoxContainer *bc; @@ -1521,7 +1521,7 @@ void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_no_slider) { } EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); BoxContainer *bc; @@ -1605,7 +1605,7 @@ void EditorPropertyVector3i::setup(int p_min, int p_max, bool p_no_slider) { } EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); BoxContainer *bc; if (p_force_wide) { @@ -1690,7 +1690,7 @@ void EditorPropertyPlane::setup(double p_min, double p_max, double p_step, bool } EditorPropertyPlane::EditorPropertyPlane(bool p_force_wide) { - bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + bool horizontal = p_force_wide || bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing")); BoxContainer *bc; diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 3170ea5ff8..9723ae188b 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -30,8 +30,6 @@ #include "editor_resource_preview.h" -#include "core/method_bind_ext.gen.inc" - #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/message_queue.h" diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 422534a2e1..639da371bd 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -76,8 +76,10 @@ void EditorRunNative::_notification(int p_what) { } else { mb->get_popup()->clear(); mb->show(); - mb->set_tooltip(eep->get_options_tooltip()); - if (dc > 1) { + if (dc == 1) { + mb->set_tooltip(eep->get_option_tooltip(0)); + } else { + mb->set_tooltip(eep->get_options_tooltip()); for (int i = 0; i < dc; i++) { mb->get_popup()->add_icon_item(eep->get_option_icon(i), eep->get_option_label(i)); mb->get_popup()->set_item_tooltip(mb->get_popup()->get_item_count() - 1, eep->get_option_tooltip(i)); diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 04bb49bb51..c1bb7951fa 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -31,8 +31,7 @@ #ifndef EDITOR_SETTINGS_H #define EDITOR_SETTINGS_H -#include "core/object.h" - +#include "core/class_db.h" #include "core/io/config_file.h" #include "core/os/thread_safe.h" #include "core/resource.h" diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h index ee9e51441d..6ef55f0a46 100644 --- a/editor/editor_vcs_interface.h +++ b/editor/editor_vcs_interface.h @@ -31,7 +31,7 @@ #ifndef EDITOR_VCS_INTERFACE_H #define EDITOR_VCS_INTERFACE_H -#include "core/object.h" +#include "core/class_db.h" #include "core/ustring.h" #include "scene/gui/panel_container.h" diff --git a/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h index 9645fbf39e..eefaa503c1 100644 --- a/editor/fileserver/editor_file_server.h +++ b/editor/fileserver/editor_file_server.h @@ -31,10 +31,10 @@ #ifndef EDITOR_FILE_SERVER_H #define EDITOR_FILE_SERVER_H +#include "core/class_db.h" #include "core/io/file_access_network.h" #include "core/io/packet_peer.h" #include "core/io/tcp_server.h" -#include "core/object.h" #include "core/os/thread.h" class EditorFileServer : public Object { diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 0071f169ac..14a46d77a2 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -31,6 +31,7 @@ #include "filesystem_dock.h" #include "core/io/resource_loader.h" +#include "core/list.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/keyboard.h" @@ -46,13 +47,12 @@ #include "scene/resources/packed_scene.h" #include "servers/display_server.h" -Ref<Texture2D> FileSystemDock::_get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx) { +Ref<Texture2D> FileSystemDock::_get_tree_item_icon(bool p_is_valid, String p_file_type) { Ref<Texture2D> file_icon; - if (!p_dir->get_file_import_is_valid(p_idx)) { + if (!p_is_valid) { file_icon = get_theme_icon("ImportFail", "EditorIcons"); } else { - String file_type = p_dir->get_file_type(p_idx); - file_icon = (has_theme_icon(file_type, "EditorIcons")) ? get_theme_icon(file_type, "EditorIcons") : get_theme_icon("File", "EditorIcons"); + file_icon = (has_theme_icon(p_file_type, "EditorIcons")) ? get_theme_icon(p_file_type, "EditorIcons") : get_theme_icon("File", "EditorIcons"); } return file_icon; } @@ -87,22 +87,27 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory } // Create items for all subdirectories. - for (int i = 0; i < p_dir->get_subdir_count(); i++) { + bool reversed = file_sort == FILE_SORT_NAME_REVERSE; + for (int i = reversed ? p_dir->get_subdir_count() - 1 : 0; + reversed ? i >= 0 : i < p_dir->get_subdir_count(); + reversed ? i-- : i++) { parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths, p_select_in_favorites, p_unfold_path) || parent_should_expand); } // Create all items for the files in the subdirectory. if (display_mode == DISPLAY_MODE_TREE_ONLY) { String main_scene = ProjectSettings::get_singleton()->get("application/run/main_scene"); + + // Build the list of the files to display. + List<FileInfo> file_list; for (int i = 0; i < p_dir->get_file_count(); i++) { String file_type = p_dir->get_file_type(i); - if (_is_file_type_disabled_by_feature_profile(file_type)) { // If type is disabled, file won't be displayed. continue; } - String file_name = p_dir->get_file(i); + String file_name = p_dir->get_file(i); if (searched_string.length() > 0) { if (file_name.to_lower().find(searched_string) < 0) { // The searched string is not in the file name, we skip it. @@ -113,10 +118,26 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory } } + FileInfo fi; + fi.name = p_dir->get_file(i); + fi.type = p_dir->get_file_type(i); + fi.import_broken = !p_dir->get_file_import_is_valid(i); + fi.modified_time = p_dir->get_file_modified_time(i); + + file_list.push_back(fi); + } + + // Sort the file list if needed. + _sort_file_info_list(file_list); + + // Build the tree. + for (List<FileInfo>::Element *E = file_list.front(); E; E = E->next()) { + FileInfo fi = E->get(); + TreeItem *file_item = tree->create_item(subdirectory_item); - file_item->set_text(0, file_name); - file_item->set_icon(0, _get_tree_item_icon(p_dir, i)); - String file_metadata = lpath.plus_file(file_name); + file_item->set_text(0, fi.name); + file_item->set_icon(0, _get_tree_item_icon(!fi.import_broken, fi.type)); + String file_metadata = lpath.plus_file(fi.name); file_item->set_metadata(0, file_metadata); if (!p_select_in_favorites && path == file_metadata) { file_item->select(0); @@ -220,7 +241,7 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo int index; EditorFileSystemDirectory *dir = EditorFileSystem::get_singleton()->find_file(fave, &index); if (dir) { - icon = _get_tree_item_icon(dir, index); + icon = _get_tree_item_icon(dir->get_file_import_is_valid(index), dir->get_file_type(index)); } else { icon = get_theme_icon("File", "EditorIcons"); } @@ -273,9 +294,9 @@ void FileSystemDock::_update_display_mode(bool p_force) { tree->show(); tree->set_v_size_flags(SIZE_EXPAND_FILL); if (display_mode == DISPLAY_MODE_TREE_ONLY) { - tree_search_box->show(); + toolbar2_hbc->show(); } else { - tree_search_box->hide(); + toolbar2_hbc->hide(); } _update_tree(_compute_uncollapsed_paths()); @@ -286,7 +307,7 @@ void FileSystemDock::_update_display_mode(bool p_force) { tree->show(); tree->set_v_size_flags(SIZE_EXPAND_FILL); tree->ensure_cursor_is_visible(); - tree_search_box->hide(); + toolbar2_hbc->hide(); _update_tree(_compute_uncollapsed_paths()); file_list_vb->show(); @@ -318,10 +339,14 @@ void FileSystemDock::_notification(int p_what) { files->connect("item_activated", callable_mp(this, &FileSystemDock::_file_list_activate_file)); button_hist_next->connect("pressed", callable_mp(this, &FileSystemDock::_fw_history)); button_hist_prev->connect("pressed", callable_mp(this, &FileSystemDock::_bw_history)); + tree_search_box->set_right_icon(get_theme_icon("Search", ei)); tree_search_box->set_clear_button_enabled(true); + tree_button_sort->set_icon(get_theme_icon("Sort", ei)); + file_list_search_box->set_right_icon(get_theme_icon("Search", ei)); file_list_search_box->set_clear_button_enabled(true); + file_list_button_sort->set_icon(get_theme_icon("Sort", ei)); button_hist_next->set_icon(get_theme_icon("Forward", ei)); button_hist_prev->set_icon(get_theme_icon("Back", ei)); @@ -387,8 +412,11 @@ void FileSystemDock::_notification(int p_what) { tree_search_box->set_right_icon(get_theme_icon("Search", ei)); tree_search_box->set_clear_button_enabled(true); + tree_button_sort->set_icon(get_theme_icon("Sort", ei)); + file_list_search_box->set_right_icon(get_theme_icon("Search", ei)); file_list_search_box->set_clear_button_enabled(true); + file_list_button_sort->set_icon(get_theme_icon("Sort", ei)); // Update always show folders. bool new_always_show_folders = bool(EditorSettings::get_singleton()->get("docks/filesystem/always_show_folders")); @@ -589,6 +617,7 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> * fi.type = p_path->get_file_type(i); fi.path = p_path->get_file_path(i); fi.import_broken = !p_path->get_file_import_is_valid(i); + fi.modified_time = p_path->get_file_modified_time(i); if (_is_file_type_disabled_by_feature_profile(fi.type)) { // This type is disabled, will not appear here. @@ -603,6 +632,54 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> * } } +struct FileSystemDock::FileInfoTypeComparator { + bool operator()(const FileInfo &p_a, const FileInfo &p_b) const { + // Uses the extension, then the icon name to distinguish file types. + String icon_path_a = ""; + String icon_path_b = ""; + Ref<Texture2D> icon_a = EditorNode::get_singleton()->get_class_icon(p_a.type); + if (icon_a.is_valid()) { + icon_path_a = icon_a->get_name(); + } + Ref<Texture2D> icon_b = EditorNode::get_singleton()->get_class_icon(p_b.type); + if (icon_b.is_valid()) { + icon_path_b = icon_b->get_name(); + } + return NaturalNoCaseComparator()(p_a.name.get_extension() + icon_path_a + p_a.name.get_basename(), p_b.name.get_extension() + icon_path_b + p_b.name.get_basename()); + } +}; + +struct FileSystemDock::FileInfoModifiedTimeComparator { + bool operator()(const FileInfo &p_a, const FileInfo &p_b) const { + return p_a.modified_time > p_b.modified_time; + } +}; + +void FileSystemDock::_sort_file_info_list(List<FileSystemDock::FileInfo> &r_file_list) { + // Sort the file list if needed. + switch (file_sort) { + case FILE_SORT_TYPE: + r_file_list.sort_custom<FileInfoTypeComparator>(); + break; + case FILE_SORT_TYPE_REVERSE: + r_file_list.sort_custom<FileInfoTypeComparator>(); + r_file_list.invert(); + break; + case FILE_SORT_MODIFIED_TIME: + r_file_list.sort_custom<FileInfoModifiedTimeComparator>(); + break; + case FILE_SORT_MODIFIED_TIME_REVERSE: + r_file_list.sort_custom<FileInfoModifiedTimeComparator>(); + r_file_list.invert(); + break; + case FILE_SORT_NAME_REVERSE: + r_file_list.invert(); + break; + default: // FILE_SORT_NAME + break; + } +} + void FileSystemDock::_update_file_list(bool p_keep_selection) { // Register the previously selected items. Set<String> cselection; @@ -660,7 +737,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { const Color folder_color = get_theme_color("folder_icon_modulate", "FileDialog"); // Build the FileInfo list. - List<FileInfo> filelist; + List<FileInfo> file_list; if (path == "Favorites") { // Display the favorites. Vector<String> favorites = EditorSettings::get_singleton()->get_favorites(); @@ -692,13 +769,15 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { if (efd) { fi.type = efd->get_file_type(index); fi.import_broken = !efd->get_file_import_is_valid(index); + fi.modified_time = efd->get_file_modified_time(index); } else { fi.type = ""; fi.import_broken = true; + fi.modified_time = 0; } if (searched_string.length() == 0 || fi.name.to_lower().find(searched_string) >= 0) { - filelist.push_back(fi); + file_list.push_back(fi); } } } @@ -719,7 +798,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { if (searched_string.length() > 0) { // Display the search results. - _search(EditorFileSystem::get_singleton()->get_filesystem(), &filelist, 128); + _search(EditorFileSystem::get_singleton()->get_filesystem(), &file_list, 128); } else { if (display_mode == DISPLAY_MODE_TREE_ONLY || always_show_folders) { // Display folders in the list. @@ -736,7 +815,10 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { files->set_item_icon_modulate(files->get_item_count() - 1, folder_color); } - for (int i = 0; i < efd->get_subdir_count(); i++) { + bool reversed = file_sort == FILE_SORT_NAME_REVERSE; + for (int i = reversed ? efd->get_subdir_count() - 1 : 0; + reversed ? i >= 0 : i < efd->get_subdir_count(); + reversed ? i-- : i++) { String dname = efd->get_subdir(i)->get_name(); files->add_item(dname, folder_icon, true); @@ -756,17 +838,21 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { fi.path = directory.plus_file(fi.name); fi.type = efd->get_file_type(i); fi.import_broken = !efd->get_file_import_is_valid(i); + fi.modified_time = efd->get_file_modified_time(i); - filelist.push_back(fi); + file_list.push_back(fi); } } - filelist.sort(); + file_list.sort(); } + // Sort the file list if needed. + _sort_file_info_list(file_list); + // Fills the ItemList control node from the FileInfos. String main_scene = ProjectSettings::get_singleton()->get("application/run/main_scene"); String oi = "Object"; - for (List<FileInfo>::Element *E = filelist.front(); E; E = E->next()) { + for (List<FileInfo>::Element *E = file_list.front(); E; E = E->next()) { FileInfo *finfo = &(E->get()); String fname = finfo->name; String fpath = finfo->path; @@ -2516,6 +2602,39 @@ void FileSystemDock::_feature_profile_changed() { _update_display_mode(true); } +void FileSystemDock::set_file_sort(FileSortOption p_file_sort) { + for (int i = 0; i != FILE_SORT_MAX; i++) { + tree_button_sort->get_popup()->set_item_checked(i, (i == (int)p_file_sort)); + file_list_button_sort->get_popup()->set_item_checked(i, (i == (int)p_file_sort)); + } + file_sort = p_file_sort; + + // Update everything needed. + _update_tree(_compute_uncollapsed_paths()); + _update_file_list(true); +} + +void FileSystemDock::_file_sort_popup(int p_id) { + set_file_sort((FileSortOption)p_id); +} + +MenuButton *FileSystemDock::_create_file_menu_button() { + MenuButton *button = memnew(MenuButton); + button->set_flat(true); + button->set_tooltip(TTR("Sort files")); + + PopupMenu *p = button->get_popup(); + p->connect("id_pressed", callable_mp(this, &FileSystemDock::_file_sort_popup)); + p->add_radio_check_item("Sort by Name (Ascending)", FILE_SORT_NAME); + p->add_radio_check_item("Sort by Name (Descending)", FILE_SORT_NAME_REVERSE); + p->add_radio_check_item("Sort by Type (Ascending)", FILE_SORT_TYPE); + p->add_radio_check_item("Sort by Type (Descending)", FILE_SORT_TYPE_REVERSE); + p->add_radio_check_item("Sort by Last Modified", FILE_SORT_MODIFIED_TIME); + p->add_radio_check_item("Sort by First Modified", FILE_SORT_MODIFIED_TIME_REVERSE); + p->set_item_checked(file_sort, true); + return button; +} + void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_update_tree"), &FileSystemDock::_update_tree); @@ -2593,7 +2712,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { button_toggle_display_mode->set_tooltip(TTR("Toggle Split Mode")); toolbar_hbc->add_child(button_toggle_display_mode); - HBoxContainer *toolbar2_hbc = memnew(HBoxContainer); + toolbar2_hbc = memnew(HBoxContainer); toolbar2_hbc->add_theme_constant_override("separation", 0); top_vbc->add_child(toolbar2_hbc); @@ -2603,6 +2722,9 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { tree_search_box->connect("text_changed", callable_mp(this, &FileSystemDock::_search_changed), varray(tree_search_box)); toolbar2_hbc->add_child(tree_search_box); + tree_button_sort = _create_file_menu_button(); + toolbar2_hbc->add_child(tree_button_sort); + file_list_popup = memnew(PopupMenu); add_child(file_list_popup); @@ -2644,6 +2766,9 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { file_list_search_box->connect("text_changed", callable_mp(this, &FileSystemDock::_search_changed), varray(file_list_search_box)); path_hb->add_child(file_list_search_box); + file_list_button_sort = _create_file_menu_button(); + path_hb->add_child(file_list_button_sort); + button_file_list_display_mode = memnew(Button); button_file_list_display_mode->set_flat(true); path_hb->add_child(button_file_list_display_mode); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index ec2a075834..1db1485426 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -69,6 +69,16 @@ public: DISPLAY_MODE_SPLIT, }; + enum FileSortOption { + FILE_SORT_NAME = 0, + FILE_SORT_NAME_REVERSE, + FILE_SORT_TYPE, + FILE_SORT_TYPE_REVERSE, + FILE_SORT_MODIFIED_TIME, + FILE_SORT_MODIFIED_TIME_REVERSE, + FILE_SORT_MAX, + }; + private: enum FileMenu { FILE_OPEN, @@ -95,6 +105,8 @@ private: FOLDER_COLLAPSE_ALL, }; + FileSortOption file_sort = FILE_SORT_NAME; + VBoxContainer *scanning_vb; ProgressBar *scanning_progress; VSplitContainer *split_box; @@ -109,8 +121,13 @@ private: Button *button_hist_next; Button *button_hist_prev; LineEdit *current_path; + + HBoxContainer *toolbar2_hbc; LineEdit *tree_search_box; + MenuButton *tree_button_sort; + LineEdit *file_list_search_box; + MenuButton *file_list_button_sort; String searched_string; Vector<String> uncollapsed_paths_before_search; @@ -173,7 +190,7 @@ private: ItemList *files; bool import_dock_needs_update; - Ref<Texture2D> _get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx); + Ref<Texture2D> _get_tree_item_icon(bool p_is_valid, String p_file_type); bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites, bool p_unfold_path = false); Vector<String> _compute_uncollapsed_paths(); void _update_tree(const Vector<String> &p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false, bool p_select_in_favorites = false, bool p_unfold_path = false); @@ -238,6 +255,9 @@ private: void _search_changed(const String &p_text, const Control *p_from); + MenuButton *_create_file_menu_button(); + void _file_sort_popup(int p_id); + void _file_and_folders_fill_popup(PopupMenu *p_popup, Vector<String> p_paths, bool p_display_path_dependent_options = true); void _tree_rmb_select(const Vector2 &p_pos); void _tree_rmb_empty(const Vector2 &p_pos); @@ -251,12 +271,18 @@ private: StringName type; Vector<String> sources; bool import_broken; + uint64_t modified_time; bool operator<(const FileInfo &fi) const { return NaturalNoCaseComparator()(name, fi.name); } }; + struct FileInfoTypeComparator; + struct FileInfoModifiedTimeComparator; + + void _sort_file_info_list(List<FileSystemDock::FileInfo> &r_file_list); + void _search(EditorFileSystemDirectory *p_path, List<FileInfo> *matches, int p_max_items); void _set_current_path_text(const String &p_path); @@ -299,6 +325,9 @@ public: void set_display_mode(DisplayMode p_display_mode); DisplayMode get_display_mode() { return display_mode; } + void set_file_sort(FileSortOption p_file_sort); + FileSortOption get_file_sort() { return file_sort; } + void set_file_list_display_mode(FileListDisplayMode p_mode); FileListDisplayMode get_file_list_display_mode() { return file_list_display_mode; }; diff --git a/editor/icons/Callable.svg b/editor/icons/Callable.svg index 8f421f4fed..d689f1a4c4 100644 --- a/editor/icons/Callable.svg +++ b/editor/icons/Callable.svg @@ -1,5 +1 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333 4.2333" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -292.77)"> -<path transform="matrix(.26458 0 0 .26458 0 292.77)" d="m12 1c-2 2-4 4-7 4h-4v5h4c3 3.8e-5 5 2 7 4v-13zm1 4v5c2.5896-0.015798 2.5896-4.9849 0-5zm-11 6v4h2l1-4h-3z" fill="#e0e0e0"/> -</g> -</svg> +<svg height="16" viewBox="0 0 4.2333 4.2333" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 1c-2 2-4 4-7 4h-4v5h4c3 .000038 5 2 7 4zm1 4v5c2.5896-.015798 2.5896-4.9849 0-5zm-11 6v4h2l1-4z" fill="#e0e0e0" transform="scale(.26458)"/></svg> diff --git a/editor/icons/Keyboard.svg b/editor/icons/Keyboard.svg index 9c372bc08d..b9dfab71ed 100644 --- a/editor/icons/Keyboard.svg +++ b/editor/icons/Keyboard.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M4 2a1 1 0 0 0-1 1v9.084c0 .506.448.916 1 .916h8c.552 0 1-.41 1-.916V3a1 1 0 0 0-1-1H4zm1.543 1.139h1.393L8.77 7.338h1.295v.437c.708.052 1.246.239 1.61.559.368.316.55.747.55 1.295 0 .552-.182.99-.55 1.314-.368.32-.906.505-1.61.553v.467H8.771v-.473c-.708-.06-1.247-.248-1.615-.564-.364-.316-.545-.75-.545-1.297 0-.548.181-.977.545-1.29.368-.315.907-.504 1.615-.564v-.437H7.307l-.282-.733H5.43l-.284.733H3.707l1.836-4.2zm.684 1.39l-.409 1.057h.817l-.408-1.057zm3.84 4.338v1.526c.28-.04.483-.12.607-.24.124-.125.185-.302.185-.53 0-.224-.063-.396-.191-.516-.124-.12-.326-.2-.602-.24zm-1.296.006c-.284.04-.487.12-.61.24-.12.116-.182.288-.182.516 0 .22.065.392.193.512.132.12.331.202.6.246V8.873z" fill="#e0e0e0" fill-opacity=".996"/><path d="M27 2h7v14h-7z" fill="#fff" fill-opacity=".996"/><path fill="#e0e0e0" fill-opacity=".996" d="M1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-1v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4z"/></svg> +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".996"><path d="m4 2a1 1 0 0 0 -1 1v9.084c0 .506.448.916 1 .916h8c.552 0 1-.41 1-.916v-9.084a1 1 0 0 0 -1-1zm1.543 1.139h1.393l1.834 4.199h1.295v.437c.708.052 1.246.239 1.61.559.368.316.55.747.55 1.295 0 .552-.182.99-.55 1.314-.368.32-.906.505-1.61.553v.467h-1.294v-.473c-.708-.06-1.247-.248-1.615-.564-.364-.316-.545-.75-.545-1.297 0-.548.181-.977.545-1.29.368-.315.907-.504 1.615-.564v-.437h-1.464l-.282-.733h-1.595l-.284.733h-1.439l1.836-4.2zm.684 1.39-.409 1.057h.817zm3.84 4.338v1.526c.28-.04.483-.12.607-.24.124-.125.185-.302.185-.53 0-.224-.063-.396-.191-.516-.124-.12-.326-.2-.602-.24zm-1.296.006c-.284.04-.487.12-.61.24-.12.116-.182.288-.182.516 0 .22.065.392.193.512.132.12.331.202.6.246v-1.514z" fill="#e0e0e0"/><path d="m27 2h7v14h-7z" fill="#fff"/><path d="m1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9h-1v9a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-9z" fill="#e0e0e0"/></g></svg> diff --git a/editor/icons/KeyboardPhysical.svg b/editor/icons/KeyboardPhysical.svg index 0f20315fca..4364e0b4fa 100644 --- a/editor/icons/KeyboardPhysical.svg +++ b/editor/icons/KeyboardPhysical.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M4 2a1 1 0 0 0-1 1v9.084c0 .506.448.916 1 .916h8c.552 0 1-.41 1-.916V3a1 1 0 0 0-1-1zm2.762 1.768h2.476l3.264 7.464H9.898l-.502-1.3H6.561l-.502 1.3H3.498zm1.217 2.474L7.254 8.12h1.45z" fill="#e0e0e0" fill-opacity=".996"/><path d="M27 2h7v14h-7z" fill="#fff" fill-opacity=".996"/><path fill="#e0e0e0" fill-opacity=".996" d="M1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4h-1v9a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4z"/></svg> +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".996"><path d="m4 2a1 1 0 0 0 -1 1v9.084c0 .506.448.916 1 .916h8c.552 0 1-.41 1-.916v-9.084a1 1 0 0 0 -1-1zm2.762 1.768h2.476l3.264 7.464h-2.604l-.502-1.3h-2.835l-.502 1.3h-2.561zm1.217 2.474-.725 1.878h1.45z" fill="#e0e0e0"/><path d="m27 2h7v14h-7z" fill="#fff"/><path d="m1 4v9a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-9h-1v9a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-9z" fill="#e0e0e0"/></g></svg> diff --git a/editor/icons/ORMMaterial3D.svg b/editor/icons/ORMMaterial3D.svg index 3dd6013436..3d6db6910d 100644 --- a/editor/icons/ORMMaterial3D.svg +++ b/editor/icons/ORMMaterial3D.svg @@ -1,66 +1 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="16" - height="16" - version="1.1" - viewBox="0 0 16 16" - id="svg18" - sodipodi:docname="icon_o_r_m_material_3d.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> - <metadata - id="metadata24"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs22" /> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1010" - inkscape:window-height="553" - id="namedview20" - showgrid="false" - inkscape:zoom="7.375" - inkscape:cx="16.698858" - inkscape:cy="18.275823" - inkscape:window-x="345" - inkscape:window-y="144" - inkscape:window-maximized="0" - inkscape:current-layer="svg18" /> - <path - inkscape:connector-curvature="0" - id="path4541" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Uroob;-inkscape-font-specification:Uroob;letter-spacing:0px;word-spacing:0px;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.33291078" - d="m 5.0534707,10.652714 q 0,0.729229 -0.4538398,1.253141 -0.4538403,0.516832 -1.0868283,0.516832 H 2.3184864 q -0.6389592,0 -1.1047425,-0.509753 -0.47175502,-0.509751 -0.47175502,-1.26022 V 5.1304021 q 0,-0.7575473 0.47175502,-1.2672998 0.4717549,-0.5097517 1.1047425,-0.5097517 h 1.1943162 q 0.6270165,0 1.0868283,0.516832 0.4538398,0.5168313 0.4538398,1.2602195 z M 3.9726148,10.419078 V 5.3640385 q 0,-0.5734707 -0.3344086,-0.8141867 Q 3.5307175,4.4648927 3.381428,4.471973 H 2.3901454 q -0.2567779,0 -0.4120391,0.2690357 -0.1552611,0.2690357 -0.1552611,0.6230298 v 5.0550395 q 0,0.559311 0.3164938,0.807108 0.1074885,0.08496 0.2508064,0.08496 H 3.381428 q 0.2746925,0 0.4359254,-0.276116 0.1552614,-0.276115 0.1552614,-0.61595 z" /> - <path - inkscape:connector-curvature="0" - id="path4543" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Uroob;-inkscape-font-specification:Uroob;letter-spacing:0px;word-spacing:0px;fill:#008000;fill-opacity:1;stroke:none;stroke-width:0.32084218" - d="M 9.9872948,12.451006 H 8.9445586 L 7.4747449,8.5287488 H 6.6815992 V 12.451006 H 5.6721419 V 3.37459 h 2.739956 q 0.5435541,0 0.9318066,0.4601926 0.3882524,0.4601933 0.3882524,1.1540217 V 7.112771 q 0,1.0053443 -0.6766682,1.3168588 -0.2107668,0.099119 -0.4659043,0.099119 z M 8.7282467,6.808336 V 5.2224407 q 0,-0.4743524 -0.2884169,-0.6867495 -0.088743,-0.070798 -0.2052192,-0.063719 H 6.6815992 v 2.9452329 h 1.7194053 q 0.2828702,-0.00708 0.3161488,-0.389394 0.011093,-0.1132781 0.011093,-0.2194752 z" /> - <path - inkscape:connector-curvature="0" - id="path4545" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:Uroob;-inkscape-font-specification:Uroob;letter-spacing:0px;word-spacing:0px;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:0.31984535" - d="m 10.201004,3.7285848 q 0,-0.4106342 0.529158,-0.3681546 0.126777,0.014161 0.209458,0.014161 v 0.00708 h 0.115753 l 1.692202,4.9205216 1.697714,-4.9205216 h 0.06063 v -0.00708 h 0.463013 q 0.198434,0 0.297651,0.212397 0.03307,0.063719 0.03307,0.1415978 v 8.694102 h -1.01422 V 6.8224966 L 13.227119,10.050925 H 12.273535 L 11.21522,7.1198527 v 5.3028353 h -1.014218 z" /> -</svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5.0534707 10.652714q0 .729229-.4538398 1.253141-.4538403.516832-1.0868283.516832h-1.1943162q-.6389592 0-1.1047425-.509753-.47175502-.509751-.47175502-1.26022v-5.5223119q0-.7575473.47175502-1.2672998.4717549-.5097517 1.1047425-.5097517h1.1943162q.6270165 0 1.0868283.516832.4538398.5168313.4538398 1.2602195zm-1.0808559-.233636v-5.0550395q0-.5734707-.3344086-.8141867-.1074887-.0849591-.2567782-.0778788h-.9912826q-.2567779 0-.4120391.2690357-.1552611.2690357-.1552611.6230298v5.0550395q0 .559311.3164938.807108.1074885.08496.2508064.08496h.9912826q.2746925 0 .4359254-.276116.1552614-.276115.1552614-.61595z" fill="#f00"/><path d="m9.9872948 12.451006h-1.0427362l-1.4698137-3.9222572h-.7931457v3.9222572h-1.0094573v-9.076416h2.739956q.5435541 0 .9318066.4601926.3882524.4601933.3882524 1.1540217v2.1239667q0 1.0053443-.6766682 1.3168588-.2107668.099119-.4659043.099119zm-1.2590481-5.64267v-1.5858953q0-.4743524-.2884169-.6867495-.088743-.070798-.2052192-.063719h-1.5530114v2.9452329h1.7194053q.2828702-.00708.3161488-.389394.011093-.1132781.011093-.2194752z" fill="#008000"/><path d="m10.201004 3.7285848q0-.4106342.529158-.3681546.126777.014161.209458.014161v.00708h.115753l1.692202 4.9205216 1.697714-4.9205216h.06063v-.00708h.463013q.198434 0 .297651.212397.03307.063719.03307.1415978v8.694102h-1.01422v-5.6001914l-1.058314 3.2284284h-.953584l-1.058315-2.9310723v5.3028353h-1.014218z" fill="#00f"/></svg> diff --git a/editor/icons/PaintVertex.svg b/editor/icons/PaintVertex.svg deleted file mode 100644 index 5a13e4b7d0..0000000000 --- a/editor/icons/PaintVertex.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="8.372881" cy="8.169492" fill="#fff" rx="6.677966" ry="6.067797"/></svg> diff --git a/editor/icons/Rect2i.svg b/editor/icons/Rect2i.svg index d28c098ed6..142ad88515 100644 --- a/editor/icons/Rect2i.svg +++ b/editor/icons/Rect2i.svg @@ -1,4 +1 @@ -<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg"> -<path d="m9 2v2h-1c-1.7267 0-3 1.3359-3 3 0 1.6569 1.3431 3 3 3h1v-2h-1c-0.55228 0-1-0.44772-1-1s0.44772-1 1-1h1v1c0 1.6569 1.3431 3 3 3v-2c-0.55228 0-0.93526-0.45152-1-1v-1h1v-2h-1v-2zm-5 2c-1.6569 0-2.9547 1.3438-3 3v3h2v-3c0-0.55228 0.44772-1 1-1h1v-2z" fill="#f191a5"/> -<path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#7dc6ef"/> -</svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m9 2v2h-1c-1.7267 0-3 1.3359-3 3 0 1.6569 1.3431 3 3 3h1v-2h-1c-.55228 0-1-.44772-1-1s.44772-1 1-1h1v1c0 1.6569 1.3431 3 3 3v-2c-.55228 0-.93526-.45152-1-1v-1h1v-2h-1v-2zm-5 2c-1.6569 0-2.9547 1.3438-3 3v3h2v-3c0-.55228.44772-1 1-1h1v-2z" fill="#f191a5"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#7dc6ef"/></svg> diff --git a/editor/icons/Rectangle.svg b/editor/icons/Rectangle.svg new file mode 100644 index 0000000000..415940e68f --- /dev/null +++ b/editor/icons/Rectangle.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><rect fill="none" height="8" rx=".000017" stroke="#e0e0e0" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2" width="12" x="2" y="4"/></svg> diff --git a/editor/icons/StandardMaterial3D.svg b/editor/icons/StandardMaterial3D.svg index aa8bfc9a5b..7c52665a89 100644 --- a/editor/icons/StandardMaterial3D.svg +++ b/editor/icons/StandardMaterial3D.svg @@ -1,11 +1 @@ -<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="m7.9629 1.002a1.0001 1.0001 0 0 0 -0.41016 0.10352l-3.7891 1.8945h8.4727l-3.7891-1.8945a1.0001 1.0001 0 0 0 -0.48438 -0.10352z" fill="#ff7070"/> -<path transform="translate(0 1036.4)" d="m3.7637 3l-2.2109 1.1055a1.0001 1.0001 0 0 0 -0.55273 0.89453h3.2363l3.7637-1.8809 3.7637 1.8809h3.2363a1.0001 1.0001 0 0 0 -0.55273 -0.89453l-2.2109-1.1055h-8.4727z" fill="#ffeb70"/> -<path transform="translate(0 1036.4)" d="m1 5v2h2v-0.38086l0.76172 0.38086h8.4766l0.76172-0.38086v0.38086h2v-2h-3.2363l-3.7637 1.8828-3.7637-1.8828h-3.2363z" fill="#9dff70"/> -<path transform="translate(0 1036.4)" d="m1 7v2h2v-2h-2zm2.7617 0l3.2383 1.6191v0.38086h2v-0.38086l3.2383-1.6191h-8.4766zm9.2383 0v2h2v-2h-2z" fill="#70ffb9"/> -<path transform="translate(0 1036.4)" d="m1 9v2h3.2344l-1.2344-0.61719v-1.3828h-2zm6 0v2h2v-2h-2zm6 0v1.3828l-1.2344 0.61719h3.2344v-2h-2z" fill="#70deff"/> -<path transform="translate(0 1036.4)" d="m3.7637 13l3.7891 1.8945a1.0001 1.0001 0 0 0 0.48438 0.10547 1.0001 1.0001 0 0 0 0.41016 -0.10547l3.7891-1.8945h-8.4727z" fill="#ff70ac"/> -<path transform="translate(0 1036.4)" d="m1 11a1.0001 1.0001 0 0 0 0.55273 0.89453l2.2109 1.1055h8.4727l2.2109-1.1055a1.0001 1.0001 0 0 0 0.55273 -0.89453h-3.2344l-2.7656 1.3828v-1.3828h-2v1.3828l-2.7656-1.3828h-3.2344z" fill="#9f70ff"/> -</g> -</svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7.9629 1.002a1.0001 1.0001 0 0 0 -.41016.10352l-3.7891 1.8945h8.4727l-3.7891-1.8945a1.0001 1.0001 0 0 0 -.48438-.10352z" fill="#ff7070"/><path d="m3.7637 3-2.2109 1.1055a1.0001 1.0001 0 0 0 -.55273.89453h3.2363l3.7637-1.8809 3.7637 1.8809h3.2363a1.0001 1.0001 0 0 0 -.55273-.89453l-2.2109-1.1055h-8.4727z" fill="#ffeb70"/><path d="m1 5v2h2v-.38086l.76172.38086h8.4766l.76172-.38086v.38086h2v-2h-3.2363l-3.7637 1.8828-3.7637-1.8828h-3.2363z" fill="#9dff70"/><path d="m1 7v2h2v-2zm2.7617 0 3.2383 1.6191v.38086h2v-.38086l3.2383-1.6191zm9.2383 0v2h2v-2z" fill="#70ffb9"/><path d="m1 9v2h3.2344l-1.2344-.61719v-1.3828h-2zm6 0v2h2v-2zm6 0v1.3828l-1.2344.61719h3.2344v-2h-2z" fill="#70deff"/><path d="m3.7637 13 3.7891 1.8945a1.0001 1.0001 0 0 0 .48438.10547 1.0001 1.0001 0 0 0 .41016-.10547l3.7891-1.8945h-8.4727z" fill="#ff70ac"/><path d="m1 11a1.0001 1.0001 0 0 0 .55273.89453l2.2109 1.1055h8.4727l2.2109-1.1055a1.0001 1.0001 0 0 0 .55273-.89453h-3.2344l-2.7656 1.3828v-1.3828h-2v1.3828l-2.7656-1.3828h-3.2344z" fill="#9f70ff"/></svg> diff --git a/editor/icons/StringName.svg b/editor/icons/StringName.svg index bedaa6d634..8f2ef13a37 100644 --- a/editor/icons/StringName.svg +++ b/editor/icons/StringName.svg @@ -1,4 +1 @@ -<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg"> -<path d="m5 2c-1.6569 0-3 1.3431-3 3v2c0 0.55228-0.44772 1-1 1h-1v2h1c1.6569 0 3-1.3431 3-3v-2c0-0.55228 0.44772-1 1-1h1v3c0 1.6569 1.3431 3 3 3h3v-4h1c0.55228 0 1 0.44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3h-5v-2zm3 4h2v2h-1c-0.55228 0-1-0.44772-1-1z" fill="#6ba7ec"/> -<path d="m10 4v6h2v-4h1c0.55228 0 1 0.44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3h-1z" fill="#fff" fill-opacity=".39216"/> -</svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 2c-1.6569 0-3 1.3431-3 3v2c0 .55228-.44772 1-1 1h-1v2h1c1.6569 0 3-1.3431 3-3v-2c0-.55228.44772-1 1-1h1v3c0 1.6569 1.3431 3 3 3h3v-4h1c.55228 0 1 .44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3h-5v-2zm3 4h2v2h-1c-.55228 0-1-.44772-1-1z" fill="#6ba7ec"/><path d="m10 4v6h2v-4h1c.55228 0 1 .44772 1 1v3h2v-3c0-1.6569-1.3431-3-3-3h-1z" fill="#fff" fill-opacity=".39216"/></svg> diff --git a/editor/icons/TrackColor.svg b/editor/icons/TrackColor.svg index 6a736c7a84..cfffc48599 100644 --- a/editor/icons/TrackColor.svg +++ b/editor/icons/TrackColor.svg @@ -1,61 +1 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - height="10" - viewBox="0 0 10 10" - width="10" - version="1.1" - id="svg4" - sodipodi:docname="icon_track_color.svg" - inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> - <metadata - id="metadata10"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs8" /> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="838" - inkscape:window-height="480" - id="namedview6" - showgrid="false" - inkscape:zoom="23.6" - inkscape:cx="5" - inkscape:cy="5" - inkscape:window-x="593" - inkscape:window-y="314" - inkscape:window-maximized="0" - inkscape:current-layer="svg4" /> - <rect - fill="#5792f6" - height="6.1027" - ry=".76286" - transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" - width="6.1027" - x="-740.13947" - y="741.10779" - id="rect2" - style="fill:#ffffff;fill-opacity:1" /> -</svg> +<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#fff" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg> diff --git a/editor/icons/UnpaintVertex.svg b/editor/icons/UnpaintVertex.svg deleted file mode 100644 index 059fcf6e25..0000000000 --- a/editor/icons/UnpaintVertex.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><ellipse cx="8.372881" cy="8.169492" rx="6.677966" ry="6.067797"/></svg> diff --git a/editor/icons/Vector2i.svg b/editor/icons/Vector2i.svg index 6cf9a896f3..39803fd6a4 100644 --- a/editor/icons/Vector2i.svg +++ b/editor/icons/Vector2i.svg @@ -1,5 +1 @@ -<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg"> -<path d="m8 2v2h1c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1c-0.71466-1.248e-4 -1.3751 0.38109-1.7324 1-0.17472 0.30426-0.26633 0.64914-0.26562 1h-2e-3v2h5v-2h-3c1.0717-1.344e-4 2.0619-0.57191 2.5977-1.5 0.5359-0.9282 0.5359-2.0718 0-3-0.53578-0.92809-1.526-1.4999-2.5977-1.5zm-7 2v6h2c1.6569 0 3-1.3431 3-3v-3h-2v3c0 0.55228-0.44772 1-1 1v-4z" fill="#bd91f1"/> -<path d="m8 2v2h1c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1c-0.71466-1.248e-4 -1.3751 0.38109-1.7324 1-0.17472 0.30426-0.26633 0.64914-0.26562 1h-0.001953v2h5v-2h-3c1.0717-1.344e-4 2.0619-0.57191 2.5977-1.5 0.5359-0.9282 0.5359-2.0718 0-3-0.53583-0.92809-1.526-1.4999-2.5977-1.5z" fill="#fff" fill-opacity=".39216"/> -<path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#7dc6ef"/> -</svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2v2h1c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001248-1.3751.38109-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.002v2h5v-2h-3c1.0717-.0001344 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53578-.92809-1.526-1.4999-2.5977-1.5zm-7 2v6h2c1.6569 0 3-1.3431 3-3v-3h-2v3c0 .55228-.44772 1-1 1v-4z" fill="#bd91f1"/><path d="m8 2v2h1c.55228 0 1 .44772 1 1s-.44772 1-1 1c-.71466-.0001248-1.3751.38109-1.7324 1-.17472.30426-.26633.64914-.26562 1h-.001953v2h5v-2h-3c1.0717-.0001344 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.53583-.92809-1.526-1.4999-2.5977-1.5z" fill="#fff" fill-opacity=".39216"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#7dc6ef"/></svg> diff --git a/editor/icons/Vector3i.svg b/editor/icons/Vector3i.svg index d0be27886d..09651193a5 100644 --- a/editor/icons/Vector3i.svg +++ b/editor/icons/Vector3i.svg @@ -1,5 +1 @@ -<svg width="16" height="12" version="1.1" viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg"> -<path d="m8 2v2h2c0 0.55228-0.44772 1-1 1v2c0.55228 0 1 0.44772 1 1s-0.45296 0.92408-1 1h-1v2h1c1.0717-1.34e-4 2.0619-0.57191 2.5977-1.5 0.5359-0.9282 0.5359-2.0718 0-3-0.10406-0.1795-0.22646-0.34771-0.36523-0.50195 0.13855-0.15301 0.26094-0.31991 0.36523-0.49805 0.26209-0.45639 0.3995-0.97371 0.39844-1.5h0.0039v-2zm-7 2v6h2c1.6569 0 3-1.3431 3-3v-3h-2v3c0 0.55228-0.44772 1-1 1v-4z" fill="#e286f0"/> -<path d="m8 2v2h2c0 0.55228-0.44772 1-1 1v2c0.55228 0 1 0.44772 1 1s-0.44948 0.95585-1 1h-1v2h1c1.0717-1.34e-4 2.0619-0.57191 2.5977-1.5 0.5359-0.9282 0.5359-2.0718 0-3-0.10406-0.1795-0.22646-0.34771-0.36523-0.50195 0.13855-0.15301 0.26094-0.31991 0.36523-0.49805 0.26209-0.45639 0.3995-0.97371 0.39844-1.5h0.0039v-2z" fill="#fff" fill-opacity=".39216"/> -<path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#7dc6ef"/> -</svg> +<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.45296.92408-1 1h-1v2h1c1.0717-.000134 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34771-.36523-.50195.13855-.15301.26094-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.0039v-2zm-7 2v6h2c1.6569 0 3-1.3431 3-3v-3h-2v3c0 .55228-.44772 1-1 1v-4z" fill="#e286f0"/><path d="m8 2v2h2c0 .55228-.44772 1-1 1v2c.55228 0 1 .44772 1 1s-.44948.95585-1 1h-1v2h1c1.0717-.000134 2.0619-.57191 2.5977-1.5.5359-.9282.5359-2.0718 0-3-.10406-.1795-.22646-.34771-.36523-.50195.13855-.15301.26094-.31991.36523-.49805.26209-.45639.3995-.97371.39844-1.5h.0039v-2z" fill="#fff" fill-opacity=".39216"/><path d="m13 2v2h2v-2zm0 4v4h2v-4z" fill="#7dc6ef"/></svg> diff --git a/editor/input_map_editor.h b/editor/input_map_editor.h index cc806fc660..87a25e91b0 100644 --- a/editor/input_map_editor.h +++ b/editor/input_map_editor.h @@ -69,7 +69,7 @@ class InputMapEditor : public Control { AcceptDialog *message; UndoRedo *undo_redo; String inputmap_changed; - bool setting; + bool setting = false; void _update_actions(); void _add_item(int p_item, Ref<InputEvent> p_exiting_event = Ref<InputEvent>()); diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp index 8f1b8838d8..c88cd8ea5f 100644 --- a/editor/inspector_dock.cpp +++ b/editor/inspector_dock.cpp @@ -164,7 +164,7 @@ void InspectorDock::_resource_file_selected(String p_file) { editor->push_item(res.operator->()); } -void InspectorDock::_save_resource(bool save_as) const { +void InspectorDock::_save_resource(bool save_as) { ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current(); Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; @@ -179,7 +179,7 @@ void InspectorDock::_save_resource(bool save_as) const { } } -void InspectorDock::_unref_resource() const { +void InspectorDock::_unref_resource() { ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current(); Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; @@ -190,7 +190,7 @@ void InspectorDock::_unref_resource() const { editor->edit_current(); } -void InspectorDock::_copy_resource() const { +void InspectorDock::_copy_resource() { ObjectID current = EditorNode::get_singleton()->get_editor_history()->get_current(); Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr; @@ -201,7 +201,7 @@ void InspectorDock::_copy_resource() const { EditorSettings::get_singleton()->set_resource_clipboard(current_res); } -void InspectorDock::_paste_resource() const { +void InspectorDock::_paste_resource() { RES r = EditorSettings::get_singleton()->get_resource_clipboard(); if (r.is_valid()) { editor->push_item(EditorSettings::get_singleton()->get_resource_clipboard().ptr(), String()); diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h index 551d3d1643..b2dabf19c5 100644 --- a/editor/inspector_dock.h +++ b/editor/inspector_dock.h @@ -96,10 +96,10 @@ class InspectorDock : public VBoxContainer { void _load_resource(const String &p_type = ""); void _open_resource_selector() { _load_resource(); }; // just used to call from arg-less signal void _resource_file_selected(String p_file); - void _save_resource(bool save_as) const; - void _unref_resource() const; - void _copy_resource() const; - void _paste_resource() const; + void _save_resource(bool save_as); + void _unref_resource(); + void _copy_resource(); + void _paste_resource(); void _warning_pressed(); void _resource_created(); diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp index 6764f70d9b..e4562c57af 100644 --- a/editor/localization_editor.cpp +++ b/editor/localization_editor.cpp @@ -319,7 +319,7 @@ void LocalizationEditor::_translation_filter_option_changed() { } } - f_locales = f_locales.sort(); + f_locales.sort(); undo_redo->create_action(TTR("Changed Locale Filter")); undo_redo->add_do_property(ProjectSettings::get_singleton(), "locale/locale_filter", f_locales_all); diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp index b0f65af245..231f5588a4 100644 --- a/editor/plugins/audio_stream_editor_plugin.cpp +++ b/editor/plugins/audio_stream_editor_plugin.cpp @@ -44,8 +44,8 @@ void AudioStreamEditor::_notification(int p_what) { if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) { _play_button->set_icon(get_theme_icon("MainPlay", "EditorIcons")); _stop_button->set_icon(get_theme_icon("Stop", "EditorIcons")); - _preview->set_frame_color(get_theme_color("dark_color_2", "Editor")); - set_frame_color(get_theme_color("dark_color_1", "Editor")); + _preview->set_color(get_theme_color("dark_color_2", "Editor")); + set_color(get_theme_color("dark_color_1", "Editor")); _indicator->update(); _preview->update(); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index c06580df26..1af60b59a2 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -52,6 +52,7 @@ #include "scene/gui/subviewport_container.h" #include "scene/main/canvas_layer.h" #include "scene/main/window.h" +#include "scene/resources/dynamic_font.h" #include "scene/resources/packed_scene.h" // Min and Max are power of two in order to play nicely with successive increment. @@ -1410,9 +1411,16 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) { } // Confirm the pivot move - if ((b.is_valid() && !b->is_pressed() && b->get_button_index() == BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) || - (k.is_valid() && !k->is_pressed() && k->get_keycode() == KEY_V)) { - _commit_canvas_item_state(drag_selection, TTR("Move pivot")); + if (drag_selection.size() >= 1 && + ((b.is_valid() && !b->is_pressed() && b->get_button_index() == BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) || + (k.is_valid() && !k->is_pressed() && k->get_keycode() == KEY_V))) { + _commit_canvas_item_state( + drag_selection, + vformat( + TTR("Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"), + drag_selection[0]->get_name(), + drag_selection[0]->_edit_get_pivot().x, + drag_selection[0]->_edit_get_pivot().y)); drag_type = DRAG_NONE; return true; } @@ -1549,7 +1557,20 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) { // Confirms the node rotation if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { - _commit_canvas_item_state(drag_selection, TTR("Rotate CanvasItem")); + if (drag_selection.size() != 1) { + _commit_canvas_item_state( + drag_selection, + vformat(TTR("Rotate %d CanvasItems"), drag_selection.size()), + true); + } else { + _commit_canvas_item_state( + drag_selection, + vformat(TTR("Rotate CanvasItem \"%s\" to %d degrees"), + drag_selection[0]->get_name(), + Math::rad2deg(drag_selection[0]->_edit_get_rotation())), + true); + } + if (key_auto_insert_button->is_pressed()) { _insert_animation_keys(false, true, false, true); } @@ -1708,8 +1729,10 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) { } // Confirms new anchor position - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { - _commit_canvas_item_state(drag_selection, TTR("Move anchor")); + if (drag_selection.size() >= 1 && b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { + _commit_canvas_item_state( + drag_selection, + vformat(TTR("Move CanvasItem \"%s\" Anchor"), drag_selection[0]->get_name())); drag_type = DRAG_NONE; return true; } @@ -1885,8 +1908,31 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { } // Confirm resize - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { - _commit_canvas_item_state(drag_selection, TTR("Resize CanvasItem")); + if (drag_selection.size() >= 1 && b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { + const Node2D *node2d = Object::cast_to<Node2D>(drag_selection[0]); + if (node2d) { + // Extends from Node2D. + // Node2D doesn't have an actual stored rect size, unlike Controls. + _commit_canvas_item_state( + drag_selection, + vformat( + TTR("Scale Node2D \"%s\" to (%s, %s)"), + drag_selection[0]->get_name(), + Math::stepify(drag_selection[0]->_edit_get_scale().x, 0.01), + Math::stepify(drag_selection[0]->_edit_get_scale().y, 0.01)), + true); + } else { + // Extends from Control. + _commit_canvas_item_state( + drag_selection, + vformat( + TTR("Resize Control \"%s\" to (%d, %d)"), + drag_selection[0]->get_name(), + drag_selection[0]->_edit_get_rect().size.x, + drag_selection[0]->_edit_get_rect().size.y), + true); + } + if (key_auto_insert_button->is_pressed()) { _insert_animation_keys(false, false, true, true); } @@ -2014,7 +2060,20 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { // Confirm resize if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && !b->is_pressed()) { - _commit_canvas_item_state(drag_selection, TTR("Scale CanvasItem")); + if (drag_selection.size() != 1) { + _commit_canvas_item_state( + drag_selection, + vformat(TTR("Scale %d CanvasItems"), drag_selection.size()), + true); + } else { + _commit_canvas_item_state( + drag_selection, + vformat(TTR("Scale CanvasItem \"%s\" to (%s, %s)"), + drag_selection[0]->get_name(), + Math::stepify(drag_selection[0]->_edit_get_scale().x, 0.01), + Math::stepify(drag_selection[0]->_edit_get_scale().y, 0.01)), + true); + } if (key_auto_insert_button->is_pressed()) { _insert_animation_keys(false, false, true, true); } @@ -2145,7 +2204,21 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { // Confirm the move (only if it was moved) if (b.is_valid() && !b->is_pressed() && b->get_button_index() == BUTTON_LEFT) { if (transform.affine_inverse().xform(b->get_position()) != drag_from) { - _commit_canvas_item_state(drag_selection, TTR("Move CanvasItem"), true); + if (drag_selection.size() != 1) { + _commit_canvas_item_state( + drag_selection, + vformat(TTR("Move %d CanvasItems"), drag_selection.size()), + true); + } else { + _commit_canvas_item_state( + drag_selection, + vformat( + TTR("Move CanvasItem \"%s\" to (%d, %d)"), + drag_selection[0]->get_name(), + drag_selection[0]->_edit_get_position().x, + drag_selection[0]->_edit_get_position().y), + true); + } } if (key_auto_insert_button->is_pressed()) { @@ -2270,7 +2343,20 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { (!Input::get_singleton()->is_key_pressed(KEY_DOWN)) && (!Input::get_singleton()->is_key_pressed(KEY_LEFT)) && (!Input::get_singleton()->is_key_pressed(KEY_RIGHT))) { - _commit_canvas_item_state(drag_selection, TTR("Move CanvasItem"), true); + if (drag_selection.size() != 1) { + _commit_canvas_item_state( + drag_selection, + vformat(TTR("Move %d CanvasItems"), drag_selection.size()), + true); + } else { + _commit_canvas_item_state( + drag_selection, + vformat(TTR("Move CanvasItem \"%s\" to (%d, %d)"), + drag_selection[0]->get_name(), + drag_selection[0]->_edit_get_position().x, + drag_selection[0]->_edit_get_position().y), + true); + } drag_type = DRAG_NONE; } viewport->update(); @@ -5642,6 +5728,11 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { zoom_reset = memnew(Button); zoom_reset->set_flat(true); zoom_hb->add_child(zoom_reset); + Ref<DynamicFont> font = zoom_reset->get_theme_font("font")->duplicate(false); + font->set_outline_size(1); + font->set_outline_color(Color(0, 0, 0)); + zoom_reset->add_theme_font_override("font", font); + zoom_reset->add_theme_color_override("font_color", Color(1, 1, 1)); zoom_reset->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_zoom_reset)); zoom_reset->set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", TTR("Zoom Reset"), KEY_MASK_CMD | KEY_0)); zoom_reset->set_focus_mode(FOCUS_NONE); diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h index 59cf787020..4d3fc0d8a9 100644 --- a/editor/plugins/gradient_editor_plugin.h +++ b/editor/plugins/gradient_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ -#define TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ +#ifndef GRADIENT_EDITOR_PLUGIN_H +#define GRADIENT_EDITOR_PLUGIN_H #include "editor/editor_node.h" #include "editor/editor_plugin.h" @@ -65,9 +65,9 @@ class GradientEditorPlugin : public EditorPlugin { GDCLASS(GradientEditorPlugin, EditorPlugin); public: - virtual String get_name() const override { return "ColorRamp"; } + virtual String get_name() const override { return "Gradient"; } GradientEditorPlugin(EditorNode *p_node); }; -#endif /* TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ */ +#endif // GRADIENT_EDITOR_PLUGIN_H diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index aecbf817c4..5038941784 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2464,12 +2464,14 @@ void Node3DEditorViewport::_notification(int p_what) { subviewport_container->set_stretch_shrink(shrink ? 2 : 1); } - //update msaa if changed + // Update MSAA, screen-space AA and debanding if changed - int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/screen_filters/msaa"); + const int msaa_mode = ProjectSettings::get_singleton()->get("rendering/quality/screen_filters/msaa"); viewport->set_msaa(Viewport::MSAA(msaa_mode)); - int ssaa_mode = GLOBAL_GET("rendering/quality/screen_filters/screen_space_aa"); + const int ssaa_mode = GLOBAL_GET("rendering/quality/screen_filters/screen_space_aa"); viewport->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode)); + const bool use_debanding = GLOBAL_GET("rendering/quality/screen_filters/use_debanding"); + viewport->set_use_debanding(use_debanding); bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION)); if (show_info != info_label->is_visible()) { @@ -6725,7 +6727,6 @@ void EditorNode3DGizmoPlugin::create_handle_material(const String &p_name, bool handle_material->set_point_size(handle_t->get_width()); handle_material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, handle_t); handle_material->set_albedo(Color(1, 1, 1)); - handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); handle_material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); handle_material->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); handle_material->set_on_top_of_alpha(); @@ -6733,6 +6734,7 @@ void EditorNode3DGizmoPlugin::create_handle_material(const String &p_name, bool handle_material->set_billboard_mode(StandardMaterial3D::BILLBOARD_ENABLED); handle_material->set_on_top_of_alpha(); } + handle_material->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); materials[p_name] = Vector<Ref<StandardMaterial3D>>(); materials[p_name].push_back(handle_material); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 4f627b1d0c..e4a384449b 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SPATIAL_EDITOR_PLUGIN_H -#define SPATIAL_EDITOR_PLUGIN_H +#ifndef NODE_3D_EDITOR_PLUGIN_H +#define NODE_3D_EDITOR_PLUGIN_H #include "editor/editor_node.h" #include "editor/editor_plugin.h" @@ -890,4 +890,4 @@ public: virtual ~EditorNode3DGizmoPlugin(); }; -#endif +#endif // NODE_3D_EDITOR_PLUGIN_H diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index dd1194d020..ac90ee9570 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -79,8 +79,8 @@ void Polygon2DEditor::_notification(int p_what) { uv_button[UV_MODE_SCALE]->set_icon(get_theme_icon("ToolScale", "EditorIcons")); uv_button[UV_MODE_ADD_POLYGON]->set_icon(get_theme_icon("Edit", "EditorIcons")); uv_button[UV_MODE_REMOVE_POLYGON]->set_icon(get_theme_icon("Close", "EditorIcons")); - uv_button[UV_MODE_PAINT_WEIGHT]->set_icon(get_theme_icon("PaintVertex", "EditorIcons")); - uv_button[UV_MODE_CLEAR_WEIGHT]->set_icon(get_theme_icon("UnpaintVertex", "EditorIcons")); + uv_button[UV_MODE_PAINT_WEIGHT]->set_icon(get_theme_icon("Bucket", "EditorIcons")); + uv_button[UV_MODE_CLEAR_WEIGHT]->set_icon(get_theme_icon("Clear", "EditorIcons")); b_snap_grid->set_icon(get_theme_icon("Grid", "EditorIcons")); b_snap_enable->set_icon(get_theme_icon("SnapGrid", "EditorIcons")); @@ -1325,11 +1325,16 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) : uv_main_hsc->add_child(uv_edit_draw); uv_edit_draw->set_h_size_flags(SIZE_EXPAND_FILL); uv_edit_draw->set_custom_minimum_size(Size2(200, 200) * EDSCALE); + + Control *space = memnew(Control); + uv_mode_hb->add_child(space); + space->set_h_size_flags(SIZE_EXPAND_FILL); + uv_menu = memnew(MenuButton); uv_mode_hb->add_child(uv_menu); uv_menu->set_text(TTR("Edit")); - uv_menu->get_popup()->add_item(TTR("Polygon->UV"), UVEDIT_POLYGON_TO_UV); - uv_menu->get_popup()->add_item(TTR("UV->Polygon"), UVEDIT_UV_TO_POLYGON); + uv_menu->get_popup()->add_item(TTR("Copy Polygon to UV"), UVEDIT_POLYGON_TO_UV); + uv_menu->get_popup()->add_item(TTR("Copy UV to Polygon"), UVEDIT_UV_TO_POLYGON); uv_menu->get_popup()->add_separator(); uv_menu->get_popup()->add_item(TTR("Clear UV"), UVEDIT_UV_CLEAR); uv_menu->get_popup()->add_separator(); diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 8cd8aaf277..e43b8c4b7f 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -65,7 +65,7 @@ void TileMapEditor::_notification(int p_what) { paint_button->set_icon(get_theme_icon("Edit", "EditorIcons")); line_button->set_icon(get_theme_icon("CurveLinear", "EditorIcons")); - rectangle_button->set_icon(get_theme_icon("RectangleShape2D", "EditorIcons")); + rectangle_button->set_icon(get_theme_icon("Rectangle", "EditorIcons")); bucket_fill_button->set_icon(get_theme_icon("Bucket", "EditorIcons")); picker_button->set_icon(get_theme_icon("ColorPick", "EditorIcons")); select_button->set_icon(get_theme_icon("ActionCopy", "EditorIcons")); @@ -89,6 +89,25 @@ void TileMapEditor::_notification(int p_what) { case NOTIFICATION_EXIT_TREE: { get_tree()->disconnect("node_removed", callable_mp(this, &TileMapEditor::_node_removed)); } break; + + case NOTIFICATION_APPLICATION_FOCUS_OUT: { + if (tool == TOOL_PAINTING) { + Vector<int> ids = get_selected_tiles(); + + if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) { + _set_cell(over_tile, ids, flip_h, flip_v, transpose); + _finish_undo(); + + paint_undo.clear(); + } + + tool = TOOL_NONE; + _update_button_tool(); + } + + // set flag to ignore over_tile on refocus + refocus_over_tile = true; + } break; } } @@ -394,7 +413,9 @@ struct _PaletteEntry { String name; bool operator<(const _PaletteEntry &p_rhs) const { - return name < p_rhs.name; + // Natural no case comparison will compare strings based on CharType + // order (except digits) and on numbers that start on the same position. + return name.naturalnocasecmp_to(p_rhs.name) < 0; } }; } // namespace @@ -1299,6 +1320,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { CanvasItemEditor::get_singleton()->update_viewport(); } + if (refocus_over_tile) { + // editor lost focus; forget last tile position + old_over_tile = new_over_tile; + refocus_over_tile = false; + } + int tile_under = node->get_cell(over_tile.x, over_tile.y); String tile_name = "none"; diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index 996e904853..f57616db1f 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -119,6 +119,7 @@ class TileMapEditor : public VBoxContainer { Rect2i rectangle; Point2i over_tile; + bool refocus_over_tile = false; bool *bucket_cache_visited; Rect2i bucket_cache_rect; diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 684d8f0f10..9c589267fc 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -60,7 +60,6 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) { Sprite2D *mi = Object::cast_to<Sprite2D>(child); Ref<Texture2D> texture = mi->get_texture(); - Ref<Texture2D> normal_map = mi->get_normal_map(); Ref<ShaderMaterial> material = mi->get_material(); if (texture.is_null()) { @@ -75,7 +74,6 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) { } p_library->tile_set_texture(id, texture); - p_library->tile_set_normal_map(id, normal_map); p_library->tile_set_material(id, material); p_library->tile_set_modulate(id, mi->get_modulate()); @@ -2368,7 +2366,6 @@ void TileSetEditor::_select_edited_shape_coord() { void TileSetEditor::_undo_tile_removal(int p_id) { undo_redo->add_undo_method(tileset.ptr(), "create_tile", p_id); undo_redo->add_undo_method(tileset.ptr(), "tile_set_name", p_id, tileset->tile_get_name(p_id)); - undo_redo->add_undo_method(tileset.ptr(), "tile_set_normal_map", p_id, tileset->tile_get_normal_map(p_id)); undo_redo->add_undo_method(tileset.ptr(), "tile_set_texture_offset", p_id, tileset->tile_get_texture_offset(p_id)); undo_redo->add_undo_method(tileset.ptr(), "tile_set_material", p_id, tileset->tile_get_material(p_id)); undo_redo->add_undo_method(tileset.ptr(), "tile_set_modulate", p_id, tileset->tile_get_modulate(p_id)); @@ -3541,7 +3538,6 @@ void TilesetEditorContext::_get_property_list(List<PropertyInfo> *p_list) const int id = tileset_editor->get_current_tile(); p_list->push_back(PropertyInfo(Variant::NIL, "Selected Tile", PROPERTY_HINT_NONE, "tile_", PROPERTY_USAGE_GROUP)); p_list->push_back(PropertyInfo(Variant::STRING, "tile_name")); - p_list->push_back(PropertyInfo(Variant::OBJECT, "tile_normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D")); p_list->push_back(PropertyInfo(Variant::VECTOR2, "tile_tex_offset")); p_list->push_back(PropertyInfo(Variant::OBJECT, "tile_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial")); p_list->push_back(PropertyInfo(Variant::COLOR, "tile_modulate")); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 2d0f4a19e7..ddcba18a78 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -107,6 +107,8 @@ void VisualShaderGraphPlugin::_bind_methods() { ClassDB::bind_method("update_node_deferred", &VisualShaderGraphPlugin::update_node_deferred); ClassDB::bind_method("set_input_port_default_value", &VisualShaderGraphPlugin::set_input_port_default_value); ClassDB::bind_method("set_uniform_name", &VisualShaderGraphPlugin::set_uniform_name); + ClassDB::bind_method("set_expression", &VisualShaderGraphPlugin::set_expression); + ClassDB::bind_method("update_curve", &VisualShaderGraphPlugin::update_curve); ClassDB::bind_method("update_constant", &VisualShaderGraphPlugin::update_constant); } @@ -205,6 +207,14 @@ void VisualShaderGraphPlugin::set_uniform_name(VisualShader::Type p_type, int p_ } } +void VisualShaderGraphPlugin::update_curve(int p_node_id) { + if (links.has(p_node_id) && links[p_node_id].curve_editor) { + if (((VisualShaderNodeCurveTexture *)links[p_node_id].visual_node)->get_texture().is_valid()) { + links[p_node_id].curve_editor->set_curve(((VisualShaderNodeCurveTexture *)links[p_node_id].visual_node)->get_texture()->get_curve()); + } + } +} + int VisualShaderGraphPlugin::get_constant_index(float p_constant) const { for (int i = 0; i < MAX_FLOAT_CONST_DEFS; i++) { if (Math::is_equal_approx(p_constant, float_constant_defs[i].value)) { @@ -226,6 +236,13 @@ void VisualShaderGraphPlugin::update_constant(VisualShader::Type p_type, int p_n links[p_node_id].graph_node->set_size(Size2(-1, -1)); } +void VisualShaderGraphPlugin::set_expression(VisualShader::Type p_type, int p_node_id, const String &p_expression) { + if (p_type != visual_shader->get_shader_type() || !links.has(p_node_id) || !links[p_node_id].expression_edit) { + return; + } + links[p_node_id].expression_edit->set_text(p_expression); +} + void VisualShaderGraphPlugin::update_node_size(int p_node_id) { if (!links.has(p_node_id)) { return; @@ -241,6 +258,14 @@ void VisualShaderGraphPlugin::register_constant_option_btn(int p_node_id, Option links[p_node_id].const_op = p_button; } +void VisualShaderGraphPlugin::register_expression_edit(int p_node_id, CodeEdit *p_expression_edit) { + links[p_node_id].expression_edit = p_expression_edit; +} + +void VisualShaderGraphPlugin::register_curve_editor(int p_node_id, CurveEditor *p_curve_editor) { + links[p_node_id].curve_editor = p_curve_editor; +} + void VisualShaderGraphPlugin::update_uniform_refs() { for (Map<int, Link>::Element *E = links.front(); E; E = E->next()) { VisualShaderNodeUniformRef *ref = Object::cast_to<VisualShaderNodeUniformRef>(E->get().visual_node); @@ -284,7 +309,7 @@ void VisualShaderGraphPlugin::make_dirty(bool p_enabled) { } void VisualShaderGraphPlugin::register_link(VisualShader::Type p_type, int p_id, VisualShaderNode *p_visual_node, GraphNode *p_graph_node) { - links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, Map<int, InputPort>(), Map<int, Port>(), nullptr, nullptr, nullptr }); + links.insert(p_id, { p_type, p_visual_node, p_graph_node, p_visual_node->get_output_port_for_preview() != -1, -1, Map<int, InputPort>(), Map<int, Port>(), nullptr, nullptr, nullptr, nullptr, nullptr }); } void VisualShaderGraphPlugin::register_output_port(int p_node_id, int p_port, TextureButton *p_button) { @@ -315,9 +340,12 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { Ref<VisualShaderNode> vsnode = visual_shader->get_node(p_type, p_id); + Ref<VisualShaderNodeResizableBase> resizable_node = Object::cast_to<VisualShaderNodeResizableBase>(vsnode.ptr()); + bool is_resizable = !resizable_node.is_null(); + Size2 size = Size2(0, 0); + Ref<VisualShaderNodeGroupBase> group_node = Object::cast_to<VisualShaderNodeGroupBase>(vsnode.ptr()); bool is_group = !group_node.is_null(); - Size2 size = Size2(0, 0); Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(group_node.ptr()); bool is_expression = !expression_node.is_null(); @@ -326,8 +354,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { GraphNode *node = memnew(GraphNode); register_link(p_type, p_id, vsnode.ptr(), node); - if (is_group) { - size = group_node->get_size(); + if (is_resizable) { + size = resizable_node->get_size(); node->set_resizable(true); node->connect("resize_request", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_node_resized), varray((int)p_type, p_id)); @@ -342,7 +370,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (p_id >= 2) { node->set_show_close_button(true); - node->connect("close_request", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_delete_request), varray(p_id), CONNECT_DEFERRED); + node->connect("close_request", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_delete_node_request), varray(p_type, p_id), CONNECT_DEFERRED); } node->connect("dragged", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_node_dragged), varray(p_id)); @@ -391,6 +419,18 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } } + Ref<VisualShaderNodeCurveTexture> curve = vsnode; + if (curve.is_valid()) { + if (curve->get_texture().is_valid() && !curve->get_texture()->is_connected("changed", callable_mp(VisualShaderEditor::get_singleton()->get_graph_plugin(), &VisualShaderGraphPlugin::update_curve))) { + curve->get_texture()->connect("changed", callable_mp(VisualShaderEditor::get_singleton()->get_graph_plugin(), &VisualShaderGraphPlugin::update_curve), varray(p_id)); + } + + HBoxContainer *hbox = memnew(HBoxContainer); + custom_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL); + hbox->add_child(custom_editor); + custom_editor = hbox; + } + Ref<VisualShaderNodeFloatConstant> float_const = vsnode; if (float_const.is_valid()) { HBoxContainer *hbox = memnew(HBoxContainer); @@ -413,6 +453,37 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { } else if (custom_editor) { port_offset++; node->add_child(custom_editor); + + if (curve.is_valid()) { + VisualShaderEditor::get_singleton()->graph->add_child(node); + VisualShaderEditor::get_singleton()->_update_created_node(node); + + CurveEditor *curve_editor = memnew(CurveEditor); + node->add_child(curve_editor); + register_curve_editor(p_id, curve_editor); + curve_editor->set_custom_minimum_size(Size2(300, 0)); + curve_editor->set_h_size_flags(Control::SIZE_EXPAND_FILL); + if (curve->get_texture().is_valid()) { + curve_editor->set_curve(curve->get_texture()->get_curve()); + } + + TextureButton *preview = memnew(TextureButton); + preview->set_toggle_mode(true); + preview->set_normal_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityHidden", "EditorIcons")); + preview->set_pressed_texture(VisualShaderEditor::get_singleton()->get_theme_icon("GuiVisibilityVisible", "EditorIcons")); + preview->set_v_size_flags(Control::SIZE_SHRINK_CENTER); + + register_output_port(p_id, 0, preview); + + preview->connect("pressed", callable_mp(VisualShaderEditor::get_singleton(), &VisualShaderEditor::_preview_select_port), varray(p_id, 0), CONNECT_DEFERRED); + custom_editor->add_child(preview); + + VisualShaderNode::PortType port_left = vsnode->get_input_port_type(0); + VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0); + node->set_slot(0, true, port_left, type_color[port_left], true, port_right, type_color[port_right]); + + VisualShaderEditor::get_singleton()->call_deferred("_set_node_size", (int)p_type, p_id, size); + } if (vsnode->is_use_prop_slots()) { return; } @@ -623,6 +694,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { expression_syntax_highlighter.instance(); expression_node->set_control(expression_box, 0); node->add_child(expression_box); + register_expression_edit(p_id, expression_box); Color background_color = EDITOR_GET("text_editor/highlighting/background_color"); Color text_color = EDITOR_GET("text_editor/highlighting/text_color"); @@ -659,7 +731,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) { if (!uniform.is_valid()) { VisualShaderEditor::get_singleton()->graph->add_child(node); VisualShaderEditor::get_singleton()->_update_created_node(node); - if (is_group) { + if (is_resizable) { VisualShaderEditor::get_singleton()->call_deferred("_set_node_size", (int)p_type, p_id, size); } } @@ -1210,7 +1282,7 @@ void VisualShaderEditor::_add_input_port(int p_node, int p_port, int p_port_type return; } - undo_redo->create_action(TTR("Add input port")); + undo_redo->create_action(TTR("Add Input Port")); undo_redo->add_do_method(node.ptr(), "add_input_port", p_port, p_port_type, p_name); undo_redo->add_undo_method(node.ptr(), "remove_input_port", p_port); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node); @@ -1225,7 +1297,7 @@ void VisualShaderEditor::_add_output_port(int p_node, int p_port, int p_port_typ return; } - undo_redo->create_action(TTR("Add output port")); + undo_redo->create_action(TTR("Add Output Port")); undo_redo->add_do_method(node.ptr(), "add_output_port", p_port, p_port_type, p_name); undo_redo->add_undo_method(node.ptr(), "remove_output_port", p_port); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node); @@ -1240,7 +1312,7 @@ void VisualShaderEditor::_change_input_port_type(int p_type, int p_node, int p_p return; } - undo_redo->create_action(TTR("Change input port type")); + undo_redo->create_action(TTR("Change Input Port Type")); undo_redo->add_do_method(node.ptr(), "set_input_port_type", p_port, p_type); undo_redo->add_undo_method(node.ptr(), "set_input_port_type", p_port, node->get_input_port_type(p_port)); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node); @@ -1255,7 +1327,7 @@ void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_ return; } - undo_redo->create_action(TTR("Change output port type")); + undo_redo->create_action(TTR("Change Output Port Type")); undo_redo->add_do_method(node.ptr(), "set_output_port_type", p_port, p_type); undo_redo->add_undo_method(node.ptr(), "set_output_port_type", p_port, node->get_output_port_type(p_port)); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node); @@ -1269,7 +1341,7 @@ void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *l Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); - undo_redo->create_action(TTR("Change input port name")); + undo_redo->create_action(TTR("Change Input Port Name")); undo_redo->add_do_method(node.ptr(), "set_input_port_name", p_port_id, p_text); undo_redo->add_undo_method(node.ptr(), "set_input_port_name", p_port_id, node->get_input_port_name(p_port_id)); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node_id); @@ -1283,7 +1355,7 @@ void VisualShaderEditor::_change_output_port_name(const String &p_text, Object * Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id); ERR_FAIL_COND(!node.is_valid()); - undo_redo->create_action(TTR("Change output port name")); + undo_redo->create_action(TTR("Change Output Port Name")); undo_redo->add_do_method(node.ptr(), "set_output_port_name", p_port_id, p_text); undo_redo->add_undo_method(node.ptr(), "set_output_port_name", p_port_id, node->get_output_port_name(p_port_id)); undo_redo->add_do_method(graph_plugin.ptr(), "update_node", type, p_node_id); @@ -1298,7 +1370,7 @@ void VisualShaderEditor::_remove_input_port(int p_node, int p_port) { return; } - undo_redo->create_action(TTR("Remove input port")); + undo_redo->create_action(TTR("Remove Input Port")); List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); @@ -1347,7 +1419,7 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) { return; } - undo_redo->create_action(TTR("Remove output port")); + undo_redo->create_action(TTR("Remove Output Port")); List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); @@ -1402,31 +1474,39 @@ void VisualShaderEditor::_expression_focus_out(Object *code_edit, int p_node) { return; } - undo_redo->create_action(TTR("Set expression")); + undo_redo->create_action(TTR("Set VisualShader Expression")); undo_redo->add_do_method(node.ptr(), "set_expression", expression_box->get_text()); undo_redo->add_undo_method(node.ptr(), "set_expression", node->get_expression()); + undo_redo->add_do_method(graph_plugin.ptr(), "set_expression", type, p_node, expression_box->get_text()); + undo_redo->add_undo_method(graph_plugin.ptr(), "set_expression", type, p_node, node->get_expression()); undo_redo->commit_action(); } void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p_size) { - VisualShader::Type type = get_current_shader_type(); - Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node); + VisualShader::Type type = VisualShader::Type(p_type); + Ref<VisualShaderNodeResizableBase> node = visual_shader->get_node(type, p_node); if (node.is_null()) { return; } - Ref<VisualShaderNodeGroupBase> group_node = Object::cast_to<VisualShaderNodeGroupBase>(node.ptr()); - - if (group_node.is_null()) { - return; + Size2 size = p_size; + if (!node->is_allow_v_resize()) { + size.y = 0; } - Vector2 size = p_size; + node->set_size(size); - group_node->set_size(size); + if (get_current_shader_type() == type) { + Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(node.ptr()); + Control *text_box = nullptr; + if (!expression_node.is_null()) { + text_box = expression_node->get_control(0); + if (text_box) { + text_box->set_custom_minimum_size(Size2(0, 0)); + } + } - GraphNode *gn = nullptr; - if (edit_type->get_selected() == p_type) { // check - otherwise the error will be emitted + GraphNode *gn = nullptr; Node *node2 = graph->get_node(itos(p_node)); gn = Object::cast_to<GraphNode>(node2); if (!gn) { @@ -1435,34 +1515,31 @@ void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p gn->set_custom_minimum_size(size); gn->set_size(Size2(1, 1)); - } - Ref<VisualShaderNodeExpression> expression_node = Object::cast_to<VisualShaderNodeExpression>(node.ptr()); - if (!expression_node.is_null()) { - Control *text_box = expression_node->get_control(0); - Size2 box_size = size; - if (gn != nullptr) { - if (box_size.x < 150 * EDSCALE || box_size.y < 0) { - box_size.x = gn->get_size().x; + if (!expression_node.is_null() && text_box) { + Size2 box_size = size; + if (gn != nullptr) { + if (box_size.x < 150 * EDSCALE || box_size.y < 0) { + box_size.x = gn->get_size().x; + } } + box_size.x -= text_box->get_margin(MARGIN_LEFT); + box_size.x -= 28 * EDSCALE; + box_size.y -= text_box->get_margin(MARGIN_TOP); + box_size.y -= 28 * EDSCALE; + text_box->set_custom_minimum_size(Size2(box_size.x, box_size.y)); + text_box->set_size(Size2(1, 1)); } - box_size.x -= text_box->get_margin(MARGIN_LEFT); - box_size.x -= 28 * EDSCALE; - box_size.y -= text_box->get_margin(MARGIN_TOP); - box_size.y -= 28 * EDSCALE; - text_box->set_custom_minimum_size(Size2(box_size.x, box_size.y)); - text_box->set_size(Size2(1, 1)); } } void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, int p_node) { - VisualShader::Type type = get_current_shader_type(); - Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node); + Ref<VisualShaderNodeResizableBase> node = visual_shader->get_node(VisualShader::Type(p_type), p_node); if (node.is_null()) { return; } - undo_redo->create_action(TTR("Resize VisualShader node"), UndoRedo::MERGE_ENDS); + undo_redo->create_action(TTR("Resize VisualShader Node"), UndoRedo::MERGE_ENDS); undo_redo->add_do_method(this, "_set_node_size", p_type, p_node, p_new_size); undo_redo->add_undo_method(this, "_set_node_size", p_type, p_node, node->get_size()); undo_redo->commit_action(); @@ -1637,6 +1714,11 @@ void VisualShaderEditor::_add_texture3d_node(const String &p_path) { texture3d->set_texture(ResourceLoader::load(p_path)); } +void VisualShaderEditor::_add_curve_node(const String &p_path) { + VisualShaderNodeCurveTexture *curve = (VisualShaderNodeCurveTexture *)_add_node(curve_node_option_idx, -1); + curve->set_texture(ResourceLoader::load(p_path)); +} + VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr); @@ -1815,6 +1897,11 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { undo_redo->add_undo_method(this, "_update_uniforms", true); } + VisualShaderNodeCurveTexture *curve = Object::cast_to<VisualShaderNodeCurveTexture>(vsnode.ptr()); + if (curve) { + graph_plugin->call_deferred("update_curve", id_to_use); + } + undo_redo->commit_action(); return vsnode.ptr(); } @@ -1903,61 +1990,112 @@ void VisualShaderEditor::_connection_from_empty(const String &p_to, int p_to_slo _show_members_dialog(true); } -void VisualShaderEditor::_delete_request(int which) { - VisualShader::Type type = get_current_shader_type(); - Ref<VisualShaderNode> node = Ref<VisualShaderNode>(visual_shader->get_node(type, which)); - - undo_redo->create_action(TTR("Delete Node")); - +void VisualShaderEditor::_delete_nodes(int p_type, const List<int> &p_nodes) { + VisualShader::Type type = VisualShader::Type(p_type); List<VisualShader::Connection> conns; visual_shader->get_node_connections(type, &conns); - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().from_node == which || E->get().to_node == which) { - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + + for (const List<int>::Element *F = p_nodes.front(); F; F = F->next()) { + for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { + if (E->get().from_node == F->get() || E->get().to_node == F->get()) { + undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + } } } - undo_redo->add_do_method(visual_shader.ptr(), "remove_node", type, which); - undo_redo->add_undo_method(visual_shader.ptr(), "add_node", type, node, visual_shader->get_node_position(type, which), which); - undo_redo->add_undo_method(graph_plugin.ptr(), "add_node", type, which); + Set<String> uniform_names; - undo_redo->add_do_method(this, "_clear_buffer"); - undo_redo->add_undo_method(this, "_clear_buffer"); + for (const List<int>::Element *F = p_nodes.front(); F; F = F->next()) { + Ref<VisualShaderNode> node = visual_shader->get_node(type, F->get()); - // restore size, inputs and outputs if node is group - VisualShaderNodeGroupBase *group = Object::cast_to<VisualShaderNodeGroupBase>(node.ptr()); - if (group) { - undo_redo->add_undo_method(group, "set_size", group->get_size()); - undo_redo->add_undo_method(group, "set_inputs", group->get_inputs()); - undo_redo->add_undo_method(group, "set_outputs", group->get_outputs()); - } + undo_redo->add_do_method(visual_shader.ptr(), "remove_node", type, F->get()); + undo_redo->add_undo_method(visual_shader.ptr(), "add_node", type, node, visual_shader->get_node_position(type, F->get()), F->get()); + undo_redo->add_undo_method(graph_plugin.ptr(), "add_node", type, F->get()); + + undo_redo->add_do_method(this, "_clear_buffer"); + undo_redo->add_undo_method(this, "_clear_buffer"); + + // restore size, inputs and outputs if node is group + VisualShaderNodeGroupBase *group = Object::cast_to<VisualShaderNodeGroupBase>(node.ptr()); + if (group) { + undo_redo->add_undo_method(group, "set_size", group->get_size()); + undo_redo->add_undo_method(group, "set_inputs", group->get_inputs()); + undo_redo->add_undo_method(group, "set_outputs", group->get_outputs()); + } - // restore expression text if node is expression - VisualShaderNodeExpression *expression = Object::cast_to<VisualShaderNodeExpression>(node.ptr()); - if (expression) { - undo_redo->add_undo_method(expression, "set_expression", expression->get_expression()); + // restore expression text if node is expression + VisualShaderNodeExpression *expression = Object::cast_to<VisualShaderNodeExpression>(node.ptr()); + if (expression) { + undo_redo->add_undo_method(expression, "set_expression", expression->get_expression()); + } + + VisualShaderNodeUniform *uniform = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); + if (uniform) { + uniform_names.insert(uniform->get_uniform_name()); + } } - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().from_node == which || E->get().to_node == which) { - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + List<VisualShader::Connection> used_conns; + for (const List<int>::Element *F = p_nodes.front(); F; F = F->next()) { + for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { + if (E->get().from_node == F->get() || E->get().to_node == F->get()) { + bool cancel = false; + for (List<VisualShader::Connection>::Element *R = used_conns.front(); R; R = R->next()) { + if (R->get().from_node == E->get().from_node && R->get().from_port == E->get().from_port && R->get().to_node == E->get().to_node && R->get().to_port == E->get().to_port) { + cancel = true; // to avoid ERR_ALREADY_EXISTS warning + break; + } + } + if (!cancel) { + undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); + used_conns.push_back(E->get()); + } + } } } - // delete a node from the graph - undo_redo->add_do_method(graph_plugin.ptr(), "remove_node", type, which); - VisualShaderNodeUniform *uniform = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); - if (uniform) { + // delete nodes from the graph + for (const List<int>::Element *F = p_nodes.front(); F; F = F->next()) { + undo_redo->add_do_method(graph_plugin.ptr(), "remove_node", type, F->get()); + } + + // update uniform refs if any uniform has been deleted + if (uniform_names.size() > 0) { undo_redo->add_do_method(this, "_update_uniforms", true); undo_redo->add_undo_method(this, "_update_uniforms", true); - Set<String> uniform_names; - uniform_names.insert(uniform->get_uniform_name()); - _update_uniform_refs(uniform_names); } +} + +void VisualShaderEditor::_delete_node_request(int p_type, int p_node) { + List<int> to_erase; + to_erase.push_back(p_node); + + undo_redo->create_action(TTR("Delete VisualShader Node")); + _delete_nodes(p_type, to_erase); + undo_redo->commit_action(); +} + +void VisualShaderEditor::_delete_nodes_request() { + List<int> to_erase; + + for (int i = 0; i < graph->get_child_count(); i++) { + GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); + if (gn) { + if (gn->is_selected() && gn->is_close_button_visible()) { + to_erase.push_back(gn->get_name().operator String().to_int()); + } + } + } + + if (to_erase.empty()) { + return; + } + undo_redo->create_action(TTR("Delete VisualShader Node(s)")); + _delete_nodes(get_current_shader_type(), to_erase); undo_redo->commit_action(); } @@ -2280,7 +2418,7 @@ void VisualShaderEditor::_clear_buffer() { } void VisualShaderEditor::_duplicate_nodes() { - int type = edit_type->get_selected(); + int type = get_current_shader_type(); List<int> nodes; Set<int> excluded; @@ -2291,13 +2429,13 @@ void VisualShaderEditor::_duplicate_nodes() { return; } - undo_redo->create_action(TTR("Duplicate Nodes")); + undo_redo->create_action(TTR("Duplicate VisualShader Node(s)")); _dup_paste_nodes(type, type, nodes, excluded, Vector2(10, 10) * EDSCALE, true); } void VisualShaderEditor::_copy_nodes() { - copy_type = edit_type->get_selected(); + copy_type = get_current_shader_type(); _clear_buffer(); @@ -2309,9 +2447,7 @@ void VisualShaderEditor::_paste_nodes(bool p_use_custom_position, const Vector2 return; } - int type = edit_type->get_selected(); - - undo_redo->create_action(TTR("Paste Nodes")); + int type = get_current_shader_type(); float scale = graph->get_zoom(); @@ -2322,109 +2458,13 @@ void VisualShaderEditor::_paste_nodes(bool p_use_custom_position, const Vector2 mpos = graph->get_local_mouse_position(); } + undo_redo->create_action(TTR("Paste VisualShader Node(s)")); + _dup_paste_nodes(type, copy_type, copy_nodes_buffer, copy_nodes_excluded_buffer, (graph->get_scroll_ofs() / scale + mpos / scale - selection_center), false); _dup_update_excluded(type, copy_nodes_excluded_buffer); // to prevent selection of previous copies at new paste } -void VisualShaderEditor::_delete_nodes() { - VisualShader::Type type = get_current_shader_type(); - List<int> to_erase; - - for (int i = 0; i < graph->get_child_count(); i++) { - GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); - if (gn) { - if (gn->is_selected() && gn->is_close_button_visible()) { - to_erase.push_back(gn->get_name().operator String().to_int()); - } - } - } - - if (to_erase.empty()) { - return; - } - - undo_redo->create_action(TTR("Delete Nodes")); - - List<VisualShader::Connection> conns; - visual_shader->get_node_connections(type, &conns); - - for (List<int>::Element *F = to_erase.front(); F; F = F->next()) { - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().from_node == F->get() || E->get().to_node == F->get()) { - undo_redo->add_do_method(graph_plugin.ptr(), "disconnect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - } - } - } - - Set<String> uniform_names; - - for (List<int>::Element *F = to_erase.front(); F; F = F->next()) { - Ref<VisualShaderNode> node = visual_shader->get_node(type, F->get()); - - undo_redo->add_do_method(visual_shader.ptr(), "remove_node", type, F->get()); - undo_redo->add_undo_method(visual_shader.ptr(), "add_node", type, node, visual_shader->get_node_position(type, F->get()), F->get()); - undo_redo->add_undo_method(graph_plugin.ptr(), "add_node", type, F->get()); - - undo_redo->add_do_method(this, "_clear_buffer"); - undo_redo->add_undo_method(this, "_clear_buffer"); - - // restore size, inputs and outputs if node is group - VisualShaderNodeGroupBase *group = Object::cast_to<VisualShaderNodeGroupBase>(node.ptr()); - if (group) { - undo_redo->add_undo_method(group, "set_size", group->get_size()); - undo_redo->add_undo_method(group, "set_inputs", group->get_inputs()); - undo_redo->add_undo_method(group, "set_outputs", group->get_outputs()); - } - - // restore expression text if node is expression - VisualShaderNodeExpression *expression = Object::cast_to<VisualShaderNodeExpression>(node.ptr()); - if (expression) { - undo_redo->add_undo_method(expression, "set_expression", expression->get_expression()); - } - - VisualShaderNodeUniform *uniform = Object::cast_to<VisualShaderNodeUniform>(node.ptr()); - if (uniform) { - uniform_names.insert(uniform->get_uniform_name()); - } - } - - List<VisualShader::Connection> used_conns; - for (List<int>::Element *F = to_erase.front(); F; F = F->next()) { - for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().from_node == F->get() || E->get().to_node == F->get()) { - bool cancel = false; - for (List<VisualShader::Connection>::Element *R = used_conns.front(); R; R = R->next()) { - if (R->get().from_node == E->get().from_node && R->get().from_port == E->get().from_port && R->get().to_node == E->get().to_node && R->get().to_port == E->get().to_port) { - cancel = true; // to avoid ERR_ALREADY_EXISTS warning - break; - } - } - if (!cancel) { - undo_redo->add_undo_method(visual_shader.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - undo_redo->add_undo_method(graph_plugin.ptr(), "connect_nodes", type, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port); - used_conns.push_back(E->get()); - } - } - } - } - - // delete nodes from the graph - for (List<int>::Element *F = to_erase.front(); F; F = F->next()) { - undo_redo->add_do_method(graph_plugin.ptr(), "remove_node", type, F->get()); - } - - // update uniform refs if any uniform has been deleted - if (uniform_names.size() > 0) { - undo_redo->add_do_method(this, "_update_uniforms", true); - undo_redo->add_undo_method(this, "_update_uniforms", true); - - _update_uniform_refs(uniform_names); - } - - undo_redo->commit_action(); -} - void VisualShaderEditor::_mode_selected(int p_id) { visual_shader->set_shader_type(particles_mode ? VisualShader::Type(p_id + 3) : VisualShader::Type(p_id)); _update_options_menu(); @@ -2630,7 +2670,7 @@ void VisualShaderEditor::_node_menu_id_pressed(int p_idx) { _paste_nodes(true, menu_point); break; case NodeMenuOptions::DELETE: - _delete_nodes(); + _delete_nodes_request(); break; case NodeMenuOptions::DUPLICATE: _duplicate_nodes(); @@ -2705,6 +2745,11 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da _add_custom_node(arr[i]); j++; } + } else if (type == "CurveTexture") { + saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE); + saved_node_pos_dirty = true; + _add_curve_node(arr[i]); + j++; } else if (ClassDB::get_parent_class(type) == "Texture2D") { saved_node_pos = p_point + Vector2(0, j * 210 * EDSCALE); saved_node_pos_dirty = true; @@ -2842,8 +2887,8 @@ VisualShaderEditor::VisualShaderEditor() { graph->connect("scroll_offset_changed", callable_mp(this, &VisualShaderEditor::_scroll_changed)); graph->connect("duplicate_nodes_request", callable_mp(this, &VisualShaderEditor::_duplicate_nodes)); graph->connect("copy_nodes_request", callable_mp(this, &VisualShaderEditor::_copy_nodes)); - graph->connect("paste_nodes_request", callable_mp(this, &VisualShaderEditor::_paste_nodes)); - graph->connect("delete_nodes_request", callable_mp(this, &VisualShaderEditor::_delete_nodes)); + graph->connect("paste_nodes_request", callable_mp(this, &VisualShaderEditor::_paste_nodes), varray(false, Point2())); + graph->connect("delete_nodes_request", callable_mp(this, &VisualShaderEditor::_delete_nodes_request)); graph->connect("gui_input", callable_mp(this, &VisualShaderEditor::_graph_gui_input)); graph->connect("connection_to_empty", callable_mp(this, &VisualShaderEditor::_connection_to_empty)); graph->connect("connection_from_empty", callable_mp(this, &VisualShaderEditor::_connection_from_empty)); @@ -3330,6 +3375,8 @@ VisualShaderEditor::VisualShaderEditor() { // TEXTURES cubemap_node_option_idx = add_options.size(); add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1)); + curve_node_option_idx = add_options.size(); + add_options.push_back(AddOption("CurveTexture", "Textures", "Functions", "VisualShaderNodeCurveTexture", TTR("Perform the curve texture lookup."), -1, -1)); texture2d_node_option_idx = add_options.size(); add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the 2D texture lookup."), -1, -1)); texture2d_array_node_option_idx = add_options.size(); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index d43af82238..73bebcd192 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -33,6 +33,7 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" +#include "editor/plugins/curve_editor_plugin.h" #include "editor/property_editor.h" #include "scene/gui/button.h" #include "scene/gui/graph_edit.h" @@ -73,6 +74,8 @@ private: VBoxContainer *preview_box; LineEdit *uniform_name; OptionButton *const_op; + CodeEdit *expression_edit; + CurveEditor *curve_editor; }; Ref<VisualShader> visual_shader; @@ -91,6 +94,8 @@ public: void register_uniform_name(int p_id, LineEdit *p_uniform_name); void register_default_input_button(int p_node_id, int p_port_id, Button *p_button); void register_constant_option_btn(int p_node_id, OptionButton *p_button); + void register_expression_edit(int p_node_id, CodeEdit *p_expression_edit); + void register_curve_editor(int p_node_id, CurveEditor *p_curve_editor); void clear_links(); void set_shader_type(VisualShader::Type p_type); bool is_preview_visible(int p_id) const; @@ -109,7 +114,9 @@ public: void set_input_port_default_value(VisualShader::Type p_type, int p_node_id, int p_port_id, Variant p_value); void update_uniform_refs(); void set_uniform_name(VisualShader::Type p_type, int p_node_id, const String &p_name); + void update_curve(int p_node_id); void update_constant(VisualShader::Type p_type, int p_node_id); + void set_expression(VisualShader::Type p_type, int p_node_id, const String &p_expression); int get_constant_index(float p_constant) const; void update_node_size(int p_node_id); VisualShader::Type get_shader_type() const; @@ -251,6 +258,7 @@ class VisualShaderEditor : public VBoxContainer { int texture2d_array_node_option_idx; int texture3d_node_option_idx; int custom_node_option_idx; + int curve_node_option_idx; List<String> keyword_list; List<VisualShaderNodeUniformRef> uniform_refs; @@ -262,6 +270,8 @@ class VisualShaderEditor : public VBoxContainer { void _add_texture2d_node(const String &p_path); void _add_texture2d_array_node(const String &p_path); void _add_texture3d_node(const String &p_path); + void _add_curve_node(const String &p_path); + VisualShaderNode *_add_node(int p_idx, int p_op_idx = -1); void _update_options_menu(); void _set_mode(int p_which); @@ -290,8 +300,9 @@ class VisualShaderEditor : public VBoxContainer { void _scroll_changed(const Vector2 &p_scroll); void _node_selected(Object *p_node); - void _delete_request(int); - void _delete_nodes(); + void _delete_nodes(int p_type, const List<int> &p_nodes); + void _delete_node_request(int p_type, int p_node); + void _delete_nodes_request(); void _removed_from_graph(); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 1f553ba0de..71522bb253 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -51,10 +51,6 @@ void ProjectExportDialog::_theme_changed() { duplicate_preset->set_icon(presets->get_theme_icon("Duplicate", "EditorIcons")); delete_preset->set_icon(presets->get_theme_icon("Remove", "EditorIcons")); - Control *panel = custom_feature_display->get_parent_control(); - if (panel) { - panel->add_theme_style_override("panel", patches->get_theme_stylebox("bg", "Tree")); - } } void ProjectExportDialog::_notification(int p_what) { @@ -68,7 +64,6 @@ void ProjectExportDialog::_notification(int p_what) { duplicate_preset->set_icon(presets->get_theme_icon("Duplicate", "EditorIcons")); delete_preset->set_icon(presets->get_theme_icon("Remove", "EditorIcons")); connect("confirmed", callable_mp(this, &ProjectExportDialog::_export_pck_zip)); - custom_feature_display->get_parent_control()->add_theme_style_override("panel", patches->get_theme_stylebox("bg", "Tree")); } break; } } @@ -205,7 +200,6 @@ void ProjectExportDialog::_edit_preset(int p_index) { duplicate_preset->set_disabled(true); delete_preset->set_disabled(true); sections->hide(); - patches->clear(); export_error->hide(); export_templates_error->hide(); return; @@ -241,34 +235,6 @@ void ProjectExportDialog::_edit_preset(int p_index) { include_filters->set_text(current->get_include_filter()); exclude_filters->set_text(current->get_exclude_filter()); - patches->clear(); - TreeItem *patch_root = patches->create_item(); - Vector<String> patchlist = current->get_patches(); - for (int i = 0; i < patchlist.size(); i++) { - TreeItem *patch = patches->create_item(patch_root); - patch->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - String file = patchlist[i].get_file(); - patch->set_editable(0, true); - patch->set_text(0, file.get_file().replace("*", "")); - if (file.ends_with("*")) { - patch->set_checked(0, true); - } - patch->set_tooltip(0, patchlist[i]); - patch->set_metadata(0, i); - patch->add_button(0, presets->get_theme_icon("Remove", "EditorIcons"), 0); - patch->add_button(0, presets->get_theme_icon("folder", "FileDialog"), 1); - } - - TreeItem *patch_add = patches->create_item(patch_root); - patch_add->set_metadata(0, patchlist.size()); - if (patchlist.size() == 0) { - patch_add->set_text(0, TTR("Add initial export...")); - } else { - patch_add->set_text(0, TTR("Add previous patches...")); - } - - patch_add->add_button(0, presets->get_theme_icon("folder", "FileDialog"), 1); - _fill_resource_tree(); bool needs_templates; @@ -401,74 +367,6 @@ void ProjectExportDialog::_tab_changed(int) { _update_feature_list(); } -void ProjectExportDialog::_patch_button_pressed(Object *p_item, int p_column, int p_id) { - TreeItem *ti = (TreeItem *)p_item; - - patch_index = ti->get_metadata(0); - - Ref<EditorExportPreset> current = get_current_preset(); - ERR_FAIL_COND(current.is_null()); - - if (p_id == 0) { - Vector<String> patches = current->get_patches(); - ERR_FAIL_INDEX(patch_index, patches.size()); - patch_erase->set_text(vformat(TTR("Delete patch '%s' from list?"), patches[patch_index].get_file())); - patch_erase->popup_centered(); - } else { - patch_dialog->popup_file_dialog(); - } -} - -void ProjectExportDialog::_patch_edited() { - TreeItem *item = patches->get_edited(); - if (!item) { - return; - } - int index = item->get_metadata(0); - - Ref<EditorExportPreset> current = get_current_preset(); - ERR_FAIL_COND(current.is_null()); - - Vector<String> patches = current->get_patches(); - - ERR_FAIL_INDEX(index, patches.size()); - - String patch = patches[index].replace("*", ""); - - if (item->is_checked(0)) { - patch += "*"; - } - - current->set_patch(index, patch); -} - -void ProjectExportDialog::_patch_selected(const String &p_path) { - Ref<EditorExportPreset> current = get_current_preset(); - ERR_FAIL_COND(current.is_null()); - - Vector<String> patches = current->get_patches(); - - if (patch_index >= patches.size()) { - current->add_patch(ProjectSettings::get_singleton()->get_resource_path().path_to(p_path) + "*"); - } else { - String enabled = patches[patch_index].ends_with("*") ? String("*") : String(); - current->set_patch(patch_index, ProjectSettings::get_singleton()->get_resource_path().path_to(p_path) + enabled); - } - - _update_current_preset(); -} - -void ProjectExportDialog::_patch_deleted() { - Ref<EditorExportPreset> current = get_current_preset(); - ERR_FAIL_COND(current.is_null()); - - Vector<String> patches = current->get_patches(); - if (patch_index < patches.size()) { - current->remove_patch(patch_index); - _update_current_preset(); - } -} - void ProjectExportDialog::_update_parameters(const String &p_edited_property) { _update_current_preset(); } @@ -663,10 +561,6 @@ void ProjectExportDialog::_duplicate_preset() { preset->set_export_filter(current->get_export_filter()); preset->set_include_filter(current->get_include_filter()); preset->set_exclude_filter(current->get_exclude_filter()); - Vector<String> list = current->get_patches(); - for (int i = 0; i < list.size(); i++) { - preset->add_patch(list[i]); - } preset->set_custom_features(current->get_custom_features()); for (const List<PropertyInfo>::Element *E = current->get_properties().front(); E; E = E->next()) { @@ -718,21 +612,6 @@ Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_ return d; } - } else if (p_from == patches) { - TreeItem *item = patches->get_item_at_position(p_point); - - if (item && item->get_cell_mode(0) == TreeItem::CELL_MODE_CHECK) { - int metadata = item->get_metadata(0); - Dictionary d; - d["type"] = "export_patch"; - d["patch"] = metadata; - - Label *label = memnew(Label); - label->set_text(item->get_text(0)); - patches->set_drag_preview(label); - - return d; - } } return Variant(); @@ -748,19 +627,6 @@ bool ProjectExportDialog::can_drop_data_fw(const Point2 &p_point, const Variant if (presets->get_item_at_position(p_point, true) < 0 && !presets->is_pos_at_end_of_items(p_point)) { return false; } - } else if (p_from == patches) { - Dictionary d = p_data; - if (!d.has("type") || String(d["type"]) != "export_patch") { - return false; - } - - patches->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM); - - TreeItem *item = patches->get_item_at_position(p_point); - - if (!item) { - return false; - } } return true; @@ -797,33 +663,6 @@ void ProjectExportDialog::drop_data_fw(const Point2 &p_point, const Variant &p_d } else { _edit_preset(presets->get_item_count() - 1); } - } else if (p_from == patches) { - Dictionary d = p_data; - if (!d.has("type") || String(d["type"]) != "export_patch") { - return; - } - - int from_pos = d["patch"]; - - TreeItem *item = patches->get_item_at_position(p_point); - if (!item) { - return; - } - - int to_pos = item->get_cell_mode(0) == TreeItem::CELL_MODE_CHECK ? int(item->get_metadata(0)) : -1; - - if (to_pos == from_pos) { - return; - } else if (to_pos > from_pos) { - to_pos--; - } - - Ref<EditorExportPreset> preset = get_current_preset(); - String patch = preset->get_patch(from_pos); - preset->remove_patch(from_pos); - preset->add_patch(patch, to_pos); - - _update_current_preset(); } } @@ -1222,48 +1061,6 @@ ProjectExportDialog::ProjectExportDialog() { script_mode->add_item(TTR("Compiled"), (int)EditorExportPreset::MODE_SCRIPT_COMPILED); script_mode->connect("item_selected", callable_mp(this, &ProjectExportDialog::_script_export_mode_changed)); - // Patch packages. - - VBoxContainer *patch_vb = memnew(VBoxContainer); - sections->add_child(patch_vb); - patch_vb->set_name(TTR("Patches")); - - // FIXME: Patching support doesn't seem properly implemented yet, so we hide it. - // The rest of the code is still kept for now, in the hope that it will be made - // functional and reactivated. - patch_vb->hide(); - - patches = memnew(Tree); - patch_vb->add_child(patches); - patches->set_v_size_flags(Control::SIZE_EXPAND_FILL); - patches->set_hide_root(true); - patches->connect("button_pressed", callable_mp(this, &ProjectExportDialog::_patch_button_pressed)); - patches->connect("item_edited", callable_mp(this, &ProjectExportDialog::_patch_edited)); -#ifndef _MSC_VER -#warning must reimplement drag forward -#endif - //patches->set_drag_forwarding(this); - patches->set_edit_checkbox_cell_only_when_checkbox_is_pressed(true); - - HBoxContainer *patches_hb = memnew(HBoxContainer); - patch_vb->add_child(patches_hb); - patches_hb->add_spacer(); - patch_export = memnew(Button); - patch_export->set_text(TTR("Make Patch")); - patches_hb->add_child(patch_export); - patches_hb->add_spacer(); - - patch_dialog = memnew(EditorFileDialog); - patch_dialog->add_filter("*.pck ; " + TTR("Pack File")); - patch_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - patch_dialog->connect("file_selected", callable_mp(this, &ProjectExportDialog::_patch_selected)); - add_child(patch_dialog); - - patch_erase = memnew(ConfirmationDialog); - patch_erase->get_ok()->set_text(TTR("Delete")); - patch_erase->connect("confirmed", callable_mp(this, &ProjectExportDialog::_patch_deleted)); - add_child(patch_erase); - // Feature tags. VBoxContainer *feature_vb = memnew(VBoxContainer); diff --git a/editor/project_export.h b/editor/project_export.h index 75402dc334..026daac2ad 100644 --- a/editor/project_export.h +++ b/editor/project_export.h @@ -87,12 +87,6 @@ private: StringName editor_icons; - Tree *patches; - Button *patch_export; - int patch_index; - EditorFileDialog *patch_dialog; - ConfirmationDialog *patch_erase; - Button *export_button; Button *export_all_button; AcceptDialog *export_all_dialog; @@ -109,9 +103,6 @@ private: String default_filename; - void _patch_selected(const String &p_path); - void _patch_deleted(); - void _runnable_pressed(); void _update_parameters(const String &p_edited_property); void _name_changed(const String &p_string); @@ -133,9 +124,6 @@ private: bool _fill_tree(EditorFileSystemDirectory *p_dir, TreeItem *p_item, Ref<EditorExportPreset> ¤t, bool p_only_scenes); void _tree_changed(); - void _patch_button_pressed(Object *p_item, int p_column, int p_id); - void _patch_edited(); - Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index cb56358ae6..7f1b5347cf 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -1697,13 +1697,18 @@ void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns, int int cell_width = 95; int cell_height = 25; int cell_margin = 5; - int hor_spacing = 5; // Spacing between labels and their values - int rows = ((p_amount - 1) / p_columns) + 1; set_size(Size2(cell_margin + p_label_w + (cell_width + cell_margin + p_label_w) * p_columns, cell_margin + (cell_height + cell_margin) * rows) * EDSCALE); for (int i = 0; i < MAX_VALUE_EDITORS; i++) { + value_label[i]->get_parent()->remove_child(value_label[i]); + value_editor[i]->get_parent()->remove_child(value_editor[i]); + + int box_id = i / p_columns; + value_hboxes[box_id]->add_child(value_label[i]); + value_hboxes[box_id]->add_child(value_editor[i]); + if (i < MAX_VALUE_EDITORS / 4) { if (i <= p_amount / 4) { value_hboxes[i]->show(); @@ -1712,16 +1717,10 @@ void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns, int } } - int c = i % p_columns; - int r = i / p_columns; - if (i < p_amount) { value_editor[i]->show(); value_label[i]->show(); value_label[i]->set_text(i < p_strings.size() ? p_strings[i] : String("")); - value_editor[i]->set_position(Point2(cell_margin + p_label_w + hor_spacing + (cell_width + cell_margin + p_label_w + hor_spacing) * c, cell_margin + (cell_height + cell_margin) * r) * EDSCALE); - value_editor[i]->set_size(Size2(cell_width, cell_height)); - value_label[i]->set_position(Point2(cell_margin + (cell_width + cell_margin + p_label_w + hor_spacing) * c, cell_margin + (cell_height + cell_margin) * r) * EDSCALE); value_editor[i]->set_editable(!read_only); } else { value_editor[i]->hide(); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index fa2270dcd6..46e9cd4676 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1762,6 +1762,8 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) { void SceneTreeDock::_script_creation_closed() { script_create_dialog->disconnect("script_created", callable_mp(this, &SceneTreeDock::_script_created)); + script_create_dialog->disconnect("confirmed", callable_mp(this, &SceneTreeDock::_script_creation_closed)); + script_create_dialog->disconnect("cancelled", callable_mp(this, &SceneTreeDock::_script_creation_closed)); } void SceneTreeDock::_toggle_editable_children_from_selection() { @@ -2107,8 +2109,12 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop } if (E->get().name == "__meta__") { - if (Object::cast_to<CanvasItem>(newnode)) { - Dictionary metadata = n->get(E->get().name); + Dictionary metadata = n->get(E->get().name); + if (metadata.has("_editor_description_")) { + newnode->set_meta("_editor_description_", metadata["_editor_description_"]); + } + + if (Object::cast_to<CanvasItem>(newnode) || Object::cast_to<Node3D>(newnode)) { if (metadata.has("_edit_group_") && metadata["_edit_group_"]) { newnode->set_meta("_edit_group_", true); } @@ -2647,7 +2653,8 @@ void SceneTreeDock::attach_script_to_selected(bool p_extend) { } script_create_dialog->connect("script_created", callable_mp(this, &SceneTreeDock::_script_created)); - script_create_dialog->connect("popup_hide", callable_mp(this, &SceneTreeDock::_script_creation_closed), varray(), CONNECT_ONESHOT); + script_create_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_script_creation_closed)); + script_create_dialog->connect("cancelled", callable_mp(this, &SceneTreeDock::_script_creation_closed)); script_create_dialog->set_inheritance_base_type("Node"); script_create_dialog->config(inherits, path); script_create_dialog->popup_centered(); diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index aa88b0ef39..915aec6d9a 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -284,7 +284,13 @@ static Variant create_var(RS::GlobalVariableType p_type) { return Vector3i(); } case RS::GLOBAL_VAR_TYPE_UVEC4: { - return Rect2i(); + Vector<int> v4; + v4.resize(4); + v4.write[0] = 0; + v4.write[1] = 0; + v4.write[2] = 0; + v4.write[3] = 0; + return v4; } case RS::GLOBAL_VAR_TYPE_FLOAT: { return 0.0; @@ -324,7 +330,7 @@ static Variant create_var(RS::GlobalVariableType p_type) { } case RS::GLOBAL_VAR_TYPE_MAT4: { Vector<real_t> xform; - xform.resize(4); + xform.resize(16); xform.write[0] = 1; xform.write[1] = 0; xform.write[2] = 0; @@ -437,6 +443,9 @@ void ShaderGlobalsEditor::_notification(int p_what) { inspector->edit(interface); } } + if (p_what == NOTIFICATION_PREDELETE) { + inspector->edit(nullptr); + } } ShaderGlobalsEditor::ShaderGlobalsEditor() { @@ -474,6 +483,5 @@ ShaderGlobalsEditor::ShaderGlobalsEditor() { } ShaderGlobalsEditor::~ShaderGlobalsEditor() { - inspector->edit(nullptr); memdelete(interface); } |