2014-02-10 01:10:30 +00:00
/*************************************************************************/
/* editor_node.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 12:16:55 +00:00
/* https://godotengine.org */
2014-02-10 01:10:30 +00:00
/*************************************************************************/
2022-01-03 20:27:34 +00:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 01:10:30 +00:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-04 23:50:27 +00:00
2014-02-10 01:10:30 +00:00
# include "editor_node.h"
2017-01-16 07:04:19 +00:00
2020-11-07 22:33:38 +00:00
# include "core/config/project_settings.h"
2020-04-28 13:19:37 +00:00
# include "core/input/input.h"
2017-08-26 15:46:49 +00:00
# include "core/io/config_file.h"
2021-06-11 12:51:48 +00:00
# include "core/io/file_access.h"
2019-10-23 18:11:04 +00:00
# include "core/io/image_loader.h"
2014-02-10 01:10:30 +00:00
# include "core/io/resource_loader.h"
2017-03-05 15:44:50 +00:00
# include "core/io/resource_saver.h"
2017-08-26 15:46:49 +00:00
# include "core/io/stream_peer_ssl.h"
2020-11-07 22:33:38 +00:00
# include "core/object/class_db.h"
# include "core/object/message_queue.h"
2017-08-26 15:46:49 +00:00
# include "core/os/keyboard.h"
# include "core/os/os.h"
2021-05-24 11:54:05 +00:00
# include "core/os/time.h"
2020-11-07 22:33:38 +00:00
# include "core/string/print_string.h"
# include "core/string/translation.h"
2017-08-26 15:46:49 +00:00
# include "core/version.h"
2019-04-07 18:46:52 +00:00
# include "main/main.h"
2021-09-21 01:24:31 +00:00
# include "scene/3d/importer_mesh_instance_3d.h"
2019-12-24 07:17:23 +00:00
# include "scene/gui/center_container.h"
# include "scene/gui/control.h"
# include "scene/gui/dialogs.h"
# include "scene/gui/file_dialog.h"
2019-12-24 00:20:54 +00:00
# include "scene/gui/link_button.h"
2019-12-24 07:17:23 +00:00
# include "scene/gui/menu_button.h"
# include "scene/gui/panel.h"
# include "scene/gui/panel_container.h"
# include "scene/gui/split_container.h"
2021-10-17 16:55:44 +00:00
# include "scene/gui/tab_bar.h"
2019-12-24 07:17:23 +00:00
# include "scene/gui/tab_container.h"
2020-12-14 20:10:09 +00:00
# include "scene/gui/texture_progress_bar.h"
2020-12-10 14:44:05 +00:00
# include "scene/main/window.h"
2017-03-05 15:44:50 +00:00
# include "scene/resources/packed_scene.h"
2020-12-10 14:44:05 +00:00
# include "servers/display_server.h"
2020-03-27 18:21:27 +00:00
# include "servers/navigation_server_2d.h"
# include "servers/navigation_server_3d.h"
# include "servers/physics_server_2d.h"
2020-04-18 23:30:57 +00:00
# include "servers/rendering/rendering_device.h"
2017-08-26 15:46:49 +00:00
2022-02-14 13:00:03 +00:00
# include "editor/animation_track_editor.h"
2019-12-24 07:17:23 +00:00
# include "editor/audio_stream_preview.h"
2021-06-04 18:39:38 +00:00
# include "editor/debugger/debug_adapter/debug_adapter_server.h"
2020-03-08 17:58:31 +00:00
# include "editor/debugger/editor_debugger_node.h"
2019-12-24 07:17:23 +00:00
# include "editor/dependency_editor.h"
# include "editor/editor_about.h"
2017-08-26 15:46:49 +00:00
# include "editor/editor_audio_buses.h"
2021-05-29 13:28:16 +00:00
# include "editor/editor_command_palette.h"
2022-02-12 01:46:22 +00:00
# include "editor/editor_data.h"
2019-12-24 07:17:23 +00:00
# include "editor/editor_export.h"
# include "editor/editor_feature_profile.h"
2022-02-12 01:46:22 +00:00
# include "editor/editor_file_dialog.h"
2017-08-26 15:46:49 +00:00
# include "editor/editor_file_system.h"
2022-02-12 01:46:22 +00:00
# include "editor/editor_folding.h"
2017-08-26 15:46:49 +00:00
# include "editor/editor_help.h"
2019-12-24 07:17:23 +00:00
# include "editor/editor_inspector.h"
# include "editor/editor_layouts_dialog.h"
# include "editor/editor_log.h"
2021-05-25 00:25:11 +00:00
# include "editor/editor_paths.h"
2019-12-24 07:17:23 +00:00
# include "editor/editor_plugin.h"
2018-05-15 20:12:35 +00:00
# include "editor/editor_properties.h"
2022-03-03 10:25:11 +00:00
# include "editor/editor_property_name_processor.h"
2021-05-17 12:25:38 +00:00
# include "editor/editor_resource_picker.h"
2019-12-24 07:17:23 +00:00
# include "editor/editor_resource_preview.h"
2022-02-12 01:46:22 +00:00
# include "editor/editor_run.h"
2019-12-24 07:17:23 +00:00
# include "editor/editor_run_native.h"
# include "editor/editor_run_script.h"
# include "editor/editor_scale.h"
2017-08-26 15:46:49 +00:00
# include "editor/editor_settings.h"
2022-01-31 23:19:01 +00:00
# include "editor/editor_settings_dialog.h"
2019-10-20 15:43:14 +00:00
# include "editor/editor_spin_slider.h"
2017-08-26 15:46:49 +00:00
# include "editor/editor_themes.h"
2021-09-22 15:36:40 +00:00
# include "editor/editor_toaster.h"
2020-06-23 11:48:59 +00:00
# include "editor/editor_translation_parser.h"
2019-12-24 07:17:23 +00:00
# include "editor/export_template_manager.h"
# include "editor/filesystem_dock.h"
2022-02-14 13:00:03 +00:00
# include "editor/import/dynamic_font_import_settings.h"
2017-08-26 15:46:49 +00:00
# include "editor/import/editor_import_collada.h"
2018-01-06 19:36:49 +00:00
# include "editor/import/resource_importer_bitmask.h"
2020-12-27 13:30:33 +00:00
# include "editor/import/resource_importer_bmfont.h"
2017-08-26 15:46:49 +00:00
# include "editor/import/resource_importer_csv_translation.h"
2022-02-14 13:00:03 +00:00
# include "editor/import/resource_importer_dynamic_font.h"
2018-07-29 19:45:23 +00:00
# include "editor/import/resource_importer_image.h"
2020-12-27 13:30:33 +00:00
# include "editor/import/resource_importer_imagefont.h"
2018-08-06 17:56:06 +00:00
# include "editor/import/resource_importer_layered_texture.h"
2017-08-26 15:46:49 +00:00
# include "editor/import/resource_importer_obj.h"
# include "editor/import/resource_importer_scene.h"
2020-04-20 02:19:21 +00:00
# include "editor/import/resource_importer_shader_file.h"
2017-08-26 15:46:49 +00:00
# include "editor/import/resource_importer_texture.h"
2019-04-19 18:54:33 +00:00
# include "editor/import/resource_importer_texture_atlas.h"
2017-08-26 15:46:49 +00:00
# include "editor/import/resource_importer_wav.h"
2021-03-19 12:57:52 +00:00
# include "editor/import/scene_import_settings.h"
2019-12-24 07:17:23 +00:00
# include "editor/import_dock.h"
2019-11-10 08:37:51 +00:00
# include "editor/multi_node_edit.h"
2019-12-24 07:17:23 +00:00
# include "editor/node_dock.h"
# include "editor/plugin_config_dialog.h"
2018-06-22 19:52:13 +00:00
# include "editor/plugins/animation_blend_space_1d_editor.h"
# include "editor/plugins/animation_blend_space_2d_editor.h"
2018-06-19 01:10:48 +00:00
# include "editor/plugins/animation_blend_tree_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/animation_player_editor_plugin.h"
2018-06-25 19:21:57 +00:00
# include "editor/plugins/animation_state_machine_editor.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/animation_tree_editor_plugin.h"
# include "editor/plugins/asset_library_editor_plugin.h"
2018-07-16 07:30:27 +00:00
# include "editor/plugins/audio_stream_editor_plugin.h"
2021-09-12 06:57:09 +00:00
# include "editor/plugins/audio_stream_randomizer_editor_plugin.h"
2022-03-31 01:25:14 +00:00
# include "editor/plugins/bit_map_editor_plugin.h"
2020-03-27 07:44:44 +00:00
# include "editor/plugins/camera_3d_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/canvas_item_editor_plugin.h"
# include "editor/plugins/collision_polygon_2d_editor_plugin.h"
# include "editor/plugins/collision_shape_2d_editor_plugin.h"
2021-11-08 20:53:41 +00:00
# include "editor/plugins/control_editor_plugin.h"
2019-03-19 16:28:57 +00:00
# include "editor/plugins/cpu_particles_2d_editor_plugin.h"
2020-03-27 07:44:44 +00:00
# include "editor/plugins/cpu_particles_3d_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/curve_editor_plugin.h"
2020-02-07 01:52:05 +00:00
# include "editor/plugins/debugger_editor_plugin.h"
2020-05-18 14:55:49 +00:00
# include "editor/plugins/editor_debugger_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/editor_preview_plugins.h"
2020-09-03 11:22:16 +00:00
# include "editor/plugins/font_editor_plugin.h"
2022-03-10 07:48:25 +00:00
# include "editor/plugins/gdextension_export_plugin.h"
2020-03-27 07:44:44 +00:00
# include "editor/plugins/gpu_particles_2d_editor_plugin.h"
# include "editor/plugins/gpu_particles_3d_editor_plugin.h"
2020-10-08 00:29:49 +00:00
# include "editor/plugins/gpu_particles_collision_sdf_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/gradient_editor_plugin.h"
2022-02-22 04:35:20 +00:00
# include "editor/plugins/gradient_texture_2d_editor_plugin.h"
2021-06-27 14:15:56 +00:00
# include "editor/plugins/input_event_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/light_occluder_2d_editor_plugin.h"
2021-06-04 22:47:26 +00:00
# include "editor/plugins/lightmap_gi_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/line_2d_editor_plugin.h"
# include "editor/plugins/material_editor_plugin.h"
# include "editor/plugins/mesh_editor_plugin.h"
2020-03-27 07:44:44 +00:00
# include "editor/plugins/mesh_instance_3d_editor_plugin.h"
2018-08-21 22:06:52 +00:00
# include "editor/plugins/mesh_library_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/multimesh_editor_plugin.h"
# include "editor/plugins/navigation_polygon_editor_plugin.h"
2020-03-27 07:44:44 +00:00
# include "editor/plugins/node_3d_editor_plugin.h"
2021-04-20 16:40:24 +00:00
# include "editor/plugins/occluder_instance_3d_editor_plugin.h"
2020-09-03 11:22:16 +00:00
# include "editor/plugins/ot_features_plugin.h"
2020-06-23 11:48:59 +00:00
# include "editor/plugins/packed_scene_translation_parser_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/path_2d_editor_plugin.h"
2020-03-27 07:44:44 +00:00
# include "editor/plugins/path_3d_editor_plugin.h"
# include "editor/plugins/physical_bone_3d_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/polygon_2d_editor_plugin.h"
2022-02-04 15:28:18 +00:00
# include "editor/plugins/polygon_3d_editor_plugin.h"
2022-03-18 19:22:41 +00:00
# include "editor/plugins/ray_cast_2d_editor_plugin.h"
2021-12-01 07:24:46 +00:00
# include "editor/plugins/replication_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/resource_preloader_editor_plugin.h"
2018-06-26 22:05:11 +00:00
# include "editor/plugins/root_motion_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/script_editor_plugin.h"
# include "editor/plugins/script_text_editor.h"
# include "editor/plugins/shader_editor_plugin.h"
2020-04-20 02:19:21 +00:00
# include "editor/plugins/shader_file_editor_plugin.h"
2018-02-21 20:23:27 +00:00
# include "editor/plugins/skeleton_2d_editor_plugin.h"
2020-03-27 07:44:44 +00:00
# include "editor/plugins/skeleton_3d_editor_plugin.h"
# include "editor/plugins/skeleton_ik_3d_editor_plugin.h"
# include "editor/plugins/sprite_2d_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/sprite_frames_editor_plugin.h"
# include "editor/plugins/style_box_editor_plugin.h"
2021-03-21 21:33:17 +00:00
# include "editor/plugins/sub_viewport_preview_editor_plugin.h"
2021-10-26 06:40:11 +00:00
# include "editor/plugins/text_control_editor_plugin.h"
2018-05-28 15:52:28 +00:00
# include "editor/plugins/text_editor.h"
2020-09-09 15:40:51 +00:00
# include "editor/plugins/texture_3d_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/texture_editor_plugin.h"
2020-05-01 12:34:23 +00:00
# include "editor/plugins/texture_layered_editor_plugin.h"
2017-08-26 15:46:49 +00:00
# include "editor/plugins/texture_region_editor_plugin.h"
# include "editor/plugins/theme_editor_plugin.h"
2021-05-07 13:41:39 +00:00
# include "editor/plugins/tiles/tiles_editor_plugin.h"
2019-09-03 14:42:08 +00:00
# include "editor/plugins/version_control_editor_plugin.h"
2018-07-14 21:15:42 +00:00
# include "editor/plugins/visual_shader_editor_plugin.h"
2021-06-04 22:47:26 +00:00
# include "editor/plugins/voxel_gi_editor_plugin.h"
2019-12-24 07:17:23 +00:00
# include "editor/progress_dialog.h"
# include "editor/project_export.h"
# include "editor/project_settings_editor.h"
# include "editor/quick_open.h"
2017-08-26 15:46:49 +00:00
# include "editor/register_exporters.h"
2022-02-12 01:46:22 +00:00
# include "editor/scene_tree_dock.h"
2020-12-10 14:44:05 +00:00
2017-03-05 15:44:50 +00:00
# include <stdio.h>
2019-12-29 15:11:58 +00:00
# include <stdlib.h>
2014-02-18 04:21:06 +00:00
2020-04-01 23:20:12 +00:00
EditorNode * EditorNode : : singleton = nullptr ;
2014-02-10 01:10:30 +00:00
2019-12-24 00:20:54 +00:00
// The metadata key used to store and retrieve the version text to copy to the clipboard.
static const String META_TEXT_TO_COPY = " text_to_copy " ;
2020-05-27 04:49:05 +00:00
void EditorNode : : disambiguate_filenames ( const Vector < String > p_full_paths , Vector < String > & r_filenames ) {
// Keep track of a list of "index sets," i.e. sets of indices
// within disambiguated_scene_names which contain the same name.
2022-05-13 13:04:37 +00:00
Vector < RBSet < int > > index_sets ;
HashMap < String , int > scene_name_to_set_index ;
2020-05-27 04:49:05 +00:00
for ( int i = 0 ; i < r_filenames . size ( ) ; i + + ) {
String scene_name = r_filenames [ i ] ;
if ( ! scene_name_to_set_index . has ( scene_name ) ) {
2022-05-13 13:04:37 +00:00
index_sets . append ( RBSet < int > ( ) ) ;
2020-05-27 04:49:05 +00:00
scene_name_to_set_index . insert ( r_filenames [ i ] , index_sets . size ( ) - 1 ) ;
}
index_sets . write [ scene_name_to_set_index [ scene_name ] ] . insert ( i ) ;
}
2022-03-30 18:12:26 +00:00
// For each index set with a size > 1, we need to disambiguate.
2020-05-27 04:49:05 +00:00
for ( int i = 0 ; i < index_sets . size ( ) ; i + + ) {
2022-05-13 13:04:37 +00:00
RBSet < int > iset = index_sets [ i ] ;
2020-05-27 04:49:05 +00:00
while ( iset . size ( ) > 1 ) {
2022-03-30 18:12:26 +00:00
// Append the parent folder to each scene name.
2022-05-18 23:43:40 +00:00
for ( const int & E : iset ) {
int set_idx = E ;
2020-05-27 04:49:05 +00:00
String scene_name = r_filenames [ set_idx ] ;
String full_path = p_full_paths [ set_idx ] ;
2022-03-30 18:12:26 +00:00
// Get rid of file extensions and res:// prefixes.
2020-05-27 04:49:05 +00:00
if ( scene_name . rfind ( " . " ) > = 0 ) {
scene_name = scene_name . substr ( 0 , scene_name . rfind ( " . " ) ) ;
}
if ( full_path . begins_with ( " res:// " ) ) {
full_path = full_path . substr ( 6 ) ;
}
if ( full_path . rfind ( " . " ) > = 0 ) {
full_path = full_path . substr ( 0 , full_path . rfind ( " . " ) ) ;
}
int scene_name_size = scene_name . size ( ) ;
int full_path_size = full_path . size ( ) ;
int difference = full_path_size - scene_name_size ;
// Find just the parent folder of the current path and append it.
// If the current name is foo.tscn, and the full path is /some/folder/foo.tscn
// then slash_idx is the second '/', so that we select just "folder", and
// append that to yield "folder/foo.tscn".
if ( difference > 0 ) {
String parent = full_path . substr ( 0 , difference ) ;
int slash_idx = parent . rfind ( " / " ) ;
slash_idx = parent . rfind ( " / " , slash_idx - 1 ) ;
parent = slash_idx > = 0 ? parent . substr ( slash_idx + 1 ) : parent ;
r_filenames . write [ set_idx ] = parent + r_filenames [ set_idx ] ;
}
}
2022-03-30 18:12:26 +00:00
// Loop back through scene names and remove non-ambiguous names.
2020-05-27 04:49:05 +00:00
bool can_proceed = false ;
2022-05-13 13:04:37 +00:00
RBSet < int > : : Element * E = iset . front ( ) ;
2020-05-27 04:49:05 +00:00
while ( E ) {
String scene_name = r_filenames [ E - > get ( ) ] ;
bool duplicate_found = false ;
2022-05-18 23:43:40 +00:00
for ( const int & F : iset ) {
if ( E - > get ( ) = = F ) {
2020-05-27 04:49:05 +00:00
continue ;
}
2022-05-18 23:43:40 +00:00
String other_scene_name = r_filenames [ F ] ;
2020-05-27 04:49:05 +00:00
if ( other_scene_name = = scene_name ) {
duplicate_found = true ;
break ;
}
}
2022-05-13 13:04:37 +00:00
RBSet < int > : : Element * to_erase = duplicate_found ? nullptr : E ;
2020-05-27 04:49:05 +00:00
// We need to check that we could actually append anymore names
// if we wanted to for disambiguation. If we can't, then we have
// to abort even with ambiguous names. We clean the full path
// and the scene name first to remove extensions so that this
// comparison actually works.
String path = p_full_paths [ E - > get ( ) ] ;
if ( path . begins_with ( " res:// " ) ) {
path = path . substr ( 6 ) ;
}
if ( path . rfind ( " . " ) > = 0 ) {
path = path . substr ( 0 , path . rfind ( " . " ) ) ;
}
if ( scene_name . rfind ( " . " ) > = 0 ) {
scene_name = scene_name . substr ( 0 , scene_name . rfind ( " . " ) ) ;
}
// We can proceed iff the full path is longer than the scene name,
// meaning that there is at least one more parent folder we can
// tack onto the name.
can_proceed = can_proceed | | ( path . size ( ) - scene_name . size ( ) ) > = 1 ;
E = E - > next ( ) ;
if ( to_erase ) {
iset . erase ( to_erase ) ;
}
}
if ( ! can_proceed ) {
break ;
}
}
}
}
2022-03-02 14:37:10 +00:00
// TODO: This REALLY should be done in a better way than replacing all tabs after almost EVERY action.
2015-06-22 03:03:19 +00:00
void EditorNode : : _update_scene_tabs ( ) {
2017-12-20 18:41:02 +00:00
bool show_rb = EditorSettings : : get_singleton ( ) - > get ( " interface/scene_tabs/show_script_button " ) ;
2015-11-18 07:47:41 +00:00
2020-03-03 13:36:29 +00:00
if ( DisplayServer : : get_singleton ( ) - > has_feature ( DisplayServer : : FEATURE_GLOBAL_MENU ) ) {
DisplayServer : : get_singleton ( ) - > global_menu_clear ( " _dock " ) ;
}
2019-02-06 13:57:06 +00:00
2022-01-23 15:42:52 +00:00
// Get all scene names, which may be ambiguous.
2020-05-27 04:49:05 +00:00
Vector < String > disambiguated_scene_names ;
Vector < String > full_path_names ;
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
disambiguated_scene_names . append ( editor_data . get_scene_title ( i ) ) ;
full_path_names . append ( editor_data . get_scene_path ( i ) ) ;
}
disambiguate_filenames ( full_path_names , disambiguated_scene_names ) ;
2022-03-02 14:37:10 +00:00
// Workaround to ignore the tab_changed signal from the first added tab.
scene_tabs - > disconnect ( " tab_changed " , callable_mp ( this , & EditorNode : : _scene_tab_changed ) ) ;
2015-06-22 03:03:19 +00:00
scene_tabs - > clear_tabs ( ) ;
2021-07-17 21:22:52 +00:00
Ref < Texture2D > script_icon = gui_base - > get_theme_icon ( SNAME ( " Script " ) , SNAME ( " EditorIcons " ) ) ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
2019-03-11 21:54:23 +00:00
Node * type_node = editor_data . get_edited_scene_root ( i ) ;
2019-06-11 18:43:37 +00:00
Ref < Texture2D > icon ;
2019-03-11 21:54:23 +00:00
if ( type_node ) {
icon = EditorNode : : get_singleton ( ) - > get_object_icon ( type_node , " Node " ) ;
2015-07-24 17:18:02 +00:00
}
2015-06-22 03:03:19 +00:00
int current = editor_data . get_edited_scene ( ) ;
2017-03-05 15:44:50 +00:00
bool unsaved = ( i = = current ) ? saved_version ! = editor_data . get_undo_redo ( ) . get_version ( ) : editor_data . get_scene_version ( i ) ! = 0 ;
2020-05-27 04:49:05 +00:00
scene_tabs - > add_tab ( disambiguated_scene_names [ i ] + ( unsaved ? " (*) " : " " ) , icon ) ;
2015-07-24 17:18:02 +00:00
2020-03-03 13:36:29 +00:00
if ( DisplayServer : : get_singleton ( ) - > has_feature ( DisplayServer : : FEATURE_GLOBAL_MENU ) ) {
2020-03-07 16:02:54 +00:00
DisplayServer : : get_singleton ( ) - > global_menu_add_item ( " _dock " , editor_data . get_scene_title ( i ) + ( unsaved ? " (*) " : " " ) , callable_mp ( this , & EditorNode : : _global_menu_scene ) , i ) ;
2020-03-03 13:36:29 +00:00
}
2019-02-06 13:57:06 +00:00
2015-11-18 07:47:41 +00:00
if ( show_rb & & editor_data . get_scene_root_script ( i ) . is_valid ( ) ) {
2022-01-19 16:11:44 +00:00
scene_tabs - > set_tab_button_icon ( i , script_icon ) ;
2015-07-26 13:44:10 +00:00
}
2015-06-22 03:03:19 +00:00
}
2020-03-03 13:36:29 +00:00
if ( DisplayServer : : get_singleton ( ) - > has_feature ( DisplayServer : : FEATURE_GLOBAL_MENU ) ) {
DisplayServer : : get_singleton ( ) - > global_menu_add_separator ( " _dock " ) ;
2020-03-07 16:02:54 +00:00
DisplayServer : : get_singleton ( ) - > global_menu_add_item ( " _dock " , TTR ( " New Window " ) , callable_mp ( this , & EditorNode : : _global_menu_new_window ) ) ;
2020-03-03 13:36:29 +00:00
}
2019-02-06 13:57:06 +00:00
2022-01-23 15:42:52 +00:00
if ( scene_tabs - > get_tab_count ( ) > 0 ) {
scene_tabs - > set_current_tab ( editor_data . get_edited_scene ( ) ) ;
}
2017-11-16 22:57:57 +00:00
if ( scene_tabs - > get_offset_buttons_visible ( ) ) {
2022-01-23 15:42:52 +00:00
// Move the add button to a fixed position.
2017-11-16 22:57:57 +00:00
if ( scene_tab_add - > get_parent ( ) = = scene_tabs ) {
scene_tabs - > remove_child ( scene_tab_add ) ;
2022-01-23 15:42:52 +00:00
scene_tab_add_ph - > add_child ( scene_tab_add ) ;
scene_tab_add - > set_position ( Point2 ( ) ) ;
2017-11-16 22:57:57 +00:00
}
} else {
2022-01-23 15:42:52 +00:00
// Move the add button to be after the last tab.
if ( scene_tab_add - > get_parent ( ) = = scene_tab_add_ph ) {
scene_tab_add_ph - > remove_child ( scene_tab_add ) ;
2017-11-16 22:57:57 +00:00
scene_tabs - > add_child ( scene_tab_add ) ;
}
2022-01-23 15:42:52 +00:00
if ( scene_tabs - > get_tab_count ( ) = = 0 ) {
scene_tab_add - > set_position ( Point2 ( ) ) ;
return ;
2020-05-14 14:41:43 +00:00
}
2022-01-23 15:42:52 +00:00
Rect2 last_tab = scene_tabs - > get_tab_rect ( scene_tabs - > get_tab_count ( ) - 1 ) ;
2022-04-14 21:20:28 +00:00
int hsep = scene_tabs - > get_theme_constant ( SNAME ( " h_separation " ) ) ;
2020-09-03 11:22:16 +00:00
if ( scene_tabs - > is_layout_rtl ( ) ) {
2022-01-23 15:42:52 +00:00
scene_tab_add - > set_position ( Point2 ( last_tab . position . x - scene_tab_add - > get_size ( ) . x - hsep , last_tab . position . y ) ) ;
2020-09-03 11:22:16 +00:00
} else {
2022-01-23 15:42:52 +00:00
scene_tab_add - > set_position ( Point2 ( last_tab . position . x + last_tab . size . width + hsep , last_tab . position . y ) ) ;
2020-09-03 11:22:16 +00:00
}
2017-11-16 22:57:57 +00:00
}
2022-03-02 14:37:10 +00:00
// Reconnect after everything is done.
scene_tabs - > connect ( " tab_changed " , callable_mp ( this , & EditorNode : : _scene_tab_changed ) ) ;
2015-06-22 03:03:19 +00:00
}
2019-09-03 14:42:08 +00:00
void EditorNode : : _version_control_menu_option ( int p_idx ) {
switch ( vcs_actions_menu - > get_item_id ( p_idx ) ) {
2020-09-29 19:01:26 +00:00
case RUN_VCS_METADATA : {
VersionControlEditorPlugin : : get_singleton ( ) - > popup_vcs_metadata_dialog ( ) ;
} break ;
2019-09-03 14:42:08 +00:00
case RUN_VCS_SETTINGS : {
VersionControlEditorPlugin : : get_singleton ( ) - > popup_vcs_set_up_dialog ( gui_base ) ;
} break ;
case RUN_VCS_SHUT_DOWN : {
VersionControlEditorPlugin : : get_singleton ( ) - > shut_down ( ) ;
} break ;
}
}
2014-02-10 01:10:30 +00:00
void EditorNode : : _update_title ( ) {
2021-04-06 17:28:23 +00:00
const String appname = ProjectSettings : : get_singleton ( ) - > get ( " application/config/name " ) ;
2022-04-11 04:50:10 +00:00
String title = ( appname . is_empty ( ) ? TTR ( " Unnamed Project " ) : appname ) + String ( " - " ) + VERSION_NAME ;
2021-09-30 14:30:55 +00:00
const String edited = editor_data . get_edited_scene_root ( ) ? editor_data . get_edited_scene_root ( ) - > get_scene_file_path ( ) : String ( ) ;
2020-12-15 12:04:21 +00:00
if ( ! edited . is_empty ( ) ) {
2021-04-06 17:28:23 +00:00
// Display the edited scene name before the program name so that it can be seen in the OS task bar.
title = vformat ( " %s - %s " , edited . get_file ( ) , title ) ;
2020-05-14 14:41:43 +00:00
}
if ( unsaved_cache ) {
2021-04-06 17:28:23 +00:00
// Display the "modified" mark before anything else so that it can always be seen in the OS task bar.
title = vformat ( " (*) %s " , title ) ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2020-03-03 13:36:29 +00:00
DisplayServer : : get_singleton ( ) - > window_set_title ( title ) ;
2014-02-10 01:10:30 +00:00
}
2022-01-11 13:59:52 +00:00
void EditorNode : : shortcut_input ( const Ref < InputEvent > & p_event ) {
2021-04-05 06:52:21 +00:00
ERR_FAIL_COND ( p_event . is_null ( ) ) ;
2017-05-20 15:38:03 +00:00
Ref < InputEventKey > k = p_event ;
2021-05-29 13:28:16 +00:00
if ( ( k . is_valid ( ) & & k - > is_pressed ( ) & & ! k - > is_echo ( ) ) | | Object : : cast_to < InputEventShortcut > ( * p_event ) ) {
2018-03-13 20:20:59 +00:00
EditorPlugin * old_editor = editor_plugin_screen ;
2016-06-25 04:42:09 +00:00
if ( ED_IS_SHORTCUT ( " editor/next_tab " , p_event ) ) {
int next_tab = editor_data . get_edited_scene ( ) + 1 ;
next_tab % = editor_data . get_edited_scene_count ( ) ;
_scene_tab_changed ( next_tab ) ;
}
if ( ED_IS_SHORTCUT ( " editor/prev_tab " , p_event ) ) {
int next_tab = editor_data . get_edited_scene ( ) - 1 ;
next_tab = next_tab > = 0 ? next_tab : editor_data . get_edited_scene_count ( ) - 1 ;
_scene_tab_changed ( next_tab ) ;
}
2017-01-21 12:07:29 +00:00
if ( ED_IS_SHORTCUT ( " editor/filter_files " , p_event ) ) {
2021-11-17 20:08:55 +00:00
FileSystemDock : : get_singleton ( ) - > focus_on_filter ( ) ;
2017-01-21 12:07:29 +00:00
}
2016-06-15 16:25:17 +00:00
2017-05-16 19:26:32 +00:00
if ( ED_IS_SHORTCUT ( " editor/editor_2d " , p_event ) ) {
_editor_select ( EDITOR_2D ) ;
} else if ( ED_IS_SHORTCUT ( " editor/editor_3d " , p_event ) ) {
_editor_select ( EDITOR_3D ) ;
} else if ( ED_IS_SHORTCUT ( " editor/editor_script " , p_event ) ) {
_editor_select ( EDITOR_SCRIPT ) ;
} else if ( ED_IS_SHORTCUT ( " editor/editor_help " , p_event ) ) {
2021-07-17 21:22:52 +00:00
emit_signal ( SNAME ( " request_help_search " ) , " " ) ;
2019-07-02 13:28:34 +00:00
} else if ( ED_IS_SHORTCUT ( " editor/editor_assetlib " , p_event ) & & StreamPeerSSL : : is_available ( ) ) {
2017-05-16 19:26:32 +00:00
_editor_select ( EDITOR_ASSETLIB ) ;
} else if ( ED_IS_SHORTCUT ( " editor/editor_next " , p_event ) ) {
_editor_select_next ( ) ;
} else if ( ED_IS_SHORTCUT ( " editor/editor_prev " , p_event ) ) {
_editor_select_prev ( ) ;
2021-05-29 13:28:16 +00:00
} else if ( ED_IS_SHORTCUT ( " editor/command_palette " , p_event ) ) {
_open_command_palette ( ) ;
} else {
2014-02-10 01:10:30 +00:00
}
2018-01-19 08:04:55 +00:00
2018-03-13 20:20:59 +00:00
if ( old_editor ! = editor_plugin_screen ) {
2020-03-04 16:36:09 +00:00
get_tree ( ) - > get_root ( ) - > set_input_as_handled ( ) ;
2018-03-13 20:20:59 +00:00
}
2014-02-10 01:10:30 +00:00
}
}
2021-02-13 14:06:56 +00:00
void EditorNode : : _update_from_settings ( ) {
2021-02-17 16:44:49 +00:00
int current_filter = GLOBAL_GET ( " rendering/textures/canvas_textures/default_texture_filter " ) ;
2021-02-13 14:06:56 +00:00
if ( current_filter ! = scene_root - > get_default_canvas_item_texture_filter ( ) ) {
Viewport : : DefaultCanvasItemTextureFilter tf = ( Viewport : : DefaultCanvasItemTextureFilter ) current_filter ;
scene_root - > set_default_canvas_item_texture_filter ( tf ) ;
}
2021-02-17 16:44:49 +00:00
int current_repeat = GLOBAL_GET ( " rendering/textures/canvas_textures/default_texture_repeat " ) ;
2021-02-13 14:06:56 +00:00
if ( current_repeat ! = scene_root - > get_default_canvas_item_texture_repeat ( ) ) {
Viewport : : DefaultCanvasItemTextureRepeat tr = ( Viewport : : DefaultCanvasItemTextureRepeat ) current_repeat ;
scene_root - > set_default_canvas_item_texture_repeat ( tr ) ;
}
2021-02-17 16:44:49 +00:00
RS : : DOFBokehShape dof_shape = RS : : DOFBokehShape ( int ( GLOBAL_GET ( " rendering/camera/depth_of_field/depth_of_field_bokeh_shape " ) ) ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > camera_effects_set_dof_blur_bokeh_shape ( dof_shape ) ;
2021-02-17 16:44:49 +00:00
RS : : DOFBlurQuality dof_quality = RS : : DOFBlurQuality ( int ( GLOBAL_GET ( " rendering/camera/depth_of_field/depth_of_field_bokeh_quality " ) ) ) ;
bool dof_jitter = GLOBAL_GET ( " rendering/camera/depth_of_field/depth_of_field_use_jitter " ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > camera_effects_set_dof_blur_quality ( dof_quality , dof_jitter ) ;
2021-02-17 16:44:49 +00:00
RS : : get_singleton ( ) - > environment_set_ssao_quality ( RS : : EnvironmentSSAOQuality ( int ( GLOBAL_GET ( " rendering/environment/ssao/quality " ) ) ) , GLOBAL_GET ( " rendering/environment/ssao/half_size " ) , GLOBAL_GET ( " rendering/environment/ssao/adaptive_target " ) , GLOBAL_GET ( " rendering/environment/ssao/blur_passes " ) , GLOBAL_GET ( " rendering/environment/ssao/fadeout_from " ) , GLOBAL_GET ( " rendering/environment/ssao/fadeout_to " ) ) ;
RS : : get_singleton ( ) - > screen_space_roughness_limiter_set_active ( GLOBAL_GET ( " rendering/anti_aliasing/screen_space_roughness_limiter/enabled " ) , GLOBAL_GET ( " rendering/anti_aliasing/screen_space_roughness_limiter/amount " ) , GLOBAL_GET ( " rendering/anti_aliasing/screen_space_roughness_limiter/limit " ) ) ;
bool glow_bicubic = int ( GLOBAL_GET ( " rendering/environment/glow/upscale_mode " ) ) > 0 ;
2021-08-03 07:07:32 +00:00
RS : : get_singleton ( ) - > environment_set_ssil_quality ( RS : : EnvironmentSSILQuality ( int ( GLOBAL_GET ( " rendering/environment/ssil/quality " ) ) ) , GLOBAL_GET ( " rendering/environment/ssil/half_size " ) , GLOBAL_GET ( " rendering/environment/ssil/adaptive_target " ) , GLOBAL_GET ( " rendering/environment/ssil/blur_passes " ) , GLOBAL_GET ( " rendering/environment/ssil/fadeout_from " ) , GLOBAL_GET ( " rendering/environment/ssil/fadeout_to " ) ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > environment_glow_set_use_bicubic_upscale ( glow_bicubic ) ;
2021-02-17 16:44:49 +00:00
bool glow_high_quality = GLOBAL_GET ( " rendering/environment/glow/use_high_quality " ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > environment_glow_set_use_high_quality ( glow_high_quality ) ;
2021-02-17 16:44:49 +00:00
RS : : EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS : : EnvironmentSSRRoughnessQuality ( int ( GLOBAL_GET ( " rendering/environment/screen_space_reflection/roughness_quality " ) ) ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > environment_set_ssr_roughness_quality ( ssr_roughness_quality ) ;
2021-02-17 16:44:49 +00:00
RS : : SubSurfaceScatteringQuality sss_quality = RS : : SubSurfaceScatteringQuality ( int ( GLOBAL_GET ( " rendering/environment/subsurface_scattering/subsurface_scattering_quality " ) ) ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > sub_surface_scattering_set_quality ( sss_quality ) ;
2021-02-17 16:44:49 +00:00
float sss_scale = GLOBAL_GET ( " rendering/environment/subsurface_scattering/subsurface_scattering_scale " ) ;
float sss_depth_scale = GLOBAL_GET ( " rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale " ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > sub_surface_scattering_set_scale ( sss_scale , sss_depth_scale ) ;
2021-02-17 16:44:49 +00:00
uint32_t directional_shadow_size = GLOBAL_GET ( " rendering/shadows/directional_shadow/size " ) ;
uint32_t directional_shadow_16_bits = GLOBAL_GET ( " rendering/shadows/directional_shadow/16_bits " ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > directional_shadow_atlas_set_size ( directional_shadow_size , directional_shadow_16_bits ) ;
2021-02-17 16:44:49 +00:00
RS : : ShadowQuality shadows_quality = RS : : ShadowQuality ( int ( GLOBAL_GET ( " rendering/shadows/shadows/soft_shadow_quality " ) ) ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > shadows_quality_set ( shadows_quality ) ;
2021-02-17 16:44:49 +00:00
RS : : ShadowQuality directional_shadow_quality = RS : : ShadowQuality ( int ( GLOBAL_GET ( " rendering/shadows/directional_shadow/soft_shadow_quality " ) ) ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > directional_shadow_quality_set ( directional_shadow_quality ) ;
2021-02-17 16:44:49 +00:00
float probe_update_speed = GLOBAL_GET ( " rendering/lightmapping/probe_capture/update_speed " ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > lightmap_set_probe_capture_update_speed ( probe_update_speed ) ;
2021-02-17 16:44:49 +00:00
RS : : EnvironmentSDFGIFramesToConverge frames_to_converge = RS : : EnvironmentSDFGIFramesToConverge ( int ( GLOBAL_GET ( " rendering/global_illumination/sdfgi/frames_to_converge " ) ) ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > environment_set_sdfgi_frames_to_converge ( frames_to_converge ) ;
2021-02-17 16:44:49 +00:00
RS : : EnvironmentSDFGIRayCount ray_count = RS : : EnvironmentSDFGIRayCount ( int ( GLOBAL_GET ( " rendering/global_illumination/sdfgi/probe_ray_count " ) ) ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > environment_set_sdfgi_ray_count ( ray_count ) ;
2021-06-04 22:47:26 +00:00
RS : : VoxelGIQuality voxel_gi_quality = RS : : VoxelGIQuality ( int ( GLOBAL_GET ( " rendering/global_illumination/voxel_gi/quality " ) ) ) ;
RS : : get_singleton ( ) - > voxel_gi_set_quality ( voxel_gi_quality ) ;
2021-02-17 16:44:49 +00:00
RS : : get_singleton ( ) - > environment_set_volumetric_fog_volume_size ( GLOBAL_GET ( " rendering/environment/volumetric_fog/volume_size " ) , GLOBAL_GET ( " rendering/environment/volumetric_fog/volume_depth " ) ) ;
RS : : get_singleton ( ) - > environment_set_volumetric_fog_filter_active ( bool ( GLOBAL_GET ( " rendering/environment/volumetric_fog/use_filter " ) ) ) ;
RS : : get_singleton ( ) - > canvas_set_shadow_texture_size ( GLOBAL_GET ( " rendering/2d/shadow_atlas/size " ) ) ;
2021-02-13 14:06:56 +00:00
2021-02-17 16:44:49 +00:00
bool use_half_res_gi = GLOBAL_DEF ( " rendering/global_illumination/gi/use_half_resolution " , false ) ;
2021-02-13 14:06:56 +00:00
RS : : get_singleton ( ) - > gi_set_use_half_resolution ( use_half_res_gi ) ;
2021-02-17 16:44:49 +00:00
bool snap_2d_transforms = GLOBAL_GET ( " rendering/2d/snap/snap_2d_transforms_to_pixel " ) ;
2021-02-13 14:06:56 +00:00
scene_root - > set_snap_2d_transforms_to_pixel ( snap_2d_transforms ) ;
2021-02-17 16:44:49 +00:00
bool snap_2d_vertices = GLOBAL_GET ( " rendering/2d/snap/snap_2d_vertices_to_pixel " ) ;
2021-02-13 14:06:56 +00:00
scene_root - > set_snap_2d_vertices_to_pixel ( snap_2d_vertices ) ;
2021-02-17 16:44:49 +00:00
Viewport : : SDFOversize sdf_oversize = Viewport : : SDFOversize ( int ( GLOBAL_GET ( " rendering/2d/sdf/oversize " ) ) ) ;
2021-02-13 14:06:56 +00:00
scene_root - > set_sdf_oversize ( sdf_oversize ) ;
2021-02-17 16:44:49 +00:00
Viewport : : SDFScale sdf_scale = Viewport : : SDFScale ( int ( GLOBAL_GET ( " rendering/2d/sdf/scale " ) ) ) ;
2021-02-13 14:06:56 +00:00
scene_root - > set_sdf_scale ( sdf_scale ) ;
2021-12-28 23:10:41 +00:00
float mesh_lod_threshold = GLOBAL_GET ( " rendering/mesh_lod/lod_change/threshold_pixels " ) ;
scene_root - > set_mesh_lod_threshold ( mesh_lod_threshold ) ;
2021-07-19 19:41:55 +00:00
RS : : get_singleton ( ) - > decals_set_filter ( RS : : DecalFilter ( int ( GLOBAL_GET ( " rendering/textures/decals/filter " ) ) ) ) ;
RS : : get_singleton ( ) - > light_projectors_set_filter ( RS : : LightProjectorFilter ( int ( GLOBAL_GET ( " rendering/textures/light_projectors/filter " ) ) ) ) ;
2022-03-28 02:49:18 +00:00
SceneTree * tree = get_tree ( ) ;
tree - > set_debug_collisions_color ( GLOBAL_GET ( " debug/shapes/collision/shape_color " ) ) ;
tree - > set_debug_collision_contact_color ( GLOBAL_GET ( " debug/shapes/collision/contact_color " ) ) ;
tree - > set_debug_navigation_color ( GLOBAL_GET ( " debug/shapes/navigation/geometry_color " ) ) ;
tree - > set_debug_navigation_disabled_color ( GLOBAL_GET ( " debug/shapes/navigation/disabled_geometry_color " ) ) ;
2021-02-13 14:06:56 +00:00
}
2020-08-05 03:14:39 +00:00
void EditorNode : : _select_default_main_screen_plugin ( ) {
if ( EDITOR_3D < main_editor_buttons . size ( ) & & main_editor_buttons [ EDITOR_3D ] - > is_visible ( ) ) {
// If the 3D editor is enabled, use this as the default.
_editor_select ( EDITOR_3D ) ;
return ;
}
// Switch to the first main screen plugin that is enabled. Usually this is
// 2D, but may be subsequent ones if 2D is disabled in the feature profile.
for ( int i = 0 ; i < main_editor_buttons . size ( ) ; i + + ) {
Button * editor_button = main_editor_buttons [ i ] ;
if ( editor_button - > is_visible ( ) ) {
_editor_select ( i ) ;
return ;
}
}
_editor_select ( - 1 ) ;
}
2014-02-10 01:10:30 +00:00
void EditorNode : : _notification ( int p_what ) {
2019-07-14 10:26:22 +00:00
switch ( p_what ) {
case NOTIFICATION_PROCESS : {
2020-05-14 14:41:43 +00:00
if ( opening_prev & & ! confirmation - > is_visible ( ) ) {
2019-07-14 10:26:22 +00:00
opening_prev = false ;
2020-05-14 14:41:43 +00:00
}
2015-04-20 22:38:02 +00:00
2019-07-14 10:26:22 +00:00
if ( unsaved_cache ! = ( saved_version ! = editor_data . get_undo_redo ( ) . get_version ( ) ) ) {
unsaved_cache = ( saved_version ! = editor_data . get_undo_redo ( ) . get_version ( ) ) ;
_update_title ( ) ;
}
2014-02-10 01:10:30 +00:00
2019-07-14 10:26:22 +00:00
if ( last_checked_version ! = editor_data . get_undo_redo ( ) . get_version ( ) ) {
_update_scene_tabs ( ) ;
last_checked_version = editor_data . get_undo_redo ( ) . get_version ( ) ;
}
2014-02-10 01:10:30 +00:00
2021-10-26 06:44:50 +00:00
// Update the animation frame of the update spinner.
2019-07-14 10:26:22 +00:00
uint64_t frame = Engine : : get_singleton ( ) - > get_frames_drawn ( ) ;
2021-10-26 06:44:50 +00:00
uint64_t tick = OS : : get_singleton ( ) - > get_ticks_msec ( ) ;
2014-02-10 01:10:30 +00:00
2019-07-14 10:26:22 +00:00
if ( frame ! = update_spinner_step_frame & & ( tick - update_spinner_step_msec ) > ( 1000 / 8 ) ) {
update_spinner_step + + ;
2020-05-14 14:41:43 +00:00
if ( update_spinner_step > = 8 ) {
2019-07-14 10:26:22 +00:00
update_spinner_step = 0 ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2019-07-14 10:26:22 +00:00
update_spinner_step_msec = tick ;
update_spinner_step_frame = frame + 1 ;
2014-02-10 01:10:30 +00:00
2021-10-26 06:44:50 +00:00
// Update the icon itself only when the spinner is visible.
2019-07-14 10:26:22 +00:00
if ( EditorSettings : : get_singleton ( ) - > get ( " interface/editor/show_update_spinner " ) ) {
2021-08-20 12:48:34 +00:00
update_spinner - > set_icon ( gui_base - > get_theme_icon ( " Progress " + itos ( update_spinner_step + 1 ) , SNAME ( " EditorIcons " ) ) ) ;
2019-07-14 10:26:22 +00:00
}
}
2014-02-10 01:10:30 +00:00
2019-07-14 10:26:22 +00:00
editor_selection - > update ( ) ;
2014-02-10 01:10:30 +00:00
2021-02-13 14:06:56 +00:00
ResourceImporterTexture : : get_singleton ( ) - > update_imports ( ) ;
2020-01-16 00:23:21 +00:00
2021-02-13 14:06:56 +00:00
if ( settings_changed ) {
_update_from_settings ( ) ;
settings_changed = false ;
2021-07-17 21:22:52 +00:00
emit_signal ( SNAME ( " project_settings_changed " ) ) ;
2019-06-25 01:24:07 +00:00
}
2020-11-18 18:11:30 +00:00
ResourceImporterTexture : : get_singleton ( ) - > update_imports ( ) ;
2019-07-14 10:26:22 +00:00
} break ;
2014-02-10 01:10:30 +00:00
2019-07-14 10:26:22 +00:00
case NOTIFICATION_ENTER_TREE : {
Engine : : get_singleton ( ) - > set_editor_hint ( true ) ;
2017-06-12 19:18:17 +00:00
2019-07-14 10:26:22 +00:00
OS : : get_singleton ( ) - > set_low_processor_usage_mode_sleep_usec ( int ( EDITOR_GET ( " interface/editor/low_processor_mode_sleep_usec " ) ) ) ;
2021-08-02 17:31:51 +00:00
get_tree ( ) - > get_root ( ) - > set_as_audio_listener_3d ( false ) ;
2019-07-14 10:26:22 +00:00
get_tree ( ) - > get_root ( ) - > set_as_audio_listener_2d ( false ) ;
2020-10-29 21:09:16 +00:00
get_tree ( ) - > get_root ( ) - > set_snap_2d_transforms_to_pixel ( false ) ;
get_tree ( ) - > get_root ( ) - > set_snap_2d_vertices_to_pixel ( false ) ;
2019-07-14 10:26:22 +00:00
get_tree ( ) - > set_auto_accept_quit ( false ) ;
2021-06-25 13:45:16 +00:00
# ifdef ANDROID_ENABLED
get_tree ( ) - > set_quit_on_go_back ( false ) ;
# endif
2020-03-04 16:36:09 +00:00
get_tree ( ) - > get_root ( ) - > connect ( " files_dropped " , callable_mp ( this , & EditorNode : : _dropped_files ) ) ;
2014-02-10 01:10:30 +00:00
2021-05-29 13:28:16 +00:00
command_palette - > register_shortcuts_as_command ( ) ;
2019-07-14 10:26:22 +00:00
/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
} break ;
2017-08-13 14:21:45 +00:00
2019-07-14 10:26:22 +00:00
case NOTIFICATION_EXIT_TREE : {
editor_data . save_editor_external_data ( ) ;
2020-04-01 23:20:12 +00:00
FileAccess : : set_file_close_fail_notify_callback ( nullptr ) ;
2022-03-30 18:12:26 +00:00
log - > deinit ( ) ; // Do not get messages anymore.
2019-07-14 10:26:22 +00:00
editor_data . clear_edited_scenes ( ) ;
} break ;
2019-02-27 14:00:11 +00:00
2022-01-23 15:42:52 +00:00
case Control : : NOTIFICATION_THEME_CHANGED : {
scene_tab_add_ph - > set_custom_minimum_size ( scene_tab_add - > get_minimum_size ( ) ) ;
} break ;
2019-07-14 10:26:22 +00:00
case NOTIFICATION_READY : {
2021-11-15 15:08:19 +00:00
{
2022-03-30 18:12:26 +00:00
_initializing_plugins = true ;
2021-11-15 15:08:19 +00:00
Vector < String > addons ;
if ( ProjectSettings : : get_singleton ( ) - > has_setting ( " editor_plugins/enabled " ) ) {
addons = ProjectSettings : : get_singleton ( ) - > get ( " editor_plugins/enabled " ) ;
}
for ( int i = 0 ; i < addons . size ( ) ; i + + ) {
set_addon_plugin_enabled ( addons [ i ] , true ) ;
}
2022-03-30 18:12:26 +00:00
_initializing_plugins = false ;
2021-11-15 15:08:19 +00:00
}
2021-07-01 02:17:47 +00:00
RenderingServer : : get_singleton ( ) - > viewport_set_disable_2d ( get_scene_root ( ) - > get_viewport_rid ( ) , true ) ;
2020-03-27 18:21:27 +00:00
RenderingServer : : get_singleton ( ) - > viewport_set_disable_environment ( get_viewport ( ) - > get_viewport_rid ( ) , true ) ;
2015-06-22 03:03:19 +00:00
2019-07-14 10:26:22 +00:00
feature_profile_manager - > notify_changed ( ) ;
2014-02-10 01:10:30 +00:00
2020-08-05 03:14:39 +00:00
_select_default_main_screen_plugin ( ) ;
2015-03-16 03:47:37 +00:00
2021-07-23 10:44:35 +00:00
// Save the project after opening to mark it as last modified, except in headless mode.
if ( DisplayServer : : get_singleton ( ) - > window_can_draw ( ) ) {
ProjectSettings : : get_singleton ( ) - > save ( ) ;
}
2021-03-26 13:10:41 +00:00
2019-07-14 10:26:22 +00:00
/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
} break ;
2019-04-08 22:18:03 +00:00
2020-06-29 23:47:18 +00:00
case NOTIFICATION_APPLICATION_FOCUS_IN : {
2021-04-11 13:39:31 +00:00
// Restore the original FPS cap after focusing back on the editor.
2019-07-14 10:26:22 +00:00
OS : : get_singleton ( ) - > set_low_processor_usage_mode_sleep_usec ( int ( EDITOR_GET ( " interface/editor/low_processor_mode_sleep_usec " ) ) ) ;
2014-02-10 01:10:30 +00:00
2019-07-14 10:26:22 +00:00
EditorFileSystem : : get_singleton ( ) - > scan_changes ( ) ;
2019-08-28 17:42:27 +00:00
_scan_external_changes ( ) ;
2019-07-14 10:26:22 +00:00
} break ;
2014-02-10 01:10:30 +00:00
2020-06-29 23:47:18 +00:00
case NOTIFICATION_APPLICATION_FOCUS_OUT : {
2021-04-11 13:39:31 +00:00
// Save on focus loss before applying the FPS limit to avoid slowing down the saving process.
if ( EDITOR_GET ( " interface/editor/save_on_focus_loss " ) ) {
_menu_option_confirm ( FILE_SAVE_SCENE , false ) ;
}
// Set a low FPS cap to decrease CPU/GPU usage while the editor is unfocused.
2019-07-14 10:26:22 +00:00
OS : : get_singleton ( ) - > set_low_processor_usage_mode_sleep_usec ( int ( EDITOR_GET ( " interface/editor/unfocused_low_processor_mode_sleep_usec " ) ) ) ;
} break ;
2014-02-10 01:10:30 +00:00
2020-03-04 16:36:09 +00:00
case NOTIFICATION_WM_ABOUT : {
2019-08-05 17:46:23 +00:00
show_about ( ) ;
} break ;
2020-03-04 16:36:09 +00:00
case NOTIFICATION_WM_CLOSE_REQUEST : {
2019-07-14 10:26:22 +00:00
_menu_option_confirm ( FILE_QUIT , false ) ;
} break ;
2019-05-29 21:12:19 +00:00
2019-07-14 10:26:22 +00:00
case EditorSettings : : NOTIFICATION_EDITOR_SETTINGS_CHANGED : {
2022-03-13 01:03:26 +00:00
scene_tabs - > set_tab_close_display_policy ( ( TabBar : : CloseButtonDisplayPolicy ) EDITOR_GET ( " interface/scene_tabs/display_close_button " ) . operator int ( ) ) ;
2021-10-15 12:34:52 +00:00
bool theme_changed =
EditorSettings : : get_singleton ( ) - > check_changed_settings_in_group ( " interface/theme " ) | |
2022-03-21 06:20:09 +00:00
EditorSettings : : get_singleton ( ) - > check_changed_settings_in_group ( " text_editor/theme " ) | |
EditorSettings : : get_singleton ( ) - > check_changed_settings_in_group ( " interface/editor/font " ) | |
EditorSettings : : get_singleton ( ) - > check_changed_settings_in_group ( " interface/editor/main_font " ) | |
EditorSettings : : get_singleton ( ) - > check_changed_settings_in_group ( " interface/editor/code_font " ) ;
2021-10-15 12:34:52 +00:00
if ( theme_changed ) {
theme = create_custom_theme ( theme_base - > get_theme ( ) ) ;
theme_base - > set_theme ( theme ) ;
gui_base - > set_theme ( theme ) ;
gui_base - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " Background " ) , SNAME ( " EditorStyles " ) ) ) ;
scene_root_parent - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " Content " ) , SNAME ( " EditorStyles " ) ) ) ;
bottom_panel - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " panel " ) , SNAME ( " TabContainer " ) ) ) ;
scene_tabs - > add_theme_style_override ( " tab_selected " , gui_base - > get_theme_stylebox ( SNAME ( " SceneTabFG " ) , SNAME ( " EditorStyles " ) ) ) ;
scene_tabs - > add_theme_style_override ( " tab_unselected " , gui_base - > get_theme_stylebox ( SNAME ( " SceneTabBG " ) , SNAME ( " EditorStyles " ) ) ) ;
file_menu - > add_theme_style_override ( " hover " , gui_base - > get_theme_stylebox ( SNAME ( " MenuHover " ) , SNAME ( " EditorStyles " ) ) ) ;
project_menu - > add_theme_style_override ( " hover " , gui_base - > get_theme_stylebox ( SNAME ( " MenuHover " ) , SNAME ( " EditorStyles " ) ) ) ;
debug_menu - > add_theme_style_override ( " hover " , gui_base - > get_theme_stylebox ( SNAME ( " MenuHover " ) , SNAME ( " EditorStyles " ) ) ) ;
settings_menu - > add_theme_style_override ( " hover " , gui_base - > get_theme_stylebox ( SNAME ( " MenuHover " ) , SNAME ( " EditorStyles " ) ) ) ;
help_menu - > add_theme_style_override ( " hover " , gui_base - > get_theme_stylebox ( SNAME ( " MenuHover " ) , SNAME ( " EditorStyles " ) ) ) ;
}
2017-10-20 10:24:00 +00:00
2022-02-03 05:45:31 +00:00
scene_tabs - > set_max_tab_width ( int ( EDITOR_GET ( " interface/scene_tabs/maximum_width " ) ) * EDSCALE ) ;
2019-07-14 10:26:22 +00:00
_update_scene_tabs ( ) ;
2022-03-05 23:57:42 +00:00
recent_scenes - > reset_size ( ) ;
2019-07-14 10:26:22 +00:00
2022-03-30 18:12:26 +00:00
// Update debugger area.
2020-05-14 14:41:43 +00:00
if ( EditorDebuggerNode : : get_singleton ( ) - > is_visible ( ) ) {
2022-02-08 09:14:58 +00:00
bottom_panel - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " BottomPanelDebuggerOverride " ) , SNAME ( " EditorStyles " ) ) ) ;
2020-05-14 14:41:43 +00:00
}
2017-09-18 19:06:55 +00:00
2022-03-30 18:12:26 +00:00
// Update icons.
2019-07-14 10:26:22 +00:00
for ( int i = 0 ; i < singleton - > main_editor_buttons . size ( ) ; i + + ) {
2020-06-19 18:49:04 +00:00
Button * tb = singleton - > main_editor_buttons [ i ] ;
2019-07-14 10:26:22 +00:00
EditorPlugin * p_editor = singleton - > editor_table [ i ] ;
2019-06-11 18:43:37 +00:00
Ref < Texture2D > icon = p_editor - > get_icon ( ) ;
2017-12-06 22:27:45 +00:00
2019-07-14 10:26:22 +00:00
if ( icon . is_valid ( ) ) {
tb - > set_icon ( icon ) ;
2022-02-06 14:53:53 +00:00
} else if ( singleton - > gui_base - > has_theme_icon ( p_editor - > get_name ( ) , SNAME ( " EditorIcons " ) ) ) {
tb - > set_icon ( singleton - > gui_base - > get_theme_icon ( p_editor - > get_name ( ) , SNAME ( " EditorIcons " ) ) ) ;
2019-07-14 10:26:22 +00:00
}
2017-12-06 22:27:45 +00:00
}
2018-02-25 16:04:16 +00:00
2019-07-14 10:26:22 +00:00
_build_icon_type_cache ( ) ;
2018-02-25 16:04:16 +00:00
2021-07-17 21:22:52 +00:00
play_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " MainPlay " ) , SNAME ( " EditorIcons " ) ) ) ;
play_scene_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " PlayScene " ) , SNAME ( " EditorIcons " ) ) ) ;
play_custom_scene_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " PlayCustom " ) , SNAME ( " EditorIcons " ) ) ) ;
pause_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " Pause " ) , SNAME ( " EditorIcons " ) ) ) ;
stop_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " Stop " ) , SNAME ( " EditorIcons " ) ) ) ;
2017-08-29 23:03:13 +00:00
2021-07-17 21:22:52 +00:00
prev_scene - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " PrevScene " ) , SNAME ( " EditorIcons " ) ) ) ;
distraction_free - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " DistractionFree " ) , SNAME ( " EditorIcons " ) ) ) ;
scene_tab_add - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " Add " ) , SNAME ( " EditorIcons " ) ) ) ;
2017-08-29 23:03:13 +00:00
2021-07-17 21:22:52 +00:00
bottom_panel_raise - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " ExpandBottomDock " ) , SNAME ( " EditorIcons " ) ) ) ;
2019-07-29 21:08:05 +00:00
2020-09-03 11:22:16 +00:00
if ( gui_base - > is_layout_rtl ( ) ) {
2022-02-06 14:53:53 +00:00
dock_tab_move_left - > set_icon ( theme - > get_icon ( SNAME ( " Forward " ) , SNAME ( " EditorIcons " ) ) ) ;
dock_tab_move_right - > set_icon ( theme - > get_icon ( SNAME ( " Back " ) , SNAME ( " EditorIcons " ) ) ) ;
2020-09-03 11:22:16 +00:00
} else {
2022-02-06 14:53:53 +00:00
dock_tab_move_left - > set_icon ( theme - > get_icon ( SNAME ( " Back " ) , SNAME ( " EditorIcons " ) ) ) ;
dock_tab_move_right - > set_icon ( theme - > get_icon ( SNAME ( " Forward " ) , SNAME ( " EditorIcons " ) ) ) ;
2020-09-03 11:22:16 +00:00
}
2018-02-25 16:04:16 +00:00
2019-07-14 10:26:22 +00:00
PopupMenu * p = help_menu - > get_popup ( ) ;
2021-07-17 21:22:52 +00:00
p - > set_item_icon ( p - > get_item_index ( HELP_SEARCH ) , gui_base - > get_theme_icon ( SNAME ( " HelpSearch " ) , SNAME ( " EditorIcons " ) ) ) ;
2022-04-24 15:21:14 +00:00
p - > set_item_icon ( p - > get_item_index ( HELP_DOCS ) , gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) ) ;
p - > set_item_icon ( p - > get_item_index ( HELP_QA ) , gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) ) ;
p - > set_item_icon ( p - > get_item_index ( HELP_REPORT_A_BUG ) , gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) ) ;
p - > set_item_icon ( p - > get_item_index ( HELP_SUGGEST_A_FEATURE ) , gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) ) ;
p - > set_item_icon ( p - > get_item_index ( HELP_SEND_DOCS_FEEDBACK ) , gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) ) ;
p - > set_item_icon ( p - > get_item_index ( HELP_COMMUNITY ) , gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) ) ;
2021-07-17 21:22:52 +00:00
p - > set_item_icon ( p - > get_item_index ( HELP_ABOUT ) , gui_base - > get_theme_icon ( SNAME ( " Godot " ) , SNAME ( " EditorIcons " ) ) ) ;
p - > set_item_icon ( p - > get_item_index ( HELP_SUPPORT_GODOT_DEVELOPMENT ) , gui_base - > get_theme_icon ( SNAME ( " Heart " ) , SNAME ( " EditorIcons " ) ) ) ;
2018-12-11 15:52:25 +00:00
2021-05-27 15:32:30 +00:00
for ( int i = 0 ; i < main_editor_buttons . size ( ) ; i + + ) {
2022-02-08 09:14:58 +00:00
main_editor_buttons . write [ i ] - > add_theme_font_override ( " font " , gui_base - > get_theme_font ( SNAME ( " main_button_font " ) , SNAME ( " EditorFonts " ) ) ) ;
main_editor_buttons . write [ i ] - > add_theme_font_size_override ( " font_size " , gui_base - > get_theme_font_size ( SNAME ( " main_button_font_size " ) , SNAME ( " EditorFonts " ) ) ) ;
2021-05-27 15:32:30 +00:00
}
2022-05-19 15:00:06 +00:00
HashSet < String > updated_textfile_extensions ;
2021-09-23 21:09:15 +00:00
bool extensions_match = true ;
const Vector < String > textfile_ext = ( ( String ) ( EditorSettings : : get_singleton ( ) - > get ( " docks/filesystem/textfile_extensions " ) ) ) . split ( " , " , false ) ;
for ( const String & E : textfile_ext ) {
updated_textfile_extensions . insert ( E ) ;
if ( extensions_match & & ! textfile_extensions . has ( E ) ) {
extensions_match = false ;
}
}
if ( ! extensions_match | | updated_textfile_extensions . size ( ) < textfile_extensions . size ( ) ) {
textfile_extensions = updated_textfile_extensions ;
EditorFileSystem : : get_singleton ( ) - > scan ( ) ;
}
2019-07-14 10:26:22 +00:00
_update_update_spinner ( ) ;
} break ;
2017-11-16 22:57:57 +00:00
}
2014-02-10 01:10:30 +00:00
}
2018-12-11 15:52:25 +00:00
void EditorNode : : _update_update_spinner ( ) {
update_spinner - > set_visible ( EditorSettings : : get_singleton ( ) - > get ( " interface/editor/show_update_spinner " ) ) ;
2021-08-03 15:22:46 +00:00
const bool update_continuously = EditorSettings : : get_singleton ( ) - > get ( " interface/editor/update_continuously " ) ;
2018-12-11 15:52:25 +00:00
PopupMenu * update_popup = update_spinner - > get_popup ( ) ;
update_popup - > set_item_checked ( update_popup - > get_item_index ( SETTINGS_UPDATE_CONTINUOUSLY ) , update_continuously ) ;
update_popup - > set_item_checked ( update_popup - > get_item_index ( SETTINGS_UPDATE_WHEN_CHANGED ) , ! update_continuously ) ;
2021-08-03 15:22:46 +00:00
if ( update_continuously ) {
update_spinner - > set_tooltip ( TTR ( " Spins when the editor window redraws. \n Update Continuously is enabled, which can increase power usage. Click to disable it. " ) ) ;
// Use a different color for the update spinner when Update Continuously is enabled,
// as this feature should only be enabled for troubleshooting purposes.
// Make the icon modulate color overbright because icons are not completely white on a dark theme.
// On a light theme, icons are dark, so we need to modulate them with an even brighter color.
const bool dark_theme = EditorSettings : : get_singleton ( ) - > is_dark_theme ( ) ;
update_spinner - > set_self_modulate (
2021-08-20 12:48:34 +00:00
gui_base - > get_theme_color ( SNAME ( " error_color " ) , SNAME ( " Editor " ) ) * ( dark_theme ? Color ( 1.1 , 1.1 , 1.1 ) : Color ( 4.25 , 4.25 , 4.25 ) ) ) ;
2021-08-03 15:22:46 +00:00
} else {
update_spinner - > set_tooltip ( TTR ( " Spins when the editor window redraws. " ) ) ;
update_spinner - > set_self_modulate ( Color ( 1 , 1 , 1 ) ) ;
}
2018-12-11 15:52:25 +00:00
OS : : get_singleton ( ) - > set_low_processor_usage_mode ( ! update_continuously ) ;
}
2018-07-19 15:34:22 +00:00
void EditorNode : : _on_plugin_ready ( Object * p_script , const String & p_activate_name ) {
Ref < Script > script = Object : : cast_to < Script > ( p_script ) ;
2020-05-14 14:41:43 +00:00
if ( script . is_null ( ) ) {
2018-07-19 15:34:22 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2018-07-19 15:34:22 +00:00
if ( p_activate_name . length ( ) ) {
set_addon_plugin_enabled ( p_activate_name , true ) ;
}
2022-01-31 23:19:01 +00:00
project_settings_editor - > update_plugins ( ) ;
project_settings_editor - > hide ( ) ;
2018-07-19 15:34:22 +00:00
push_item ( script . operator - > ( ) ) ;
}
2021-05-09 12:17:15 +00:00
void EditorNode : : _remove_plugin_from_enabled ( const String & p_name ) {
ProjectSettings * ps = ProjectSettings : : get_singleton ( ) ;
PackedStringArray enabled_plugins = ps - > get ( " editor_plugins/enabled " ) ;
for ( int i = 0 ; i < enabled_plugins . size ( ) ; + + i ) {
if ( enabled_plugins . get ( i ) = = p_name ) {
2021-07-03 22:17:03 +00:00
enabled_plugins . remove_at ( i ) ;
2021-05-09 12:17:15 +00:00
break ;
}
}
ps - > set ( " editor_plugins/enabled " , enabled_plugins ) ;
}
2020-02-17 21:06:54 +00:00
void EditorNode : : _resources_changed ( const Vector < String > & p_resources ) {
2020-03-17 06:33:00 +00:00
List < Ref < Resource > > changed ;
2014-02-10 01:10:30 +00:00
2018-11-21 00:47:48 +00:00
int rc = p_resources . size ( ) ;
for ( int i = 0 ; i < rc ; i + + ) {
Ref < Resource > res ( ResourceCache : : get ( p_resources . get ( i ) ) ) ;
if ( res . is_null ( ) ) {
continue ;
}
2015-05-31 04:59:42 +00:00
2020-05-14 14:41:43 +00:00
if ( ! res - > editor_can_reload_from_file ( ) ) {
2018-11-21 00:47:48 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2021-06-03 13:41:22 +00:00
if ( ! res - > get_path ( ) . is_resource_file ( ) & & ! res - > get_path ( ) . is_absolute_path ( ) ) {
2018-11-21 00:47:48 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
if ( ! FileAccess : : exists ( res - > get_path ( ) ) ) {
2018-11-21 00:47:48 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2016-02-10 06:41:48 +00:00
2021-12-09 09:42:46 +00:00
if ( ! res - > get_import_path ( ) . is_empty ( ) ) {
2022-03-30 18:12:26 +00:00
// This is an imported resource, will be reloaded if reimported via the _resources_reimported() callback.
2018-11-21 00:47:48 +00:00
continue ;
}
2014-02-10 01:10:30 +00:00
2018-11-21 00:47:48 +00:00
changed . push_back ( res ) ;
}
2016-05-27 17:18:40 +00:00
2018-11-21 00:47:48 +00:00
if ( changed . size ( ) ) {
2021-07-26 15:50:35 +00:00
for ( Ref < Resource > & res : changed ) {
res - > reload_from_file ( ) ;
2018-11-21 00:47:48 +00:00
}
}
}
2016-05-27 17:18:40 +00:00
2018-11-21 00:47:48 +00:00
void EditorNode : : _fs_changed ( ) {
2022-05-18 23:43:40 +00:00
for ( FileDialog * E : file_dialogs ) {
E - > invalidate ( ) ;
2018-11-21 00:47:48 +00:00
}
2016-05-27 17:18:40 +00:00
2022-05-18 23:43:40 +00:00
for ( EditorFileDialog * E : editor_file_dialogs ) {
E - > invalidate ( ) ;
2016-05-27 17:18:40 +00:00
}
2017-06-29 17:37:54 +00:00
_mark_unsaved_scenes ( ) ;
2017-12-30 09:39:09 +00:00
2022-03-30 18:12:26 +00:00
// FIXME: Move this to a cleaner location, it's hacky to do this in _fs_changed.
2020-01-07 12:29:02 +00:00
String export_error ;
2021-12-09 09:42:46 +00:00
if ( ! export_defer . preset . is_empty ( ) & & ! EditorFileSystem : : get_singleton ( ) - > is_scanning ( ) ) {
2020-01-07 12:29:02 +00:00
String preset_name = export_defer . preset ;
// Ensures export_project does not loop infinitely, because notifications may
// come during the export.
export_defer . preset = " " ;
2022-03-30 18:12:26 +00:00
Ref < EditorExportPreset > export_preset ;
2017-12-30 09:39:09 +00:00
for ( int i = 0 ; i < EditorExport : : get_singleton ( ) - > get_export_preset_count ( ) ; + + i ) {
2022-03-30 18:12:26 +00:00
export_preset = EditorExport : : get_singleton ( ) - > get_export_preset ( i ) ;
if ( export_preset - > get_name ( ) = = preset_name ) {
2017-12-30 09:39:09 +00:00
break ;
}
2022-03-30 18:12:26 +00:00
export_preset . unref ( ) ;
2017-12-30 09:39:09 +00:00
}
2021-04-05 23:44:15 +00:00
2022-03-30 18:12:26 +00:00
if ( export_preset . is_null ( ) ) {
2022-03-23 09:08:58 +00:00
Ref < DirAccess > da = DirAccess : : create ( DirAccess : : ACCESS_RESOURCES ) ;
2021-04-05 23:44:15 +00:00
if ( da - > file_exists ( " res://export_presets.cfg " ) ) {
export_error = vformat (
" Invalid export preset name: %s. \n The following presets were detected in this project's `export_presets.cfg`: \n \n " ,
preset_name ) ;
for ( int i = 0 ; i < EditorExport : : get_singleton ( ) - > get_export_preset_count ( ) ; + + i ) {
// Write the preset name between double quotes since it needs to be written between quotes on the command line if it contains spaces.
export_error + = vformat ( " \" %s \" \n " , EditorExport : : get_singleton ( ) - > get_export_preset ( i ) - > get_name ( ) ) ;
}
} else {
export_error = " This project doesn't have an `export_presets.cfg` file at its root. \n Create an export preset from the \" Project > Export \" dialog and try again. " ;
}
2017-12-30 09:39:09 +00:00
} else {
2022-03-30 18:12:26 +00:00
Ref < EditorExportPlatform > platform = export_preset - > get_platform ( ) ;
const String export_path = export_defer . path . is_empty ( ) ? export_preset - > get_export_path ( ) : export_defer . path ;
2020-12-15 12:04:21 +00:00
if ( export_path . is_empty ( ) ) {
2021-04-05 23:44:15 +00:00
export_error = vformat ( " Export preset \" %s \" doesn't have a default export path, and none was specified. " , preset_name ) ;
2020-11-17 17:02:41 +00:00
} else if ( platform . is_null ( ) ) {
2021-04-05 23:44:15 +00:00
export_error = vformat ( " Export preset \" %s \" doesn't have a matching platform. " , preset_name ) ;
2017-12-30 09:39:09 +00:00
} else {
2018-04-19 11:04:41 +00:00
Error err = OK ;
2020-01-08 13:22:50 +00:00
if ( export_defer . pack_only ) { // Only export .pck or .zip data pack.
2020-11-17 17:02:41 +00:00
if ( export_path . ends_with ( " .zip " ) ) {
2022-03-30 18:12:26 +00:00
err = platform - > export_zip ( export_preset , export_defer . debug , export_path ) ;
2020-11-17 17:02:41 +00:00
} else if ( export_path . ends_with ( " .pck " ) ) {
2022-03-30 18:12:26 +00:00
err = platform - > export_pack ( export_preset , export_defer . debug , export_path ) ;
2017-12-30 09:39:09 +00:00
}
2020-01-07 12:29:02 +00:00
} else { // Normal project export.
String config_error ;
bool missing_templates ;
2022-03-30 18:12:26 +00:00
if ( ! platform - > can_export ( export_preset , config_error , missing_templates ) ) {
2021-04-05 23:44:15 +00:00
ERR_PRINT ( vformat ( " Cannot export project with preset \" %s \" due to configuration errors: \n %s " , preset_name , config_error ) ) ;
2020-01-07 12:29:02 +00:00
err = missing_templates ? ERR_FILE_NOT_FOUND : ERR_UNCONFIGURED ;
} else {
2022-03-30 18:12:26 +00:00
err = platform - > export_project ( export_preset , export_defer . debug , export_path ) ;
2020-01-07 12:29:02 +00:00
}
2018-04-04 14:13:06 +00:00
}
2020-01-07 12:29:02 +00:00
switch ( err ) {
case OK :
break ;
case ERR_FILE_NOT_FOUND :
2021-04-05 23:44:15 +00:00
export_error = vformat ( " Project export failed for preset \" %s \" . The export template appears to be missing. " , preset_name ) ;
2020-01-07 12:29:02 +00:00
break ;
case ERR_FILE_BAD_PATH :
2021-04-05 23:44:15 +00:00
export_error = vformat ( " Project export failed for preset \" %s \" . The target path \" %s \" appears to be invalid. " , preset_name , export_path ) ;
2020-01-07 12:29:02 +00:00
break ;
default :
2021-04-05 23:44:15 +00:00
export_error = vformat ( " Project export failed with error code %d for preset \" %s \" . " , ( int ) err , preset_name ) ;
2020-01-07 12:29:02 +00:00
break ;
2017-12-30 09:39:09 +00:00
}
}
}
2020-12-15 12:04:21 +00:00
if ( ! export_error . is_empty ( ) ) {
2020-01-07 12:29:02 +00:00
ERR_PRINT ( export_error ) ;
2022-01-18 11:48:12 +00:00
_exit_editor ( EXIT_FAILURE ) ;
} else {
_exit_editor ( EXIT_SUCCESS ) ;
2020-01-07 12:29:02 +00:00
}
2017-12-30 09:39:09 +00:00
}
2017-02-01 12:45:45 +00:00
}
2016-05-27 17:18:40 +00:00
2017-08-31 21:57:03 +00:00
void EditorNode : : _resources_reimported ( const Vector < String > & p_resources ) {
2022-03-30 18:12:26 +00:00
List < String > scenes ;
2019-06-04 03:36:23 +00:00
int current_tab = scene_tabs - > get_current_tab ( ) ;
2017-08-31 21:57:03 +00:00
for ( int i = 0 ; i < p_resources . size ( ) ; i + + ) {
String file_type = ResourceLoader : : get_resource_type ( p_resources [ i ] ) ;
if ( file_type = = " PackedScene " ) {
scenes . push_back ( p_resources [ i ] ) ;
2022-03-30 18:12:26 +00:00
// Reload later if needed, first go with normal resources.
2017-08-31 21:57:03 +00:00
continue ;
}
if ( ! ResourceCache : : has ( p_resources [ i ] ) ) {
2022-03-30 18:12:26 +00:00
// Not loaded, no need to reload.
continue ;
2017-08-31 21:57:03 +00:00
}
2022-03-30 18:12:26 +00:00
// Reload normally.
2017-08-31 21:57:03 +00:00
Resource * resource = ResourceCache : : get ( p_resources [ i ] ) ;
if ( resource ) {
resource - > reload_from_file ( ) ;
}
}
2021-07-24 13:46:25 +00:00
for ( const String & E : scenes ) {
2021-07-16 03:45:57 +00:00
reload_scene ( E ) ;
2017-08-31 21:57:03 +00:00
}
2019-06-04 03:36:23 +00:00
scene_tabs - > set_current_tab ( current_tab ) ;
2017-08-31 21:57:03 +00:00
}
2017-02-01 12:45:45 +00:00
void EditorNode : : _sources_changed ( bool p_exist ) {
if ( waiting_for_first_scan ) {
2019-02-27 21:14:24 +00:00
waiting_for_first_scan = false ;
2014-02-10 01:10:30 +00:00
2020-04-17 02:52:00 +00:00
// Reload the global shader variables, but this time
Fix various typos with codespell
Found via `codespell -q 3 -S ./thirdparty,*.po,./DONORS.md -L ackward,ang,ans,ba,beng,cas,childs,childrens,dof,doubleclick,fave,findn,hist,inout,leapyear,lod,nd,numer,ois,ony,paket,seeked,sinc,switchs,te,uint`
2021-07-07 15:17:32 +00:00
// loading textures, as they are now properly imported.
2020-04-17 02:52:00 +00:00
RenderingServer : : get_singleton ( ) - > global_variables_load_settings ( true ) ;
2020-01-14 10:32:15 +00:00
// Start preview thread now that it's safe.
if ( ! singleton - > cmdline_export_mode ) {
EditorResourcePreview : : get_singleton ( ) - > start ( ) ;
}
2019-02-27 16:31:11 +00:00
2019-02-27 14:00:11 +00:00
_load_docks ( ) ;
2021-12-09 09:42:46 +00:00
if ( ! defer_load_scene . is_empty ( ) ) {
2017-02-01 12:45:45 +00:00
load_scene ( defer_load_scene ) ;
2017-03-05 15:44:50 +00:00
defer_load_scene = " " ;
2017-02-01 12:45:45 +00:00
}
2014-02-10 01:10:30 +00:00
}
}
2019-08-28 17:42:27 +00:00
void EditorNode : : _scan_external_changes ( ) {
disk_changed_list - > clear ( ) ;
TreeItem * r = disk_changed_list - > create_item ( ) ;
disk_changed_list - > set_hide_root ( true ) ;
bool need_reload = false ;
// Check if any edited scene has changed.
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
2022-03-23 09:08:58 +00:00
Ref < DirAccess > da = DirAccess : : create ( DirAccess : : ACCESS_RESOURCES ) ;
2021-02-26 22:18:50 +00:00
if ( editor_data . get_scene_path ( i ) = = " " | | ! da - > file_exists ( editor_data . get_scene_path ( i ) ) ) {
2019-08-28 17:42:27 +00:00
continue ;
}
uint64_t last_date = editor_data . get_scene_modified_time ( i ) ;
uint64_t date = FileAccess : : get_modified_time ( editor_data . get_scene_path ( i ) ) ;
if ( date > last_date ) {
TreeItem * ti = disk_changed_list - > create_item ( r ) ;
ti - > set_text ( 0 , editor_data . get_scene_path ( i ) . get_file ( ) ) ;
need_reload = true ;
}
}
2021-01-17 00:09:17 +00:00
String project_settings_path = ProjectSettings : : get_singleton ( ) - > get_resource_path ( ) . plus_file ( " project.godot " ) ;
if ( FileAccess : : get_modified_time ( project_settings_path ) > ProjectSettings : : get_singleton ( ) - > get_last_saved_time ( ) ) {
TreeItem * ti = disk_changed_list - > create_item ( r ) ;
ti - > set_text ( 0 , " project.godot " ) ;
need_reload = true ;
}
2019-08-28 17:42:27 +00:00
if ( need_reload ) {
2021-07-17 21:22:52 +00:00
disk_changed - > call_deferred ( SNAME ( " popup_centered_ratio " ) , 0.5 ) ;
2019-08-28 17:42:27 +00:00
}
}
void EditorNode : : _resave_scenes ( String p_str ) {
save_all_scenes ( ) ;
2021-01-17 00:09:17 +00:00
ProjectSettings : : get_singleton ( ) - > save ( ) ;
2019-08-28 17:42:27 +00:00
disk_changed - > hide ( ) ;
}
void EditorNode : : _reload_modified_scenes ( ) {
int current_idx = editor_data . get_edited_scene ( ) ;
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
if ( editor_data . get_scene_path ( i ) = = " " ) {
continue ;
}
uint64_t last_date = editor_data . get_scene_modified_time ( i ) ;
uint64_t date = FileAccess : : get_modified_time ( editor_data . get_scene_path ( i ) ) ;
if ( date > last_date ) {
String filename = editor_data . get_scene_path ( i ) ;
editor_data . set_edited_scene ( i ) ;
_remove_edited_scene ( false ) ;
Error err = load_scene ( filename , false , false , true , false , true ) ;
if ( err ! = OK ) {
2021-01-17 00:09:17 +00:00
ERR_PRINT ( vformat ( " Failed to load scene: %s " , filename ) ) ;
2019-08-28 17:42:27 +00:00
}
editor_data . move_edited_scene_to_index ( i ) ;
}
}
get_undo_redo ( ) - > clear_history ( false ) ;
set_current_scene ( current_idx ) ;
_update_scene_tabs ( ) ;
disk_changed - > hide ( ) ;
}
2021-01-17 00:09:17 +00:00
void EditorNode : : _reload_project_settings ( ) {
ProjectSettings : : get_singleton ( ) - > setup ( ProjectSettings : : get_singleton ( ) - > get_resource_path ( ) , String ( ) , true ) ;
2021-02-13 14:06:56 +00:00
settings_changed = true ;
2021-01-17 00:09:17 +00:00
}
2014-02-10 01:10:30 +00:00
void EditorNode : : _vp_resized ( ) {
}
2019-12-24 00:20:54 +00:00
void EditorNode : : _version_button_pressed ( ) {
DisplayServer : : get_singleton ( ) - > clipboard_set ( version_btn - > get_meta ( META_TEXT_TO_COPY ) ) ;
}
2014-02-10 01:10:30 +00:00
void EditorNode : : _node_renamed ( ) {
2021-11-17 20:08:55 +00:00
if ( InspectorDock : : get_inspector_singleton ( ) ) {
InspectorDock : : get_inspector_singleton ( ) - > update_tree ( ) ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
}
2017-05-16 19:26:32 +00:00
void EditorNode : : _editor_select_next ( ) {
int editor = _get_current_main_editor ( ) ;
2019-04-08 22:18:03 +00:00
do {
if ( editor = = editor_table . size ( ) - 1 ) {
editor = 0 ;
} else {
editor + + ;
}
2019-12-11 05:27:21 +00:00
} while ( ! main_editor_buttons [ editor ] - > is_visible ( ) ) ;
2019-04-08 22:18:03 +00:00
2017-05-16 19:26:32 +00:00
_editor_select ( editor ) ;
}
2021-05-29 13:28:16 +00:00
void EditorNode : : _open_command_palette ( ) {
command_palette - > open_popup ( ) ;
}
2017-05-16 19:26:32 +00:00
void EditorNode : : _editor_select_prev ( ) {
int editor = _get_current_main_editor ( ) ;
2019-04-08 22:18:03 +00:00
do {
if ( editor = = 0 ) {
editor = editor_table . size ( ) - 1 ;
} else {
editor - - ;
}
2019-12-11 05:27:21 +00:00
} while ( ! main_editor_buttons [ editor ] - > is_visible ( ) ) ;
2019-04-08 22:18:03 +00:00
2017-05-16 19:26:32 +00:00
_editor_select ( editor ) ;
}
2018-11-02 03:44:40 +00:00
Error EditorNode : : load_resource ( const String & p_resource , bool p_ignore_broken_deps ) {
dependency_errors . clear ( ) ;
Error err ;
2021-09-23 21:09:15 +00:00
2022-05-02 23:43:50 +00:00
Ref < Resource > res ;
2021-09-23 21:09:15 +00:00
if ( ResourceLoader : : exists ( p_resource , " " ) ) {
res = ResourceLoader : : load ( p_resource , " " , ResourceFormatLoader : : CACHE_MODE_REUSE , & err ) ;
} else if ( textfile_extensions . has ( p_resource . get_extension ( ) ) ) {
res = ScriptEditor : : get_singleton ( ) - > open_file ( p_resource ) ;
}
2017-03-05 15:44:50 +00:00
ERR_FAIL_COND_V ( ! res . is_valid ( ) , ERR_CANT_OPEN ) ;
2014-02-10 01:10:30 +00:00
2018-11-02 03:44:40 +00:00
if ( ! p_ignore_broken_deps & & dependency_errors . has ( p_resource ) ) {
Vector < String > errors ;
2022-05-18 23:43:40 +00:00
for ( const String & E : dependency_errors [ p_resource ] ) {
errors . push_back ( E ) ;
2018-11-02 03:44:40 +00:00
}
dependency_error - > show ( DependencyErrorDialog : : MODE_RESOURCE , p_resource , errors ) ;
dependency_errors . erase ( p_resource ) ;
return ERR_FILE_MISSING_DEPENDENCIES ;
}
2021-11-17 20:08:55 +00:00
InspectorDock : : get_singleton ( ) - > edit_resource ( res ) ;
2014-02-10 01:10:30 +00:00
return OK ;
}
void EditorNode : : edit_node ( Node * p_node ) {
push_item ( p_node ) ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : save_resource_in_path ( const Ref < Resource > & p_resource , const String & p_path ) {
2015-09-01 03:49:47 +00:00
editor_data . apply_changes_in_editors ( ) ;
2017-03-05 15:44:50 +00:00
int flg = 0 ;
2020-05-14 14:41:43 +00:00
if ( EditorSettings : : get_singleton ( ) - > get ( " filesystem/on_save/compress_binary_resources " ) ) {
2017-03-05 15:44:50 +00:00
flg | = ResourceSaver : : FLAG_COMPRESS ;
2020-05-14 14:41:43 +00:00
}
2015-09-01 03:49:47 +00:00
2017-07-19 20:00:46 +00:00
String path = ProjectSettings : : get_singleton ( ) - > localize_path ( p_path ) ;
2017-03-05 15:44:50 +00:00
Error err = ResourceSaver : : save ( path , p_resource , flg | ResourceSaver : : FLAG_REPLACE_SUBRESOURCE_PATHS ) ;
2015-09-01 03:49:47 +00:00
2017-03-05 15:44:50 +00:00
if ( err ! = OK ) {
2019-03-04 14:06:15 +00:00
if ( ResourceLoader : : is_imported ( p_resource - > get_path ( ) ) ) {
show_accept ( TTR ( " Imported resources can't be saved. " ) , TTR ( " OK " ) ) ;
} else {
show_accept ( TTR ( " Error saving resource! " ) , TTR ( " OK " ) ) ;
}
2017-03-05 15:44:50 +00:00
return ;
2015-09-01 03:49:47 +00:00
}
2017-03-05 15:44:50 +00:00
( ( Resource * ) p_resource . ptr ( ) ) - > set_path ( path ) ;
2021-07-17 21:22:52 +00:00
emit_signal ( SNAME ( " resource_saved " ) , p_resource ) ;
2018-01-12 21:43:29 +00:00
editor_data . notify_resource_saved ( p_resource ) ;
2015-09-01 03:49:47 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : save_resource ( const Ref < Resource > & p_resource ) {
2015-09-01 03:49:47 +00:00
if ( p_resource - > get_path ( ) . is_resource_file ( ) ) {
2017-03-05 15:44:50 +00:00
save_resource_in_path ( p_resource , p_resource - > get_path ( ) ) ;
2015-09-01 03:49:47 +00:00
} else {
save_resource_as ( p_resource ) ;
}
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : save_resource_as ( const Ref < Resource > & p_resource , const String & p_at_path ) {
2019-03-04 14:06:15 +00:00
{
String path = p_resource - > get_path ( ) ;
int srpos = path . find ( " :: " ) ;
if ( srpos ! = - 1 ) {
String base = path . substr ( 0 , srpos ) ;
2021-09-30 14:30:55 +00:00
if ( ! get_edited_scene ( ) | | get_edited_scene ( ) - > get_scene_file_path ( ) ! = base ) {
2019-03-04 14:06:15 +00:00
show_warning ( TTR ( " This resource can't be saved because it does not belong to the edited scene. Make it unique first. " ) ) ;
return ;
}
}
}
2020-03-06 17:00:16 +00:00
file - > set_file_mode ( EditorFileDialog : : FILE_MODE_SAVE_FILE ) ;
2018-11-18 14:17:04 +00:00
saving_resource = p_resource ;
2014-02-10 01:10:30 +00:00
2022-03-30 18:12:26 +00:00
current_menu_option = RESOURCE_SAVE_AS ;
2015-09-01 03:49:47 +00:00
List < String > extensions ;
2017-03-05 15:44:50 +00:00
Ref < PackedScene > sd = memnew ( PackedScene ) ;
ResourceSaver : : get_recognized_extensions ( p_resource , & extensions ) ;
2015-09-01 03:49:47 +00:00
file - > clear_filters ( ) ;
2015-12-31 16:12:27 +00:00
List < String > preferred ;
2021-07-24 13:46:25 +00:00
for ( const String & E : extensions ) {
2021-07-16 03:45:57 +00:00
if ( p_resource - > is_class ( " Script " ) & & ( E = = " tres " | | E = = " res " ) ) {
2022-03-30 18:12:26 +00:00
// This serves no purpose and confused people.
2015-12-31 16:12:27 +00:00
continue ;
}
2021-07-16 03:45:57 +00:00
file - > add_filter ( " *. " + E + " ; " + E . to_upper ( ) ) ;
preferred . push_back ( E ) ;
2020-12-13 01:37:23 +00:00
}
2022-03-30 18:12:26 +00:00
// Lowest priority extension.
2020-12-13 01:37:23 +00:00
List < String > : : Element * res_element = preferred . find ( " res " ) ;
if ( res_element ) {
preferred . move_to_back ( res_element ) ;
}
2022-03-30 18:12:26 +00:00
// Highest priority extension.
2020-12-13 01:37:23 +00:00
List < String > : : Element * tres_element = preferred . find ( " tres " ) ;
if ( tres_element ) {
preferred . move_to_front ( tres_element ) ;
2015-09-01 03:49:47 +00:00
}
2021-12-09 09:42:46 +00:00
if ( ! p_at_path . is_empty ( ) ) {
2016-05-11 14:46:08 +00:00
file - > set_current_dir ( p_at_path ) ;
if ( p_resource - > get_path ( ) . is_resource_file ( ) ) {
file - > set_current_file ( p_resource - > get_path ( ) . get_file ( ) ) ;
} else {
2017-03-05 15:44:50 +00:00
if ( extensions . size ( ) ) {
2021-07-30 00:42:07 +00:00
String resource_name_snake_case = p_resource - > get_class ( ) . camelcase_to_underscore ( ) ;
file - > set_current_file ( " new_ " + resource_name_snake_case + " . " + preferred . front ( ) - > get ( ) . to_lower ( ) ) ;
2016-05-11 14:46:08 +00:00
} else {
file - > set_current_file ( String ( ) ) ;
}
}
2021-12-09 09:42:46 +00:00
} else if ( ! p_resource - > get_path ( ) . is_empty ( ) ) {
2015-09-01 03:49:47 +00:00
file - > set_current_path ( p_resource - > get_path ( ) ) ;
if ( extensions . size ( ) ) {
2017-03-05 15:44:50 +00:00
String ext = p_resource - > get_path ( ) . get_extension ( ) . to_lower ( ) ;
2020-04-01 23:20:12 +00:00
if ( extensions . find ( ext ) = = nullptr ) {
2017-03-05 15:44:50 +00:00
file - > set_current_path ( p_resource - > get_path ( ) . replacen ( " . " + ext , " . " + extensions . front ( ) - > get ( ) ) ) ;
2015-09-01 03:49:47 +00:00
}
}
2015-12-31 16:12:27 +00:00
} else if ( preferred . size ( ) ) {
2015-09-01 03:49:47 +00:00
String existing ;
if ( extensions . size ( ) ) {
2021-07-30 00:42:07 +00:00
String resource_name_snake_case = p_resource - > get_class ( ) . camelcase_to_underscore ( ) ;
existing = " new_ " + resource_name_snake_case + " . " + preferred . front ( ) - > get ( ) . to_lower ( ) ;
2015-09-01 03:49:47 +00:00
}
file - > set_current_path ( existing ) ;
}
2018-04-22 17:36:01 +00:00
file - > set_title ( TTR ( " Save Resource As... " ) ) ;
2020-07-11 16:45:19 +00:00
file - > popup_file_dialog ( ) ;
2014-02-10 01:10:30 +00:00
}
void EditorNode : : _menu_option ( int p_option ) {
2017-03-05 15:44:50 +00:00
_menu_option_confirm ( p_option , false ) ;
2014-02-10 01:10:30 +00:00
}
void EditorNode : : _menu_confirm_current ( ) {
2022-03-30 18:12:26 +00:00
_menu_option_confirm ( current_menu_option , true ) ;
2014-02-10 01:10:30 +00:00
}
2017-08-28 03:24:50 +00:00
void EditorNode : : _dialog_display_save_error ( String p_file , Error p_error ) {
2014-02-10 01:10:30 +00:00
if ( p_error ) {
2017-03-05 15:44:50 +00:00
switch ( p_error ) {
2014-02-10 01:10:30 +00:00
case ERR_FILE_CANT_WRITE : {
2018-08-05 14:47:41 +00:00
show_accept ( TTR ( " Can't open file for writing: " ) + " " + p_file . get_extension ( ) , TTR ( " OK " ) ) ;
2014-02-10 01:10:30 +00:00
} break ;
case ERR_FILE_UNRECOGNIZED : {
2018-08-05 14:47:41 +00:00
show_accept ( TTR ( " Requested file format unknown: " ) + " " + p_file . get_extension ( ) , TTR ( " OK " ) ) ;
2014-02-10 01:10:30 +00:00
} break ;
default : {
2018-08-05 14:47:41 +00:00
show_accept ( TTR ( " Error while saving. " ) , TTR ( " OK " ) ) ;
2017-03-05 15:44:50 +00:00
} break ;
2014-02-10 01:10:30 +00:00
}
}
}
2017-08-28 03:24:50 +00:00
void EditorNode : : _dialog_display_load_error ( String p_file , Error p_error ) {
if ( p_error ) {
switch ( p_error ) {
case ERR_CANT_OPEN : {
2020-06-08 11:05:09 +00:00
show_accept ( vformat ( TTR ( " Can't open file '%s'. The file could have been moved or deleted. " ) , p_file . get_file ( ) ) , TTR ( " OK " ) ) ;
2017-08-28 03:24:50 +00:00
} break ;
case ERR_PARSE_ERROR : {
2020-06-08 11:05:09 +00:00
show_accept ( vformat ( TTR ( " Error while parsing file '%s'. " ) , p_file . get_file ( ) ) , TTR ( " OK " ) ) ;
2017-08-28 03:24:50 +00:00
} break ;
case ERR_FILE_CORRUPT : {
2020-06-08 11:05:09 +00:00
show_accept ( vformat ( TTR ( " Scene file '%s' appears to be invalid/corrupt. " ) , p_file . get_file ( ) ) , TTR ( " OK " ) ) ;
2017-08-28 03:24:50 +00:00
} break ;
case ERR_FILE_NOT_FOUND : {
2020-06-08 11:05:09 +00:00
show_accept ( vformat ( TTR ( " Missing file '%s' or one its dependencies. " ) , p_file . get_file ( ) ) , TTR ( " OK " ) ) ;
2017-08-28 03:24:50 +00:00
} break ;
default : {
2020-06-08 11:05:09 +00:00
show_accept ( vformat ( TTR ( " Error while loading file '%s'. " ) , p_file . get_file ( ) ) , TTR ( " OK " ) ) ;
2017-08-28 03:24:50 +00:00
} break ;
}
}
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _get_scene_metadata ( const String & p_file ) {
2015-06-22 03:03:19 +00:00
Node * scene = editor_data . get_edited_scene_root ( ) ;
2014-02-10 01:10:30 +00:00
2020-05-14 14:41:43 +00:00
if ( ! scene ) {
2014-02-10 01:10:30 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2017-11-17 14:50:18 +00:00
String path = EditorSettings : : get_singleton ( ) - > get_project_settings_dir ( ) . plus_file ( p_file . get_file ( ) + " -editstate- " + p_file . md5_text ( ) + " .cfg " ) ;
2014-02-10 01:10:30 +00:00
2015-12-31 03:31:00 +00:00
Ref < ConfigFile > cf ;
2021-06-17 22:03:09 +00:00
cf . instantiate ( ) ;
2014-02-10 01:10:30 +00:00
2015-12-31 03:31:00 +00:00
Error err = cf - > load ( path ) ;
2020-05-14 14:41:43 +00:00
if ( err ! = OK | | ! cf - > has_section ( " editor_states " ) ) {
2022-03-30 18:12:26 +00:00
// Must not exist.
return ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2015-12-31 03:31:00 +00:00
List < String > esl ;
2017-03-05 15:44:50 +00:00
cf - > get_section_keys ( " editor_states " , & esl ) ;
2014-02-10 01:10:30 +00:00
2015-12-31 03:31:00 +00:00
Dictionary md ;
2021-07-24 13:46:25 +00:00
for ( const String & E : esl ) {
2021-07-16 03:45:57 +00:00
Variant st = cf - > get_value ( " editor_states " , E ) ;
2019-07-20 06:09:57 +00:00
if ( st . get_type ( ) ! = Variant : : NIL ) {
2021-07-16 03:45:57 +00:00
md [ E ] = st ;
2015-12-31 03:31:00 +00:00
}
2014-02-10 01:10:30 +00:00
}
2015-12-31 03:31:00 +00:00
editor_data . set_editor_states ( md ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _set_scene_metadata ( const String & p_file , int p_idx ) {
2016-06-26 03:54:17 +00:00
Node * scene = editor_data . get_edited_scene_root ( p_idx ) ;
2014-02-10 01:10:30 +00:00
2020-05-14 14:41:43 +00:00
if ( ! scene ) {
2014-02-10 01:10:30 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2017-11-17 14:50:18 +00:00
String path = EditorSettings : : get_singleton ( ) - > get_project_settings_dir ( ) . plus_file ( p_file . get_file ( ) + " -editstate- " + p_file . md5_text ( ) + " .cfg " ) ;
2014-02-10 01:10:30 +00:00
2015-12-31 03:31:00 +00:00
Ref < ConfigFile > cf ;
2021-06-17 22:03:09 +00:00
cf . instantiate ( ) ;
2014-02-10 01:10:30 +00:00
2016-07-17 19:59:15 +00:00
Dictionary md ;
2017-03-05 15:44:50 +00:00
if ( p_idx < 0 | | editor_data . get_edited_scene ( ) = = p_idx ) {
2016-07-17 19:59:15 +00:00
md = editor_data . get_editor_states ( ) ;
} else {
md = editor_data . get_scene_editor_states ( p_idx ) ;
}
2015-12-31 03:31:00 +00:00
List < Variant > keys ;
md . get_key_list ( & keys ) ;
2014-02-10 01:10:30 +00:00
2021-07-24 13:46:25 +00:00
for ( const Variant & E : keys ) {
2021-07-16 03:45:57 +00:00
cf - > set_value ( " editor_states " , E , md [ E ] ) ;
2015-12-31 03:31:00 +00:00
}
2014-02-10 01:10:30 +00:00
2015-12-31 03:31:00 +00:00
Error err = cf - > save ( path ) ;
2019-09-25 08:28:50 +00:00
ERR_FAIL_COND_MSG ( err ! = OK , " Cannot save config file to ' " + path + " '. " ) ;
2014-02-10 01:10:30 +00:00
}
2022-05-13 13:04:37 +00:00
bool EditorNode : : _find_and_save_resource ( Ref < Resource > p_res , HashMap < Ref < Resource > , bool > & processed , int32_t flags ) {
2020-05-14 14:41:43 +00:00
if ( p_res . is_null ( ) ) {
2015-05-17 16:11:55 +00:00
return false ;
2020-05-14 14:41:43 +00:00
}
2015-05-17 16:11:55 +00:00
2017-08-12 16:52:50 +00:00
if ( processed . has ( p_res ) ) {
return processed [ p_res ] ;
2017-03-05 15:44:50 +00:00
}
2015-05-17 16:11:55 +00:00
2017-08-12 16:52:50 +00:00
bool changed = p_res - > is_edited ( ) ;
p_res - > set_edited ( false ) ;
2015-05-17 16:11:55 +00:00
2017-08-12 16:52:50 +00:00
bool subchanged = _find_and_save_edited_subresources ( p_res . ptr ( ) , processed , flags ) ;
2015-05-17 16:11:55 +00:00
2017-08-12 16:52:50 +00:00
if ( p_res - > get_path ( ) . is_resource_file ( ) ) {
2015-05-17 16:11:55 +00:00
if ( changed | | subchanged ) {
2017-08-12 16:52:50 +00:00
ResourceSaver : : save ( p_res - > get_path ( ) , p_res , flags ) ;
2015-05-17 16:11:55 +00:00
}
2022-03-30 18:12:26 +00:00
processed [ p_res ] = false ; // Because it's a file.
2015-05-17 16:11:55 +00:00
return false ;
} else {
2017-08-12 16:52:50 +00:00
processed [ p_res ] = changed ;
2015-05-17 16:11:55 +00:00
return changed ;
}
}
2022-05-13 13:04:37 +00:00
bool EditorNode : : _find_and_save_edited_subresources ( Object * obj , HashMap < Ref < Resource > , bool > & processed , int32_t flags ) {
2017-03-05 15:44:50 +00:00
bool ret_changed = false ;
2014-02-10 01:10:30 +00:00
List < PropertyInfo > pi ;
obj - > get_property_list ( & pi ) ;
2021-07-24 13:46:25 +00:00
for ( const PropertyInfo & E : pi ) {
2021-07-16 03:45:57 +00:00
if ( ! ( E . usage & PROPERTY_USAGE_STORAGE ) ) {
2014-02-10 01:10:30 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2021-07-16 03:45:57 +00:00
switch ( E . type ) {
2014-02-10 01:10:30 +00:00
case Variant : : OBJECT : {
2022-05-02 23:43:50 +00:00
Ref < Resource > res = obj - > get ( E . name ) ;
2014-02-10 01:10:30 +00:00
2020-05-14 14:41:43 +00:00
if ( _find_and_save_resource ( res , processed , flags ) ) {
2017-03-05 15:44:50 +00:00
ret_changed = true ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
} break ;
case Variant : : ARRAY : {
2021-07-16 03:45:57 +00:00
Array varray = obj - > get ( E . name ) ;
2017-03-05 15:44:50 +00:00
int len = varray . size ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
2019-12-10 04:13:02 +00:00
const Variant & v = varray . get ( i ) ;
2022-05-02 23:43:50 +00:00
Ref < Resource > res = v ;
2020-05-14 14:41:43 +00:00
if ( _find_and_save_resource ( res , processed , flags ) ) {
2017-03-05 15:44:50 +00:00
ret_changed = true ;
2020-05-14 14:41:43 +00:00
}
2015-05-17 16:11:55 +00:00
}
2014-02-10 01:10:30 +00:00
} break ;
case Variant : : DICTIONARY : {
2021-07-16 03:45:57 +00:00
Dictionary d = obj - > get ( E . name ) ;
2014-02-10 01:10:30 +00:00
List < Variant > keys ;
d . get_key_list ( & keys ) ;
2021-07-24 13:46:25 +00:00
for ( const Variant & F : keys ) {
2021-07-16 03:45:57 +00:00
Variant v = d [ F ] ;
2022-05-02 23:43:50 +00:00
Ref < Resource > res = v ;
2020-05-14 14:41:43 +00:00
if ( _find_and_save_resource ( res , processed , flags ) ) {
2017-03-05 15:44:50 +00:00
ret_changed = true ;
2020-05-14 14:41:43 +00:00
}
2015-05-17 16:11:55 +00:00
}
2014-02-10 01:10:30 +00:00
} break ;
2019-04-09 15:08:36 +00:00
default : {
}
2014-02-10 01:10:30 +00:00
}
}
return ret_changed ;
}
2022-05-13 13:04:37 +00:00
void EditorNode : : _save_edited_subresources ( Node * scene , HashMap < Ref < Resource > , bool > & processed , int32_t flags ) {
2017-03-05 15:44:50 +00:00
_find_and_save_edited_subresources ( scene , processed , flags ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < scene - > get_child_count ( ) ; i + + ) {
2014-02-10 01:10:30 +00:00
Node * n = scene - > get_child ( i ) ;
2020-05-14 14:41:43 +00:00
if ( n - > get_owner ( ) ! = editor_data . get_edited_scene_root ( ) ) {
2014-02-10 01:10:30 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2017-03-05 15:44:50 +00:00
_save_edited_subresources ( n , processed , flags ) ;
2014-02-10 01:10:30 +00:00
}
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _find_node_types ( Node * p_node , int & count_2d , int & count_3d ) {
2020-05-14 14:41:43 +00:00
if ( p_node - > is_class ( " Viewport " ) | | ( p_node ! = editor_data . get_edited_scene_root ( ) & & p_node - > get_owner ( ) ! = editor_data . get_edited_scene_root ( ) ) ) {
2015-05-31 04:59:42 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2015-05-31 04:59:42 +00:00
2020-05-14 14:41:43 +00:00
if ( p_node - > is_class ( " CanvasItem " ) ) {
2015-05-31 04:59:42 +00:00
count_2d + + ;
2020-05-14 14:41:43 +00:00
} else if ( p_node - > is_class ( " Node3D " ) ) {
2015-05-31 04:59:42 +00:00
count_3d + + ;
2020-05-14 14:41:43 +00:00
}
2015-05-31 04:59:42 +00:00
2020-05-14 14:41:43 +00:00
for ( int i = 0 ; i < p_node - > get_child_count ( ) ; i + + ) {
2017-03-05 15:44:50 +00:00
_find_node_types ( p_node - > get_child ( i ) , count_2d , count_3d ) ;
2020-05-14 14:41:43 +00:00
}
2015-05-31 04:59:42 +00:00
}
2017-11-12 03:48:00 +00:00
void EditorNode : : _save_scene_with_preview ( String p_file , int p_idx ) {
2017-03-05 15:44:50 +00:00
EditorProgress save ( " save " , TTR ( " Saving Scene " ) , 4 ) ;
2017-08-26 15:46:49 +00:00
2020-04-01 23:20:12 +00:00
if ( editor_data . get_edited_scene_root ( ) ! = nullptr ) {
2019-12-26 08:15:36 +00:00
save . step ( TTR ( " Analyzing " ) , 0 ) ;
2015-05-31 04:59:42 +00:00
2019-12-26 08:15:36 +00:00
int c2d = 0 ;
int c3d = 0 ;
2017-06-09 03:23:50 +00:00
2019-12-26 08:15:36 +00:00
_find_node_types ( editor_data . get_edited_scene_root ( ) , c2d , c3d ) ;
2015-05-31 04:59:42 +00:00
2019-12-26 08:15:36 +00:00
save . step ( TTR ( " Creating Thumbnail " ) , 1 ) ;
2022-03-30 18:12:26 +00:00
// Current view?
2019-01-27 16:39:16 +00:00
2019-12-26 08:15:36 +00:00
Ref < Image > img ;
2020-07-06 15:55:07 +00:00
// If neither 3D or 2D nodes are present, make a 1x1 black texture.
// We cannot fallback on the 2D editor, because it may not have been used yet,
// which would result in an invalid texture.
if ( c3d = = 0 & & c2d = = 0 ) {
2021-06-17 22:03:09 +00:00
img . instantiate ( ) ;
2021-04-05 11:16:16 +00:00
img - > create ( 1 , 1 , false , Image : : FORMAT_RGB8 ) ;
2020-07-06 15:55:07 +00:00
} else if ( c3d < c2d ) {
2020-07-27 13:49:56 +00:00
Ref < ViewportTexture > viewport_texture = scene_root - > get_texture ( ) ;
if ( viewport_texture - > get_width ( ) > 0 & & viewport_texture - > get_height ( ) > 0 ) {
2021-03-28 11:32:17 +00:00
img = viewport_texture - > get_image ( ) ;
2020-07-27 13:49:56 +00:00
}
2019-12-26 08:15:36 +00:00
} else {
2020-07-06 15:55:07 +00:00
// The 3D editor may be disabled as a feature, but scenes can still be opened.
// This check prevents the preview from regenerating in case those scenes are then saved.
2021-03-19 19:54:29 +00:00
// The preview will be generated if no feature profile is set (as the 3D editor is enabled by default).
2020-07-06 15:55:07 +00:00
Ref < EditorFeatureProfile > profile = feature_profile_manager - > get_current_profile ( ) ;
2021-03-19 19:54:29 +00:00
if ( ! profile . is_valid ( ) | | ! profile - > is_feature_disabled ( EditorFeatureProfile : : FEATURE_3D ) ) {
2021-03-28 11:32:17 +00:00
img = Node3DEditor : : get_singleton ( ) - > get_editor_viewport ( 0 ) - > get_viewport_node ( ) - > get_texture ( ) - > get_image ( ) ;
2020-07-06 15:55:07 +00:00
}
2019-12-26 08:15:36 +00:00
}
2019-01-27 16:39:16 +00:00
2020-07-27 13:49:56 +00:00
if ( img . is_valid ( ) & & img - > get_width ( ) > 0 & & img - > get_height ( ) > 0 ) {
2019-12-26 08:15:36 +00:00
img = img - > duplicate ( ) ;
2015-05-31 04:59:42 +00:00
2019-12-26 08:15:36 +00:00
save . step ( TTR ( " Creating Thumbnail " ) , 2 ) ;
save . step ( TTR ( " Creating Thumbnail " ) , 3 ) ;
2015-05-31 04:59:42 +00:00
2019-12-26 08:15:36 +00:00
int preview_size = EditorSettings : : get_singleton ( ) - > get ( " filesystem/file_dialog/thumbnail_size " ) ;
preview_size * = EDSCALE ;
2015-05-31 04:59:42 +00:00
2022-03-30 18:12:26 +00:00
// Consider a square region.
2019-12-26 08:15:36 +00:00
int vp_size = MIN ( img - > get_width ( ) , img - > get_height ( ) ) ;
int x = ( img - > get_width ( ) - vp_size ) / 2 ;
int y = ( img - > get_height ( ) - vp_size ) / 2 ;
2017-11-18 03:42:14 +00:00
2019-12-26 08:15:36 +00:00
if ( vp_size < preview_size ) {
2022-03-30 18:12:26 +00:00
// Just square it.
2019-12-26 08:15:36 +00:00
img - > crop_from_point ( x , y , vp_size , vp_size ) ;
} else {
int ratio = vp_size / preview_size ;
int size = preview_size * MAX ( 1 , ratio / 2 ) ;
2015-05-31 04:59:42 +00:00
2019-12-26 08:15:36 +00:00
x = ( img - > get_width ( ) - size ) / 2 ;
y = ( img - > get_height ( ) - size ) / 2 ;
2015-05-31 04:59:42 +00:00
2019-12-26 08:15:36 +00:00
img - > crop_from_point ( x , y , size , size ) ;
img - > resize ( preview_size , preview_size , Image : : INTERPOLATE_LANCZOS ) ;
}
img - > convert ( Image : : FORMAT_RGB8 ) ;
2015-05-31 04:59:42 +00:00
2022-03-30 18:12:26 +00:00
// Save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5.
2021-05-25 00:25:11 +00:00
String temp_path = EditorPaths : : get_singleton ( ) - > get_cache_dir ( ) ;
2019-12-26 08:15:36 +00:00
String cache_base = ProjectSettings : : get_singleton ( ) - > globalize_path ( p_file ) . md5_text ( ) ;
cache_base = temp_path . plus_file ( " resthumb- " + cache_base ) ;
2017-06-09 03:23:50 +00:00
2022-03-30 18:12:26 +00:00
// Does not have it, try to load a cached thumbnail.
2019-12-26 08:15:36 +00:00
String file = cache_base + " .png " ;
post_process_preview ( img ) ;
img - > save_png ( file ) ;
}
2015-05-31 04:59:42 +00:00
}
2017-06-09 03:23:50 +00:00
2017-03-05 15:44:50 +00:00
save . step ( TTR ( " Saving Scene " ) , 4 ) ;
2017-11-12 03:48:00 +00:00
_save_scene ( p_file , p_idx ) ;
2020-01-14 10:32:15 +00:00
if ( ! singleton - > cmdline_export_mode ) {
EditorResourcePreview : : get_singleton ( ) - > check_for_invalidation ( p_file ) ;
}
2015-05-31 04:59:42 +00:00
}
2018-11-27 21:56:31 +00:00
bool EditorNode : : _validate_scene_recursive ( const String & p_filename , Node * p_node ) {
for ( int i = 0 ; i < p_node - > get_child_count ( ) ; i + + ) {
Node * child = p_node - > get_child ( i ) ;
2021-09-30 14:30:55 +00:00
if ( child - > get_scene_file_path ( ) = = p_filename ) {
2018-11-27 21:56:31 +00:00
return true ;
}
if ( _validate_scene_recursive ( p_filename , child ) ) {
return true ;
}
}
return false ;
}
2022-05-19 15:00:06 +00:00
static bool _find_edited_resources ( const Ref < Resource > & p_resource , HashSet < Ref < Resource > > & edited_resources ) {
2019-02-27 02:48:30 +00:00
if ( p_resource - > is_edited ( ) ) {
edited_resources . insert ( p_resource ) ;
return true ;
}
List < PropertyInfo > plist ;
p_resource - > get_property_list ( & plist ) ;
2021-07-24 13:46:25 +00:00
for ( const PropertyInfo & E : plist ) {
2021-07-16 03:45:57 +00:00
if ( E . type = = Variant : : OBJECT & & E . usage & PROPERTY_USAGE_STORAGE & & ! ( E . usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT ) ) {
2022-05-02 23:43:50 +00:00
Ref < Resource > res = p_resource - > get ( E . name ) ;
2019-02-27 02:48:30 +00:00
if ( res . is_null ( ) ) {
continue ;
}
2022-03-30 18:12:26 +00:00
if ( res - > get_path ( ) . is_resource_file ( ) ) { // Not a subresource, continue.
2019-02-27 02:48:30 +00:00
continue ;
}
if ( _find_edited_resources ( res , edited_resources ) ) {
return true ;
}
}
}
return false ;
}
2019-02-27 23:00:40 +00:00
int EditorNode : : _save_external_resources ( ) {
2022-03-30 18:12:26 +00:00
// Save external resources and its subresources if any was modified.
2019-02-27 23:00:40 +00:00
int flg = 0 ;
2020-05-14 14:41:43 +00:00
if ( EditorSettings : : get_singleton ( ) - > get ( " filesystem/on_save/compress_binary_resources " ) ) {
2019-02-27 23:00:40 +00:00
flg | = ResourceSaver : : FLAG_COMPRESS ;
2020-05-14 14:41:43 +00:00
}
2019-02-27 23:00:40 +00:00
flg | = ResourceSaver : : FLAG_REPLACE_SUBRESOURCE_PATHS ;
2022-05-19 15:00:06 +00:00
HashSet < Ref < Resource > > edited_subresources ;
2019-02-27 23:00:40 +00:00
int saved = 0 ;
2020-03-17 06:33:00 +00:00
List < Ref < Resource > > cached ;
2019-02-27 23:00:40 +00:00
ResourceCache : : get_cached_resources ( & cached ) ;
2021-07-26 15:50:35 +00:00
for ( const Ref < Resource > & res : cached ) {
2020-05-14 14:41:43 +00:00
if ( ! res - > get_path ( ) . is_resource_file ( ) ) {
2019-02-27 23:00:40 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2021-10-17 16:55:44 +00:00
// not only check if this resource is edited, check contained subresources too
2019-02-27 23:00:40 +00:00
if ( _find_edited_resources ( res , edited_subresources ) ) {
ResourceSaver : : save ( res - > get_path ( ) , res , flg ) ;
saved + + ;
}
}
2022-03-30 18:12:26 +00:00
// Clear later, because user may have put the same subresource in two different resources,
// which will be shared until the next reload.
2019-02-27 23:00:40 +00:00
2022-05-18 23:43:40 +00:00
for ( const Ref < Resource > & E : edited_subresources ) {
Ref < Resource > res = E ;
2019-02-27 23:00:40 +00:00
res - > set_edited ( false ) ;
}
return saved ;
}
2020-12-20 10:46:44 +00:00
static void _reset_animation_players ( Node * p_node , List < Ref < AnimatedValuesBackup > > * r_anim_backups ) {
for ( int i = 0 ; i < p_node - > get_child_count ( ) ; i + + ) {
AnimationPlayer * player = Object : : cast_to < AnimationPlayer > ( p_node - > get_child ( i ) ) ;
if ( player & & player - > is_reset_on_save_enabled ( ) & & player - > can_apply_reset ( ) ) {
Ref < AnimatedValuesBackup > old_values = player - > apply_reset ( ) ;
2021-08-12 02:53:35 +00:00
if ( old_values . is_valid ( ) ) {
r_anim_backups - > push_back ( old_values ) ;
}
2020-12-20 10:46:44 +00:00
}
_reset_animation_players ( p_node - > get_child ( i ) , r_anim_backups ) ;
}
}
2016-06-26 03:54:17 +00:00
void EditorNode : : _save_scene ( String p_file , int idx ) {
Node * scene = editor_data . get_edited_scene_root ( idx ) ;
2014-02-10 01:10:30 +00:00
if ( ! scene ) {
2018-08-05 14:47:41 +00:00
show_accept ( TTR ( " This operation can't be done without a tree root. " ) , TTR ( " OK " ) ) ;
2014-02-10 01:10:30 +00:00
return ;
}
2021-12-09 09:42:46 +00:00
if ( ! scene - > get_scene_file_path ( ) . is_empty ( ) & & _validate_scene_recursive ( scene - > get_scene_file_path ( ) , scene ) ) {
2018-11-27 21:56:31 +00:00
show_accept ( TTR ( " This scene can't be saved because there is a cyclic instancing inclusion. \n Please resolve it and then attempt to save again. " ) , TTR ( " OK " ) ) ;
return ;
}
New and improved IK system for Skeleton2D
This PR and commit adds a new IK system for 2D with the Skeleton2D node
that adds several new IK solvers, a way to control bones in a Skeleton2D
node similar to that in Skeleton3D. It also adds additional changes
and functionality.
This work was sponsored by GSoC 2020 and TwistedTwigleg.
Full list of changes:
* Adds a SkeletonModifier2D resource
* This resource is the base where all IK code is written and executed
* Has a function for clamping angles, since it is so commonly used
* Modifiers are unique when duplicated so it works with instancing
* Adds a SkeletonModifierStack2D resource
* This resource manages a series of SkeletonModification2Ds
* This is what the Skeleton2D directly interfaces with to make IK possible
* Adds SkeletonModifier2D resources for LookAt, CCDIK, FABRIK, Jiggle, and TwoBoneIK
* Each modification is in its own file
* There is also a SkeletonModifier2D resource that acts as a stack for using multiple stacks together
* Adds a PhysicalBone2D node
* Works similar to the PhysicalBone3D node, but uses a RigidBody2D node
* Changes to Skeleton2D listed below:
* Skeleton2D now holds a single SkeletonModificationStack2D for IK
* Skeleton2D now has a local_pose_override, which overrides the Bone2D position similar to how the overrides work in Skeleton3D
* Changes to Bone2D listed below:
* The default_length property has been changed to length. Length is the length of the bone to its child bone node
* New bone_angle property, which is the angle the bone has to its first child bone node
* Bone2D caches its transform when not modified by IK for IK interpolation purposes
* Bone2D draws its own editor gizmo, though this is stated to change in the future
* Changes to CanvasItemEditor listed below:
* Bone2D gizmo drawing code removed
* The 2D IK code is removed. Now Bone2D is the only bone system for 2D
* Transform2D now has a looking_at function for rotating to face a position
* Two new node notifications: NOTIFICATION_EDITOR_PRE_SAVE and NOTIFICATION_EDITOR_POST_SAVE
* These notifications only are called in the editor right before and after saving a scene
* Needed for not saving the IK position when executing IK in the editor
* Documentation for all the changes listed above.
2020-08-03 18:02:24 +00:00
scene - > propagate_notification ( NOTIFICATION_EDITOR_PRE_SAVE ) ;
2014-02-10 01:10:30 +00:00
editor_data . apply_changes_in_editors ( ) ;
2020-12-20 10:46:44 +00:00
List < Ref < AnimatedValuesBackup > > anim_backups ;
_reset_animation_players ( scene , & anim_backups ) ;
2017-05-29 00:46:48 +00:00
_save_default_environment ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
_set_scene_metadata ( p_file , idx ) ;
2015-12-13 23:39:01 +00:00
Ref < PackedScene > sdata ;
if ( ResourceCache : : has ( p_file ) ) {
2022-03-30 18:12:26 +00:00
// Something may be referencing this resource and we are good with that.
// We must update it, but also let the previous scene state go, as
// old version still work for referencing changes in instantiated or inherited scenes.
2015-12-13 23:39:01 +00:00
2017-08-24 20:58:51 +00:00
sdata = Ref < PackedScene > ( Object : : cast_to < PackedScene > ( ResourceCache : : get ( p_file ) ) ) ;
2020-05-14 14:41:43 +00:00
if ( sdata . is_valid ( ) ) {
2015-12-13 23:39:01 +00:00
sdata - > recreate_state ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2021-06-17 22:03:09 +00:00
sdata . instantiate ( ) ;
2020-05-14 14:41:43 +00:00
}
2015-12-13 23:39:01 +00:00
} else {
2021-06-17 22:03:09 +00:00
sdata . instantiate ( ) ;
2015-12-13 23:39:01 +00:00
}
2014-02-10 01:10:30 +00:00
Error err = sdata - > pack ( scene ) ;
2017-03-05 15:44:50 +00:00
if ( err ! = OK ) {
2018-08-05 14:47:41 +00:00
show_accept ( TTR ( " Couldn't save scene. Likely dependencies (instances or inheritance) couldn't be satisfied. " ) , TTR ( " OK " ) ) ;
2014-02-10 01:10:30 +00:00
return ;
}
2017-03-05 15:44:50 +00:00
int flg = 0 ;
2020-05-14 14:41:43 +00:00
if ( EditorSettings : : get_singleton ( ) - > get ( " filesystem/on_save/compress_binary_resources " ) ) {
2017-03-05 15:44:50 +00:00
flg | = ResourceSaver : : FLAG_COMPRESS ;
2020-05-14 14:41:43 +00:00
}
2017-03-05 15:44:50 +00:00
flg | = ResourceSaver : : FLAG_REPLACE_SUBRESOURCE_PATHS ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
err = ResourceSaver : : save ( p_file , sdata , flg ) ;
2019-02-27 02:48:30 +00:00
2021-11-06 01:15:19 +00:00
// This needs to be emitted before saving external resources.
emit_signal ( SNAME ( " scene_saved " ) , p_file ) ;
2018-07-01 20:44:15 +00:00
2021-11-06 01:15:19 +00:00
_save_external_resources ( ) ;
2014-02-10 01:10:30 +00:00
editor_data . save_editor_external_data ( ) ;
2020-12-20 10:46:44 +00:00
2021-07-26 15:50:35 +00:00
for ( Ref < AnimatedValuesBackup > & E : anim_backups ) {
2021-07-16 03:45:57 +00:00
E - > restore ( ) ;
2020-12-20 10:46:44 +00:00
}
2017-03-05 15:44:50 +00:00
if ( err = = OK ) {
2021-09-30 14:30:55 +00:00
scene - > set_scene_file_path ( ProjectSettings : : get_singleton ( ) - > localize_path ( p_file ) ) ;
2020-05-14 14:41:43 +00:00
if ( idx < 0 | | idx = = editor_data . get_edited_scene ( ) ) {
2016-06-26 03:54:17 +00:00
set_current_version ( editor_data . get_undo_redo ( ) . get_version ( ) ) ;
2020-05-14 14:41:43 +00:00
} else {
2017-03-05 15:44:50 +00:00
editor_data . set_edited_scene_version ( 0 , idx ) ;
2020-05-14 14:41:43 +00:00
}
2019-08-28 17:42:27 +00:00
editor_data . set_scene_modified_time ( idx , FileAccess : : get_modified_time ( p_file ) ) ;
2018-10-29 19:36:31 +00:00
editor_folding . save_scene_folding ( scene , p_file ) ;
2014-02-10 01:10:30 +00:00
_update_title ( ) ;
2015-08-12 20:35:37 +00:00
_update_scene_tabs ( ) ;
2014-02-10 01:10:30 +00:00
} else {
2017-08-28 03:24:50 +00:00
_dialog_display_save_error ( p_file , err ) ;
2014-02-10 01:10:30 +00:00
}
New and improved IK system for Skeleton2D
This PR and commit adds a new IK system for 2D with the Skeleton2D node
that adds several new IK solvers, a way to control bones in a Skeleton2D
node similar to that in Skeleton3D. It also adds additional changes
and functionality.
This work was sponsored by GSoC 2020 and TwistedTwigleg.
Full list of changes:
* Adds a SkeletonModifier2D resource
* This resource is the base where all IK code is written and executed
* Has a function for clamping angles, since it is so commonly used
* Modifiers are unique when duplicated so it works with instancing
* Adds a SkeletonModifierStack2D resource
* This resource manages a series of SkeletonModification2Ds
* This is what the Skeleton2D directly interfaces with to make IK possible
* Adds SkeletonModifier2D resources for LookAt, CCDIK, FABRIK, Jiggle, and TwoBoneIK
* Each modification is in its own file
* There is also a SkeletonModifier2D resource that acts as a stack for using multiple stacks together
* Adds a PhysicalBone2D node
* Works similar to the PhysicalBone3D node, but uses a RigidBody2D node
* Changes to Skeleton2D listed below:
* Skeleton2D now holds a single SkeletonModificationStack2D for IK
* Skeleton2D now has a local_pose_override, which overrides the Bone2D position similar to how the overrides work in Skeleton3D
* Changes to Bone2D listed below:
* The default_length property has been changed to length. Length is the length of the bone to its child bone node
* New bone_angle property, which is the angle the bone has to its first child bone node
* Bone2D caches its transform when not modified by IK for IK interpolation purposes
* Bone2D draws its own editor gizmo, though this is stated to change in the future
* Changes to CanvasItemEditor listed below:
* Bone2D gizmo drawing code removed
* The 2D IK code is removed. Now Bone2D is the only bone system for 2D
* Transform2D now has a looking_at function for rotating to face a position
* Two new node notifications: NOTIFICATION_EDITOR_PRE_SAVE and NOTIFICATION_EDITOR_POST_SAVE
* These notifications only are called in the editor right before and after saving a scene
* Needed for not saving the IK position when executing IK in the editor
* Documentation for all the changes listed above.
2020-08-03 18:02:24 +00:00
scene - > propagate_notification ( NOTIFICATION_EDITOR_POST_SAVE ) ;
2017-05-29 00:46:48 +00:00
}
2014-02-10 01:10:30 +00:00
2019-01-25 20:23:56 +00:00
void EditorNode : : save_all_scenes ( ) {
2018-07-19 21:58:15 +00:00
_menu_option_confirm ( RUN_STOP , true ) ;
_save_all_scenes ( ) ;
2019-01-25 20:23:56 +00:00
}
2019-06-04 03:36:23 +00:00
void EditorNode : : save_scene_list ( Vector < String > p_scene_filenames ) {
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
Node * scene = editor_data . get_edited_scene_root ( i ) ;
2021-09-30 14:30:55 +00:00
if ( scene & & ( p_scene_filenames . find ( scene - > get_scene_file_path ( ) ) > = 0 ) ) {
_save_scene ( scene - > get_scene_file_path ( ) , i ) ;
2019-06-04 03:36:23 +00:00
}
}
}
2019-01-25 20:23:56 +00:00
void EditorNode : : restart_editor ( ) {
exiting = true ;
2018-07-19 21:58:15 +00:00
String to_reopen ;
if ( get_tree ( ) - > get_edited_scene_root ( ) ) {
2021-09-30 14:30:55 +00:00
to_reopen = get_tree ( ) - > get_edited_scene_root ( ) - > get_scene_file_path ( ) ;
2018-07-19 21:58:15 +00:00
}
2022-01-18 11:48:12 +00:00
_exit_editor ( EXIT_SUCCESS ) ;
2018-07-19 21:58:15 +00:00
List < String > args ;
args . push_back ( " --path " ) ;
args . push_back ( ProjectSettings : : get_singleton ( ) - > get_resource_path ( ) ) ;
args . push_back ( " -e " ) ;
2021-12-09 09:42:46 +00:00
if ( ! to_reopen . is_empty ( ) ) {
2018-07-19 21:58:15 +00:00
args . push_back ( to_reopen ) ;
}
OS : : get_singleton ( ) - > set_restart_on_exit ( true , args ) ;
}
2017-06-24 10:57:30 +00:00
void EditorNode : : _save_all_scenes ( ) {
2021-10-12 10:14:02 +00:00
bool all_saved = true ;
2018-06-29 06:38:15 +00:00
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
2017-06-24 10:57:30 +00:00
Node * scene = editor_data . get_edited_scene_root ( i ) ;
2021-10-12 10:14:02 +00:00
if ( scene ) {
2021-12-09 09:42:46 +00:00
if ( ! scene - > get_scene_file_path ( ) . is_empty ( ) & & DirAccess : : exists ( scene - > get_scene_file_path ( ) . get_base_dir ( ) ) ) {
2021-10-12 10:14:02 +00:00
if ( i ! = editor_data . get_edited_scene ( ) ) {
_save_scene ( scene - > get_scene_file_path ( ) , i ) ;
} else {
_save_scene_with_preview ( scene - > get_scene_file_path ( ) ) ;
}
2021-12-09 09:42:46 +00:00
} else if ( ! scene - > get_scene_file_path ( ) . is_empty ( ) ) {
2021-10-12 10:14:02 +00:00
all_saved = false ;
2020-05-14 14:41:43 +00:00
}
2021-09-11 01:35:13 +00:00
}
2017-06-24 10:57:30 +00:00
}
2021-10-12 10:14:02 +00:00
if ( ! all_saved ) {
show_warning ( TTR ( " Could not save one or more scenes! " ) , TTR ( " Save All Scenes " ) ) ;
}
2017-06-24 10:57:30 +00:00
_save_default_environment ( ) ;
}
2017-06-29 17:37:54 +00:00
void EditorNode : : _mark_unsaved_scenes ( ) {
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
Node * node = editor_data . get_edited_scene_root ( i ) ;
2020-05-14 14:41:43 +00:00
if ( ! node ) {
2017-06-29 17:37:54 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2017-06-29 17:37:54 +00:00
2021-09-30 14:30:55 +00:00
String path = node - > get_scene_file_path ( ) ;
2021-12-09 09:42:46 +00:00
if ( ! ( path . is_empty ( ) | | FileAccess : : exists ( path ) ) ) {
2020-05-14 14:41:43 +00:00
if ( i = = editor_data . get_edited_scene ( ) ) {
2017-06-29 17:37:54 +00:00
set_current_version ( - 1 ) ;
2020-05-14 14:41:43 +00:00
} else {
2017-06-29 17:37:54 +00:00
editor_data . set_edited_scene_version ( - 1 , i ) ;
2020-05-14 14:41:43 +00:00
}
2017-06-29 17:37:54 +00:00
}
}
_update_title ( ) ;
_update_scene_tabs ( ) ;
}
2014-02-10 01:10:30 +00:00
void EditorNode : : _dialog_action ( String p_file ) {
2022-03-30 18:12:26 +00:00
switch ( current_menu_option ) {
2015-10-10 12:09:09 +00:00
case FILE_NEW_INHERITED_SCENE : {
2019-05-08 06:12:39 +00:00
Node * scene = editor_data . get_edited_scene_root ( ) ;
// If the previous scene is rootless, just close it in favor of the new one.
2020-05-14 14:41:43 +00:00
if ( ! scene ) {
2019-05-31 00:08:37 +00:00
_menu_option_confirm ( FILE_CLOSE , true ) ;
2020-05-14 14:41:43 +00:00
}
2019-05-08 06:12:39 +00:00
2017-03-05 15:44:50 +00:00
load_scene ( p_file , false , true ) ;
2015-10-10 12:09:09 +00:00
} break ;
2014-02-10 01:10:30 +00:00
case FILE_OPEN_SCENE : {
load_scene ( p_file ) ;
} break ;
2016-06-27 22:59:33 +00:00
case SETTINGS_PICK_MAIN_SCENE : {
2017-07-19 20:00:46 +00:00
ProjectSettings : : get_singleton ( ) - > set ( " application/run/main_scene " , p_file ) ;
ProjectSettings : : get_singleton ( ) - > save ( ) ;
2022-03-30 18:12:26 +00:00
// TODO: Would be nice to show the project manager opened with the highlighted field.
2019-03-22 01:08:28 +00:00
2022-04-01 18:30:23 +00:00
if ( ( bool ) pick_main_scene - > get_meta ( " from_native " , false ) ) {
2019-03-22 01:08:28 +00:00
run_native - > resume_run_native ( ) ;
} else {
2022-03-30 18:12:26 +00:00
_run ( false , " " ) ; // Automatically run the project.
2019-03-22 01:08:28 +00:00
}
2014-02-10 01:10:30 +00:00
} break ;
2017-06-21 04:15:39 +00:00
case FILE_CLOSE :
2017-06-26 14:04:53 +00:00
case FILE_CLOSE_ALL_AND_QUIT :
case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER :
2022-03-23 11:07:29 +00:00
case FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT :
2017-06-21 04:15:39 +00:00
case SCENE_TAB_CLOSE :
2014-02-10 01:10:30 +00:00
case FILE_SAVE_SCENE :
case FILE_SAVE_AS_SCENE : {
2022-03-30 18:12:26 +00:00
int scene_idx = ( current_menu_option = = FILE_SAVE_SCENE | | current_menu_option = = FILE_SAVE_AS_SCENE ) ? - 1 : tab_closing_idx ;
2017-06-21 04:15:39 +00:00
2020-03-06 17:00:16 +00:00
if ( file - > get_file_mode ( ) = = EditorFileDialog : : FILE_MODE_SAVE_FILE ) {
2018-09-07 13:54:26 +00:00
bool same_open_scene = false ;
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
2020-05-14 14:41:43 +00:00
if ( editor_data . get_scene_path ( i ) = = p_file & & i ! = scene_idx ) {
2018-09-07 13:54:26 +00:00
same_open_scene = true ;
2020-05-14 14:41:43 +00:00
}
2018-09-07 13:54:26 +00:00
}
if ( same_open_scene ) {
show_warning ( TTR ( " Can't overwrite scene that is still open! " ) ) ;
return ;
}
2014-02-10 01:10:30 +00:00
2017-05-29 00:46:48 +00:00
_save_default_environment ( ) ;
2017-11-12 03:48:00 +00:00
_save_scene_with_preview ( p_file , scene_idx ) ;
2018-01-09 12:42:45 +00:00
_add_to_recent_scenes ( p_file ) ;
2019-04-15 20:17:49 +00:00
save_layout ( ) ;
2017-06-21 04:15:39 +00:00
2020-05-14 14:41:43 +00:00
if ( scene_idx ! = - 1 ) {
2017-06-21 04:15:39 +00:00
_discard_changes ( ) ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
}
} break ;
2015-01-06 22:28:25 +00:00
case FILE_SAVE_AND_RUN : {
2020-03-06 17:00:16 +00:00
if ( file - > get_file_mode ( ) = = EditorFileDialog : : FILE_MODE_SAVE_FILE ) {
2017-05-29 00:46:48 +00:00
_save_default_environment ( ) ;
2015-05-31 04:59:42 +00:00
_save_scene_with_preview ( p_file ) ;
2017-11-19 21:59:05 +00:00
_run ( false , p_file ) ;
2015-01-06 22:28:25 +00:00
}
} break ;
2014-02-10 01:10:30 +00:00
case FILE_EXPORT_MESH_LIBRARY : {
Ref < MeshLibrary > ml ;
if ( file_export_lib_merge - > is_pressed ( ) & & FileAccess : : exists ( p_file ) ) {
2017-03-05 15:44:50 +00:00
ml = ResourceLoader : : load ( p_file , " MeshLibrary " ) ;
2014-02-10 01:10:30 +00:00
if ( ml . is_null ( ) ) {
2018-08-05 14:47:41 +00:00
show_accept ( TTR ( " Can't load MeshLibrary for merging! " ) , TTR ( " OK " ) ) ;
2014-02-10 01:10:30 +00:00
return ;
}
}
if ( ml . is_null ( ) ) {
2017-03-05 15:44:50 +00:00
ml = Ref < MeshLibrary > ( memnew ( MeshLibrary ) ) ;
2014-02-10 01:10:30 +00:00
}
2021-08-31 23:17:33 +00:00
MeshLibraryEditor : : update_library_file ( editor_data . get_edited_scene_root ( ) , ml , true , file_export_lib_apply_xforms - > is_pressed ( ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
Error err = ResourceSaver : : save ( p_file , ml ) ;
2014-02-10 01:10:30 +00:00
if ( err ) {
2018-08-05 14:47:41 +00:00
show_accept ( TTR ( " Error saving MeshLibrary! " ) , TTR ( " OK " ) ) ;
2014-02-10 01:10:30 +00:00
return ;
}
} break ;
2015-09-01 03:49:47 +00:00
case RESOURCE_SAVE :
case RESOURCE_SAVE_AS : {
2019-06-11 12:49:34 +00:00
ERR_FAIL_COND ( saving_resource . is_null ( ) ) ;
2018-11-18 14:17:04 +00:00
save_resource_in_path ( saving_resource , p_file ) ;
saving_resource = Ref < Resource > ( ) ;
ObjectID current = editor_history . get_current ( ) ;
2020-04-01 23:20:12 +00:00
Object * current_obj = current . is_valid ( ) ? ObjectDB : : get_instance ( current ) : nullptr ;
2018-11-18 14:17:04 +00:00
ERR_FAIL_COND ( ! current_obj ) ;
2021-02-10 20:18:45 +00:00
current_obj - > notify_property_list_changed ( ) ;
2015-11-22 18:11:17 +00:00
} break ;
case SETTINGS_LAYOUT_SAVE : {
2020-12-15 12:04:21 +00:00
if ( p_file . is_empty ( ) ) {
2015-11-22 18:11:17 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2015-11-22 18:11:17 +00:00
Ref < ConfigFile > config ;
2021-06-17 22:03:09 +00:00
config . instantiate ( ) ;
2017-11-17 20:48:24 +00:00
Error err = config - > load ( EditorSettings : : get_singleton ( ) - > get_editor_layouts_config ( ) ) ;
2016-01-01 17:48:14 +00:00
2019-10-23 13:02:51 +00:00
if ( err = = ERR_FILE_CANT_OPEN | | err = = ERR_FILE_NOT_FOUND ) {
2022-03-30 18:12:26 +00:00
config . instantiate ( ) ;
2017-03-05 15:44:50 +00:00
} else if ( err ! = OK ) {
2020-08-02 12:12:50 +00:00
show_warning ( TTR ( " An error occurred while trying to save the editor layout. \n Make sure the editor's user data path is writable. " ) ) ;
2016-01-01 17:48:14 +00:00
return ;
2015-11-22 18:11:17 +00:00
}
_save_docks_to_config ( config , p_file ) ;
2017-11-17 20:48:24 +00:00
config - > save ( EditorSettings : : get_singleton ( ) - > get_editor_layouts_config ( ) ) ;
2015-11-22 18:11:17 +00:00
layout_dialog - > hide ( ) ;
_update_layouts_menu ( ) ;
2017-03-05 15:44:50 +00:00
if ( p_file = = " Default " ) {
2020-08-02 12:12:50 +00:00
show_warning ( TTR ( " Default editor layout overridden. \n To restore the Default layout to its base settings, use the Delete Layout option and delete the Default layout. " ) ) ;
2016-01-11 21:23:45 +00:00
}
2015-11-22 18:11:17 +00:00
} break ;
case SETTINGS_LAYOUT_DELETE : {
2020-12-15 12:04:21 +00:00
if ( p_file . is_empty ( ) ) {
2015-11-22 18:11:17 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2015-11-22 18:11:17 +00:00
Ref < ConfigFile > config ;
2021-06-17 22:03:09 +00:00
config . instantiate ( ) ;
2017-11-17 20:48:24 +00:00
Error err = config - > load ( EditorSettings : : get_singleton ( ) - > get_editor_layouts_config ( ) ) ;
2015-11-22 18:11:17 +00:00
2017-03-05 15:44:50 +00:00
if ( err ! = OK | | ! config - > has_section ( p_file ) ) {
2016-05-04 01:25:37 +00:00
show_warning ( TTR ( " Layout name not found! " ) ) ;
2015-11-22 18:11:17 +00:00
return ;
}
2022-03-30 18:12:26 +00:00
// Erase key values.
2015-11-22 18:11:17 +00:00
List < String > keys ;
config - > get_section_keys ( p_file , & keys ) ;
2022-03-30 18:12:26 +00:00
for ( const String & key : keys ) {
config - > set_value ( p_file , key , Variant ( ) ) ;
2015-11-22 18:11:17 +00:00
}
2017-11-17 20:48:24 +00:00
config - > save ( EditorSettings : : get_singleton ( ) - > get_editor_layouts_config ( ) ) ;
2015-11-22 18:11:17 +00:00
layout_dialog - > hide ( ) ;
_update_layouts_menu ( ) ;
2017-03-05 15:44:50 +00:00
if ( p_file = = " Default " ) {
2020-08-02 12:12:50 +00:00
show_warning ( TTR ( " Restored the Default layout to its base settings. " ) ) ;
2016-01-11 21:23:45 +00:00
}
2015-09-01 03:49:47 +00:00
} break ;
2022-03-30 18:12:26 +00:00
default : {
// Save scene?
2020-03-06 17:00:16 +00:00
if ( file - > get_file_mode ( ) = = EditorFileDialog : : FILE_MODE_SAVE_FILE ) {
2015-05-31 04:59:42 +00:00
_save_scene_with_preview ( p_file ) ;
2014-02-10 01:10:30 +00:00
}
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
} break ;
}
}
2018-06-19 01:10:48 +00:00
bool EditorNode : : item_has_editor ( Object * p_object ) {
2019-04-08 22:18:03 +00:00
if ( _is_class_editor_disabled_by_feature_profile ( p_object - > get_class ( ) ) ) {
return false ;
}
2018-06-19 01:10:48 +00:00
return editor_data . get_subeditors ( p_object ) . size ( ) > 0 ;
}
2022-05-02 23:43:50 +00:00
void EditorNode : : edit_item_resource ( Ref < Resource > p_resource ) {
2019-02-22 20:42:29 +00:00
edit_item ( p_resource . ptr ( ) ) ;
}
2019-04-08 22:18:03 +00:00
bool EditorNode : : _is_class_editor_disabled_by_feature_profile ( const StringName & p_class ) {
Ref < EditorFeatureProfile > profile = EditorFeatureProfileManager : : get_singleton ( ) - > get_current_profile ( ) ;
if ( profile . is_null ( ) ) {
return false ;
}
StringName class_name = p_class ;
while ( class_name ! = StringName ( ) ) {
2019-04-08 23:20:20 +00:00
if ( profile - > is_class_disabled ( class_name ) ) {
return true ;
}
2019-04-08 22:18:03 +00:00
if ( profile - > is_class_editor_disabled ( class_name ) ) {
return true ;
}
class_name = ClassDB : : get_parent_class ( class_name ) ;
}
return false ;
}
2018-06-19 01:10:48 +00:00
void EditorNode : : edit_item ( Object * p_object ) {
2018-06-21 21:08:11 +00:00
Vector < EditorPlugin * > sub_plugins ;
if ( p_object ) {
2019-04-08 22:18:03 +00:00
if ( _is_class_editor_disabled_by_feature_profile ( p_object - > get_class ( ) ) ) {
return ;
}
2018-06-21 21:08:11 +00:00
sub_plugins = editor_data . get_subeditors ( p_object ) ;
}
2018-06-19 01:10:48 +00:00
2020-12-15 12:04:21 +00:00
if ( ! sub_plugins . is_empty ( ) ) {
2019-03-06 15:42:01 +00:00
bool same = true ;
if ( sub_plugins . size ( ) = = editor_plugins_over - > get_plugins_list ( ) . size ( ) ) {
for ( int i = 0 ; i < sub_plugins . size ( ) ; i + + ) {
if ( sub_plugins [ i ] ! = editor_plugins_over - > get_plugins_list ( ) [ i ] ) {
same = false ;
}
}
} else {
same = false ;
}
if ( ! same ) {
_display_top_editors ( false ) ;
_set_top_editors ( sub_plugins ) ;
}
2018-06-19 01:10:48 +00:00
_set_editing_top_editors ( p_object ) ;
_display_top_editors ( true ) ;
2018-06-21 21:08:11 +00:00
} else {
2019-03-04 19:44:39 +00:00
hide_top_editors ( ) ;
2018-06-19 01:10:48 +00:00
}
}
void EditorNode : : push_item ( Object * p_object , const String & p_property , bool p_inspector_only ) {
2014-02-10 01:10:30 +00:00
if ( ! p_object ) {
2021-11-17 20:08:55 +00:00
InspectorDock : : get_inspector_singleton ( ) - > edit ( nullptr ) ;
NodeDock : : get_singleton ( ) - > set_node ( nullptr ) ;
SceneTreeDock : : get_singleton ( ) - > set_selected ( nullptr ) ;
InspectorDock : : get_singleton ( ) - > update ( nullptr ) ;
2020-10-30 22:29:07 +00:00
_display_top_editors ( false ) ;
2014-02-10 01:10:30 +00:00
return ;
}
2020-02-12 17:24:06 +00:00
ObjectID id = p_object - > get_instance_id ( ) ;
2017-03-05 15:44:50 +00:00
if ( id ! = editor_history . get_current ( ) ) {
2018-06-19 01:10:48 +00:00
if ( p_inspector_only ) {
2022-03-30 18:12:26 +00:00
editor_history . add_object ( id , String ( ) , true ) ;
2021-12-09 09:42:46 +00:00
} else if ( p_property . is_empty ( ) ) {
2014-02-10 01:10:30 +00:00
editor_history . add_object ( id ) ;
2020-05-14 14:41:43 +00:00
} else {
2017-03-05 15:44:50 +00:00
editor_history . add_object ( id , p_property ) ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
}
_edit_current ( ) ;
}
2017-05-29 00:46:48 +00:00
void EditorNode : : _save_default_environment ( ) {
2020-04-18 09:00:51 +00:00
Ref < Environment > fallback = get_tree ( ) - > get_root ( ) - > get_world_3d ( ) - > get_fallback_environment ( ) ;
2017-05-29 00:46:48 +00:00
if ( fallback . is_valid ( ) & & fallback - > get_path ( ) . is_resource_file ( ) ) {
2022-05-13 13:04:37 +00:00
HashMap < Ref < Resource > , bool > processed ;
2017-05-29 00:46:48 +00:00
_find_and_save_edited_subresources ( fallback . ptr ( ) , processed , 0 ) ;
2018-06-29 06:38:15 +00:00
save_resource_in_path ( fallback , fallback - > get_path ( ) ) ;
2017-05-29 00:46:48 +00:00
}
}
2019-03-04 19:44:39 +00:00
void EditorNode : : hide_top_editors ( ) {
2016-03-29 23:02:53 +00:00
_display_top_editors ( false ) ;
2014-02-10 01:10:30 +00:00
2016-03-29 23:02:53 +00:00
editor_plugins_over - > clear ( ) ;
}
void EditorNode : : _display_top_editors ( bool p_display ) {
editor_plugins_over - > make_visible ( p_display ) ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _set_top_editors ( Vector < EditorPlugin * > p_editor_plugins_over ) {
2016-03-29 23:02:53 +00:00
editor_plugins_over - > set_plugins_list ( p_editor_plugins_over ) ;
}
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
void EditorNode : : _set_editing_top_editors ( Object * p_current_object ) {
2016-03-29 23:02:53 +00:00
editor_plugins_over - > edit ( p_current_object ) ;
2014-02-10 01:10:30 +00:00
}
2017-09-03 19:23:36 +00:00
static bool overrides_external_editor ( Object * p_object ) {
Script * script = Object : : cast_to < Script > ( p_object ) ;
2020-05-14 14:41:43 +00:00
if ( ! script ) {
2017-09-03 19:23:36 +00:00
return false ;
2020-05-14 14:41:43 +00:00
}
2017-09-03 19:23:36 +00:00
return script - > get_language ( ) - > overrides_external_editor ( ) ;
}
2021-09-12 19:17:34 +00:00
void EditorNode : : _edit_current ( bool p_skip_foreign ) {
2020-02-12 17:24:06 +00:00
ObjectID current = editor_history . get_current ( ) ;
2020-04-01 23:20:12 +00:00
Object * current_obj = current . is_valid ( ) ? ObjectDB : : get_instance ( current ) : nullptr ;
2014-02-10 01:10:30 +00:00
2022-05-02 23:43:50 +00:00
Ref < Resource > res = Object : : cast_to < Resource > ( current_obj ) ;
2021-09-12 19:17:34 +00:00
if ( p_skip_foreign & & res . is_valid ( ) ) {
if ( res - > get_path ( ) . find ( " :: " ) > - 1 & & res - > get_path ( ) . get_slice ( " :: " , 0 ) ! = editor_data . get_scene_path ( get_current_tab ( ) ) ) {
// Trying to edit resource that belongs to another scene; abort.
current_obj = nullptr ;
}
}
bool inspector_only = editor_history . is_current_inspector_only ( ) ;
2017-03-05 15:44:50 +00:00
this - > current = current_obj ;
2017-09-14 13:38:59 +00:00
2014-02-10 01:10:30 +00:00
if ( ! current_obj ) {
2021-11-17 20:08:55 +00:00
SceneTreeDock : : get_singleton ( ) - > set_selected ( nullptr ) ;
InspectorDock : : get_inspector_singleton ( ) - > edit ( nullptr ) ;
NodeDock : : get_singleton ( ) - > set_node ( nullptr ) ;
InspectorDock : : get_singleton ( ) - > update ( nullptr ) ;
2015-12-03 15:30:55 +00:00
2016-03-29 23:02:53 +00:00
_display_top_editors ( false ) ;
2015-12-03 15:30:55 +00:00
2014-02-10 01:10:30 +00:00
return ;
}
2021-11-17 20:08:55 +00:00
Object * prev_inspected_object = InspectorDock : : get_inspector_singleton ( ) - > get_edited_object ( ) ;
2020-01-24 17:08:27 +00:00
2018-06-14 18:36:38 +00:00
bool disable_folding = bool ( EDITOR_GET ( " interface/inspector/disable_folding " ) ) ;
2017-01-03 02:03:46 +00:00
bool is_resource = current_obj - > is_class ( " Resource " ) ;
bool is_node = current_obj - > is_class ( " Node " ) ;
2018-05-17 06:01:47 +00:00
2022-03-30 18:12:26 +00:00
String editable_warning ; // None by default.
2018-11-27 21:56:31 +00:00
2015-09-01 03:49:47 +00:00
if ( is_resource ) {
2017-08-24 20:58:51 +00:00
Resource * current_res = Object : : cast_to < Resource > ( current_obj ) ;
2014-02-10 01:10:30 +00:00
ERR_FAIL_COND ( ! current_res ) ;
2021-11-17 20:08:55 +00:00
InspectorDock : : get_inspector_singleton ( ) - > edit ( current_res ) ;
SceneTreeDock : : get_singleton ( ) - > set_selected ( nullptr ) ;
NodeDock : : get_singleton ( ) - > set_node ( nullptr ) ;
InspectorDock : : get_singleton ( ) - > update ( nullptr ) ;
ImportDock : : get_singleton ( ) - > set_edit_path ( current_res - > get_path ( ) ) ;
2017-09-14 13:38:59 +00:00
int subr_idx = current_res - > get_path ( ) . find ( " :: " ) ;
2017-09-14 22:38:38 +00:00
if ( subr_idx ! = - 1 ) {
String base_path = current_res - > get_path ( ) . substr ( 0 , subr_idx ) ;
if ( FileAccess : : exists ( base_path + " .import " ) ) {
editable_warning = TTR ( " This resource belongs to a scene that was imported, so it's not editable. \n Please read the documentation relevant to importing scenes to better understand this workflow. " ) ;
2017-09-14 13:38:59 +00:00
} else {
2021-09-30 14:30:55 +00:00
if ( ( ! get_edited_scene ( ) | | get_edited_scene ( ) - > get_scene_file_path ( ) ! = base_path ) & & ResourceLoader : : get_resource_type ( base_path ) = = " PackedScene " ) {
2021-06-17 22:03:09 +00:00
editable_warning = TTR ( " This resource belongs to a scene that was instantiated or inherited. \n Changes to it won't be kept when saving the current scene. " ) ;
2017-09-14 13:38:59 +00:00
}
}
2017-09-14 22:38:38 +00:00
} else if ( current_res - > get_path ( ) . is_resource_file ( ) ) {
if ( FileAccess : : exists ( current_res - > get_path ( ) + " .import " ) ) {
2017-10-20 02:40:12 +00:00
editable_warning = TTR ( " This resource was imported, so it's not editable. Change its settings in the import panel and then re-import. " ) ;
2017-09-14 13:38:59 +00:00
}
}
2016-07-09 14:46:59 +00:00
} else if ( is_node ) {
2017-08-24 20:58:51 +00:00
Node * current_node = Object : : cast_to < Node > ( current_obj ) ;
2014-02-10 01:10:30 +00:00
ERR_FAIL_COND ( ! current_node ) ;
2021-11-17 20:08:55 +00:00
InspectorDock : : get_inspector_singleton ( ) - > edit ( current_node ) ;
2017-05-29 00:46:48 +00:00
if ( current_node - > is_inside_tree ( ) ) {
2021-11-17 20:08:55 +00:00
NodeDock : : get_singleton ( ) - > set_node ( current_node ) ;
SceneTreeDock : : get_singleton ( ) - > set_selected ( current_node ) ;
InspectorDock : : get_singleton ( ) - > update ( current_node ) ;
2017-05-29 00:46:48 +00:00
} else {
2021-11-17 20:08:55 +00:00
NodeDock : : get_singleton ( ) - > set_node ( nullptr ) ;
SceneTreeDock : : get_singleton ( ) - > set_selected ( nullptr ) ;
InspectorDock : : get_singleton ( ) - > update ( nullptr ) ;
2017-05-29 00:46:48 +00:00
}
2014-02-10 01:10:30 +00:00
2021-12-09 09:42:46 +00:00
if ( get_edited_scene ( ) & & ! get_edited_scene ( ) - > get_scene_file_path ( ) . is_empty ( ) ) {
2021-09-30 14:30:55 +00:00
String source_scene = get_edited_scene ( ) - > get_scene_file_path ( ) ;
2017-09-14 22:38:38 +00:00
if ( FileAccess : : exists ( source_scene + " .import " ) ) {
2019-03-25 00:54:29 +00:00
editable_warning = TTR ( " This scene was imported, so changes to it won't be kept. \n Instancing it or inheriting will allow making changes to it. \n Please read the documentation relevant to importing scenes to better understand this workflow. " ) ;
2017-09-14 13:38:59 +00:00
}
}
2015-08-25 03:08:45 +00:00
} else {
2020-04-01 23:20:12 +00:00
Node * selected_node = nullptr ;
2019-11-10 08:37:51 +00:00
2020-02-07 01:52:05 +00:00
if ( current_obj - > is_class ( " EditorDebuggerRemoteObject " ) ) {
2019-03-25 00:54:29 +00:00
editable_warning = TTR ( " This is a remote object, so changes to it won't be kept. \n Please read the documentation relevant to debugging to better understand this workflow. " ) ;
2018-06-14 18:36:38 +00:00
disable_folding = true ;
2019-11-10 08:37:51 +00:00
} else if ( current_obj - > is_class ( " MultiNodeEdit " ) ) {
Node * scene = get_edited_scene ( ) ;
if ( scene ) {
MultiNodeEdit * multi_node_edit = Object : : cast_to < MultiNodeEdit > ( current_obj ) ;
int node_count = multi_node_edit - > get_node_count ( ) ;
if ( node_count > 0 ) {
List < Node * > multi_nodes ;
for ( int node_index = 0 ; node_index < node_count ; + + node_index ) {
Node * node = scene - > get_node ( multi_node_edit - > get_node ( node_index ) ) ;
if ( node ) {
multi_nodes . push_back ( node ) ;
}
}
2020-12-15 12:04:21 +00:00
if ( ! multi_nodes . is_empty ( ) ) {
2022-03-30 18:12:26 +00:00
// Pick the top-most node.
2019-11-10 08:37:51 +00:00
multi_nodes . sort_custom < Node : : Comparator > ( ) ;
selected_node = multi_nodes . front ( ) - > get ( ) ;
}
}
}
2017-10-17 14:39:31 +00:00
}
2021-11-17 20:08:55 +00:00
InspectorDock : : get_inspector_singleton ( ) - > edit ( current_obj ) ;
NodeDock : : get_singleton ( ) - > set_node ( nullptr ) ;
SceneTreeDock : : get_singleton ( ) - > set_selected ( selected_node ) ;
InspectorDock : : get_singleton ( ) - > update ( nullptr ) ;
2014-02-10 01:10:30 +00:00
}
2020-01-24 17:08:27 +00:00
if ( current_obj = = prev_inspected_object ) {
// Make sure inspected properties are restored.
2021-11-17 20:08:55 +00:00
InspectorDock : : get_inspector_singleton ( ) - > update_tree ( ) ;
2020-01-24 17:08:27 +00:00
}
2021-11-17 20:08:55 +00:00
InspectorDock : : get_singleton ( ) - > set_warning ( editable_warning ) ;
2017-09-14 13:38:59 +00:00
2021-11-17 20:08:55 +00:00
if ( InspectorDock : : get_inspector_singleton ( ) - > is_using_folding ( ) = = disable_folding ) {
InspectorDock : : get_inspector_singleton ( ) - > set_use_folding ( ! disable_folding ) ;
2018-06-14 18:36:38 +00:00
}
2022-03-30 18:12:26 +00:00
// Take care of the main editor plugin.
2014-02-10 01:10:30 +00:00
2018-06-19 01:10:48 +00:00
if ( ! inspector_only ) {
EditorPlugin * main_plugin = editor_data . get_editor ( current_obj ) ;
2014-02-10 01:10:30 +00:00
2021-06-08 23:27:30 +00:00
int plugin_index = 0 ;
for ( ; plugin_index < editor_table . size ( ) ; plugin_index + + ) {
if ( editor_table [ plugin_index ] = = main_plugin ) {
if ( ! main_editor_buttons [ plugin_index ] - > is_visible ( ) ) {
2022-03-30 18:12:26 +00:00
main_plugin = nullptr ; // If button is not visible, then no plugin is active.
2021-06-08 23:27:30 +00:00
}
break ;
2019-04-08 22:18:03 +00:00
}
}
2018-06-19 01:10:48 +00:00
if ( main_plugin ) {
2022-03-30 18:12:26 +00:00
// Special case if use of external editor is true.
2022-01-04 09:40:17 +00:00
Resource * current_res = Object : : cast_to < Resource > ( current_obj ) ;
2022-05-13 23:27:01 +00:00
if ( main_plugin - > get_name ( ) = = " Script " & & ! current_obj - > is_class ( " VisualScript " ) & & current_res & & ! current_res - > is_built_in ( ) & & ( bool ( EditorSettings : : get_singleton ( ) - > get ( " text_editor/external/use_external_editor " ) ) | | overrides_external_editor ( current_obj ) ) ) {
2020-05-14 14:41:43 +00:00
if ( ! changing_scene ) {
2018-06-19 01:10:48 +00:00
main_plugin - > edit ( current_obj ) ;
2020-05-14 14:41:43 +00:00
}
2018-06-19 01:10:48 +00:00
}
2014-02-10 01:10:30 +00:00
2018-06-19 01:10:48 +00:00
else if ( main_plugin ! = editor_plugin_screen & & ( ! ScriptEditor : : get_singleton ( ) | | ! ScriptEditor : : get_singleton ( ) - > is_visible_in_tree ( ) | | ScriptEditor : : get_singleton ( ) - > can_take_away_focus ( ) ) ) {
2022-03-30 18:12:26 +00:00
// Update screen main_plugin.
2021-06-08 23:27:30 +00:00
_editor_select ( plugin_index ) ;
main_plugin - > edit ( current_obj ) ;
2018-06-19 01:10:48 +00:00
} else {
editor_plugin_screen - > edit ( current_obj ) ;
}
2014-02-10 01:10:30 +00:00
}
2019-04-08 22:18:03 +00:00
Vector < EditorPlugin * > sub_plugins ;
if ( ! _is_class_editor_disabled_by_feature_profile ( current_obj - > get_class ( ) ) ) {
sub_plugins = editor_data . get_subeditors ( current_obj ) ;
}
2014-02-10 01:10:30 +00:00
2020-12-15 12:04:21 +00:00
if ( ! sub_plugins . is_empty ( ) ) {
2018-06-19 01:10:48 +00:00
_display_top_editors ( false ) ;
2014-02-10 01:10:30 +00:00
2018-06-19 01:10:48 +00:00
_set_top_editors ( sub_plugins ) ;
_set_editing_top_editors ( current_obj ) ;
_display_top_editors ( true ) ;
2020-12-15 12:04:21 +00:00
} else if ( ! editor_plugins_over - > get_plugins_list ( ) . is_empty ( ) ) {
2019-03-04 19:44:39 +00:00
hide_top_editors ( ) ;
2018-06-19 01:10:48 +00:00
}
2014-02-10 01:10:30 +00:00
}
2021-11-17 20:08:55 +00:00
InspectorDock : : get_singleton ( ) - > update ( current_obj ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _run ( bool p_current , const String & p_custom ) {
if ( editor_run . get_status ( ) = = EditorRun : : STATUS_PLAY ) {
2014-02-10 01:10:30 +00:00
play_button - > set_pressed ( ! _playing_edited ) ;
play_scene_button - > set_pressed ( _playing_edited ) ;
return ;
}
play_button - > set_pressed ( false ) ;
2021-07-17 21:22:52 +00:00
play_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " MainPlay " ) , SNAME ( " EditorIcons " ) ) ) ;
2014-02-10 01:10:30 +00:00
play_scene_button - > set_pressed ( false ) ;
2021-07-17 21:22:52 +00:00
play_scene_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " PlayScene " ) , SNAME ( " EditorIcons " ) ) ) ;
2016-02-17 19:51:56 +00:00
play_custom_scene_button - > set_pressed ( false ) ;
2021-07-17 21:22:52 +00:00
play_custom_scene_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " PlayCustom " ) , SNAME ( " EditorIcons " ) ) ) ;
2014-02-10 01:10:30 +00:00
String run_filename ;
2021-12-09 09:42:46 +00:00
if ( p_current | | ( editor_data . get_edited_scene_root ( ) & & ! p_custom . is_empty ( ) & & p_custom = = editor_data . get_edited_scene_root ( ) - > get_scene_file_path ( ) ) ) {
2015-06-22 03:03:19 +00:00
Node * scene = editor_data . get_edited_scene_root ( ) ;
2014-02-10 01:10:30 +00:00
if ( ! scene ) {
2018-08-05 14:47:41 +00:00
show_accept ( TTR ( " There is no defined scene to run. " ) , TTR ( " OK " ) ) ;
2014-02-10 01:10:30 +00:00
return ;
}
2021-12-09 09:42:46 +00:00
if ( scene - > get_scene_file_path ( ) . is_empty ( ) ) {
2022-03-30 18:12:26 +00:00
current_menu_option = - 1 ;
2021-01-06 01:17:56 +00:00
_menu_option ( FILE_SAVE_AS_SCENE ) ;
// Set the option to save and run so when the dialog is accepted, the scene runs.
2022-03-30 18:12:26 +00:00
current_menu_option = FILE_SAVE_AND_RUN ;
2021-01-06 01:17:56 +00:00
file - > set_title ( TTR ( " Save scene before running... " ) ) ;
2014-02-10 01:10:30 +00:00
return ;
}
2021-09-30 14:30:55 +00:00
run_filename = scene - > get_scene_file_path ( ) ;
2021-12-09 09:42:46 +00:00
} else if ( ! p_custom . is_empty ( ) ) {
2017-02-27 14:20:47 +00:00
run_filename = p_custom ;
2014-02-10 01:10:30 +00:00
}
2021-12-09 09:42:46 +00:00
if ( run_filename . is_empty ( ) ) {
2022-03-30 18:12:26 +00:00
// Evidently, run the scene.
2019-03-22 01:08:28 +00:00
if ( ! ensure_main_scene ( false ) ) {
2016-06-27 13:59:37 +00:00
return ;
}
2014-02-10 01:10:30 +00:00
}
2018-05-17 21:02:16 +00:00
if ( bool ( EDITOR_GET ( " run/auto_save/save_before_running " ) ) ) {
2014-02-10 01:10:30 +00:00
if ( unsaved_cache ) {
2015-06-22 03:03:19 +00:00
Node * scene = editor_data . get_edited_scene_root ( ) ;
2014-02-10 01:10:30 +00:00
2021-12-09 09:42:46 +00:00
if ( scene & & ! scene - > get_scene_file_path ( ) . is_empty ( ) ) { // Only autosave if there is a scene and if it has a path.
2021-09-30 14:30:55 +00:00
_save_scene_with_preview ( scene - > get_scene_file_path ( ) ) ;
2014-02-10 01:10:30 +00:00
}
}
2016-06-26 03:54:17 +00:00
_menu_option ( FILE_SAVE_ALL_SCENES ) ;
2014-02-10 01:10:30 +00:00
editor_data . save_editor_external_data ( ) ;
}
2020-05-14 14:41:43 +00:00
if ( ! call_build ( ) ) {
2017-08-29 21:59:20 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2017-08-29 21:59:20 +00:00
2018-05-17 21:02:16 +00:00
if ( bool ( EDITOR_GET ( " run/output/always_clear_output_on_play " ) ) ) {
2015-07-29 22:03:25 +00:00
log - > clear ( ) ;
}
2018-05-17 21:02:16 +00:00
if ( bool ( EDITOR_GET ( " run/output/always_open_output_on_play " ) ) ) {
2016-12-24 22:39:16 +00:00
make_bottom_panel_item_visible ( log ) ;
}
2014-02-10 01:10:30 +00:00
2020-03-16 08:37:43 +00:00
EditorDebuggerNode : : get_singleton ( ) - > start ( ) ;
2021-09-30 02:06:28 +00:00
Error error = editor_run . run ( run_filename ) ;
2017-03-05 15:44:50 +00:00
if ( error ! = OK ) {
2020-03-16 08:37:43 +00:00
EditorDebuggerNode : : get_singleton ( ) - > stop ( ) ;
2021-09-30 02:06:28 +00:00
show_accept ( TTR ( " Could not start subprocess(es)! " ) , TTR ( " OK " ) ) ;
2014-02-10 01:10:30 +00:00
return ;
}
2021-07-17 21:22:52 +00:00
emit_signal ( SNAME ( " play_pressed " ) ) ;
2014-02-10 01:10:30 +00:00
if ( p_current ) {
play_scene_button - > set_pressed ( true ) ;
2021-07-17 21:22:52 +00:00
play_scene_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " Reload " ) , SNAME ( " EditorIcons " ) ) ) ;
2021-12-09 09:42:46 +00:00
} else if ( ! p_custom . is_empty ( ) ) {
2017-03-05 15:44:50 +00:00
run_custom_filename = p_custom ;
2016-02-17 19:51:56 +00:00
play_custom_scene_button - > set_pressed ( true ) ;
2021-07-17 21:22:52 +00:00
play_custom_scene_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " Reload " ) , SNAME ( " EditorIcons " ) ) ) ;
2014-02-10 01:10:30 +00:00
} else {
play_button - > set_pressed ( true ) ;
2021-07-17 21:22:52 +00:00
play_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " Reload " ) , SNAME ( " EditorIcons " ) ) ) ;
2014-02-10 01:10:30 +00:00
}
2017-12-04 19:48:46 +00:00
stop_button - > set_disabled ( false ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
_playing_edited = p_current ;
2014-02-10 01:10:30 +00:00
}
2020-03-16 08:37:43 +00:00
void EditorNode : : _run_native ( const Ref < EditorExportPreset > & p_preset ) {
bool autosave = EDITOR_GET ( " run/auto_save/save_before_running " ) ;
if ( autosave ) {
_menu_option_confirm ( FILE_SAVE_ALL_SCENES , false ) ;
}
if ( run_native - > is_deploy_debug_remote_enabled ( ) ) {
_menu_option_confirm ( RUN_STOP , true ) ;
2020-05-14 14:41:43 +00:00
if ( ! call_build ( ) ) {
2022-03-30 18:12:26 +00:00
return ; // Build failed.
2020-05-14 14:41:43 +00:00
}
2020-03-16 08:37:43 +00:00
EditorDebuggerNode : : get_singleton ( ) - > start ( p_preset - > get_platform ( ) - > get_debug_protocol ( ) ) ;
2021-07-17 21:22:52 +00:00
emit_signal ( SNAME ( " play_pressed " ) ) ;
2020-03-16 08:37:43 +00:00
editor_run . run_native_notify ( ) ;
}
}
2021-07-15 13:12:56 +00:00
void EditorNode : : _android_build_source_selected ( const String & p_file ) {
export_template_manager - > install_android_template_from_file ( p_file ) ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _menu_option_confirm ( int p_option , bool p_confirmed ) {
2022-03-30 18:12:26 +00:00
if ( ! p_confirmed ) { // FIXME: this may be a hack.
current_menu_option = ( MenuOptions ) p_option ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
switch ( p_option ) {
2014-02-10 01:10:30 +00:00
case FILE_NEW_SCENE : {
2019-08-15 17:47:21 +00:00
new_scene ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
2015-10-10 12:09:09 +00:00
case FILE_NEW_INHERITED_SCENE :
2014-02-10 01:10:30 +00:00
case FILE_OPEN_SCENE : {
2020-03-06 17:00:16 +00:00
file - > set_file_mode ( EditorFileDialog : : FILE_MODE_OPEN_FILE ) ;
2014-02-10 01:10:30 +00:00
List < String > extensions ;
2017-03-05 15:44:50 +00:00
ResourceLoader : : get_recognized_extensions_for_type ( " PackedScene " , & extensions ) ;
2014-02-10 01:10:30 +00:00
file - > clear_filters ( ) ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < extensions . size ( ) ; i + + ) {
file - > add_filter ( " *. " + extensions [ i ] + " ; " + extensions [ i ] . to_upper ( ) ) ;
2014-02-10 01:10:30 +00:00
}
2016-03-08 23:00:52 +00:00
2015-06-22 03:03:19 +00:00
Node * scene = editor_data . get_edited_scene_root ( ) ;
2014-02-10 01:10:30 +00:00
if ( scene ) {
2021-09-30 14:30:55 +00:00
file - > set_current_path ( scene - > get_scene_file_path ( ) ) ;
2014-02-10 01:10:30 +00:00
} ;
2017-03-05 15:44:50 +00:00
file - > set_title ( p_option = = FILE_OPEN_SCENE ? TTR ( " Open Scene " ) : TTR ( " Open Base Scene " ) ) ;
2020-07-11 16:45:19 +00:00
file - > popup_file_dialog ( ) ;
2016-03-08 23:00:52 +00:00
2019-05-09 20:06:35 +00:00
} break ;
case FILE_QUICK_OPEN : {
quick_open - > popup_dialog ( " Resource " , true ) ;
quick_open - > set_title ( TTR ( " Quick Open... " ) ) ;
2014-02-10 01:10:30 +00:00
} break ;
case FILE_QUICK_OPEN_SCENE : {
2018-10-02 10:07:44 +00:00
quick_open - > popup_dialog ( " PackedScene " , true ) ;
2018-04-22 17:36:01 +00:00
quick_open - > set_title ( TTR ( " Quick Open Scene... " ) ) ;
2014-02-10 01:10:30 +00:00
} break ;
case FILE_QUICK_OPEN_SCRIPT : {
2018-10-02 10:07:44 +00:00
quick_open - > popup_dialog ( " Script " , true ) ;
2018-04-22 17:36:01 +00:00
quick_open - > set_title ( TTR ( " Quick Open Script... " ) ) ;
2014-02-10 01:10:30 +00:00
} break ;
case FILE_OPEN_PREV : {
2020-12-15 12:04:21 +00:00
if ( previous_scenes . is_empty ( ) ) {
2014-02-10 01:10:30 +00:00
break ;
2020-05-14 14:41:43 +00:00
}
2017-03-05 15:44:50 +00:00
opening_prev = true ;
2014-02-10 01:10:30 +00:00
open_request ( previous_scenes . back ( ) - > get ( ) ) ;
2019-04-10 15:21:26 +00:00
previous_scenes . pop_back ( ) ;
2014-02-10 01:10:30 +00:00
2019-04-21 09:44:21 +00:00
} break ;
case FILE_CLOSE_OTHERS :
case FILE_CLOSE_RIGHT :
case FILE_CLOSE_ALL : {
2022-03-30 18:12:26 +00:00
if ( editor_data . get_edited_scene_count ( ) > 1 & & ( current_menu_option ! = FILE_CLOSE_RIGHT | | editor_data . get_edited_scene ( ) < editor_data . get_edited_scene_count ( ) - 1 ) ) {
2019-04-21 09:44:21 +00:00
int next_tab = editor_data . get_edited_scene ( ) + 1 ;
next_tab % = editor_data . get_edited_scene_count ( ) ;
2022-03-30 18:12:26 +00:00
_scene_tab_closed ( next_tab , current_menu_option ) ;
2019-04-21 09:44:21 +00:00
} else {
2022-03-30 18:12:26 +00:00
if ( current_menu_option ! = FILE_CLOSE_ALL ) {
current_menu_option = - 1 ;
2020-05-14 14:41:43 +00:00
} else {
2019-04-21 09:44:21 +00:00
_scene_tab_closed ( editor_data . get_edited_scene ( ) ) ;
2020-05-14 14:41:43 +00:00
}
2019-04-21 09:44:21 +00:00
}
2020-05-14 14:41:43 +00:00
if ( p_confirmed ) {
2019-05-17 21:47:02 +00:00
_menu_option_confirm ( SCENE_TAB_CLOSE , true ) ;
2020-05-14 14:41:43 +00:00
}
2019-05-17 21:47:02 +00:00
2015-06-22 03:03:19 +00:00
} break ;
case FILE_CLOSE : {
2020-07-19 23:09:36 +00:00
_scene_tab_closed ( editor_data . get_edited_scene ( ) ) ;
} break ;
case FILE_CLOSE_ALL_AND_QUIT :
2022-03-23 11:07:29 +00:00
case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER :
case FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT : {
2019-12-06 13:46:01 +00:00
if ( ! p_confirmed ) {
2022-03-30 18:12:26 +00:00
tab_closing_idx = _next_unsaved_scene ( false ) ;
_scene_tab_changed ( tab_closing_idx ) ;
2019-12-06 13:46:01 +00:00
2022-03-23 11:07:29 +00:00
if ( unsaved_cache | | p_option = = FILE_CLOSE_ALL_AND_QUIT | | p_option = = FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER | | p_option = = FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT ) {
2022-03-30 18:12:26 +00:00
Node * scene_root = editor_data . get_edited_scene_root ( tab_closing_idx ) ;
2021-03-13 17:19:29 +00:00
if ( scene_root ) {
2021-09-30 14:30:55 +00:00
String scene_filename = scene_root - > get_scene_file_path ( ) ;
2022-03-23 11:07:29 +00:00
if ( p_option = = FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT ) {
save_confirmation - > get_ok_button ( ) - > set_text ( TTR ( " Save & Reload " ) ) ;
save_confirmation - > set_text ( vformat ( TTR ( " Save changes to '%s' before reloading? " ) , ! scene_filename . is_empty ( ) ? scene_filename : " unsaved scene " ) ) ;
} else {
save_confirmation - > get_ok_button ( ) - > set_text ( TTR ( " Save & Quit " ) ) ;
save_confirmation - > set_text ( vformat ( TTR ( " Save changes to '%s' before closing? " ) , ! scene_filename . is_empty ( ) ? scene_filename : " unsaved scene " ) ) ;
}
2021-03-13 17:19:29 +00:00
save_confirmation - > popup_centered ( ) ;
break ;
}
2019-12-06 13:46:01 +00:00
}
2015-06-22 03:03:19 +00:00
}
2022-03-30 18:12:26 +00:00
if ( ! editor_data . get_edited_scene_root ( tab_closing_idx ) ) {
// Empty tab.
_scene_tab_closed ( tab_closing_idx ) ;
2018-01-02 07:10:49 +00:00
break ;
}
2017-12-10 12:48:03 +00:00
2020-02-22 19:47:50 +00:00
[[fallthrough]] ;
2019-04-05 12:06:16 +00:00
}
2017-06-21 04:15:39 +00:00
case SCENE_TAB_CLOSE :
2014-02-10 01:10:30 +00:00
case FILE_SAVE_SCENE : {
2022-03-30 18:12:26 +00:00
int scene_idx = ( p_option = = FILE_SAVE_SCENE ) ? - 1 : tab_closing_idx ;
2017-06-21 04:15:39 +00:00
Node * scene = editor_data . get_edited_scene_root ( scene_idx ) ;
2021-12-09 09:42:46 +00:00
if ( scene & & ! scene - > get_scene_file_path ( ) . is_empty ( ) ) {
2021-09-30 14:30:55 +00:00
if ( DirAccess : : exists ( scene - > get_scene_file_path ( ) . get_base_dir ( ) ) ) {
2021-09-11 01:35:13 +00:00
if ( scene_idx ! = editor_data . get_edited_scene ( ) ) {
2021-09-30 14:30:55 +00:00
_save_scene_with_preview ( scene - > get_scene_file_path ( ) , scene_idx ) ;
2021-09-11 01:35:13 +00:00
} else {
2021-09-30 14:30:55 +00:00
_save_scene_with_preview ( scene - > get_scene_file_path ( ) ) ;
2021-09-11 01:35:13 +00:00
}
2017-06-21 04:15:39 +00:00
2021-09-11 01:35:13 +00:00
if ( scene_idx ! = - 1 ) {
_discard_changes ( ) ;
}
save_layout ( ) ;
} else {
2021-09-30 14:30:55 +00:00
show_save_accept ( vformat ( TTR ( " %s no longer exists! Please specify a new save location. " ) , scene - > get_scene_file_path ( ) . get_base_dir ( ) ) , TTR ( " OK " ) ) ;
2020-05-14 14:41:43 +00:00
}
2017-06-26 14:04:53 +00:00
break ;
}
2020-02-22 19:47:50 +00:00
[[fallthrough]] ;
2019-04-05 12:06:16 +00:00
}
2014-02-10 01:10:30 +00:00
case FILE_SAVE_AS_SCENE : {
2022-03-30 18:12:26 +00:00
int scene_idx = ( p_option = = FILE_SAVE_SCENE | | p_option = = FILE_SAVE_AS_SCENE ) ? - 1 : tab_closing_idx ;
2016-03-08 23:00:52 +00:00
2017-06-26 14:04:53 +00:00
Node * scene = editor_data . get_edited_scene_root ( scene_idx ) ;
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
if ( ! scene ) {
2021-05-09 10:29:50 +00:00
if ( p_option = = FILE_SAVE_SCENE ) {
// Pressing Ctrl + S saves the current script if a scene is currently open, but it won't if the scene has no root node.
// Work around this by explicitly saving the script in this case (similar to pressing Ctrl + Alt + S).
ScriptEditor : : get_singleton ( ) - > save_current_script ( ) ;
}
const int saved = _save_external_resources ( ) ;
2019-02-27 23:00:40 +00:00
if ( saved > 0 ) {
2021-05-09 10:29:50 +00:00
show_accept (
vformat ( TTR ( " The current scene has no root node, but %d modified external resource(s) were saved anyway. " ) , saved ) ,
TTR ( " OK " ) ) ;
} else if ( p_option = = FILE_SAVE_AS_SCENE ) {
// Don't show this dialog when pressing Ctrl + S to avoid interfering with script saving.
show_accept (
TTR ( " A root node is required to save the scene. You can add a root node using the Scene tree dock. " ) ,
TTR ( " OK " ) ) ;
2019-02-27 23:00:40 +00:00
}
2016-03-08 23:00:52 +00:00
break ;
2014-02-10 01:10:30 +00:00
}
2016-03-08 23:00:52 +00:00
2020-03-06 17:00:16 +00:00
file - > set_file_mode ( EditorFileDialog : : FILE_MODE_SAVE_FILE ) ;
2014-02-10 01:10:30 +00:00
List < String > extensions ;
2017-03-05 15:44:50 +00:00
Ref < PackedScene > sd = memnew ( PackedScene ) ;
ResourceSaver : : get_recognized_extensions ( sd , & extensions ) ;
2014-02-10 01:10:30 +00:00
file - > clear_filters ( ) ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < extensions . size ( ) ; i + + ) {
file - > add_filter ( " *. " + extensions [ i ] + " ; " + extensions [ i ] . to_upper ( ) ) ;
2014-02-10 01:10:30 +00:00
}
2016-03-08 23:00:52 +00:00
2021-12-09 09:42:46 +00:00
if ( ! scene - > get_scene_file_path ( ) . is_empty ( ) ) {
2021-09-30 14:30:55 +00:00
String path = scene - > get_scene_file_path ( ) ;
2020-10-13 18:28:45 +00:00
file - > set_current_path ( path ) ;
2014-02-10 01:10:30 +00:00
if ( extensions . size ( ) ) {
2020-10-13 18:28:45 +00:00
String ext = path . get_extension ( ) . to_lower ( ) ;
2020-04-01 23:20:12 +00:00
if ( extensions . find ( ext ) = = nullptr ) {
2020-10-13 18:28:45 +00:00
file - > set_current_path ( path . replacen ( " . " + ext , " . " + extensions . front ( ) - > get ( ) ) ) ;
2014-02-10 01:10:30 +00:00
}
}
2021-09-12 11:21:24 +00:00
} else if ( extensions . size ( ) ) {
String root_name = scene - > get_name ( ) ;
// Very similar to node naming logic.
switch ( ProjectSettings : : get_singleton ( ) - > get ( " editor/scene/scene_naming " ) . operator int ( ) ) {
case SCENE_NAME_CASING_AUTO :
// Use casing of the root node.
break ;
case SCENE_NAME_CASING_PASCAL_CASE : {
root_name = root_name . capitalize ( ) . replace ( " " , " " ) ;
} break ;
case SCENE_NAME_CASING_SNAKE_CASE :
root_name = root_name . capitalize ( ) . replace ( " " , " " ) . replace ( " - " , " _ " ) . camelcase_to_underscore ( ) ;
break ;
2014-02-10 01:10:30 +00:00
}
2021-09-12 11:21:24 +00:00
file - > set_current_path ( root_name + " . " + extensions . front ( ) - > get ( ) . to_lower ( ) ) ;
2014-02-10 01:10:30 +00:00
}
2020-07-11 16:45:19 +00:00
file - > popup_file_dialog ( ) ;
2018-04-22 17:36:01 +00:00
file - > set_title ( TTR ( " Save Scene As... " ) ) ;
2016-03-08 23:00:52 +00:00
2014-02-10 01:10:30 +00:00
} break ;
2016-06-26 03:54:17 +00:00
case FILE_SAVE_ALL_SCENES : {
2017-06-24 10:57:30 +00:00
_save_all_scenes ( ) ;
2015-01-06 22:28:25 +00:00
} break ;
2014-02-10 01:10:30 +00:00
case FILE_EXPORT_PROJECT : {
2017-02-20 02:19:30 +00:00
project_export - > popup_export ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
case FILE_EXTERNAL_OPEN_SCENE : {
if ( unsaved_cache & & ! p_confirmed ) {
2020-12-14 18:37:30 +00:00
confirmation - > get_ok_button ( ) - > set_text ( TTR ( " Open " ) ) ;
2016-05-04 01:25:37 +00:00
confirmation - > set_text ( TTR ( " Current scene not saved. Open anyway? " ) ) ;
2020-03-06 17:00:16 +00:00
confirmation - > popup_centered ( ) ;
2014-02-10 01:10:30 +00:00
break ;
}
2017-03-05 15:44:50 +00:00
bool oprev = opening_prev ;
2014-02-10 01:10:30 +00:00
Error err = load_scene ( external_file ) ;
if ( err = = OK & & oprev ) {
previous_scenes . pop_back ( ) ;
2017-03-05 15:44:50 +00:00
opening_prev = false ;
2014-02-10 01:10:30 +00:00
}
} break ;
case EDIT_UNDO : {
2021-08-13 21:31:57 +00:00
if ( ( int ) Input : : get_singleton ( ) - > get_mouse_button_mask ( ) & 0x7 ) {
2021-08-17 03:41:46 +00:00
log - > add_message ( TTR ( " Can't undo while mouse buttons are pressed. " ) , EditorLog : : MSG_TYPE_EDITOR ) ;
2018-05-27 02:41:19 +00:00
} else {
String action = editor_data . get_undo_redo ( ) . get_current_action_name ( ) ;
2014-02-10 01:10:30 +00:00
2018-05-27 02:41:19 +00:00
if ( ! editor_data . get_undo_redo ( ) . undo ( ) ) {
2021-08-17 03:41:46 +00:00
log - > add_message ( TTR ( " Nothing to undo. " ) , EditorLog : : MSG_TYPE_EDITOR ) ;
2021-12-09 09:42:46 +00:00
} else if ( ! action . is_empty ( ) ) {
2021-08-17 03:41:46 +00:00
log - > add_message ( vformat ( TTR ( " Undo: %s " ) , action ) , EditorLog : : MSG_TYPE_EDITOR ) ;
2018-05-27 02:41:19 +00:00
}
}
2014-02-10 01:10:30 +00:00
} break ;
case EDIT_REDO : {
2021-08-13 21:31:57 +00:00
if ( ( int ) Input : : get_singleton ( ) - > get_mouse_button_mask ( ) & 0x7 ) {
2021-08-17 03:41:46 +00:00
log - > add_message ( TTR ( " Can't redo while mouse buttons are pressed. " ) , EditorLog : : MSG_TYPE_EDITOR ) ;
2018-05-27 02:41:19 +00:00
} else {
if ( ! editor_data . get_undo_redo ( ) . redo ( ) ) {
2021-08-17 03:41:46 +00:00
log - > add_message ( TTR ( " Nothing to redo. " ) , EditorLog : : MSG_TYPE_EDITOR ) ;
2018-05-27 02:41:19 +00:00
} else {
String action = editor_data . get_undo_redo ( ) . get_current_action_name ( ) ;
2021-08-17 03:41:46 +00:00
log - > add_message ( vformat ( TTR ( " Redo: %s " ) , action ) , EditorLog : : MSG_TYPE_EDITOR ) ;
2018-05-27 02:41:19 +00:00
}
}
2014-02-10 01:10:30 +00:00
} break ;
2015-01-25 00:14:06 +00:00
2020-05-10 18:12:25 +00:00
case EDIT_RELOAD_SAVED_SCENE : {
2015-01-25 00:14:06 +00:00
Node * scene = get_edited_scene ( ) ;
2020-05-14 14:41:43 +00:00
if ( ! scene ) {
2015-01-25 00:14:06 +00:00
break ;
2020-05-14 14:41:43 +00:00
}
2016-01-23 21:28:30 +00:00
2021-09-30 14:30:55 +00:00
String filename = scene - > get_scene_file_path ( ) ;
2016-01-23 21:28:30 +00:00
2021-12-09 09:42:46 +00:00
if ( filename . is_empty ( ) ) {
2016-05-18 22:08:12 +00:00
show_warning ( TTR ( " Can't reload a scene that was never saved. " ) ) ;
2016-01-23 21:28:30 +00:00
break ;
}
2015-01-27 00:00:07 +00:00
if ( unsaved_cache & & ! p_confirmed ) {
2020-12-14 18:37:30 +00:00
confirmation - > get_ok_button ( ) - > set_text ( TTR ( " Reload Saved Scene " ) ) ;
2020-05-10 18:12:25 +00:00
confirmation - > set_text (
TTR ( " The current scene has unsaved changes. \n Reload the saved scene anyway? This action cannot be undone. " ) ) ;
2020-03-06 17:00:16 +00:00
confirmation - > popup_centered ( ) ;
2015-01-27 00:00:07 +00:00
break ;
}
2015-01-25 00:14:06 +00:00
2016-01-23 21:28:30 +00:00
int cur_idx = editor_data . get_edited_scene ( ) ;
_remove_edited_scene ( ) ;
Error err = load_scene ( filename ) ;
2020-05-14 14:41:43 +00:00
if ( err ! = OK ) {
2017-09-02 20:32:31 +00:00
ERR_PRINT ( " Failed to load scene " ) ;
2020-05-14 14:41:43 +00:00
}
2016-01-23 21:28:30 +00:00
editor_data . move_edited_scene_to_index ( cur_idx ) ;
2018-11-18 20:07:38 +00:00
get_undo_redo ( ) - > clear_history ( false ) ;
2016-01-23 21:28:30 +00:00
scene_tabs - > set_current_tab ( cur_idx ) ;
2015-01-25 00:14:06 +00:00
2014-11-02 14:31:01 +00:00
} break ;
2014-02-10 01:10:30 +00:00
case RUN_PLAY : {
2020-04-05 14:19:24 +00:00
run_play ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
case RUN_PLAY_CUSTOM_SCENE : {
2020-12-15 12:04:21 +00:00
if ( run_custom_filename . is_empty ( ) | | editor_run . get_status ( ) = = EditorRun : : STATUS_STOP ) {
2017-03-05 15:44:50 +00:00
_menu_option_confirm ( RUN_STOP , true ) ;
2018-10-02 10:07:44 +00:00
quick_run - > popup_dialog ( " PackedScene " , true ) ;
2018-04-22 17:36:01 +00:00
quick_run - > set_title ( TTR ( " Quick Run Scene... " ) ) ;
2016-02-18 12:16:31 +00:00
play_custom_scene_button - > set_pressed ( false ) ;
2016-02-17 19:51:56 +00:00
} else {
2017-03-05 15:44:50 +00:00
String last_custom_scene = run_custom_filename ;
2020-04-05 14:19:24 +00:00
run_play_custom ( last_custom_scene ) ;
2016-02-17 19:51:56 +00:00
}
2014-02-10 01:10:30 +00:00
} break ;
case RUN_STOP : {
2020-05-14 14:41:43 +00:00
if ( editor_run . get_status ( ) = = EditorRun : : STATUS_STOP ) {
2014-02-10 01:10:30 +00:00
break ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
editor_run . stop ( ) ;
2016-02-17 19:51:56 +00:00
run_custom_filename . clear ( ) ;
2014-02-10 01:10:30 +00:00
play_button - > set_pressed ( false ) ;
2021-07-17 21:22:52 +00:00
play_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " MainPlay " ) , SNAME ( " EditorIcons " ) ) ) ;
2014-02-10 01:10:30 +00:00
play_scene_button - > set_pressed ( false ) ;
2021-07-17 21:22:52 +00:00
play_scene_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " PlayScene " ) , SNAME ( " EditorIcons " ) ) ) ;
2016-02-17 19:51:56 +00:00
play_custom_scene_button - > set_pressed ( false ) ;
2021-07-17 21:22:52 +00:00
play_custom_scene_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " PlayCustom " ) , SNAME ( " EditorIcons " ) ) ) ;
2017-12-04 19:48:46 +00:00
stop_button - > set_disabled ( true ) ;
2018-05-17 21:02:16 +00:00
if ( bool ( EDITOR_GET ( " run/output/always_close_output_on_stop " ) ) ) {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < bottom_panel_items . size ( ) ; i + + ) {
if ( bottom_panel_items [ i ] . control = = log ) {
_bottom_panel_switch ( false , i ) ;
2017-02-06 16:50:01 +00:00
break ;
}
}
}
2020-03-16 08:37:43 +00:00
EditorDebuggerNode : : get_singleton ( ) - > stop ( ) ;
2021-07-17 21:22:52 +00:00
emit_signal ( SNAME ( " stop_pressed " ) ) ;
2014-02-10 01:10:30 +00:00
} break ;
2018-09-13 17:06:40 +00:00
case FILE_SHOW_IN_FILESYSTEM : {
String path = editor_data . get_scene_path ( editor_data . get_edited_scene ( ) ) ;
2021-12-09 09:42:46 +00:00
if ( ! path . is_empty ( ) ) {
2021-11-17 20:08:55 +00:00
FileSystemDock : : get_singleton ( ) - > navigate_to_path ( path ) ;
2018-09-13 17:06:40 +00:00
}
} break ;
2014-02-10 01:10:30 +00:00
case RUN_PLAY_SCENE : {
2020-04-05 14:19:24 +00:00
run_play_current ( ) ;
2014-02-10 01:10:30 +00:00
2015-08-06 05:37:40 +00:00
} break ;
2014-02-10 01:10:30 +00:00
case RUN_SETTINGS : {
2022-01-31 23:19:01 +00:00
project_settings_editor - > popup_project_settings ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
2019-04-07 18:46:52 +00:00
case FILE_INSTALL_ANDROID_SOURCE : {
if ( p_confirmed ) {
export_template_manager - > install_android_template ( ) ;
} else {
if ( DirAccess : : exists ( " res://android/build " ) ) {
2020-03-06 17:00:16 +00:00
remove_android_build_template - > popup_centered ( ) ;
2019-04-07 18:46:52 +00:00
} else if ( export_template_manager - > can_install_android_template ( ) ) {
2020-03-06 17:00:16 +00:00
install_android_build_template - > popup_centered ( ) ;
2019-04-07 18:46:52 +00:00
} else {
2020-03-06 17:00:16 +00:00
custom_build_manage_templates - > popup_centered ( ) ;
2019-04-07 18:46:52 +00:00
}
}
} break ;
2021-12-28 00:51:45 +00:00
case RUN_USER_DATA_FOLDER : {
2022-03-30 18:12:26 +00:00
// Ensure_user_data_dir() to prevent the edge case: "Open User Data Folder" won't work after the project was renamed in ProjectSettingsEditor unless the project is saved.
2020-09-13 12:49:53 +00:00
OS : : get_singleton ( ) - > ensure_user_data_dir ( ) ;
2019-09-04 17:46:12 +00:00
OS : : get_singleton ( ) - > shell_open ( String ( " file:// " ) + OS : : get_singleton ( ) - > get_user_data_dir ( ) ) ;
} break ;
2019-04-07 18:46:52 +00:00
case FILE_EXPLORE_ANDROID_BUILD_TEMPLATES : {
2019-06-16 12:12:01 +00:00
OS : : get_singleton ( ) - > shell_open ( " file:// " + ProjectSettings : : get_singleton ( ) - > get_resource_path ( ) . plus_file ( " android " ) ) ;
2019-04-07 18:46:52 +00:00
} break ;
2017-06-26 14:04:53 +00:00
case FILE_QUIT :
2022-03-23 11:07:29 +00:00
case RUN_PROJECT_MANAGER :
case RELOAD_CURRENT_PROJECT : {
2014-02-18 04:21:06 +00:00
if ( ! p_confirmed ) {
2018-05-17 21:02:16 +00:00
bool save_each = EDITOR_GET ( " interface/editor/save_each_scene_on_quit " ) ;
2017-07-26 11:29:45 +00:00
if ( _next_unsaved_scene ( ! save_each ) = = - 1 ) {
2019-09-24 21:06:21 +00:00
_discard_changes ( ) ;
break ;
2017-06-24 10:57:30 +00:00
} else {
2017-06-26 14:04:53 +00:00
if ( save_each ) {
2022-03-23 11:07:29 +00:00
if ( p_option = = RELOAD_CURRENT_PROJECT ) {
_menu_option_confirm ( FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT , false ) ;
} else if ( p_option = = FILE_QUIT ) {
_menu_option_confirm ( FILE_CLOSE_ALL_AND_QUIT , false ) ;
} else {
_menu_option_confirm ( FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER , false ) ;
}
2017-06-26 14:04:53 +00:00
} else {
String unsaved_scenes ;
2017-07-26 11:29:45 +00:00
int i = _next_unsaved_scene ( true , 0 ) ;
while ( i ! = - 1 ) {
2021-09-30 14:30:55 +00:00
unsaved_scenes + = " \n " + editor_data . get_edited_scene_root ( i ) - > get_scene_file_path ( ) ;
2017-07-26 11:29:45 +00:00
i = _next_unsaved_scene ( true , + + i ) ;
2017-06-26 14:04:53 +00:00
}
2022-03-23 11:07:29 +00:00
if ( p_option = = RELOAD_CURRENT_PROJECT ) {
save_confirmation - > get_ok_button ( ) - > set_text ( TTR ( " Save & Reload " ) ) ;
save_confirmation - > set_text ( TTR ( " Save changes to the following scene(s) before reloading? " ) + unsaved_scenes ) ;
} else {
save_confirmation - > get_ok_button ( ) - > set_text ( TTR ( " Save & Quit " ) ) ;
save_confirmation - > set_text ( ( p_option = = FILE_QUIT ? TTR ( " Save changes to the following scene(s) before quitting? " ) : TTR ( " Save changes to the following scene(s) before opening Project Manager? " ) ) + unsaved_scenes ) ;
}
2020-03-06 17:00:16 +00:00
save_confirmation - > popup_centered ( ) ;
2017-06-26 14:04:53 +00:00
}
2017-06-24 10:57:30 +00:00
}
2017-06-26 14:04:53 +00:00
2020-03-03 13:36:29 +00:00
DisplayServer : : get_singleton ( ) - > window_request_attention ( ) ;
2017-06-26 14:04:53 +00:00
break ;
2017-06-24 10:57:30 +00:00
}
2014-02-18 04:21:06 +00:00
2017-07-26 11:29:45 +00:00
if ( _next_unsaved_scene ( true ) ! = - 1 ) {
2017-06-24 10:57:30 +00:00
_save_all_scenes ( ) ;
2017-06-26 14:04:53 +00:00
}
2017-06-24 10:57:30 +00:00
_discard_changes ( ) ;
2014-02-18 04:21:06 +00:00
} break ;
2018-12-11 15:52:25 +00:00
case SETTINGS_UPDATE_CONTINUOUSLY : {
EditorSettings : : get_singleton ( ) - > set ( " interface/editor/update_continuously " , true ) ;
_update_update_spinner ( ) ;
2018-08-05 14:47:41 +00:00
show_accept ( TTR ( " This option is deprecated. Situations where refresh must be forced are now considered a bug. Please report. " ) , TTR ( " OK " ) ) ;
2014-02-10 01:10:30 +00:00
} break ;
2018-12-11 15:52:25 +00:00
case SETTINGS_UPDATE_WHEN_CHANGED : {
EditorSettings : : get_singleton ( ) - > set ( " interface/editor/update_continuously " , false ) ;
_update_update_spinner ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
2017-03-05 15:44:50 +00:00
case SETTINGS_UPDATE_SPINNER_HIDE : {
2018-12-11 15:52:25 +00:00
EditorSettings : : get_singleton ( ) - > set ( " interface/editor/show_update_spinner " , false ) ;
_update_update_spinner ( ) ;
2017-03-05 15:44:50 +00:00
} break ;
2014-02-10 01:10:30 +00:00
case SETTINGS_PREFERENCES : {
2022-01-31 23:19:01 +00:00
editor_settings_dialog - > popup_edit_settings ( ) ;
2014-02-10 01:10:30 +00:00
} break ;
2018-07-25 17:53:12 +00:00
case SETTINGS_EDITOR_DATA_FOLDER : {
2021-05-25 00:25:11 +00:00
OS : : get_singleton ( ) - > shell_open ( String ( " file:// " ) + EditorPaths : : get_singleton ( ) - > get_data_dir ( ) ) ;
2018-07-25 17:53:12 +00:00
} break ;
case SETTINGS_EDITOR_CONFIG_FOLDER : {
2021-06-03 15:24:07 +00:00
OS : : get_singleton ( ) - > shell_open ( String ( " file:// " ) + EditorPaths : : get_singleton ( ) - > get_config_dir ( ) ) ;
2018-07-25 17:53:12 +00:00
} break ;
2017-03-21 02:31:41 +00:00
case SETTINGS_MANAGE_EXPORT_TEMPLATES : {
export_template_manager - > popup_manager ( ) ;
2014-02-10 01:10:30 +00:00
2019-04-08 22:18:03 +00:00
} break ;
2021-07-15 13:12:56 +00:00
case SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE : {
custom_build_manage_templates - > hide ( ) ;
file_android_build_source - > popup_centered_ratio ( ) ;
} break ;
2019-04-08 22:18:03 +00:00
case SETTINGS_MANAGE_FEATURE_PROFILES : {
2019-04-26 19:36:44 +00:00
feature_profile_manager - > popup_centered_clamped ( Size2 ( 900 , 800 ) * EDSCALE , 0.8 ) ;
2016-09-13 12:46:17 +00:00
} break ;
2018-06-11 05:53:25 +00:00
case SETTINGS_TOGGLE_FULLSCREEN : {
2020-03-03 13:36:29 +00:00
DisplayServer : : get_singleton ( ) - > window_set_mode ( DisplayServer : : get_singleton ( ) - > window_get_mode ( ) = = DisplayServer : : WINDOW_MODE_FULLSCREEN ? DisplayServer : : WINDOW_MODE_WINDOWED : DisplayServer : : WINDOW_MODE_FULLSCREEN ) ;
2016-09-13 12:46:17 +00:00
2018-12-18 13:17:43 +00:00
} break ;
2019-03-29 13:53:11 +00:00
case EDITOR_SCREENSHOT : {
screenshot_timer - > start ( ) ;
} break ;
2016-06-27 22:59:33 +00:00
case SETTINGS_PICK_MAIN_SCENE : {
2020-03-06 17:00:16 +00:00
file - > set_file_mode ( EditorFileDialog : : FILE_MODE_OPEN_FILE ) ;
2016-06-27 22:59:33 +00:00
List < String > extensions ;
2017-03-05 15:44:50 +00:00
ResourceLoader : : get_recognized_extensions_for_type ( " PackedScene " , & extensions ) ;
2016-06-27 22:59:33 +00:00
file - > clear_filters ( ) ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < extensions . size ( ) ; i + + ) {
file - > add_filter ( " *. " + extensions [ i ] + " ; " + extensions [ i ] . to_upper ( ) ) ;
2016-06-27 22:59:33 +00:00
}
Node * scene = editor_data . get_edited_scene_root ( ) ;
if ( scene ) {
2021-09-30 14:30:55 +00:00
file - > set_current_path ( scene - > get_scene_file_path ( ) ) ;
2016-06-27 22:59:33 +00:00
} ;
2016-06-28 10:00:18 +00:00
file - > set_title ( TTR ( " Pick a Main Scene " ) ) ;
2020-07-11 16:45:19 +00:00
file - > popup_file_dialog ( ) ;
2016-06-27 22:59:33 +00:00
2014-02-10 01:10:30 +00:00
} break ;
2017-05-26 14:34:41 +00:00
case HELP_SEARCH : {
2021-07-17 21:22:52 +00:00
emit_signal ( SNAME ( " request_help_search " ) , " " ) ;
2017-05-26 14:34:41 +00:00
} break ;
2021-05-29 13:28:16 +00:00
case HELP_COMMAND_PALETTE : {
command_palette - > open_popup ( ) ;
} break ;
2017-05-26 14:34:41 +00:00
case HELP_DOCS : {
2022-02-17 17:16:11 +00:00
OS : : get_singleton ( ) - > shell_open ( VERSION_DOCS_URL " / " ) ;
2017-05-26 14:34:41 +00:00
} break ;
case HELP_QA : {
OS : : get_singleton ( ) - > shell_open ( " https://godotengine.org/qa/ " ) ;
} break ;
2020-01-29 22:10:09 +00:00
case HELP_REPORT_A_BUG : {
2017-05-26 14:34:41 +00:00
OS : : get_singleton ( ) - > shell_open ( " https://github.com/godotengine/godot/issues " ) ;
} break ;
2021-06-16 00:24:34 +00:00
case HELP_SUGGEST_A_FEATURE : {
OS : : get_singleton ( ) - > shell_open ( " https://github.com/godotengine/godot-proposals#readme " ) ;
} break ;
2020-01-29 22:10:09 +00:00
case HELP_SEND_DOCS_FEEDBACK : {
OS : : get_singleton ( ) - > shell_open ( " https://github.com/godotengine/godot-docs/issues " ) ;
} break ;
2017-05-26 14:34:41 +00:00
case HELP_COMMUNITY : {
OS : : get_singleton ( ) - > shell_open ( " https://godotengine.org/community " ) ;
} break ;
case HELP_ABOUT : {
2020-03-06 17:00:16 +00:00
about - > popup_centered ( Size2 ( 780 , 500 ) * EDSCALE ) ;
2014-02-10 01:10:30 +00:00
} break ;
2021-05-14 23:57:21 +00:00
case HELP_SUPPORT_GODOT_DEVELOPMENT : {
OS : : get_singleton ( ) - > shell_open ( " https://godotengine.org/donate " ) ;
} break ;
2020-11-18 18:11:30 +00:00
case SET_RENDERING_DRIVER_SAVE_AND_RESTART : {
ProjectSettings : : get_singleton ( ) - > set ( " rendering/driver/driver_name " , rendering_driver_request ) ;
2018-07-19 21:58:15 +00:00
ProjectSettings : : get_singleton ( ) - > save ( ) ;
2019-01-25 20:23:56 +00:00
save_all_scenes ( ) ;
restart_editor ( ) ;
2018-07-19 21:58:15 +00:00
} break ;
2016-03-08 23:00:52 +00:00
}
2014-02-10 01:10:30 +00:00
}
2019-03-29 13:53:11 +00:00
void EditorNode : : _request_screenshot ( ) {
_screenshot ( ) ;
}
void EditorNode : : _screenshot ( bool p_use_utc ) {
2021-05-24 11:54:05 +00:00
String name = " editor_screenshot_ " + Time : : get_singleton ( ) - > get_datetime_string_from_system ( p_use_utc ) . replace ( " : " , " " ) + " .png " ;
2019-03-29 13:53:11 +00:00
NodePath path = String ( " user:// " ) + name ;
_save_screenshot ( path ) ;
2019-07-23 05:05:29 +00:00
if ( EditorSettings : : get_singleton ( ) - > get ( " interface/editor/automatically_open_screenshots " ) ) {
2019-03-29 13:53:11 +00:00
OS : : get_singleton ( ) - > shell_open ( String ( " file:// " ) + ProjectSettings : : get_singleton ( ) - > globalize_path ( path ) ) ;
}
}
void EditorNode : : _save_screenshot ( NodePath p_path ) {
2020-12-19 14:17:42 +00:00
Control * editor_main_control = EditorInterface : : get_singleton ( ) - > get_editor_main_control ( ) ;
ERR_FAIL_COND_MSG ( ! editor_main_control , " Cannot get editor main control. " ) ;
Viewport * viewport = editor_main_control - > get_viewport ( ) ;
ERR_FAIL_COND_MSG ( ! viewport , " Cannot get editor main control viewport. " ) ;
2020-11-11 22:12:31 +00:00
Ref < ViewportTexture > texture = viewport - > get_texture ( ) ;
2020-12-19 14:17:42 +00:00
ERR_FAIL_COND_MSG ( texture . is_null ( ) , " Cannot get editor main control viewport texture. " ) ;
2021-03-28 11:32:17 +00:00
Ref < Image > img = texture - > get_image ( ) ;
2020-12-19 14:17:42 +00:00
ERR_FAIL_COND_MSG ( img . is_null ( ) , " Cannot get editor main control viewport texture image. " ) ;
2019-03-29 13:53:11 +00:00
Error error = img - > save_png ( p_path ) ;
2019-09-25 08:28:50 +00:00
ERR_FAIL_COND_MSG ( error ! = OK , " Cannot save screenshot to file ' " + p_path + " '. " ) ;
2019-03-29 13:53:11 +00:00
}
2018-03-17 01:50:35 +00:00
void EditorNode : : _tool_menu_option ( int p_idx ) {
switch ( tool_menu - > get_item_id ( p_idx ) ) {
case TOOLS_ORPHAN_RESOURCES : {
orphan_resources - > show ( ) ;
} break ;
case TOOLS_CUSTOM : {
if ( tool_menu - > get_item_submenu ( p_idx ) = = " " ) {
2020-12-15 23:04:21 +00:00
Callable callback = tool_menu - > get_item_metadata ( p_idx ) ;
2020-02-19 19:27:19 +00:00
Callable : : CallError ce ;
2020-12-15 23:04:21 +00:00
Variant result ;
callback . call ( nullptr , 0 , result , ce ) ;
2018-03-17 01:50:35 +00:00
2020-02-19 19:27:19 +00:00
if ( ce . error ! = Callable : : CallError : : CALL_OK ) {
2020-12-15 23:04:21 +00:00
String err = Variant : : get_callable_error_text ( callback , nullptr , 0 , ce ) ;
2019-11-06 16:03:04 +00:00
ERR_PRINT ( " Error calling function from tool menu: " + err ) ;
2018-03-17 01:50:35 +00:00
}
2022-03-30 18:12:26 +00:00
} // Else it's a submenu so don't do anything.
2018-03-17 01:50:35 +00:00
} break ;
}
}
2022-04-06 12:41:04 +00:00
void EditorNode : : _export_as_menu_option ( int p_idx ) {
if ( p_idx = = 0 ) { // MeshLibrary
current_menu_option = FILE_EXPORT_MESH_LIBRARY ;
if ( ! editor_data . get_edited_scene_root ( ) ) {
show_accept ( TTR ( " This operation can't be done without a scene. " ) , TTR ( " OK " ) ) ;
return ;
}
List < String > extensions ;
Ref < MeshLibrary > ml ( memnew ( MeshLibrary ) ) ;
ResourceSaver : : get_recognized_extensions ( ml , & extensions ) ;
file_export_lib - > clear_filters ( ) ;
for ( const String & E : extensions ) {
file_export_lib - > add_filter ( " *. " + E ) ;
}
file_export_lib - > popup_file_dialog ( ) ;
file_export_lib - > set_title ( TTR ( " Export Mesh Library " ) ) ;
} else { // Custom menu options added by plugins
if ( export_as_menu - > get_item_submenu ( p_idx ) . is_empty ( ) ) { // If not a submenu
Callable callback = export_as_menu - > get_item_metadata ( p_idx ) ;
Callable : : CallError ce ;
Variant result ;
callback . call ( nullptr , 0 , result , ce ) ;
if ( ce . error ! = Callable : : CallError : : CALL_OK ) {
String err = Variant : : get_callable_error_text ( callback , nullptr , 0 , ce ) ;
ERR_PRINT ( " Error calling function from export_as menu: " + err ) ;
}
}
}
}
2017-07-26 11:29:45 +00:00
int EditorNode : : _next_unsaved_scene ( bool p_valid_filename , int p_start ) {
for ( int i = p_start ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
2020-05-14 14:41:43 +00:00
if ( ! editor_data . get_edited_scene_root ( i ) ) {
2017-07-09 18:48:39 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2017-06-24 10:57:30 +00:00
int current = editor_data . get_edited_scene ( ) ;
bool unsaved = ( i = = current ) ? saved_version ! = editor_data . get_undo_redo ( ) . get_version ( ) : editor_data . get_scene_version ( i ) ! = 0 ;
2017-06-26 14:04:53 +00:00
if ( unsaved ) {
2021-09-30 14:30:55 +00:00
String scene_filename = editor_data . get_edited_scene_root ( i ) - > get_scene_file_path ( ) ;
2020-05-14 14:41:43 +00:00
if ( p_valid_filename & & scene_filename . length ( ) = = 0 ) {
2017-07-26 11:29:45 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2017-06-26 14:04:53 +00:00
return i ;
}
2017-06-24 10:57:30 +00:00
}
2017-06-26 14:04:53 +00:00
return - 1 ;
2017-06-24 10:57:30 +00:00
}
2022-01-18 11:48:12 +00:00
void EditorNode : : _exit_editor ( int p_exit_code ) {
2019-01-17 12:09:01 +00:00
exiting = true ;
2022-03-30 18:12:26 +00:00
resource_preview - > stop ( ) ; // Stop early to avoid crashes.
2019-04-13 11:43:35 +00:00
_save_docks ( ) ;
2019-07-04 21:45:51 +00:00
2022-03-30 18:12:26 +00:00
// Dim the editor window while it's quitting to make it clearer that it's busy.
2021-05-28 23:58:03 +00:00
dim_editor ( true ) ;
2019-07-04 21:45:51 +00:00
2022-01-18 11:48:12 +00:00
get_tree ( ) - > quit ( p_exit_code ) ;
2019-01-17 12:09:01 +00:00
}
2017-06-21 04:15:39 +00:00
void EditorNode : : _discard_changes ( const String & p_str ) {
2022-03-30 18:12:26 +00:00
switch ( current_menu_option ) {
2017-06-26 14:04:53 +00:00
case FILE_CLOSE_ALL_AND_QUIT :
case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER :
2022-03-23 11:07:29 +00:00
case FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT :
2017-06-21 04:15:39 +00:00
case FILE_CLOSE :
2019-04-21 09:44:21 +00:00
case FILE_CLOSE_OTHERS :
case FILE_CLOSE_RIGHT :
case FILE_CLOSE_ALL :
2017-06-21 04:15:39 +00:00
case SCENE_TAB_CLOSE : {
2022-03-30 18:12:26 +00:00
Node * scene = editor_data . get_edited_scene_root ( tab_closing_idx ) ;
2020-04-01 23:20:12 +00:00
if ( scene ! = nullptr ) {
2021-09-30 14:30:55 +00:00
String scene_filename = scene - > get_scene_file_path ( ) ;
2021-12-09 09:42:46 +00:00
if ( ! scene_filename . is_empty ( ) ) {
2019-07-31 21:49:16 +00:00
previous_scenes . push_back ( scene_filename ) ;
}
2019-04-10 15:21:26 +00:00
}
2022-03-30 18:12:26 +00:00
_remove_scene ( tab_closing_idx ) ;
2017-06-21 04:15:39 +00:00
_update_scene_tabs ( ) ;
2017-06-26 14:04:53 +00:00
2022-03-30 18:12:26 +00:00
if ( current_menu_option = = FILE_CLOSE_ALL_AND_QUIT | | current_menu_option = = FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER | | current_menu_option = = FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT ) {
2020-02-19 09:36:26 +00:00
// If restore tabs is enabled, reopen the scene that has just been closed, so it's remembered properly.
if ( bool ( EDITOR_GET ( " interface/scene_tabs/restore_scenes_on_load " ) ) ) {
_menu_option_confirm ( FILE_OPEN_PREV , true ) ;
}
2017-07-26 11:29:45 +00:00
if ( _next_unsaved_scene ( false ) = = - 1 ) {
2022-03-30 18:12:26 +00:00
if ( current_menu_option = = FILE_CLOSE_ALL_AND_RELOAD_CURRENT_PROJECT ) {
current_menu_option = RELOAD_CURRENT_PROJECT ;
} else if ( current_menu_option = = FILE_CLOSE_ALL_AND_QUIT ) {
current_menu_option = FILE_QUIT ;
2022-03-23 11:07:29 +00:00
} else {
2022-03-30 18:12:26 +00:00
current_menu_option = RUN_PROJECT_MANAGER ;
2022-03-23 11:07:29 +00:00
}
2017-06-26 14:04:53 +00:00
_discard_changes ( ) ;
} else {
2022-03-30 18:12:26 +00:00
_menu_option_confirm ( current_menu_option , false ) ;
2017-06-26 14:04:53 +00:00
}
2022-03-30 18:12:26 +00:00
} else if ( current_menu_option = = FILE_CLOSE_OTHERS | | current_menu_option = = FILE_CLOSE_RIGHT ) {
if ( editor_data . get_edited_scene_count ( ) = = 1 | | ( current_menu_option = = FILE_CLOSE_RIGHT & & editor_data . get_edited_scene_count ( ) < = editor_data . get_edited_scene ( ) + 1 ) ) {
current_menu_option = - 1 ;
2019-04-21 09:44:21 +00:00
save_confirmation - > hide ( ) ;
} else {
2022-03-30 18:12:26 +00:00
_menu_option_confirm ( current_menu_option , false ) ;
2019-04-21 09:44:21 +00:00
}
2022-03-30 18:12:26 +00:00
} else if ( current_menu_option = = FILE_CLOSE_ALL & & editor_data . get_edited_scene_count ( ) > 0 ) {
_menu_option_confirm ( current_menu_option , false ) ;
2017-06-26 14:04:53 +00:00
} else {
2022-03-30 18:12:26 +00:00
current_menu_option = - 1 ;
2017-06-26 14:04:53 +00:00
save_confirmation - > hide ( ) ;
}
2017-06-21 04:15:39 +00:00
} break ;
2017-06-24 10:57:30 +00:00
case FILE_QUIT : {
_menu_option_confirm ( RUN_STOP , true ) ;
2022-01-18 11:48:12 +00:00
_exit_editor ( EXIT_SUCCESS ) ;
2019-01-17 12:09:01 +00:00
2017-06-24 10:57:30 +00:00
} break ;
case RUN_PROJECT_MANAGER : {
_menu_option_confirm ( RUN_STOP , true ) ;
2022-01-18 11:48:12 +00:00
_exit_editor ( EXIT_SUCCESS ) ;
2017-06-24 10:57:30 +00:00
String exec = OS : : get_singleton ( ) - > get_executable_path ( ) ;
List < String > args ;
2017-06-21 09:09:30 +00:00
args . push_back ( " --path " ) ;
2017-06-24 10:57:30 +00:00
args . push_back ( exec . get_base_dir ( ) ) ;
2017-06-21 09:09:30 +00:00
args . push_back ( " --project-manager " ) ;
2017-06-24 10:57:30 +00:00
2021-11-01 09:12:52 +00:00
Error err = OS : : get_singleton ( ) - > create_instance ( args ) ;
2017-06-24 10:57:30 +00:00
ERR_FAIL_COND ( err ) ;
} break ;
2022-03-23 11:07:29 +00:00
case RELOAD_CURRENT_PROJECT : {
restart_editor ( ) ;
} break ;
2017-06-21 04:15:39 +00:00
}
}
2019-04-10 15:21:26 +00:00
void EditorNode : : _update_file_menu_opened ( ) {
2020-09-09 19:53:24 +00:00
Ref < Shortcut > close_scene_sc = ED_GET_SHORTCUT ( " editor/close_scene " ) ;
2019-04-10 15:21:26 +00:00
close_scene_sc - > set_name ( TTR ( " Close Scene " ) ) ;
2020-09-09 19:53:24 +00:00
Ref < Shortcut > reopen_closed_scene_sc = ED_GET_SHORTCUT ( " editor/reopen_closed_scene " ) ;
2019-04-10 15:21:26 +00:00
reopen_closed_scene_sc - > set_name ( TTR ( " Reopen Closed Scene " ) ) ;
2021-08-17 03:41:46 +00:00
2019-04-10 15:21:26 +00:00
PopupMenu * pop = file_menu - > get_popup ( ) ;
2020-12-15 12:04:21 +00:00
pop - > set_item_disabled ( pop - > get_item_index ( FILE_OPEN_PREV ) , previous_scenes . is_empty ( ) ) ;
2021-08-17 03:41:46 +00:00
const UndoRedo & undo_redo = editor_data . get_undo_redo ( ) ;
pop - > set_item_disabled ( pop - > get_item_index ( EDIT_UNDO ) , ! undo_redo . has_undo ( ) ) ;
pop - > set_item_disabled ( pop - > get_item_index ( EDIT_REDO ) , ! undo_redo . has_redo ( ) ) ;
2019-04-10 15:21:26 +00:00
}
void EditorNode : : _update_file_menu_closed ( ) {
PopupMenu * pop = file_menu - > get_popup ( ) ;
pop - > set_item_disabled ( pop - > get_item_index ( FILE_OPEN_PREV ) , false ) ;
}
2020-12-19 14:17:42 +00:00
Control * EditorNode : : get_main_control ( ) {
return main_control ;
2014-02-10 01:10:30 +00:00
}
void EditorNode : : _editor_select ( int p_which ) {
2017-03-05 15:44:50 +00:00
static bool selecting = false ;
2020-05-14 14:41:43 +00:00
if ( selecting | | changing_scene ) {
2014-02-10 01:10:30 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
ERR_FAIL_INDEX ( p_which , editor_table . size ( ) ) ;
2014-02-10 01:10:30 +00:00
2022-03-30 18:12:26 +00:00
if ( ! main_editor_buttons [ p_which ] - > is_visible ( ) ) { // Button hidden, no editor.
2019-04-08 22:18:03 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2019-04-08 22:18:03 +00:00
selecting = true ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < main_editor_buttons . size ( ) ; i + + ) {
main_editor_buttons [ i ] - > set_pressed ( i = = p_which ) ;
2015-11-18 07:47:41 +00:00
}
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
selecting = false ;
2014-02-10 01:10:30 +00:00
EditorPlugin * new_editor = editor_table [ p_which ] ;
ERR_FAIL_COND ( ! new_editor ) ;
2020-05-14 14:41:43 +00:00
if ( editor_plugin_screen = = new_editor ) {
2014-02-10 01:10:30 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
if ( editor_plugin_screen ) {
editor_plugin_screen - > make_visible ( false ) ;
}
2017-03-05 15:44:50 +00:00
editor_plugin_screen = new_editor ;
2014-02-10 01:10:30 +00:00
editor_plugin_screen - > make_visible ( true ) ;
editor_plugin_screen - > selected_notify ( ) ;
2017-04-25 11:48:35 +00:00
2017-07-06 07:18:20 +00:00
int plugin_count = editor_data . get_editor_plugin_count ( ) ;
for ( int i = 0 ; i < plugin_count ; i + + ) {
editor_data . get_editor_plugin ( i ) - > notify_main_screen_changed ( editor_plugin_screen - > get_name ( ) ) ;
}
2017-09-29 16:52:56 +00:00
if ( EditorSettings : : get_singleton ( ) - > get ( " interface/editor/separate_distraction_mode " ) ) {
2017-04-25 11:48:35 +00:00
if ( p_which = = EDITOR_SCRIPT ) {
2022-03-30 18:12:26 +00:00
set_distraction_free_mode ( script_distraction_free ) ;
2017-04-25 11:48:35 +00:00
} else {
2022-03-30 18:12:26 +00:00
set_distraction_free_mode ( scene_distraction_free ) ;
2017-04-25 11:48:35 +00:00
}
}
2014-02-10 01:10:30 +00:00
}
2019-08-05 17:57:23 +00:00
void EditorNode : : select_editor_by_name ( const String & p_name ) {
2021-12-09 09:42:46 +00:00
ERR_FAIL_COND ( p_name . is_empty ( ) ) ;
2019-08-05 17:57:23 +00:00
for ( int i = 0 ; i < main_editor_buttons . size ( ) ; i + + ) {
if ( main_editor_buttons [ i ] - > get_text ( ) = = p_name ) {
_editor_select ( i ) ;
return ;
}
}
2019-08-15 02:57:49 +00:00
ERR_FAIL_MSG ( " The editor name ' " + p_name + " ' was not found. " ) ;
2019-08-05 17:57:23 +00:00
}
2018-06-11 00:59:53 +00:00
void EditorNode : : add_editor_plugin ( EditorPlugin * p_editor , bool p_config_changed ) {
2014-02-10 01:10:30 +00:00
if ( p_editor - > has_main_screen ( ) ) {
2020-06-19 18:49:04 +00:00
Button * tb = memnew ( Button ) ;
tb - > set_flat ( true ) ;
2015-11-18 07:47:41 +00:00
tb - > set_toggle_mode ( true ) ;
2020-02-21 22:26:13 +00:00
tb - > connect ( " pressed " , callable_mp ( singleton , & EditorNode : : _editor_select ) , varray ( singleton - > main_editor_buttons . size ( ) ) ) ;
2020-08-05 03:14:39 +00:00
tb - > set_name ( p_editor - > get_name ( ) ) ;
2017-05-02 21:02:06 +00:00
tb - > set_text ( p_editor - > get_name ( ) ) ;
2017-12-06 22:27:45 +00:00
2020-08-05 03:14:39 +00:00
Ref < Texture2D > icon = p_editor - > get_icon ( ) ;
2017-12-06 22:27:45 +00:00
if ( icon . is_valid ( ) ) {
tb - > set_icon ( icon ) ;
2022-02-06 14:53:53 +00:00
} else if ( singleton - > gui_base - > has_theme_icon ( p_editor - > get_name ( ) , SNAME ( " EditorIcons " ) ) ) {
tb - > set_icon ( singleton - > gui_base - > get_theme_icon ( p_editor - > get_name ( ) , SNAME ( " EditorIcons " ) ) ) ;
2017-12-06 22:27:45 +00:00
}
2022-02-08 09:14:58 +00:00
tb - > add_theme_font_override ( " font " , singleton - > gui_base - > get_theme_font ( SNAME ( " main_button_font " ) , SNAME ( " EditorFonts " ) ) ) ;
tb - > add_theme_font_size_override ( " font_size " , singleton - > gui_base - > get_theme_font_size ( SNAME ( " main_button_font_size " ) , SNAME ( " EditorFonts " ) ) ) ;
2021-05-27 15:32:30 +00:00
2015-11-18 07:47:41 +00:00
singleton - > main_editor_buttons . push_back ( tb ) ;
singleton - > main_editor_button_vb - > add_child ( tb ) ;
2014-02-10 01:10:30 +00:00
singleton - > editor_table . push_back ( p_editor ) ;
2016-09-13 12:46:17 +00:00
singleton - > distraction_free - > raise ( ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
singleton - > editor_data . add_editor_plugin ( p_editor ) ;
2014-02-10 01:10:30 +00:00
singleton - > add_child ( p_editor ) ;
2020-05-14 14:41:43 +00:00
if ( p_config_changed ) {
2018-06-11 00:59:53 +00:00
p_editor - > enable_plugin ( ) ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
}
2018-06-11 00:59:53 +00:00
void EditorNode : : remove_editor_plugin ( EditorPlugin * p_editor , bool p_config_changed ) {
2014-02-10 01:10:30 +00:00
if ( p_editor - > has_main_screen ( ) ) {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < singleton - > main_editor_buttons . size ( ) ; i + + ) {
if ( p_editor - > get_name ( ) = = singleton - > main_editor_buttons [ i ] - > get_text ( ) ) {
2016-09-21 22:17:55 +00:00
if ( singleton - > main_editor_buttons [ i ] - > is_pressed ( ) ) {
singleton - > _editor_select ( EDITOR_SCRIPT ) ;
}
2017-03-05 15:44:50 +00:00
memdelete ( singleton - > main_editor_buttons [ i ] ) ;
2021-07-03 22:17:03 +00:00
singleton - > main_editor_buttons . remove_at ( i ) ;
2014-02-10 01:10:30 +00:00
break ;
}
}
singleton - > editor_table . erase ( p_editor ) ;
}
2016-06-18 22:29:16 +00:00
p_editor - > make_visible ( false ) ;
p_editor - > clear ( ) ;
2020-05-14 14:41:43 +00:00
if ( p_config_changed ) {
2018-06-11 00:59:53 +00:00
p_editor - > disable_plugin ( ) ;
2020-05-14 14:41:43 +00:00
}
2021-05-17 08:46:59 +00:00
singleton - > editor_plugins_over - > remove_plugin ( p_editor ) ;
singleton - > editor_plugins_force_over - > remove_plugin ( p_editor ) ;
singleton - > editor_plugins_force_input_forwarding - > remove_plugin ( p_editor ) ;
2014-02-10 01:10:30 +00:00
singleton - > remove_child ( p_editor ) ;
2017-03-05 15:44:50 +00:00
singleton - > editor_data . remove_editor_plugin ( p_editor ) ;
2014-02-10 01:10:30 +00:00
}
2016-02-28 02:10:44 +00:00
void EditorNode : : _update_addon_config ( ) {
2022-03-30 18:12:26 +00:00
if ( _initializing_plugins ) {
2016-02-28 02:10:44 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2016-02-28 02:10:44 +00:00
Vector < String > enabled_addons ;
2022-03-30 18:12:26 +00:00
for ( const KeyValue < String , EditorPlugin * > & E : addon_name_to_plugin ) {
2021-08-09 20:13:42 +00:00
enabled_addons . push_back ( E . key ) ;
2016-02-28 02:10:44 +00:00
}
2017-03-05 15:44:50 +00:00
if ( enabled_addons . size ( ) = = 0 ) {
2017-07-19 20:00:46 +00:00
ProjectSettings : : get_singleton ( ) - > set ( " editor_plugins/enabled " , Variant ( ) ) ;
2016-02-28 02:10:44 +00:00
} else {
2017-07-19 20:00:46 +00:00
ProjectSettings : : get_singleton ( ) - > set ( " editor_plugins/enabled " , enabled_addons ) ;
2016-02-28 02:10:44 +00:00
}
2022-01-31 23:19:01 +00:00
project_settings_editor - > queue_save ( ) ;
2016-02-28 02:10:44 +00:00
}
2018-06-11 00:59:53 +00:00
void EditorNode : : set_addon_plugin_enabled ( const String & p_addon , bool p_enabled , bool p_config_changed ) {
2022-06-08 17:22:30 +00:00
String addon_path = p_addon ;
if ( ! addon_path . begins_with ( " res:// " ) ) {
addon_path = " res://addons/ " + addon_path + " /plugin.cfg " ;
}
ERR_FAIL_COND ( p_enabled & & addon_name_to_plugin . has ( addon_path ) ) ;
ERR_FAIL_COND ( ! p_enabled & & ! addon_name_to_plugin . has ( addon_path ) ) ;
2016-02-28 02:10:44 +00:00
if ( ! p_enabled ) {
2022-06-08 17:22:30 +00:00
EditorPlugin * addon = addon_name_to_plugin [ addon_path ] ;
2018-06-11 00:59:53 +00:00
remove_editor_plugin ( addon , p_config_changed ) ;
2022-03-30 18:12:26 +00:00
memdelete ( addon ) ;
2022-06-08 17:22:30 +00:00
addon_name_to_plugin . erase ( addon_path ) ;
2016-02-28 02:10:44 +00:00
_update_addon_config ( ) ;
return ;
}
Ref < ConfigFile > cf ;
2021-06-17 22:03:09 +00:00
cf . instantiate ( ) ;
2022-06-08 17:22:30 +00:00
if ( ! DirAccess : : exists ( addon_path . get_base_dir ( ) ) ) {
_remove_plugin_from_enabled ( addon_path ) ;
WARN_PRINT ( " Addon ' " + addon_path + " ' failed to load. No directory found. Removing from enabled plugins. " ) ;
2019-02-16 23:53:14 +00:00
return ;
}
2022-06-08 17:22:30 +00:00
Error err = cf - > load ( addon_path ) ;
2017-03-05 15:44:50 +00:00
if ( err ! = OK ) {
2022-06-08 17:22:30 +00:00
show_warning ( vformat ( TTR ( " Unable to enable addon plugin at: '%s' parsing of config failed. " ) , addon_path ) ) ;
2016-02-28 02:10:44 +00:00
return ;
}
2017-03-05 15:44:50 +00:00
if ( ! cf - > has_section_key ( " plugin " , " script " ) ) {
2022-06-08 17:22:30 +00:00
show_warning ( vformat ( TTR ( " Unable to find script field for addon plugin at: '%s'. " ) , addon_path ) ) ;
2016-02-28 02:10:44 +00:00
return ;
}
2019-08-15 17:40:22 +00:00
String script_path = cf - > get_value ( " plugin " , " script " ) ;
Ref < Script > script ; // We need to save it for creating "ep" below.
2016-02-28 02:10:44 +00:00
2019-08-15 17:40:22 +00:00
// Only try to load the script if it has a name. Else, the plugin has no init script.
if ( script_path . length ( ) > 0 ) {
2022-06-08 17:22:30 +00:00
script_path = addon_path . get_base_dir ( ) . plus_file ( script_path ) ;
2019-08-15 17:40:22 +00:00
script = ResourceLoader : : load ( script_path ) ;
2016-02-28 02:10:44 +00:00
2019-08-15 17:40:22 +00:00
if ( script . is_null ( ) ) {
show_warning ( vformat ( TTR ( " Unable to load addon script from path: '%s'. " ) , script_path ) ) ;
return ;
}
2016-02-28 02:10:44 +00:00
2022-02-06 13:12:19 +00:00
// Errors in the script cause the base_type to be an empty StringName.
if ( script - > get_instance_base_type ( ) = = StringName ( ) ) {
2022-06-08 17:22:30 +00:00
show_warning ( vformat ( TTR ( " Unable to load addon script from path: '%s'. This might be due to a code error in that script. \n Disabling the addon at '%s' to prevent further errors. " ) , script_path , addon_path ) ) ;
_remove_plugin_from_enabled ( addon_path ) ;
2019-08-15 17:40:22 +00:00
return ;
}
2018-10-13 12:20:18 +00:00
2019-08-15 17:40:22 +00:00
// Plugin init scripts must inherit from EditorPlugin and be tools.
if ( String ( script - > get_instance_base_type ( ) ) ! = " EditorPlugin " ) {
show_warning ( vformat ( TTR ( " Unable to load addon script from path: '%s' Base type is not EditorPlugin. " ) , script_path ) ) ;
return ;
}
2016-02-28 02:10:44 +00:00
2019-08-15 17:40:22 +00:00
if ( ! script - > is_tool ( ) ) {
show_warning ( vformat ( TTR ( " Unable to load addon script from path: '%s' Script is not in tool mode. " ) , script_path ) ) ;
return ;
}
2016-02-28 02:10:44 +00:00
}
2017-03-05 15:44:50 +00:00
EditorPlugin * ep = memnew ( EditorPlugin ) ;
2020-02-13 19:03:10 +00:00
ep - > set_script ( script ) ;
2022-06-08 17:22:30 +00:00
addon_name_to_plugin [ addon_path ] = ep ;
2018-06-11 00:59:53 +00:00
add_editor_plugin ( ep , p_config_changed ) ;
2016-02-28 02:10:44 +00:00
_update_addon_config ( ) ;
}
2017-03-05 15:44:50 +00:00
bool EditorNode : : is_addon_plugin_enabled ( const String & p_addon ) const {
2022-06-08 17:22:30 +00:00
if ( p_addon . begins_with ( " res:// " ) ) {
return addon_name_to_plugin . has ( p_addon ) ;
}
return addon_name_to_plugin . has ( " res://addons/ " + p_addon + " /plugin.cfg " ) ;
2016-02-28 02:10:44 +00:00
}
2019-06-04 03:36:23 +00:00
void EditorNode : : _remove_edited_scene ( bool p_change_tab ) {
2015-06-22 03:03:19 +00:00
int new_index = editor_data . get_edited_scene ( ) ;
2017-03-05 15:44:50 +00:00
int old_index = new_index ;
2015-06-22 03:03:19 +00:00
2017-03-05 15:44:50 +00:00
if ( new_index > 0 ) {
new_index = new_index - 1 ;
} else if ( editor_data . get_edited_scene_count ( ) > 1 ) {
new_index = 1 ;
2015-06-22 03:03:19 +00:00
} else {
editor_data . add_edited_scene ( - 1 ) ;
2017-03-05 15:44:50 +00:00
new_index = 1 ;
2015-06-22 03:03:19 +00:00
}
2020-05-14 14:41:43 +00:00
if ( p_change_tab ) {
2020-05-10 10:56:01 +00:00
_scene_tab_changed ( new_index ) ;
2020-05-14 14:41:43 +00:00
}
2015-06-22 03:03:19 +00:00
editor_data . remove_scene ( old_index ) ;
2018-11-18 20:07:38 +00:00
editor_data . get_undo_redo ( ) . clear_history ( false ) ;
2015-06-22 03:03:19 +00:00
_update_title ( ) ;
_update_scene_tabs ( ) ;
}
2015-10-21 22:23:42 +00:00
2019-06-04 03:36:23 +00:00
void EditorNode : : _remove_scene ( int index , bool p_change_tab ) {
2022-05-05 12:27:29 +00:00
// Clear icon cache in case some scripts are no longer needed.
script_icon_cache . clear ( ) ;
2015-10-21 22:23:42 +00:00
if ( editor_data . get_edited_scene ( ) = = index ) {
2022-03-30 18:12:26 +00:00
// Scene to remove is current scene.
2019-06-04 03:36:23 +00:00
_remove_edited_scene ( p_change_tab ) ;
2017-03-05 15:44:50 +00:00
} else {
2022-03-30 18:12:26 +00:00
// Scene to remove is not active scene.
2015-10-21 22:23:42 +00:00
editor_data . remove_scene ( index ) ;
}
}
2014-02-10 01:10:30 +00:00
void EditorNode : : set_edited_scene ( Node * p_scene ) {
2015-06-22 03:03:19 +00:00
if ( get_editor_data ( ) . get_edited_scene_root ( ) ) {
2020-05-14 14:41:43 +00:00
if ( get_editor_data ( ) . get_edited_scene_root ( ) - > get_parent ( ) = = scene_root ) {
2015-06-22 03:03:19 +00:00
scene_root - > remove_child ( get_editor_data ( ) . get_edited_scene_root ( ) ) ;
2020-05-14 14:41:43 +00:00
}
2016-03-08 23:00:52 +00:00
}
2015-06-22 03:03:19 +00:00
get_editor_data ( ) . set_edited_scene_root ( p_scene ) ;
2016-03-08 23:00:52 +00:00
2020-05-14 14:41:43 +00:00
if ( Object : : cast_to < Popup > ( p_scene ) ) {
2022-03-30 18:12:26 +00:00
Object : : cast_to < Popup > ( p_scene ) - > show ( ) ;
2020-05-14 14:41:43 +00:00
}
2021-11-17 20:08:55 +00:00
SceneTreeDock : : get_singleton ( ) - > set_edited_scene ( p_scene ) ;
2020-05-14 14:41:43 +00:00
if ( get_tree ( ) ) {
2015-06-22 03:03:19 +00:00
get_tree ( ) - > set_edited_scene_root ( p_scene ) ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2015-06-22 03:03:19 +00:00
if ( p_scene ) {
2020-05-14 14:41:43 +00:00
if ( p_scene - > get_parent ( ) ! = scene_root ) {
2021-10-21 14:46:07 +00:00
scene_root - > add_child ( p_scene , true ) ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
}
}
2015-11-18 07:47:41 +00:00
int EditorNode : : _get_current_main_editor ( ) {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < editor_table . size ( ) ; i + + ) {
2020-05-14 14:41:43 +00:00
if ( editor_table [ i ] = = editor_plugin_screen ) {
2015-11-18 07:47:41 +00:00
return i ;
2020-05-14 14:41:43 +00:00
}
2015-11-18 07:47:41 +00:00
}
return 0 ;
}
2015-06-22 03:03:19 +00:00
Dictionary EditorNode : : _get_main_scene_state ( ) {
Dictionary state ;
2017-03-05 15:44:50 +00:00
state [ " main_tab " ] = _get_current_main_editor ( ) ;
2021-11-17 20:08:55 +00:00
state [ " scene_tree_offset " ] = SceneTreeDock : : get_singleton ( ) - > get_tree_editor ( ) - > get_scene_tree ( ) - > get_vscroll_bar ( ) - > get_value ( ) ;
state [ " property_edit_offset " ] = InspectorDock : : get_inspector_singleton ( ) - > get_scroll_offset ( ) ;
2017-03-05 15:44:50 +00:00
state [ " saved_version " ] = saved_version ;
2021-11-17 20:08:55 +00:00
state [ " node_filter " ] = SceneTreeDock : : get_singleton ( ) - > get_filter ( ) ;
2015-06-22 03:03:19 +00:00
return state ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _set_main_scene_state ( Dictionary p_state , Node * p_for_scene ) {
2020-05-14 14:41:43 +00:00
if ( get_edited_scene ( ) ! = p_for_scene & & p_for_scene ! = nullptr ) {
2022-03-30 18:12:26 +00:00
return ; // Not for this scene.
2020-05-14 14:41:43 +00:00
}
2015-06-22 03:03:19 +00:00
2017-03-05 15:44:50 +00:00
changing_scene = false ;
2015-06-22 03:03:19 +00:00
2017-09-08 21:45:04 +00:00
int current = - 1 ;
for ( int i = 0 ; i < editor_table . size ( ) ; i + + ) {
if ( editor_plugin_screen = = editor_table [ i ] ) {
current = i ;
break ;
2015-11-17 12:46:08 +00:00
}
2017-09-08 21:45:04 +00:00
}
2015-11-17 12:46:08 +00:00
2017-09-08 21:45:04 +00:00
if ( p_state . has ( " editor_index " ) ) {
int index = p_state [ " editor_index " ] ;
2022-03-30 18:12:26 +00:00
if ( current < 2 ) { // If currently in spatial/2d, only switch to spatial/2d. If currently in script, stay there.
2017-09-04 21:00:09 +00:00
if ( index < 2 | | ! get_edited_scene ( ) ) {
_editor_select ( index ) ;
2017-09-08 21:45:04 +00:00
}
}
}
if ( get_edited_scene ( ) ) {
if ( current < 2 ) {
2022-03-30 18:12:26 +00:00
// Use heuristic instead.
2017-09-08 21:45:04 +00:00
int n2d = 0 , n3d = 0 ;
_find_node_types ( get_edited_scene ( ) , n2d , n3d ) ;
if ( n2d > n3d ) {
_editor_select ( EDITOR_2D ) ;
} else if ( n3d > n2d ) {
_editor_select ( EDITOR_3D ) ;
2015-11-17 12:46:08 +00:00
}
}
}
2020-05-14 14:41:43 +00:00
if ( p_state . has ( " scene_tree_offset " ) ) {
2021-11-17 20:08:55 +00:00
SceneTreeDock : : get_singleton ( ) - > get_tree_editor ( ) - > get_scene_tree ( ) - > get_vscroll_bar ( ) - > set_value ( p_state [ " scene_tree_offset " ] ) ;
2020-05-14 14:41:43 +00:00
}
if ( p_state . has ( " property_edit_offset " ) ) {
2021-11-17 20:08:55 +00:00
InspectorDock : : get_inspector_singleton ( ) - > set_scroll_offset ( p_state [ " property_edit_offset " ] ) ;
2020-05-14 14:41:43 +00:00
}
2015-06-22 03:03:19 +00:00
2020-05-14 14:41:43 +00:00
if ( p_state . has ( " node_filter " ) ) {
2021-11-17 20:08:55 +00:00
SceneTreeDock : : get_singleton ( ) - > set_filter ( p_state [ " node_filter " ] ) ;
2020-05-14 14:41:43 +00:00
}
2015-06-22 03:03:19 +00:00
2022-03-30 18:12:26 +00:00
// This should only happen at the very end.
2015-11-17 12:46:08 +00:00
2020-02-07 01:52:05 +00:00
EditorDebuggerNode : : get_singleton ( ) - > update_live_edit_root ( ) ;
2017-03-05 15:44:50 +00:00
ScriptEditor : : get_singleton ( ) - > set_scene_root_script ( editor_data . get_scene_root_script ( editor_data . get_edited_scene ( ) ) ) ;
2015-12-09 12:08:41 +00:00
editor_data . notify_edited_scene_changed ( ) ;
2015-06-22 03:03:19 +00:00
}
void EditorNode : : set_current_version ( uint64_t p_version ) {
2017-03-05 15:44:50 +00:00
saved_version = p_version ;
2015-06-22 03:03:19 +00:00
editor_data . set_edited_scene_version ( p_version ) ;
}
bool EditorNode : : is_changing_scene ( ) const {
return changing_scene ;
}
2015-12-13 23:39:01 +00:00
void EditorNode : : _clear_undo_history ( ) {
2019-03-01 16:20:30 +00:00
get_undo_redo ( ) - > clear_history ( false ) ;
2015-12-13 23:39:01 +00:00
}
2015-06-22 03:03:19 +00:00
void EditorNode : : set_current_scene ( int p_idx ) {
2021-10-17 16:55:44 +00:00
// Save the folding in case the scene gets reloaded.
2020-05-14 14:41:43 +00:00
if ( editor_data . get_scene_path ( p_idx ) ! = " " & & editor_data . get_edited_scene_root ( p_idx ) ) {
2019-09-10 12:43:46 +00:00
editor_folding . save_scene_folding ( editor_data . get_edited_scene_root ( p_idx ) , editor_data . get_scene_path ( p_idx ) ) ;
2020-05-14 14:41:43 +00:00
}
2019-09-10 12:43:46 +00:00
2015-12-13 23:39:01 +00:00
if ( editor_data . check_and_update_scene ( p_idx ) ) {
2020-05-14 14:41:43 +00:00
if ( editor_data . get_scene_path ( p_idx ) ! = " " ) {
2019-09-10 12:43:46 +00:00
editor_folding . load_scene_folding ( editor_data . get_edited_scene_root ( p_idx ) , editor_data . get_scene_path ( p_idx ) ) ;
2020-05-14 14:41:43 +00:00
}
2019-09-10 12:43:46 +00:00
2021-07-17 21:22:52 +00:00
call_deferred ( SNAME ( " _clear_undo_history " ) ) ;
2015-12-13 23:39:01 +00:00
}
2017-03-05 15:44:50 +00:00
changing_scene = true ;
editor_data . save_edited_scene_state ( editor_selection , & editor_history , _get_main_scene_state ( ) ) ;
2015-06-22 03:03:19 +00:00
if ( get_editor_data ( ) . get_edited_scene_root ( ) ) {
2020-05-14 14:41:43 +00:00
if ( get_editor_data ( ) . get_edited_scene_root ( ) - > get_parent ( ) = = scene_root ) {
2015-06-22 03:03:19 +00:00
scene_root - > remove_child ( get_editor_data ( ) . get_edited_scene_root ( ) ) ;
2020-05-14 14:41:43 +00:00
}
2015-06-22 03:03:19 +00:00
}
editor_selection - > clear ( ) ;
editor_data . set_edited_scene ( p_idx ) ;
2017-03-05 15:44:50 +00:00
Node * new_scene = editor_data . get_edited_scene_root ( ) ;
2015-06-22 03:03:19 +00:00
2020-05-14 14:41:43 +00:00
if ( Object : : cast_to < Popup > ( new_scene ) ) {
2022-03-30 18:12:26 +00:00
Object : : cast_to < Popup > ( new_scene ) - > show ( ) ;
2020-05-14 14:41:43 +00:00
}
2015-06-22 03:03:19 +00:00
2021-11-17 20:08:55 +00:00
SceneTreeDock : : get_singleton ( ) - > set_edited_scene ( new_scene ) ;
2020-05-14 14:41:43 +00:00
if ( get_tree ( ) ) {
2015-06-22 03:03:19 +00:00
get_tree ( ) - > set_edited_scene_root ( new_scene ) ;
2020-05-14 14:41:43 +00:00
}
2015-06-22 03:03:19 +00:00
if ( new_scene ) {
2020-05-14 14:41:43 +00:00
if ( new_scene - > get_parent ( ) ! = scene_root ) {
2021-10-21 14:46:07 +00:00
scene_root - > add_child ( new_scene , true ) ;
2020-05-14 14:41:43 +00:00
}
2015-06-22 03:03:19 +00:00
}
2017-03-05 15:44:50 +00:00
Dictionary state = editor_data . restore_edited_scene_state ( editor_selection , & editor_history ) ;
2021-09-12 19:17:34 +00:00
_edit_current ( true ) ;
2015-06-22 03:03:19 +00:00
2018-09-11 10:28:32 +00:00
_update_title ( ) ;
2022-03-30 18:12:26 +00:00
call_deferred ( SNAME ( " _set_main_scene_state " ) , state , get_edited_scene ( ) ) ; // Do after everything else is done setting up.
2015-06-22 03:03:19 +00:00
}
2017-03-05 15:44:50 +00:00
bool EditorNode : : is_scene_open ( const String & p_path ) {
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
2020-05-14 14:41:43 +00:00
if ( editor_data . get_scene_path ( i ) = = p_path ) {
2015-08-23 23:15:56 +00:00
return true ;
2020-05-14 14:41:43 +00:00
}
2015-08-23 23:15:56 +00:00
}
return false ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : fix_dependencies ( const String & p_for_file ) {
2015-08-23 23:15:56 +00:00
dependency_fixer - > edit ( p_for_file ) ;
}
2019-08-15 17:47:21 +00:00
int EditorNode : : new_scene ( ) {
int idx = editor_data . add_edited_scene ( - 1 ) ;
_scene_tab_changed ( idx ) ;
editor_data . clear_editor_states ( ) ;
_update_scene_tabs ( ) ;
return idx ;
}
2019-08-28 17:42:27 +00:00
Error EditorNode : : load_scene ( const String & p_scene , bool p_ignore_broken_deps , bool p_set_inherited , bool p_clear_errors , bool p_force_open_imported , bool p_silent_change_tab ) {
2014-11-06 00:20:42 +00:00
if ( ! is_inside_tree ( ) ) {
2014-02-10 01:10:30 +00:00
defer_load_scene = p_scene ;
return OK ;
}
2017-03-05 15:44:50 +00:00
if ( ! p_set_inherited ) {
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
if ( editor_data . get_scene_path ( i ) = = p_scene ) {
2016-01-02 22:42:41 +00:00
_scene_tab_changed ( i ) ;
return OK ;
}
2015-06-22 03:03:19 +00:00
}
2017-02-04 23:31:15 +00:00
2017-03-05 15:44:50 +00:00
if ( ! p_force_open_imported & & FileAccess : : exists ( p_scene + " .import " ) ) {
open_imported - > set_text ( vformat ( TTR ( " Scene '%s' was automatically imported, so it can't be modified. \n To make changes to it, a new inherited scene can be created. " ) , p_scene . get_file ( ) ) ) ;
2020-03-06 17:00:16 +00:00
open_imported - > popup_centered ( ) ;
2017-02-04 23:31:15 +00:00
new_inherited_button - > grab_focus ( ) ;
2017-03-05 15:44:50 +00:00
open_import_request = p_scene ;
2017-02-04 23:31:15 +00:00
return OK ;
}
2015-06-22 03:03:19 +00:00
}
2020-05-14 14:41:43 +00:00
if ( p_clear_errors ) {
2016-06-26 18:37:04 +00:00
load_errors - > clear ( ) ;
2020-05-14 14:41:43 +00:00
}
2016-06-26 18:37:04 +00:00
2017-07-19 20:00:46 +00:00
String lpath = ProjectSettings : : get_singleton ( ) - > localize_path ( p_scene ) ;
2014-02-10 01:10:30 +00:00
if ( ! lpath . begins_with ( " res:// " ) ) {
2018-08-05 14:47:41 +00:00
show_accept ( TTR ( " Error loading scene, it must be inside the project path. Use 'Import' to open the scene, then save it inside the project path. " ) , TTR ( " OK " ) ) ;
2017-03-05 15:44:50 +00:00
opening_prev = false ;
2014-02-10 01:10:30 +00:00
return ERR_FILE_NOT_FOUND ;
}
2015-06-22 03:03:19 +00:00
int prev = editor_data . get_edited_scene ( ) ;
int idx = editor_data . add_edited_scene ( - 1 ) ;
2017-03-05 15:44:50 +00:00
if ( ! editor_data . get_edited_scene_root ( ) & & editor_data . get_edited_scene_count ( ) = = 2 ) {
2015-06-22 03:03:19 +00:00
_remove_edited_scene ( ) ;
2019-08-28 17:42:27 +00:00
} else if ( ! p_silent_change_tab ) {
2015-06-22 03:03:19 +00:00
_scene_tab_changed ( idx ) ;
2019-08-28 17:42:27 +00:00
} else {
set_current_scene ( idx ) ;
2015-06-22 03:03:19 +00:00
}
2015-08-23 23:15:56 +00:00
dependency_errors . clear ( ) ;
2017-08-28 03:24:50 +00:00
Error err ;
2021-02-11 17:18:45 +00:00
Ref < PackedScene > sdata = ResourceLoader : : load ( lpath , " " , ResourceFormatLoader : : CACHE_MODE_REPLACE , & err ) ;
2014-02-10 01:10:30 +00:00
if ( ! sdata . is_valid ( ) ) {
2017-08-28 03:24:50 +00:00
_dialog_display_load_error ( lpath , err ) ;
2017-03-05 15:44:50 +00:00
opening_prev = false ;
2015-06-22 03:03:19 +00:00
2017-03-05 15:44:50 +00:00
if ( prev ! = - 1 ) {
2015-06-22 03:03:19 +00:00
set_current_scene ( prev ) ;
editor_data . remove_scene ( idx ) ;
}
2014-02-10 01:10:30 +00:00
return ERR_FILE_NOT_FOUND ;
}
2015-08-23 23:15:56 +00:00
if ( ! p_ignore_broken_deps & & dependency_errors . has ( lpath ) ) {
2022-03-30 18:12:26 +00:00
current_menu_option = - 1 ;
2015-08-23 23:15:56 +00:00
Vector < String > errors ;
2022-05-18 23:43:40 +00:00
for ( const String & E : dependency_errors [ lpath ] ) {
errors . push_back ( E ) ;
2015-08-23 23:15:56 +00:00
}
2018-11-02 03:44:40 +00:00
dependency_error - > show ( DependencyErrorDialog : : MODE_SCENE , lpath , errors ) ;
2017-03-05 15:44:50 +00:00
opening_prev = false ;
2015-08-23 23:15:56 +00:00
2017-03-05 15:44:50 +00:00
if ( prev ! = - 1 ) {
2015-08-23 23:15:56 +00:00
set_current_scene ( prev ) ;
editor_data . remove_scene ( idx ) ;
}
return ERR_FILE_MISSING_DEPENDENCIES ;
}
2022-03-30 18:12:26 +00:00
dependency_errors . erase ( lpath ) ; // At least not self path.
2015-08-23 23:15:56 +00:00
2022-05-19 15:00:06 +00:00
for ( KeyValue < String , HashSet < String > > & E : dependency_errors ) {
2021-08-09 20:13:42 +00:00
String txt = vformat ( TTR ( " Scene '%s' has broken dependencies: " ) , E . key ) + " \n " ;
2022-05-18 23:43:40 +00:00
for ( const String & F : E . value ) {
txt + = " \t " + F + " \n " ;
2015-08-23 23:15:56 +00:00
}
add_io_error ( txt ) ;
}
2016-01-14 14:06:20 +00:00
if ( ResourceCache : : has ( lpath ) ) {
2022-03-30 18:12:26 +00:00
// Used from somewhere else? No problem! Update state and replace sdata.
2017-08-24 20:58:51 +00:00
Ref < PackedScene > ps = Ref < PackedScene > ( Object : : cast_to < PackedScene > ( ResourceCache : : get ( lpath ) ) ) ;
2016-01-14 14:06:20 +00:00
if ( ps . is_valid ( ) ) {
2017-03-05 15:44:50 +00:00
ps - > replace_state ( sdata - > get_state ( ) ) ;
ps - > set_last_modified_time ( sdata - > get_last_modified_time ( ) ) ;
sdata = ps ;
2016-01-14 14:06:20 +00:00
}
} else {
2022-03-30 18:12:26 +00:00
sdata - > set_path ( lpath , true ) ; // Take over path.
2016-01-14 14:06:20 +00:00
}
2015-06-26 04:14:31 +00:00
2021-10-26 19:12:25 +00:00
Node * new_scene = sdata - > instantiate ( p_set_inherited ? PackedScene : : GEN_EDIT_STATE_MAIN_INHERITED : PackedScene : : GEN_EDIT_STATE_MAIN ) ;
2014-02-10 01:10:30 +00:00
if ( ! new_scene ) {
2015-06-22 03:03:19 +00:00
sdata . unref ( ) ;
2020-06-08 11:05:09 +00:00
_dialog_display_load_error ( lpath , ERR_FILE_CORRUPT ) ;
2017-03-05 15:44:50 +00:00
opening_prev = false ;
if ( prev ! = - 1 ) {
2015-06-22 03:03:19 +00:00
set_current_scene ( prev ) ;
editor_data . remove_scene ( idx ) ;
}
2020-06-08 11:05:09 +00:00
return ERR_FILE_CORRUPT ;
2014-02-10 01:10:30 +00:00
}
2015-10-10 12:09:09 +00:00
if ( p_set_inherited ) {
Ref < SceneState > state = sdata - > get_state ( ) ;
2016-03-08 23:00:52 +00:00
state - > set_path ( lpath ) ;
2015-10-10 12:09:09 +00:00
new_scene - > set_scene_inherited_state ( state ) ;
2021-09-30 14:30:55 +00:00
new_scene - > set_scene_file_path ( String ( ) ) ;
2015-10-10 12:09:09 +00:00
}
2015-11-28 23:56:14 +00:00
new_scene - > set_scene_instance_state ( Ref < SceneState > ( ) ) ;
2015-10-10 12:09:09 +00:00
2014-02-10 01:10:30 +00:00
set_edited_scene ( new_scene ) ;
2015-12-31 03:31:00 +00:00
_get_scene_metadata ( p_scene ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
saved_version = editor_data . get_undo_redo ( ) . get_version ( ) ;
2014-02-10 01:10:30 +00:00
_update_title ( ) ;
2015-06-22 03:03:19 +00:00
_update_scene_tabs ( ) ;
2014-02-10 01:10:30 +00:00
_add_to_recent_scenes ( lpath ) ;
2018-11-25 13:46:26 +00:00
if ( editor_folding . has_folding_data ( lpath ) ) {
editor_folding . load_scene_folding ( new_scene , lpath ) ;
} else if ( EDITOR_GET ( " interface/inspector/auto_unfold_foreign_scenes " ) ) {
editor_folding . unfold_scene ( new_scene ) ;
editor_folding . save_scene_folding ( new_scene , lpath ) ;
}
2018-10-29 19:36:31 +00:00
2017-03-05 15:44:50 +00:00
prev_scene - > set_disabled ( previous_scenes . size ( ) = = 0 ) ;
opening_prev = false ;
2021-11-17 20:08:55 +00:00
SceneTreeDock : : get_singleton ( ) - > set_selected ( new_scene ) ;
2014-02-10 01:10:30 +00:00
2020-02-07 01:52:05 +00:00
EditorDebuggerNode : : get_singleton ( ) - > update_live_edit_root ( ) ;
2015-08-02 15:29:37 +00:00
2014-07-07 20:44:21 +00:00
push_item ( new_scene ) ;
2014-02-10 01:10:30 +00:00
2017-11-24 23:32:54 +00:00
if ( ! restoring_scenes ) {
save_layout ( ) ;
}
2014-02-10 01:10:30 +00:00
return OK ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : open_request ( const String & p_path ) {
2019-04-10 15:21:26 +00:00
if ( ! opening_prev ) {
List < String > : : Element * prev_scene = previous_scenes . find ( p_path ) ;
2020-04-01 23:20:12 +00:00
if ( prev_scene ! = nullptr ) {
2019-04-10 15:21:26 +00:00
prev_scene - > erase ( ) ;
}
}
2022-03-30 18:12:26 +00:00
load_scene ( p_path ) ; // As it will be opened in separate tab.
2014-02-10 01:10:30 +00:00
}
2022-05-02 23:43:50 +00:00
void EditorNode : : edit_foreign_resource ( Ref < Resource > p_resource ) {
2022-03-25 00:17:30 +00:00
load_scene ( p_resource - > get_path ( ) . get_slice ( " :: " , 0 ) ) ;
InspectorDock : : get_singleton ( ) - > call_deferred ( " edit_resource " , p_resource ) ;
}
2016-05-11 23:57:52 +00:00
void EditorNode : : request_instance_scene ( const String & p_path ) {
2021-11-17 20:08:55 +00:00
SceneTreeDock : : get_singleton ( ) - > instantiate ( p_path ) ;
2014-02-10 01:10:30 +00:00
}
2021-06-17 22:03:09 +00:00
void EditorNode : : request_instantiate_scenes ( const Vector < String > & p_files ) {
2021-11-17 20:08:55 +00:00
SceneTreeDock : : get_singleton ( ) - > instantiate_scenes ( p_files ) ;
2014-02-10 01:10:30 +00:00
}
2019-05-08 02:35:23 +00:00
void EditorNode : : _inherit_request ( String p_file ) {
2022-03-30 18:12:26 +00:00
current_menu_option = FILE_NEW_INHERITED_SCENE ;
2019-05-08 02:35:23 +00:00
_dialog_action ( p_file ) ;
}
2021-06-17 22:03:09 +00:00
void EditorNode : : _instantiate_request ( const Vector < String > & p_files ) {
request_instantiate_scenes ( p_files ) ;
2014-02-10 01:10:30 +00:00
}
void EditorNode : : _close_messages ( ) {
2015-06-14 01:12:53 +00:00
old_split_ofs = center_split - > get_split_offset ( ) ;
center_split - > set_split_offset ( 0 ) ;
2014-02-10 01:10:30 +00:00
}
void EditorNode : : _show_messages ( ) {
2015-06-14 01:12:53 +00:00
center_split - > set_split_offset ( old_split_ofs ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _add_to_recent_scenes ( const String & p_scene ) {
2018-01-09 12:42:45 +00:00
Array rc = EditorSettings : : get_singleton ( ) - > get_project_metadata ( " recent_files " , " scenes " , Array ( ) ) ;
2022-02-01 18:19:13 +00:00
if ( rc . has ( p_scene ) ) {
2018-01-09 12:42:45 +00:00
rc . erase ( p_scene ) ;
2020-05-14 14:41:43 +00:00
}
2018-01-09 12:42:45 +00:00
rc . push_front ( p_scene ) ;
2020-05-14 14:41:43 +00:00
if ( rc . size ( ) > 10 ) {
2014-02-10 01:10:30 +00:00
rc . resize ( 10 ) ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2018-01-09 12:42:45 +00:00
EditorSettings : : get_singleton ( ) - > set_project_metadata ( " recent_files " , " scenes " , rc ) ;
2014-02-10 01:10:30 +00:00
_update_recent_scenes ( ) ;
}
void EditorNode : : _open_recent_scene ( int p_idx ) {
2017-10-12 02:35:15 +00:00
if ( p_idx = = recent_scenes - > get_item_count ( ) - 1 ) {
2018-01-09 12:42:45 +00:00
EditorSettings : : get_singleton ( ) - > set_project_metadata ( " recent_files " , " scenes " , Array ( ) ) ;
2021-07-17 21:22:52 +00:00
call_deferred ( SNAME ( " _update_recent_scenes " ) ) ;
2017-10-12 02:35:15 +00:00
} else {
2018-01-09 12:42:45 +00:00
Array rc = EditorSettings : : get_singleton ( ) - > get_project_metadata ( " recent_files " , " scenes " , Array ( ) ) ;
2017-10-12 02:35:15 +00:00
ERR_FAIL_INDEX ( p_idx , rc . size ( ) ) ;
2014-02-10 01:10:30 +00:00
2018-01-09 12:42:45 +00:00
if ( load_scene ( rc [ p_idx ] ) ! = OK ) {
2021-07-03 22:17:03 +00:00
rc . remove_at ( p_idx ) ;
2018-01-09 12:42:45 +00:00
EditorSettings : : get_singleton ( ) - > set_project_metadata ( " recent_files " , " scenes " , rc ) ;
_update_recent_scenes ( ) ;
}
2017-10-12 02:35:15 +00:00
}
2014-02-10 01:10:30 +00:00
}
void EditorNode : : _update_recent_scenes ( ) {
2018-01-09 12:42:45 +00:00
Array rc = EditorSettings : : get_singleton ( ) - > get_project_metadata ( " recent_files " , " scenes " , Array ( ) ) ;
2014-02-10 01:10:30 +00:00
recent_scenes - > clear ( ) ;
2017-10-12 02:35:15 +00:00
2018-01-09 12:42:45 +00:00
String path ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < rc . size ( ) ; i + + ) {
2018-01-09 12:42:45 +00:00
path = rc [ i ] ;
recent_scenes - > add_item ( path . replace ( " res:// " , " " ) , i ) ;
2014-02-10 01:10:30 +00:00
}
2017-10-12 02:35:15 +00:00
recent_scenes - > add_separator ( ) ;
recent_scenes - > add_shortcut ( ED_SHORTCUT ( " editor/clear_recent " , TTR ( " Clear Recent Scenes " ) ) ) ;
2022-03-05 23:57:42 +00:00
recent_scenes - > reset_size ( ) ;
2014-02-10 01:10:30 +00:00
}
2016-01-08 11:27:34 +00:00
void EditorNode : : _quick_opened ( ) {
Vector < String > files = quick_open - > get_selected_files ( ) ;
2020-06-28 23:04:28 +00:00
bool open_scene_dialog = quick_open - > get_base_type ( ) = = " PackedScene " ;
2016-01-08 11:27:34 +00:00
for ( int i = 0 ; i < files . size ( ) ; i + + ) {
String res_path = files [ i ] ;
2014-02-10 01:10:30 +00:00
2020-06-28 23:04:28 +00:00
List < String > scene_extensions ;
ResourceLoader : : get_recognized_extensions_for_type ( " PackedScene " , & scene_extensions ) ;
if ( open_scene_dialog | | scene_extensions . find ( files [ i ] . get_extension ( ) ) ) {
2016-01-08 11:27:34 +00:00
open_request ( res_path ) ;
} else {
load_resource ( res_path ) ;
}
}
2014-02-10 01:10:30 +00:00
}
2016-02-17 18:40:06 +00:00
void EditorNode : : _quick_run ( ) {
2017-03-05 15:44:50 +00:00
_run ( false , quick_run - > get_selected ( ) ) ;
2014-02-10 01:10:30 +00:00
}
2020-02-07 01:52:05 +00:00
void EditorNode : : notify_all_debug_sessions_exited ( ) {
2017-03-05 15:44:50 +00:00
_menu_option_confirm ( RUN_STOP , false ) ;
2014-02-10 01:10:30 +00:00
stop_button - > set_pressed ( false ) ;
editor_run . stop ( ) ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : add_io_error ( const String & p_error ) {
_load_error_notify ( singleton , p_error ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _load_error_notify ( void * p_ud , const String & p_text ) {
2022-04-05 10:40:26 +00:00
EditorNode * en = static_cast < EditorNode * > ( p_ud ) ;
2021-07-17 21:22:52 +00:00
en - > load_errors - > add_image ( en - > gui_base - > get_theme_icon ( SNAME ( " Error " ) , SNAME ( " EditorIcons " ) ) ) ;
2017-03-05 15:44:50 +00:00
en - > load_errors - > add_text ( p_text + " \n " ) ;
2014-02-10 01:10:30 +00:00
en - > load_error_dialog - > popup_centered_ratio ( 0.5 ) ;
}
2017-03-05 15:44:50 +00:00
bool EditorNode : : _find_scene_in_use ( Node * p_node , const String & p_path ) const {
2021-09-30 14:30:55 +00:00
if ( p_node - > get_scene_file_path ( ) = = p_path ) {
2014-06-19 05:23:03 +00:00
return true ;
}
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < p_node - > get_child_count ( ) ; i + + ) {
if ( _find_scene_in_use ( p_node - > get_child ( i ) , p_path ) ) {
2014-06-19 05:23:03 +00:00
return true ;
}
}
return false ;
}
2017-03-05 15:44:50 +00:00
bool EditorNode : : is_scene_in_use ( const String & p_path ) {
2014-06-19 05:23:03 +00:00
Node * es = get_edited_scene ( ) ;
2020-05-14 14:41:43 +00:00
if ( es ) {
2017-03-05 15:44:50 +00:00
return _find_scene_in_use ( es , p_path ) ;
2020-05-14 14:41:43 +00:00
}
2014-06-19 05:23:03 +00:00
return false ;
}
2014-02-10 01:10:30 +00:00
void EditorNode : : register_editor_types ( ) {
2018-10-03 20:12:59 +00:00
ResourceLoader : : set_timestamp_on_load ( true ) ;
ResourceSaver : : set_timestamp_on_save ( true ) ;
2021-07-11 22:30:33 +00:00
GDREGISTER_CLASS ( EditorPaths ) ;
GDREGISTER_CLASS ( EditorPlugin ) ;
GDREGISTER_CLASS ( EditorTranslationParserPlugin ) ;
GDREGISTER_CLASS ( EditorImportPlugin ) ;
GDREGISTER_CLASS ( EditorScript ) ;
GDREGISTER_CLASS ( EditorSelection ) ;
GDREGISTER_CLASS ( EditorFileDialog ) ;
2022-03-10 07:17:38 +00:00
GDREGISTER_ABSTRACT_CLASS ( EditorSettings ) ;
2021-07-11 22:30:33 +00:00
GDREGISTER_CLASS ( EditorNode3DGizmo ) ;
GDREGISTER_CLASS ( EditorNode3DGizmoPlugin ) ;
2022-03-10 07:17:38 +00:00
GDREGISTER_ABSTRACT_CLASS ( EditorResourcePreview ) ;
2021-07-11 22:30:33 +00:00
GDREGISTER_CLASS ( EditorResourcePreviewGenerator ) ;
2022-03-10 07:17:38 +00:00
GDREGISTER_ABSTRACT_CLASS ( EditorFileSystem ) ;
2021-07-11 22:30:33 +00:00
GDREGISTER_CLASS ( EditorFileSystemDirectory ) ;
GDREGISTER_CLASS ( EditorVCSInterface ) ;
2022-03-10 07:17:38 +00:00
GDREGISTER_ABSTRACT_CLASS ( ScriptEditor ) ;
GDREGISTER_ABSTRACT_CLASS ( ScriptEditorBase ) ;
2021-07-11 22:30:33 +00:00
GDREGISTER_CLASS ( EditorSyntaxHighlighter ) ;
2022-03-10 07:17:38 +00:00
GDREGISTER_ABSTRACT_CLASS ( EditorInterface ) ;
2021-07-11 22:30:33 +00:00
GDREGISTER_CLASS ( EditorExportPlugin ) ;
GDREGISTER_CLASS ( EditorResourceConversionPlugin ) ;
2021-10-14 17:34:27 +00:00
GDREGISTER_CLASS ( EditorSceneFormatImporter ) ;
GDREGISTER_CLASS ( EditorScenePostImportPlugin ) ;
2021-07-11 22:30:33 +00:00
GDREGISTER_CLASS ( EditorInspector ) ;
GDREGISTER_CLASS ( EditorInspectorPlugin ) ;
GDREGISTER_CLASS ( EditorProperty ) ;
GDREGISTER_CLASS ( AnimationTrackEditPlugin ) ;
GDREGISTER_CLASS ( ScriptCreateDialog ) ;
GDREGISTER_CLASS ( EditorFeatureProfile ) ;
GDREGISTER_CLASS ( EditorSpinSlider ) ;
GDREGISTER_CLASS ( EditorResourcePicker ) ;
GDREGISTER_CLASS ( EditorScriptPicker ) ;
2022-03-10 07:17:38 +00:00
GDREGISTER_ABSTRACT_CLASS ( FileSystemDock ) ;
2022-03-31 20:00:17 +00:00
GDREGISTER_VIRTUAL_CLASS ( EditorFileSystemImportFormatSupportQuery ) ;
2017-12-07 18:44:20 +00:00
2021-07-11 22:30:33 +00:00
GDREGISTER_CLASS ( EditorScenePostImport ) ;
2021-05-29 13:28:16 +00:00
GDREGISTER_CLASS ( EditorCommandPalette ) ;
2021-07-11 22:30:33 +00:00
GDREGISTER_CLASS ( EditorDebuggerPlugin ) ;
2014-02-10 01:10:30 +00:00
}
2014-02-25 12:31:47 +00:00
void EditorNode : : unregister_editor_types ( ) {
_init_callbacks . clear ( ) ;
2021-05-25 00:25:11 +00:00
if ( EditorPaths : : get_singleton ( ) ) {
EditorPaths : : free ( ) ;
}
2021-08-03 13:52:12 +00:00
EditorResourcePicker : : clear_caches ( ) ;
2014-02-25 12:31:47 +00:00
}
2020-02-07 01:52:05 +00:00
void EditorNode : : stop_child_process ( OS : : ProcessID p_pid ) {
if ( has_child_process ( p_pid ) ) {
editor_run . stop_child_process ( p_pid ) ;
2020-05-14 14:41:43 +00:00
if ( ! editor_run . get_child_process_count ( ) ) { // All children stopped. Closing.
2020-02-07 01:52:05 +00:00
_menu_option_confirm ( RUN_STOP , false ) ;
2020-05-14 14:41:43 +00:00
}
2020-02-07 01:52:05 +00:00
}
2014-02-10 01:10:30 +00:00
}
2019-07-19 19:21:30 +00:00
Ref < Script > EditorNode : : get_object_custom_type_base ( const Object * p_object ) const {
2020-04-01 23:20:12 +00:00
ERR_FAIL_COND_V ( ! p_object , nullptr ) ;
2019-07-19 19:21:30 +00:00
Ref < Script > script = p_object - > get_script ( ) ;
if ( script . is_valid ( ) ) {
// Uncommenting would break things! Consider adding a parameter if you need it.
// StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path());
2022-02-16 12:56:32 +00:00
// if (name != StringName()) {
2019-07-19 19:21:30 +00:00
// return name;
2022-02-16 12:56:32 +00:00
// }
2019-07-19 19:21:30 +00:00
2022-03-30 18:12:26 +00:00
// TODO: Should probably be deprecated in 4.x
2019-07-19 19:21:30 +00:00
StringName base = script - > get_instance_base_type ( ) ;
if ( base ! = StringName ( ) & & EditorNode : : get_editor_data ( ) . get_custom_types ( ) . has ( base ) ) {
const Vector < EditorData : : CustomType > & types = EditorNode : : get_editor_data ( ) . get_custom_types ( ) [ base ] ;
Ref < Script > base_script = script ;
while ( base_script . is_valid ( ) ) {
for ( int i = 0 ; i < types . size ( ) ; + + i ) {
if ( types [ i ] . script = = base_script ) {
return types [ i ] . script ;
}
}
base_script = base_script - > get_base_script ( ) ;
}
}
}
2020-04-01 23:20:12 +00:00
return nullptr ;
2019-07-19 19:21:30 +00:00
}
StringName EditorNode : : get_object_custom_type_name ( const Object * p_object ) const {
ERR_FAIL_COND_V ( ! p_object , StringName ( ) ) ;
Ref < Script > script = p_object - > get_script ( ) ;
2022-02-06 13:12:19 +00:00
if ( script . is_null ( ) & & Object : : cast_to < Script > ( p_object ) ) {
2019-07-19 19:21:30 +00:00
script = p_object ;
}
if ( script . is_valid ( ) ) {
Ref < Script > base_script = script ;
while ( base_script . is_valid ( ) ) {
StringName name = EditorNode : : get_editor_data ( ) . script_class_get_name ( base_script - > get_path ( ) ) ;
2020-05-14 14:41:43 +00:00
if ( name ! = StringName ( ) ) {
2019-07-19 19:21:30 +00:00
return name ;
2020-05-14 14:41:43 +00:00
}
2019-07-19 19:21:30 +00:00
2022-03-30 18:12:26 +00:00
// TODO: Should probably be deprecated in 4.x.
2019-07-19 19:21:30 +00:00
StringName base = base_script - > get_instance_base_type ( ) ;
if ( base ! = StringName ( ) & & EditorNode : : get_editor_data ( ) . get_custom_types ( ) . has ( base ) ) {
const Vector < EditorData : : CustomType > & types = EditorNode : : get_editor_data ( ) . get_custom_types ( ) [ base ] ;
for ( int i = 0 ; i < types . size ( ) ; + + i ) {
if ( types [ i ] . script = = base_script ) {
return types [ i ] . name ;
}
}
}
base_script = base_script - > get_base_script ( ) ;
}
}
return StringName ( ) ;
}
2019-10-23 18:11:04 +00:00
Ref < ImageTexture > EditorNode : : _load_custom_class_icon ( const String & p_path ) const {
if ( p_path . length ( ) ) {
Ref < Image > img = memnew ( Image ) ;
Error err = ImageLoader : : load_image ( p_path , img ) ;
if ( err = = OK ) {
Ref < ImageTexture > icon = memnew ( ImageTexture ) ;
img - > resize ( 16 * EDSCALE , 16 * EDSCALE , Image : : INTERPOLATE_LANCZOS ) ;
icon - > create_from_image ( img ) ;
return icon ;
}
}
2020-04-01 23:20:12 +00:00
return nullptr ;
2019-10-23 18:11:04 +00:00
}
2021-07-06 14:10:07 +00:00
void EditorNode : : _pick_main_scene_custom_action ( const String & p_custom_action_name ) {
if ( p_custom_action_name = = " select_current " ) {
Node * scene = editor_data . get_edited_scene_root ( ) ;
if ( ! scene ) {
show_accept ( TTR ( " There is no defined scene to run. " ) , TTR ( " OK " ) ) ;
return ;
}
pick_main_scene - > hide ( ) ;
2022-03-30 18:12:26 +00:00
current_menu_option = SETTINGS_PICK_MAIN_SCENE ;
2021-09-30 14:30:55 +00:00
_dialog_action ( scene - > get_scene_file_path ( ) ) ;
2021-07-06 14:10:07 +00:00
}
}
2022-05-05 12:27:29 +00:00
Ref < Texture2D > EditorNode : : get_object_icon ( const Object * p_object , const String & p_fallback ) {
2020-04-01 23:20:12 +00:00
ERR_FAIL_COND_V ( ! p_object | | ! gui_base , nullptr ) ;
2018-09-02 21:40:51 +00:00
Ref < Script > script = p_object - > get_script ( ) ;
if ( script . is_null ( ) & & p_object - > is_class ( " Script " ) ) {
script = p_object ;
}
2022-05-05 12:27:29 +00:00
if ( script . is_valid ( ) & & ! script_icon_cache . has ( script ) ) {
2019-07-19 19:21:30 +00:00
Ref < Script > base_script = script ;
while ( base_script . is_valid ( ) ) {
StringName name = EditorNode : : get_editor_data ( ) . script_class_get_name ( base_script - > get_path ( ) ) ;
String icon_path = EditorNode : : get_editor_data ( ) . script_class_get_icon_path ( name ) ;
2019-10-23 18:11:04 +00:00
Ref < ImageTexture > icon = _load_custom_class_icon ( icon_path ) ;
if ( icon . is_valid ( ) ) {
2022-05-05 12:27:29 +00:00
script_icon_cache [ script ] = icon ;
2019-10-23 18:11:04 +00:00
return icon ;
}
2019-07-19 19:21:30 +00:00
2022-03-30 18:12:26 +00:00
// TODO: should probably be deprecated in 4.x
2019-07-19 19:21:30 +00:00
StringName base = base_script - > get_instance_base_type ( ) ;
if ( base ! = StringName ( ) & & EditorNode : : get_editor_data ( ) . get_custom_types ( ) . has ( base ) ) {
const Vector < EditorData : : CustomType > & types = EditorNode : : get_editor_data ( ) . get_custom_types ( ) [ base ] ;
for ( int i = 0 ; i < types . size ( ) ; + + i ) {
if ( types [ i ] . script = = base_script & & types [ i ] . icon . is_valid ( ) ) {
2022-05-05 12:27:29 +00:00
script_icon_cache [ script ] = types [ i ] . icon ;
2019-07-19 19:21:30 +00:00
return types [ i ] . icon ;
2018-11-11 04:46:20 +00:00
}
}
}
2019-07-19 19:21:30 +00:00
base_script = base_script - > get_base_script ( ) ;
2018-11-11 04:46:20 +00:00
}
2022-05-05 12:27:29 +00:00
// If no icon found, cache it as null.
script_icon_cache [ script ] = Ref < Texture > ( ) ;
} else if ( script . is_valid ( ) & & script_icon_cache . has ( script ) & & script_icon_cache [ script ] . is_valid ( ) ) {
return script_icon_cache [ script ] ;
2018-09-02 21:40:51 +00:00
}
2022-03-30 18:12:26 +00:00
// TODO: Should probably be deprecated in 4.x.
2020-05-14 14:41:43 +00:00
if ( p_object - > has_meta ( " _editor_icon " ) ) {
2018-09-02 21:40:51 +00:00
return p_object - > get_meta ( " _editor_icon " ) ;
2020-05-14 14:41:43 +00:00
}
2018-09-02 21:40:51 +00:00
2022-02-06 14:53:53 +00:00
if ( gui_base - > has_theme_icon ( p_object - > get_class ( ) , SNAME ( " EditorIcons " ) ) ) {
return gui_base - > get_theme_icon ( p_object - > get_class ( ) , SNAME ( " EditorIcons " ) ) ;
2020-05-14 14:41:43 +00:00
}
2018-09-02 21:40:51 +00:00
2020-05-14 14:41:43 +00:00
if ( p_fallback . length ( ) ) {
2021-07-17 21:22:52 +00:00
return gui_base - > get_theme_icon ( p_fallback , SNAME ( " EditorIcons " ) ) ;
2020-05-14 14:41:43 +00:00
}
2018-09-02 21:40:51 +00:00
2020-04-01 23:20:12 +00:00
return nullptr ;
2018-09-02 21:40:51 +00:00
}
2019-06-11 18:43:37 +00:00
Ref < Texture2D > EditorNode : : get_class_icon ( const String & p_class , const String & p_fallback ) const {
2020-12-15 12:04:21 +00:00
ERR_FAIL_COND_V_MSG ( p_class . is_empty ( ) , nullptr , " Class name cannot be empty. " ) ;
2018-09-02 21:40:51 +00:00
if ( ScriptServer : : is_global_class ( p_class ) ) {
2022-04-26 15:40:33 +00:00
String class_name = p_class ;
Ref < Script > script = EditorNode : : get_editor_data ( ) . script_class_load_script ( class_name ) ;
while ( true ) {
String icon_path = EditorNode : : get_editor_data ( ) . script_class_get_icon_path ( class_name ) ;
Ref < Texture > icon = _load_custom_class_icon ( icon_path ) ;
2019-10-23 18:11:04 +00:00
if ( icon . is_valid ( ) ) {
2022-04-26 15:40:33 +00:00
return icon ; // Current global class has icon.
2019-02-06 23:53:24 +00:00
}
2022-04-26 15:40:33 +00:00
// Find next global class along the inheritance chain.
do {
Ref < Script > base_script = script - > get_base_script ( ) ;
if ( base_script . is_null ( ) ) {
// We've reached a native class, use its icon.
String base_type ;
script - > get_language ( ) - > get_global_class_name ( script - > get_path ( ) , & base_type ) ;
2022-04-29 01:40:20 +00:00
if ( gui_base - > has_theme_icon ( base_type , " EditorIcons " ) ) {
return gui_base - > get_theme_icon ( base_type , " EditorIcons " ) ;
}
return gui_base - > get_theme_icon ( p_fallback , " EditorIcons " ) ;
2022-04-26 15:40:33 +00:00
}
script = base_script ;
class_name = EditorNode : : get_editor_data ( ) . script_class_get_name ( script - > get_path ( ) ) ;
} while ( class_name . is_empty ( ) ) ;
2019-02-06 23:53:24 +00:00
}
2018-09-02 21:40:51 +00:00
}
2022-05-13 13:04:37 +00:00
const HashMap < String , Vector < EditorData : : CustomType > > & p_map = EditorNode : : get_editor_data ( ) . get_custom_types ( ) ;
2021-08-09 20:13:42 +00:00
for ( const KeyValue < String , Vector < EditorData : : CustomType > > & E : p_map ) {
const Vector < EditorData : : CustomType > & ct = E . value ;
2018-09-02 21:40:51 +00:00
for ( int i = 0 ; i < ct . size ( ) ; + + i ) {
if ( ct [ i ] . name = = p_class ) {
if ( ct [ i ] . icon . is_valid ( ) ) {
return ct [ i ] . icon ;
}
}
}
}
2021-07-17 21:22:52 +00:00
if ( gui_base - > has_theme_icon ( p_class , SNAME ( " EditorIcons " ) ) ) {
return gui_base - > get_theme_icon ( p_class , SNAME ( " EditorIcons " ) ) ;
2020-06-24 23:13:13 +00:00
}
2021-07-17 21:22:52 +00:00
if ( p_fallback . length ( ) & & gui_base - > has_theme_icon ( p_fallback , SNAME ( " EditorIcons " ) ) ) {
return gui_base - > get_theme_icon ( p_fallback , SNAME ( " EditorIcons " ) ) ;
2020-05-14 14:41:43 +00:00
}
2018-09-02 21:40:51 +00:00
2020-04-01 23:20:12 +00:00
return nullptr ;
2018-09-02 21:40:51 +00:00
}
2017-12-14 11:59:46 +00:00
void EditorNode : : progress_add_task ( const String & p_task , const String & p_label , int p_steps , bool p_can_cancel ) {
2020-01-14 10:32:15 +00:00
if ( singleton - > cmdline_export_mode ) {
2018-11-28 11:45:51 +00:00
print_line ( p_task + " : begin: " + p_label + " steps: " + itos ( p_steps ) ) ;
} else {
singleton - > progress_dialog - > add_task ( p_task , p_label , p_steps , p_can_cancel ) ;
}
2014-02-10 01:10:30 +00:00
}
2017-12-14 11:59:46 +00:00
bool EditorNode : : progress_task_step ( const String & p_task , const String & p_state , int p_step , bool p_force_refresh ) {
2020-01-14 10:32:15 +00:00
if ( singleton - > cmdline_export_mode ) {
2018-11-28 11:45:51 +00:00
print_line ( " \t " + p_task + " : step " + itos ( p_step ) + " : " + p_state ) ;
return false ;
} else {
return singleton - > progress_dialog - > task_step ( p_task , p_state , p_step , p_force_refresh ) ;
}
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : progress_end_task ( const String & p_task ) {
2020-01-14 10:32:15 +00:00
if ( singleton - > cmdline_export_mode ) {
2018-11-28 11:45:51 +00:00
print_line ( p_task + " : end " ) ;
} else {
singleton - > progress_dialog - > end_task ( p_task ) ;
}
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : progress_add_task_bg ( const String & p_task , const String & p_label , int p_steps ) {
singleton - > progress_hb - > add_task ( p_task , p_label , p_steps ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : progress_task_step_bg ( const String & p_task , int p_step ) {
singleton - > progress_hb - > task_step ( p_task , p_step ) ;
2014-02-10 01:10:30 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : progress_end_task_bg ( const String & p_task ) {
2014-02-10 01:10:30 +00:00
singleton - > progress_hb - > end_task ( p_task ) ;
}
2019-06-11 18:43:37 +00:00
Ref < Texture2D > EditorNode : : _file_dialog_get_icon ( const String & p_path ) {
2017-01-14 14:07:57 +00:00
EditorFileSystemDirectory * efsd = EditorFileSystem : : get_singleton ( ) - > get_filesystem_path ( p_path . get_base_dir ( ) ) ;
2014-02-10 01:10:30 +00:00
if ( efsd ) {
String file = p_path . get_file ( ) ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < efsd - > get_file_count ( ) ; i + + ) {
if ( efsd - > get_file ( i ) = = file ) {
2014-02-10 01:10:30 +00:00
String type = efsd - > get_file_type ( i ) ;
if ( singleton - > icon_type_cache . has ( type ) ) {
return singleton - > icon_type_cache [ type ] ;
} else {
return singleton - > icon_type_cache [ " Object " ] ;
}
}
}
}
return singleton - > icon_type_cache [ " Object " ] ;
}
2018-02-25 16:04:16 +00:00
void EditorNode : : _build_icon_type_cache ( ) {
List < StringName > tl ;
2022-02-06 13:12:19 +00:00
theme_base - > get_theme ( ) - > get_icon_list ( SNAME ( " EditorIcons " ) , & tl ) ;
2021-07-24 13:46:25 +00:00
for ( const StringName & E : tl ) {
2021-07-16 03:45:57 +00:00
if ( ! ClassDB : : class_exists ( E ) ) {
2018-02-25 16:04:16 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2022-02-06 13:12:19 +00:00
icon_type_cache [ E ] = theme_base - > get_theme ( ) - > get_icon ( E , SNAME ( " EditorIcons " ) ) ;
2018-02-25 16:04:16 +00:00
}
}
2014-02-10 01:10:30 +00:00
void EditorNode : : _file_dialog_register ( FileDialog * p_dialog ) {
singleton - > file_dialogs . insert ( p_dialog ) ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _file_dialog_unregister ( FileDialog * p_dialog ) {
2014-02-10 01:10:30 +00:00
singleton - > file_dialogs . erase ( p_dialog ) ;
}
2015-05-31 04:59:42 +00:00
void EditorNode : : _editor_file_dialog_register ( EditorFileDialog * p_dialog ) {
singleton - > editor_file_dialogs . insert ( p_dialog ) ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _editor_file_dialog_unregister ( EditorFileDialog * p_dialog ) {
2015-05-31 04:59:42 +00:00
singleton - > editor_file_dialogs . erase ( p_dialog ) ;
}
2014-02-25 12:31:47 +00:00
Vector < EditorNodeInitCallback > EditorNode : : _init_callbacks ;
2014-02-10 01:10:30 +00:00
2020-01-08 13:22:50 +00:00
Error EditorNode : : export_preset ( const String & p_preset , const String & p_path , bool p_debug , bool p_pack_only ) {
2017-09-14 17:49:11 +00:00
export_defer . preset = p_preset ;
2017-03-05 15:44:50 +00:00
export_defer . path = p_path ;
export_defer . debug = p_debug ;
2020-01-08 13:22:50 +00:00
export_defer . pack_only = p_pack_only ;
2020-01-14 10:32:15 +00:00
cmdline_export_mode = true ;
2014-02-10 01:10:30 +00:00
return OK ;
}
2018-05-27 02:41:19 +00:00
void EditorNode : : show_accept ( const String & p_text , const String & p_title ) {
2022-03-30 18:12:26 +00:00
current_menu_option = - 1 ;
2020-12-14 18:37:30 +00:00
accept - > get_ok_button ( ) - > set_text ( p_title ) ;
2018-05-27 02:41:19 +00:00
accept - > set_text ( p_text ) ;
2020-03-06 17:00:16 +00:00
accept - > popup_centered ( ) ;
2018-05-27 02:41:19 +00:00
}
2021-09-11 01:35:13 +00:00
void EditorNode : : show_save_accept ( const String & p_text , const String & p_title ) {
2022-03-30 18:12:26 +00:00
current_menu_option = - 1 ;
2021-09-11 01:35:13 +00:00
save_accept - > get_ok_button ( ) - > set_text ( p_title ) ;
save_accept - > set_text ( p_text ) ;
save_accept - > popup_centered ( ) ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : show_warning ( const String & p_text , const String & p_title ) {
2019-08-21 07:04:55 +00:00
if ( warning - > is_inside_tree ( ) ) {
warning - > set_text ( p_text ) ;
warning - > set_title ( p_title ) ;
2020-03-06 17:00:16 +00:00
warning - > popup_centered ( ) ;
2019-08-21 07:04:55 +00:00
} else {
2019-11-07 08:44:15 +00:00
WARN_PRINT ( p_title + " " + p_text ) ;
2019-08-21 07:04:55 +00:00
}
2015-02-14 15:09:52 +00:00
}
2014-02-10 01:10:30 +00:00
2019-07-09 18:11:31 +00:00
void EditorNode : : _copy_warning ( const String & p_str ) {
2020-03-03 13:36:29 +00:00
DisplayServer : : get_singleton ( ) - > clipboard_set ( warning - > get_text ( ) ) ;
2019-07-09 18:11:31 +00:00
}
2020-03-06 17:00:16 +00:00
void EditorNode : : _dock_floating_close_request ( Control * p_control ) {
2020-03-27 19:48:42 +00:00
// Through the MarginContainer to the Window.
2022-04-05 10:40:26 +00:00
Window * window = static_cast < Window * > ( p_control - > get_parent ( ) - > get_parent ( ) ) ;
2020-03-06 17:00:16 +00:00
int window_slot = window - > get_meta ( " dock_slot " ) ;
2020-03-27 19:48:42 +00:00
p_control - > get_parent ( ) - > remove_child ( p_control ) ;
2020-03-06 17:00:16 +00:00
dock_slot [ window_slot ] - > add_child ( p_control ) ;
2022-03-02 14:37:10 +00:00
dock_slot [ window_slot ] - > move_child ( p_control , MIN ( ( int ) window - > get_meta ( " dock_index " ) , dock_slot [ window_slot ] - > get_tab_count ( ) ) ) ;
2020-03-27 19:48:42 +00:00
dock_slot [ window_slot ] - > set_current_tab ( window - > get_meta ( " dock_index " ) ) ;
2020-03-06 17:00:16 +00:00
window - > queue_delete ( ) ;
_update_dock_containers ( ) ;
floating_docks . erase ( p_control ) ;
2022-01-29 18:32:36 +00:00
_edit_current ( ) ;
2020-03-06 17:00:16 +00:00
}
void EditorNode : : _dock_make_float ( ) {
2022-03-30 18:12:26 +00:00
Control * dock = dock_slot [ dock_popup_selected_idx ] - > get_current_tab_control ( ) ;
2020-03-06 17:00:16 +00:00
ERR_FAIL_COND ( ! dock ) ;
2022-01-13 21:13:45 +00:00
Size2 borders = Size2 ( 4 , 4 ) * EDSCALE ;
// Remember size and position before removing it from the main window.
Size2 dock_size = dock - > get_size ( ) + borders * 2 ;
2020-04-03 19:08:20 +00:00
Point2 dock_screen_pos = dock - > get_global_position ( ) + get_tree ( ) - > get_root ( ) - > get_position ( ) - borders ;
2020-03-06 17:00:16 +00:00
2020-03-27 19:48:42 +00:00
int dock_index = dock - > get_index ( ) ;
2022-03-30 18:12:26 +00:00
dock_slot [ dock_popup_selected_idx ] - > remove_child ( dock ) ;
2020-03-06 17:00:16 +00:00
Window * window = memnew ( Window ) ;
window - > set_title ( dock - > get_name ( ) ) ;
Panel * p = memnew ( Panel ) ;
2022-01-13 21:13:45 +00:00
p - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " PanelForeground " ) , SNAME ( " EditorStyles " ) ) ) ;
2020-12-22 16:24:29 +00:00
p - > set_anchors_and_offsets_preset ( Control : : PRESET_WIDE ) ;
2020-03-06 17:00:16 +00:00
window - > add_child ( p ) ;
2020-03-27 19:48:42 +00:00
MarginContainer * margin = memnew ( MarginContainer ) ;
2020-12-22 16:24:29 +00:00
margin - > set_anchors_and_offsets_preset ( Control : : PRESET_WIDE ) ;
2022-02-08 09:14:58 +00:00
margin - > add_theme_constant_override ( " margin_right " , borders . width ) ;
margin - > add_theme_constant_override ( " margin_top " , borders . height ) ;
margin - > add_theme_constant_override ( " margin_left " , borders . width ) ;
margin - > add_theme_constant_override ( " margin_bottom " , borders . height ) ;
2020-03-27 19:48:42 +00:00
window - > add_child ( margin ) ;
2020-12-22 16:24:29 +00:00
dock - > set_anchors_and_offsets_preset ( Control : : PRESET_WIDE ) ;
2020-03-27 19:48:42 +00:00
margin - > add_child ( dock ) ;
2020-03-06 17:00:16 +00:00
window - > set_wrap_controls ( true ) ;
window - > set_size ( dock_size ) ;
window - > set_position ( dock_screen_pos ) ;
window - > set_transient ( true ) ;
window - > connect ( " close_requested " , callable_mp ( this , & EditorNode : : _dock_floating_close_request ) , varray ( dock ) ) ;
2022-03-30 18:12:26 +00:00
window - > set_meta ( " dock_slot " , dock_popup_selected_idx ) ;
2020-03-27 19:48:42 +00:00
window - > set_meta ( " dock_index " , dock_index ) ;
2020-03-06 17:00:16 +00:00
gui_base - > add_child ( window ) ;
dock_select_popup - > hide ( ) ;
_update_dock_containers ( ) ;
floating_docks . push_back ( dock ) ;
2022-01-29 18:32:36 +00:00
_edit_current ( ) ;
2020-03-06 17:00:16 +00:00
}
void EditorNode : : _update_dock_containers ( ) {
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
if ( dock_slot [ i ] - > get_tab_count ( ) = = 0 & & dock_slot [ i ] - > is_visible ( ) ) {
dock_slot [ i ] - > hide ( ) ;
}
if ( dock_slot [ i ] - > get_tab_count ( ) > 0 & & ! dock_slot [ i ] - > is_visible ( ) ) {
dock_slot [ i ] - > show ( ) ;
}
}
for ( int i = 0 ; i < vsplits . size ( ) ; i + + ) {
bool in_use = dock_slot [ i * 2 + 0 ] - > get_tab_count ( ) | | dock_slot [ i * 2 + 1 ] - > get_tab_count ( ) ;
2020-05-14 14:41:43 +00:00
if ( in_use ) {
2020-03-06 17:00:16 +00:00
vsplits [ i ] - > show ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2020-03-06 17:00:16 +00:00
vsplits [ i ] - > hide ( ) ;
2020-05-14 14:41:43 +00:00
}
2020-03-06 17:00:16 +00:00
}
2020-05-14 14:41:43 +00:00
if ( right_l_vsplit - > is_visible ( ) | | right_r_vsplit - > is_visible ( ) ) {
2020-03-06 17:00:16 +00:00
right_hsplit - > show ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2020-03-06 17:00:16 +00:00
right_hsplit - > hide ( ) ;
2020-05-14 14:41:43 +00:00
}
2020-03-06 17:00:16 +00:00
}
2017-05-20 15:38:03 +00:00
void EditorNode : : _dock_select_input ( const Ref < InputEvent > & p_input ) {
Ref < InputEventMouse > me = p_input ;
2015-06-14 01:12:53 +00:00
2017-05-20 15:38:03 +00:00
if ( me . is_valid ( ) ) {
2017-06-03 08:54:24 +00:00
Vector2 point = me - > get_position ( ) ;
2015-06-14 01:12:53 +00:00
int nrect = - 1 ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
2015-06-14 01:12:53 +00:00
if ( dock_select_rect [ i ] . has_point ( point ) ) {
2017-03-05 15:44:50 +00:00
nrect = i ;
2015-06-14 01:12:53 +00:00
break ;
}
}
2015-06-14 03:41:08 +00:00
2022-03-30 18:12:26 +00:00
if ( nrect ! = dock_select_rect_over_idx ) {
2015-06-14 01:12:53 +00:00
dock_select - > update ( ) ;
2022-03-30 18:12:26 +00:00
dock_select_rect_over_idx = nrect ;
2015-06-14 01:12:53 +00:00
}
2020-05-14 14:41:43 +00:00
if ( nrect = = - 1 ) {
2015-06-14 03:41:08 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2015-06-14 03:41:08 +00:00
2017-05-20 15:38:03 +00:00
Ref < InputEventMouseButton > mb = me ;
2022-03-30 18:12:26 +00:00
if ( mb . is_valid ( ) & & mb - > get_button_index ( ) = = MouseButton : : LEFT & & mb - > is_pressed ( ) & & dock_popup_selected_idx ! = nrect ) {
Control * dock = dock_slot [ dock_popup_selected_idx ] - > get_current_tab_control ( ) ;
2015-06-14 01:12:53 +00:00
if ( dock ) {
2022-03-30 18:12:26 +00:00
dock_slot [ dock_popup_selected_idx ] - > remove_child ( dock ) ;
2015-06-14 01:12:53 +00:00
}
2022-03-30 18:12:26 +00:00
if ( dock_slot [ dock_popup_selected_idx ] - > get_tab_count ( ) = = 0 ) {
dock_slot [ dock_popup_selected_idx ] - > hide ( ) ;
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
} else {
2022-03-30 18:12:26 +00:00
dock_slot [ dock_popup_selected_idx ] - > set_current_tab ( 0 ) ;
2015-06-14 01:12:53 +00:00
}
2015-06-14 04:09:58 +00:00
2015-06-14 01:12:53 +00:00
dock_slot [ nrect ] - > add_child ( dock ) ;
2022-03-30 18:12:26 +00:00
dock_popup_selected_idx = nrect ;
2017-03-05 15:44:50 +00:00
dock_slot [ nrect ] - > set_current_tab ( dock_slot [ nrect ] - > get_tab_count ( ) - 1 ) ;
2015-06-14 01:12:53 +00:00
dock_slot [ nrect ] - > show ( ) ;
dock_select - > update ( ) ;
2020-03-06 17:00:16 +00:00
_update_dock_containers ( ) ;
2017-12-22 18:49:14 +00:00
2017-08-18 22:51:17 +00:00
_edit_current ( ) ;
2015-06-14 01:12:53 +00:00
_save_docks ( ) ;
}
}
}
2015-06-14 03:41:08 +00:00
void EditorNode : : _dock_popup_exit ( ) {
2022-03-30 18:12:26 +00:00
dock_select_rect_over_idx = - 1 ;
2015-06-14 03:41:08 +00:00
dock_select - > update ( ) ;
}
2015-06-14 01:12:53 +00:00
void EditorNode : : _dock_pre_popup ( int p_which ) {
2022-03-30 18:12:26 +00:00
dock_popup_selected_idx = p_which ;
2015-06-14 01:12:53 +00:00
}
2015-06-14 03:41:08 +00:00
void EditorNode : : _dock_move_left ( ) {
2022-03-30 18:12:26 +00:00
if ( dock_popup_selected_idx < 0 | | dock_popup_selected_idx > = DOCK_SLOT_MAX ) {
2015-06-14 03:41:08 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2022-03-30 18:12:26 +00:00
Control * current = dock_slot [ dock_popup_selected_idx ] - > get_tab_control ( dock_slot [ dock_popup_selected_idx ] - > get_current_tab ( ) ) ;
Control * prev = dock_slot [ dock_popup_selected_idx ] - > get_tab_control ( dock_slot [ dock_popup_selected_idx ] - > get_current_tab ( ) - 1 ) ;
2020-05-14 14:41:43 +00:00
if ( ! current | | ! prev ) {
2015-06-14 03:41:08 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2022-03-30 18:12:26 +00:00
dock_slot [ dock_popup_selected_idx ] - > move_child ( current , prev - > get_index ( ) ) ;
dock_slot [ dock_popup_selected_idx ] - > set_current_tab ( dock_slot [ dock_popup_selected_idx ] - > get_current_tab ( ) - 1 ) ;
2015-06-14 03:41:08 +00:00
dock_select - > update ( ) ;
2017-08-18 22:51:17 +00:00
_edit_current ( ) ;
2015-06-14 03:41:08 +00:00
_save_docks ( ) ;
}
void EditorNode : : _dock_move_right ( ) {
2022-03-30 18:12:26 +00:00
Control * current = dock_slot [ dock_popup_selected_idx ] - > get_tab_control ( dock_slot [ dock_popup_selected_idx ] - > get_current_tab ( ) ) ;
Control * next = dock_slot [ dock_popup_selected_idx ] - > get_tab_control ( dock_slot [ dock_popup_selected_idx ] - > get_current_tab ( ) + 1 ) ;
2020-05-14 14:41:43 +00:00
if ( ! current | | ! next ) {
2015-06-14 03:41:08 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2022-03-30 18:12:26 +00:00
dock_slot [ dock_popup_selected_idx ] - > move_child ( next , current - > get_index ( ) ) ;
dock_slot [ dock_popup_selected_idx ] - > set_current_tab ( dock_slot [ dock_popup_selected_idx ] - > get_current_tab ( ) + 1 ) ;
2015-06-14 03:41:08 +00:00
dock_select - > update ( ) ;
2017-08-18 22:51:17 +00:00
_edit_current ( ) ;
2015-06-14 03:41:08 +00:00
_save_docks ( ) ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _dock_select_draw ( ) {
2015-06-14 01:12:53 +00:00
Size2 s = dock_select - > get_size ( ) ;
2017-03-05 15:44:50 +00:00
s . y / = 2.0 ;
s . x / = 6.0 ;
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
Color used = Color ( 0.6 , 0.6 , 0.6 , 0.8 ) ;
Color used_selected = Color ( 0.8 , 0.8 , 0.8 , 0.8 ) ;
2021-07-17 21:22:52 +00:00
Color tab_selected = theme_base - > get_theme_color ( SNAME ( " mono_color " ) , SNAME ( " Editor " ) ) ;
2017-03-05 15:44:50 +00:00
Color unused = used ;
unused . a = 0.4 ;
Color unusable = unused ;
unusable . a = 0.1 ;
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
Rect2 unr ( s . x * 2 , 0 , s . x * 2 , s . y * 2 ) ;
2017-06-03 22:25:13 +00:00
unr . position + = Vector2 ( 2 , 5 ) ;
2017-03-05 15:44:50 +00:00
unr . size - = Vector2 ( 4 , 7 ) ;
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
dock_select - > draw_rect ( unr , unusable ) ;
2015-06-14 01:12:53 +00:00
dock_tab_move_left - > set_disabled ( true ) ;
dock_tab_move_right - > set_disabled ( true ) ;
2022-03-30 18:12:26 +00:00
if ( dock_popup_selected_idx ! = - 1 & & dock_slot [ dock_popup_selected_idx ] - > get_tab_count ( ) ) {
dock_tab_move_left - > set_disabled ( dock_slot [ dock_popup_selected_idx ] - > get_current_tab ( ) = = 0 ) ;
dock_tab_move_right - > set_disabled ( dock_slot [ dock_popup_selected_idx ] - > get_current_tab ( ) > = dock_slot [ dock_popup_selected_idx ] - > get_tab_count ( ) - 1 ) ;
2015-06-14 01:12:53 +00:00
}
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
2015-06-14 01:12:53 +00:00
Vector2 ofs ;
2017-03-05 15:44:50 +00:00
switch ( i ) {
2015-06-14 01:12:53 +00:00
case DOCK_SLOT_LEFT_UL : {
} break ;
case DOCK_SLOT_LEFT_BL : {
2017-03-05 15:44:50 +00:00
ofs . y + = s . y ;
2015-06-14 01:12:53 +00:00
} break ;
case DOCK_SLOT_LEFT_UR : {
2017-03-05 15:44:50 +00:00
ofs . x + = s . x ;
2015-06-14 01:12:53 +00:00
} break ;
case DOCK_SLOT_LEFT_BR : {
2017-03-05 15:44:50 +00:00
ofs + = s ;
2015-06-14 01:12:53 +00:00
} break ;
case DOCK_SLOT_RIGHT_UL : {
2017-03-05 15:44:50 +00:00
ofs . x + = s . x * 4 ;
2015-06-14 01:12:53 +00:00
} break ;
case DOCK_SLOT_RIGHT_BL : {
2017-03-05 15:44:50 +00:00
ofs . x + = s . x * 4 ;
ofs . y + = s . y ;
2015-06-14 01:12:53 +00:00
} break ;
case DOCK_SLOT_RIGHT_UR : {
2017-03-05 15:44:50 +00:00
ofs . x + = s . x * 4 ;
ofs . x + = s . x ;
2015-06-14 01:12:53 +00:00
} break ;
case DOCK_SLOT_RIGHT_BR : {
2017-03-05 15:44:50 +00:00
ofs . x + = s . x * 4 ;
ofs + = s ;
2015-06-14 01:12:53 +00:00
} break ;
}
2017-03-05 15:44:50 +00:00
Rect2 r ( ofs , s ) ;
dock_select_rect [ i ] = r ;
2017-06-03 22:25:13 +00:00
r . position + = Vector2 ( 2 , 5 ) ;
2017-03-05 15:44:50 +00:00
r . size - = Vector2 ( 4 , 7 ) ;
2015-06-14 01:12:53 +00:00
2022-03-30 18:12:26 +00:00
if ( i = = dock_select_rect_over_idx ) {
2017-03-05 15:44:50 +00:00
dock_select - > draw_rect ( r , used_selected ) ;
2022-03-02 14:37:10 +00:00
} else if ( dock_slot [ i ] - > get_tab_count ( ) = = 0 ) {
2017-03-05 15:44:50 +00:00
dock_select - > draw_rect ( r , unused ) ;
2015-06-14 01:12:53 +00:00
} else {
2017-03-05 15:44:50 +00:00
dock_select - > draw_rect ( r , used ) ;
2015-06-14 01:12:53 +00:00
}
2022-03-02 14:37:10 +00:00
for ( int j = 0 ; j < MIN ( 3 , dock_slot [ i ] - > get_tab_count ( ) ) ; j + + ) {
2017-03-05 15:44:50 +00:00
int xofs = ( r . size . width / 3 ) * j ;
2015-06-14 01:12:53 +00:00
Color c = used ;
2022-03-30 18:12:26 +00:00
if ( i = = dock_popup_selected_idx & & ( dock_slot [ i ] - > get_current_tab ( ) > 3 | | dock_slot [ i ] - > get_current_tab ( ) = = j ) ) {
2017-03-05 15:44:50 +00:00
c = tab_selected ;
2020-05-14 14:41:43 +00:00
}
2017-03-05 15:44:50 +00:00
dock_select - > draw_rect ( Rect2 ( 2 + ofs . x + xofs , ofs . y , r . size . width / 3 - 1 , 3 ) , c ) ;
2015-06-14 01:12:53 +00:00
}
}
}
void EditorNode : : _save_docks ( ) {
2019-02-27 21:14:24 +00:00
if ( waiting_for_first_scan ) {
2022-03-30 18:12:26 +00:00
return ; // Scanning, do not touch docks.
2019-02-27 21:14:24 +00:00
}
2015-06-14 01:12:53 +00:00
Ref < ConfigFile > config ;
2021-06-17 22:03:09 +00:00
config . instantiate ( ) ;
2021-05-05 01:05:09 +00:00
// Load and amend existing config if it exists.
config - > load ( EditorSettings : : get_singleton ( ) - > get_project_settings_dir ( ) . plus_file ( " editor_layout.cfg " ) ) ;
2015-06-14 01:12:53 +00:00
2015-11-22 18:11:17 +00:00
_save_docks_to_config ( config , " docks " ) ;
2017-11-24 23:32:54 +00:00
_save_open_scenes_to_config ( config , " EditorNode " ) ;
2015-11-22 18:11:17 +00:00
editor_data . get_plugin_window_layout ( config ) ;
2017-11-17 14:50:18 +00:00
config - > save ( EditorSettings : : get_singleton ( ) - > get_project_settings_dir ( ) . plus_file ( " editor_layout.cfg " ) ) ;
2015-11-22 18:11:17 +00:00
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _save_docks_to_config ( Ref < ConfigFile > p_layout , const String & p_section ) {
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
2015-06-14 01:12:53 +00:00
String names ;
2017-03-05 15:44:50 +00:00
for ( int j = 0 ; j < dock_slot [ i ] - > get_tab_count ( ) ; j + + ) {
2015-06-14 01:12:53 +00:00
String name = dock_slot [ i ] - > get_tab_control ( j ) - > get_name ( ) ;
2021-12-09 09:42:46 +00:00
if ( ! names . is_empty ( ) ) {
2017-03-05 15:44:50 +00:00
names + = " , " ;
2020-05-14 14:41:43 +00:00
}
2017-03-05 15:44:50 +00:00
names + = name ;
2015-06-14 01:12:53 +00:00
}
2021-12-09 09:42:46 +00:00
if ( ! names . is_empty ( ) ) {
2017-03-05 15:44:50 +00:00
p_layout - > set_value ( p_section , " dock_ " + itos ( i + 1 ) , names ) ;
2015-06-14 01:12:53 +00:00
}
}
2021-11-17 20:08:55 +00:00
p_layout - > set_value ( p_section , " dock_filesystem_split " , FileSystemDock : : get_singleton ( ) - > get_split_offset ( ) ) ;
p_layout - > set_value ( p_section , " dock_filesystem_display_mode " , FileSystemDock : : get_singleton ( ) - > get_display_mode ( ) ) ;
p_layout - > set_value ( p_section , " dock_filesystem_file_sort " , FileSystemDock : : get_singleton ( ) - > get_file_sort ( ) ) ;
p_layout - > set_value ( p_section , " dock_filesystem_file_list_display_mode " , FileSystemDock : : get_singleton ( ) - > get_file_list_display_mode ( ) ) ;
2017-01-25 01:46:44 +00:00
2018-09-14 14:56:18 +00:00
for ( int i = 0 ; i < vsplits . size ( ) ; i + + ) {
if ( vsplits [ i ] - > is_visible_in_tree ( ) ) {
p_layout - > set_value ( p_section , " dock_split_ " + itos ( i + 1 ) , vsplits [ i ] - > get_split_offset ( ) ) ;
2015-06-14 01:12:53 +00:00
}
}
2018-09-14 14:56:18 +00:00
for ( int i = 0 ; i < hsplits . size ( ) ; i + + ) {
p_layout - > set_value ( p_section , " dock_hsplit_ " + itos ( i + 1 ) , hsplits [ i ] - > get_split_offset ( ) ) ;
2015-06-22 03:03:19 +00:00
}
2015-06-14 01:12:53 +00:00
}
2017-11-24 23:32:54 +00:00
void EditorNode : : _save_open_scenes_to_config ( Ref < ConfigFile > p_layout , const String & p_section ) {
Array scenes ;
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
String path = editor_data . get_scene_path ( i ) ;
2021-12-09 09:42:46 +00:00
if ( path . is_empty ( ) ) {
2017-11-24 23:32:54 +00:00
continue ;
}
scenes . push_back ( path ) ;
}
p_layout - > set_value ( p_section , " open_scenes " , scenes ) ;
}
2015-06-22 03:03:19 +00:00
void EditorNode : : save_layout ( ) {
dock_drag_timer - > start ( ) ;
}
2015-06-14 01:12:53 +00:00
void EditorNode : : _dock_split_dragged ( int ofs ) {
dock_drag_timer - > start ( ) ;
}
void EditorNode : : _load_docks ( ) {
Ref < ConfigFile > config ;
2021-06-17 22:03:09 +00:00
config . instantiate ( ) ;
2017-11-17 14:50:18 +00:00
Error err = config - > load ( EditorSettings : : get_singleton ( ) - > get_project_settings_dir ( ) . plus_file ( " editor_layout.cfg " ) ) ;
2017-03-05 15:44:50 +00:00
if ( err ! = OK ) {
2022-03-30 18:12:26 +00:00
// No config.
2017-03-05 15:44:50 +00:00
if ( overridden_default_layout > = 0 ) {
2016-01-11 21:23:45 +00:00
_layout_menu_option ( overridden_default_layout ) ;
}
return ;
2015-06-14 01:12:53 +00:00
}
2015-11-22 18:11:17 +00:00
_load_docks_from_config ( config , " docks " ) ;
2017-11-24 23:32:54 +00:00
_load_open_scenes_from_config ( config , " EditorNode " ) ;
2018-09-21 03:14:04 +00:00
2015-11-22 18:11:17 +00:00
editor_data . set_plugin_window_layout ( config ) ;
}
2016-02-28 02:10:44 +00:00
void EditorNode : : _update_dock_slots_visibility ( ) {
2016-05-30 18:29:43 +00:00
if ( ! docks_visible ) {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
2016-02-28 02:10:44 +00:00
dock_slot [ i ] - > hide ( ) ;
2016-05-30 18:29:43 +00:00
}
2016-02-28 02:10:44 +00:00
2018-09-14 14:56:18 +00:00
for ( int i = 0 ; i < vsplits . size ( ) ; i + + ) {
vsplits [ i ] - > hide ( ) ;
2016-05-30 18:29:43 +00:00
}
2016-02-28 02:10:44 +00:00
2016-05-30 18:29:43 +00:00
right_hsplit - > hide ( ) ;
} else {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
2019-04-08 22:18:03 +00:00
int tabs_visible = 0 ;
for ( int j = 0 ; j < dock_slot [ i ] - > get_tab_count ( ) ; j + + ) {
2022-03-02 14:37:10 +00:00
if ( ! dock_slot [ i ] - > is_tab_hidden ( j ) ) {
2019-04-08 22:18:03 +00:00
tabs_visible + + ;
}
}
2020-05-14 14:41:43 +00:00
if ( tabs_visible ) {
2016-05-30 18:29:43 +00:00
dock_slot [ i ] - > show ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2016-05-30 18:29:43 +00:00
dock_slot [ i ] - > hide ( ) ;
2020-05-14 14:41:43 +00:00
}
2016-05-30 18:29:43 +00:00
}
2016-02-28 02:10:44 +00:00
2018-09-14 14:56:18 +00:00
for ( int i = 0 ; i < vsplits . size ( ) ; i + + ) {
2017-03-05 15:44:50 +00:00
bool in_use = dock_slot [ i * 2 + 0 ] - > get_tab_count ( ) | | dock_slot [ i * 2 + 1 ] - > get_tab_count ( ) ;
2020-05-14 14:41:43 +00:00
if ( in_use ) {
2018-09-14 14:56:18 +00:00
vsplits [ i ] - > show ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2018-09-14 14:56:18 +00:00
vsplits [ i ] - > hide ( ) ;
2020-05-14 14:41:43 +00:00
}
2016-05-30 18:29:43 +00:00
}
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
2017-01-13 13:45:50 +00:00
if ( dock_slot [ i ] - > is_visible ( ) & & dock_slot [ i ] - > get_tab_count ( ) ) {
2016-05-30 18:29:43 +00:00
dock_slot [ i ] - > set_current_tab ( 0 ) ;
}
2016-02-28 02:10:44 +00:00
}
2017-12-22 18:49:14 +00:00
2020-05-14 14:41:43 +00:00
if ( right_l_vsplit - > is_visible ( ) | | right_r_vsplit - > is_visible ( ) ) {
2017-12-22 18:49:14 +00:00
right_hsplit - > show ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2017-12-22 18:49:14 +00:00
right_hsplit - > hide ( ) ;
2020-05-14 14:41:43 +00:00
}
2016-02-28 02:10:44 +00:00
}
}
2018-02-07 13:01:45 +00:00
void EditorNode : : _dock_tab_changed ( int p_tab ) {
2022-03-30 18:12:26 +00:00
// Update visibility but don't set current tab.
2018-02-07 13:01:45 +00:00
if ( ! docks_visible ) {
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
dock_slot [ i ] - > hide ( ) ;
}
2018-09-14 14:56:18 +00:00
for ( int i = 0 ; i < vsplits . size ( ) ; i + + ) {
vsplits [ i ] - > hide ( ) ;
2018-02-07 13:01:45 +00:00
}
right_hsplit - > hide ( ) ;
bottom_panel - > hide ( ) ;
} else {
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
2020-05-14 14:41:43 +00:00
if ( dock_slot [ i ] - > get_tab_count ( ) ) {
2018-02-07 13:01:45 +00:00
dock_slot [ i ] - > show ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2018-02-07 13:01:45 +00:00
dock_slot [ i ] - > hide ( ) ;
2020-05-14 14:41:43 +00:00
}
2018-02-07 13:01:45 +00:00
}
2018-09-14 14:56:18 +00:00
for ( int i = 0 ; i < vsplits . size ( ) ; i + + ) {
2018-02-07 13:01:45 +00:00
bool in_use = dock_slot [ i * 2 + 0 ] - > get_tab_count ( ) | | dock_slot [ i * 2 + 1 ] - > get_tab_count ( ) ;
2020-05-14 14:41:43 +00:00
if ( in_use ) {
2018-09-14 14:56:18 +00:00
vsplits [ i ] - > show ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2018-09-14 14:56:18 +00:00
vsplits [ i ] - > hide ( ) ;
2020-05-14 14:41:43 +00:00
}
2018-02-07 13:01:45 +00:00
}
bottom_panel - > show ( ) ;
2020-05-14 14:41:43 +00:00
if ( right_l_vsplit - > is_visible ( ) | | right_r_vsplit - > is_visible ( ) ) {
2018-02-07 13:01:45 +00:00
right_hsplit - > show ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2018-02-07 13:01:45 +00:00
right_hsplit - > hide ( ) ;
2020-05-14 14:41:43 +00:00
}
2018-02-07 13:01:45 +00:00
}
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _load_docks_from_config ( Ref < ConfigFile > p_layout , const String & p_section ) {
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
2020-05-14 14:41:43 +00:00
if ( ! p_layout - > has_section_key ( p_section , " dock_ " + itos ( i + 1 ) ) ) {
2015-06-14 01:12:53 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
Vector < String > names = String ( p_layout - > get_value ( p_section , " dock_ " + itos ( i + 1 ) ) ) . split ( " , " ) ;
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
for ( int j = 0 ; j < names . size ( ) ; j + + ) {
String name = names [ j ] ;
2022-03-30 18:12:26 +00:00
// FIXME: Find it, in a horribly inefficient way.
2017-03-05 15:44:50 +00:00
int atidx = - 1 ;
2020-04-01 23:20:12 +00:00
Control * node = nullptr ;
2017-03-05 15:44:50 +00:00
for ( int k = 0 ; k < DOCK_SLOT_MAX ; k + + ) {
2020-05-14 14:41:43 +00:00
if ( ! dock_slot [ k ] - > has_node ( name ) ) {
2015-06-14 01:12:53 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2017-08-24 20:58:51 +00:00
node = Object : : cast_to < Control > ( dock_slot [ k ] - > get_node ( name ) ) ;
2020-05-14 14:41:43 +00:00
if ( ! node ) {
2015-06-14 01:12:53 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2017-03-05 15:44:50 +00:00
atidx = k ;
2015-06-14 01:12:53 +00:00
break ;
}
2022-03-30 18:12:26 +00:00
if ( atidx = = - 1 ) { // Well, it's not anywhere.
2015-06-14 01:12:53 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
if ( atidx = = i ) {
2015-06-14 01:12:53 +00:00
node - > raise ( ) ;
continue ;
}
dock_slot [ atidx ] - > remove_child ( node ) ;
2017-03-05 15:44:50 +00:00
if ( dock_slot [ atidx ] - > get_tab_count ( ) = = 0 ) {
2015-06-14 01:12:53 +00:00
dock_slot [ atidx ] - > hide ( ) ;
}
dock_slot [ i ] - > add_child ( node ) ;
dock_slot [ i ] - > show ( ) ;
}
}
2017-03-05 15:44:50 +00:00
if ( p_layout - > has_section_key ( p_section , " dock_filesystem_split " ) ) {
2019-02-27 20:36:12 +00:00
int fs_split_ofs = p_layout - > get_value ( p_section , " dock_filesystem_split " ) ;
2021-11-17 20:08:55 +00:00
FileSystemDock : : get_singleton ( ) - > set_split_offset ( fs_split_ofs ) ;
2019-02-25 22:39:49 +00:00
}
if ( p_layout - > has_section_key ( p_section , " dock_filesystem_display_mode " ) ) {
FileSystemDock : : DisplayMode dock_filesystem_display_mode = FileSystemDock : : DisplayMode ( int ( p_layout - > get_value ( p_section , " dock_filesystem_display_mode " ) ) ) ;
2021-11-17 20:08:55 +00:00
FileSystemDock : : get_singleton ( ) - > set_display_mode ( dock_filesystem_display_mode ) ;
2019-02-25 22:39:49 +00:00
}
2020-10-07 19:56:53 +00:00
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 " ) ) ) ;
2021-11-17 20:08:55 +00:00
FileSystemDock : : get_singleton ( ) - > set_file_sort ( dock_filesystem_file_sort ) ;
2020-10-07 19:56:53 +00:00
}
2019-02-25 22:39:49 +00:00
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 " ) ) ) ;
2021-11-17 20:08:55 +00:00
FileSystemDock : : get_singleton ( ) - > set_file_list_display_mode ( dock_filesystem_file_list_display_mode ) ;
2017-01-25 01:46:44 +00:00
}
2018-09-14 14:56:18 +00:00
for ( int i = 0 ; i < vsplits . size ( ) ; i + + ) {
2020-05-14 14:41:43 +00:00
if ( ! p_layout - > has_section_key ( p_section , " dock_split_ " + itos ( i + 1 ) ) ) {
2015-06-14 01:12:53 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
int ofs = p_layout - > get_value ( p_section , " dock_split_ " + itos ( i + 1 ) ) ;
2018-09-14 14:56:18 +00:00
vsplits [ i ] - > set_split_offset ( ofs ) ;
2015-06-14 01:12:53 +00:00
}
2018-09-14 14:56:18 +00:00
for ( int i = 0 ; i < hsplits . size ( ) ; i + + ) {
2020-05-14 14:41:43 +00:00
if ( ! p_layout - > has_section_key ( p_section , " dock_hsplit_ " + itos ( i + 1 ) ) ) {
2015-06-22 03:03:19 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2017-03-05 15:44:50 +00:00
int ofs = p_layout - > get_value ( p_section , " dock_hsplit_ " + itos ( i + 1 ) ) ;
2018-09-14 14:56:18 +00:00
hsplits [ i ] - > set_split_offset ( ofs ) ;
2015-06-22 03:03:19 +00:00
}
2018-09-14 14:56:18 +00:00
for ( int i = 0 ; i < vsplits . size ( ) ; i + + ) {
2017-03-05 15:44:50 +00:00
bool in_use = dock_slot [ i * 2 + 0 ] - > get_tab_count ( ) | | dock_slot [ i * 2 + 1 ] - > get_tab_count ( ) ;
2020-05-14 14:41:43 +00:00
if ( in_use ) {
2018-09-14 14:56:18 +00:00
vsplits [ i ] - > show ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2018-09-14 14:56:18 +00:00
vsplits [ i ] - > hide ( ) ;
2020-05-14 14:41:43 +00:00
}
2015-06-14 01:12:53 +00:00
}
2015-06-14 03:41:08 +00:00
2020-05-14 14:41:43 +00:00
if ( right_l_vsplit - > is_visible ( ) | | right_r_vsplit - > is_visible ( ) ) {
2017-12-22 18:49:14 +00:00
right_hsplit - > show ( ) ;
2020-05-14 14:41:43 +00:00
} else {
2017-12-22 18:49:14 +00:00
right_hsplit - > hide ( ) ;
2020-05-14 14:41:43 +00:00
}
2017-12-22 18:49:14 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
2017-01-13 13:45:50 +00:00
if ( dock_slot [ i ] - > is_visible ( ) & & dock_slot [ i ] - > get_tab_count ( ) ) {
2015-06-14 03:41:08 +00:00
dock_slot [ i ] - > set_current_tab ( 0 ) ;
}
}
2015-11-22 18:11:17 +00:00
}
2015-06-14 03:41:08 +00:00
2017-11-24 23:32:54 +00:00
void EditorNode : : _load_open_scenes_from_config ( Ref < ConfigFile > p_layout , const String & p_section ) {
2018-05-17 21:02:16 +00:00
if ( ! bool ( EDITOR_GET ( " interface/scene_tabs/restore_scenes_on_load " ) ) ) {
2017-11-24 23:32:54 +00:00
return ;
}
if ( ! p_layout - > has_section ( p_section ) | | ! p_layout - > has_section_key ( p_section , " open_scenes " ) ) {
return ;
}
restoring_scenes = true ;
Array scenes = p_layout - > get_value ( p_section , " open_scenes " ) ;
for ( int i = 0 ; i < scenes . size ( ) ; i + + ) {
load_scene ( scenes [ i ] ) ;
}
2019-04-15 20:17:49 +00:00
save_layout ( ) ;
2017-11-24 23:32:54 +00:00
restoring_scenes = false ;
}
2018-09-21 03:14:04 +00:00
bool EditorNode : : has_scenes_in_session ( ) {
if ( ! bool ( EDITOR_GET ( " interface/scene_tabs/restore_scenes_on_load " ) ) ) {
return false ;
}
Ref < ConfigFile > config ;
2021-06-17 22:03:09 +00:00
config . instantiate ( ) ;
2018-09-21 03:14:04 +00:00
Error err = config - > load ( EditorSettings : : get_singleton ( ) - > get_project_settings_dir ( ) . plus_file ( " editor_layout.cfg " ) ) ;
if ( err ! = OK ) {
return false ;
}
if ( ! config - > has_section ( " EditorNode " ) | | ! config - > has_section_key ( " EditorNode " , " open_scenes " ) ) {
return false ;
}
Array scenes = config - > get_value ( " EditorNode " , " open_scenes " ) ;
2020-12-15 12:04:21 +00:00
return ! scenes . is_empty ( ) ;
2018-09-21 03:14:04 +00:00
}
2019-03-22 01:08:28 +00:00
bool EditorNode : : ensure_main_scene ( bool p_from_native ) {
2022-03-30 18:12:26 +00:00
pick_main_scene - > set_meta ( " from_native " , p_from_native ) ; // Whether from play button or native run.
2019-03-22 01:08:28 +00:00
String main_scene = GLOBAL_DEF ( " application/run/main_scene " , " " ) ;
2021-12-09 09:42:46 +00:00
if ( main_scene . is_empty ( ) ) {
2022-03-30 18:12:26 +00:00
current_menu_option = - 1 ;
2019-03-22 01:08:28 +00:00
pick_main_scene - > set_text ( TTR ( " No main scene has ever been defined, select one? \n You can change it later in \" Project Settings \" under the 'application' category. " ) ) ;
2020-03-06 17:00:16 +00:00
pick_main_scene - > popup_centered ( ) ;
2021-07-06 14:10:07 +00:00
if ( editor_data . get_edited_scene_root ( ) ) {
select_current_scene_button - > set_disabled ( false ) ;
select_current_scene_button - > grab_focus ( ) ;
} else {
select_current_scene_button - > set_disabled ( true ) ;
}
2019-03-22 01:08:28 +00:00
return false ;
}
if ( ! FileAccess : : exists ( main_scene ) ) {
2022-03-30 18:12:26 +00:00
current_menu_option = - 1 ;
2019-03-22 01:08:28 +00:00
pick_main_scene - > set_text ( vformat ( TTR ( " Selected scene '%s' does not exist, select a valid one? \n You can change it later in \" Project Settings \" under the 'application' category. " ) , main_scene ) ) ;
2020-03-06 17:00:16 +00:00
pick_main_scene - > popup_centered ( ) ;
2019-03-22 01:08:28 +00:00
return false ;
}
if ( ResourceLoader : : get_resource_type ( main_scene ) ! = " PackedScene " ) {
2022-03-30 18:12:26 +00:00
current_menu_option = - 1 ;
2019-03-22 01:08:28 +00:00
pick_main_scene - > set_text ( vformat ( TTR ( " Selected scene '%s' is not a scene file, select a valid one? \n You can change it later in \" Project Settings \" under the 'application' category. " ) , main_scene ) ) ;
2020-03-06 17:00:16 +00:00
pick_main_scene - > popup_centered ( ) ;
2019-03-22 01:08:28 +00:00
return false ;
}
return true ;
}
2021-07-20 11:24:56 +00:00
Error EditorNode : : run_play_native ( int p_idx , int p_platform ) {
return run_native - > run_native ( p_idx , p_platform ) ;
}
2019-07-18 02:08:24 +00:00
void EditorNode : : run_play ( ) {
_menu_option_confirm ( RUN_STOP , true ) ;
_run ( false ) ;
}
2020-04-05 14:19:24 +00:00
void EditorNode : : run_play_current ( ) {
_save_default_environment ( ) ;
_menu_option_confirm ( RUN_STOP , true ) ;
_run ( true ) ;
}
void EditorNode : : run_play_custom ( const String & p_custom ) {
_menu_option_confirm ( RUN_STOP , true ) ;
_run ( false , p_custom ) ;
}
2019-07-18 02:08:24 +00:00
void EditorNode : : run_stop ( ) {
_menu_option_confirm ( RUN_STOP , false ) ;
}
2020-04-05 14:19:24 +00:00
bool EditorNode : : is_run_playing ( ) const {
EditorRun : : Status status = editor_run . get_status ( ) ;
return ( status = = EditorRun : : STATUS_PLAY | | status = = EditorRun : : STATUS_PAUSED ) ;
}
String EditorNode : : get_run_playing_scene ( ) const {
String run_filename = editor_run . get_running_scene ( ) ;
2021-12-09 09:42:46 +00:00
if ( run_filename . is_empty ( ) & & is_run_playing ( ) ) {
2020-04-05 14:19:24 +00:00
run_filename = GLOBAL_DEF ( " application/run/main_scene " , " " ) ; // Must be the main scene then.
}
return run_filename ;
}
2021-08-20 18:32:56 +00:00
void EditorNode : : _immediate_dialog_confirmed ( ) {
immediate_dialog_confirmed = true ;
}
bool EditorNode : : immediate_confirmation_dialog ( const String & p_text , const String & p_ok_text , const String & p_cancel_text ) {
ConfirmationDialog * cd = memnew ( ConfirmationDialog ) ;
cd - > set_text ( p_text ) ;
cd - > get_ok_button ( ) - > set_text ( p_ok_text ) ;
cd - > get_cancel_button ( ) - > set_text ( p_cancel_text ) ;
cd - > connect ( " confirmed " , callable_mp ( singleton , & EditorNode : : _immediate_dialog_confirmed ) ) ;
singleton - > gui_base - > add_child ( cd ) ;
cd - > popup_centered ( ) ;
while ( true ) {
OS : : get_singleton ( ) - > delay_usec ( 1 ) ;
DisplayServer : : get_singleton ( ) - > process_events ( ) ;
Main : : iteration ( ) ;
if ( singleton - > immediate_dialog_confirmed | | ! cd - > is_visible ( ) ) {
break ;
}
}
memdelete ( cd ) ;
return singleton - > immediate_dialog_confirmed ;
}
2019-06-04 03:36:23 +00:00
int EditorNode : : get_current_tab ( ) {
return scene_tabs - > get_current_tab ( ) ;
}
void EditorNode : : set_current_tab ( int p_tab ) {
scene_tabs - > set_current_tab ( p_tab ) ;
}
2015-11-22 18:11:17 +00:00
void EditorNode : : _update_layouts_menu ( ) {
editor_layouts - > clear ( ) ;
2017-03-05 15:44:50 +00:00
overridden_default_layout = - 1 ;
2016-01-11 21:23:45 +00:00
2021-11-20 08:04:57 +00:00
editor_layouts - > reset_size ( ) ;
2017-03-05 15:44:50 +00:00
editor_layouts - > add_shortcut ( ED_SHORTCUT ( " layout/save " , TTR ( " Save Layout " ) ) , SETTINGS_LAYOUT_SAVE ) ;
editor_layouts - > add_shortcut ( ED_SHORTCUT ( " layout/delete " , TTR ( " Delete Layout " ) ) , SETTINGS_LAYOUT_DELETE ) ;
2015-11-22 18:11:17 +00:00
editor_layouts - > add_separator ( ) ;
2017-03-05 15:44:50 +00:00
editor_layouts - > add_shortcut ( ED_SHORTCUT ( " layout/default " , TTR ( " Default " ) ) , SETTINGS_LAYOUT_DEFAULT ) ;
2015-11-22 18:11:17 +00:00
Ref < ConfigFile > config ;
2021-06-17 22:03:09 +00:00
config . instantiate ( ) ;
2017-11-17 20:48:24 +00:00
Error err = config - > load ( EditorSettings : : get_singleton ( ) - > get_editor_layouts_config ( ) ) ;
2017-03-05 15:44:50 +00:00
if ( err ! = OK ) {
2022-03-30 18:12:26 +00:00
return ; // No config.
2015-11-22 18:11:17 +00:00
}
List < String > layouts ;
config . ptr ( ) - > get_sections ( & layouts ) ;
2021-07-24 13:46:25 +00:00
for ( const String & layout : layouts ) {
2017-03-05 15:44:50 +00:00
if ( layout = = TTR ( " Default " ) ) {
2016-01-11 21:23:45 +00:00
editor_layouts - > remove_item ( editor_layouts - > get_item_index ( SETTINGS_LAYOUT_DEFAULT ) ) ;
2017-03-05 15:44:50 +00:00
overridden_default_layout = editor_layouts - > get_item_count ( ) ;
2016-01-11 21:23:45 +00:00
}
editor_layouts - > add_item ( layout ) ;
2015-11-22 18:11:17 +00:00
}
}
void EditorNode : : _layout_menu_option ( int p_id ) {
switch ( p_id ) {
case SETTINGS_LAYOUT_SAVE : {
2022-03-30 18:12:26 +00:00
current_menu_option = p_id ;
2016-05-04 01:25:37 +00:00
layout_dialog - > set_title ( TTR ( " Save Layout " ) ) ;
2020-12-14 18:37:30 +00:00
layout_dialog - > get_ok_button ( ) - > set_text ( TTR ( " Save " ) ) ;
2015-11-22 18:11:17 +00:00
layout_dialog - > popup_centered ( ) ;
2019-05-30 18:16:40 +00:00
layout_dialog - > set_name_line_enabled ( true ) ;
2015-11-22 18:11:17 +00:00
} break ;
case SETTINGS_LAYOUT_DELETE : {
2022-03-30 18:12:26 +00:00
current_menu_option = p_id ;
2016-05-04 01:25:37 +00:00
layout_dialog - > set_title ( TTR ( " Delete Layout " ) ) ;
2020-12-14 18:37:30 +00:00
layout_dialog - > get_ok_button ( ) - > set_text ( TTR ( " Delete " ) ) ;
2015-11-22 18:11:17 +00:00
layout_dialog - > popup_centered ( ) ;
2019-05-30 18:16:40 +00:00
layout_dialog - > set_name_line_enabled ( false ) ;
2015-11-22 18:11:17 +00:00
} break ;
case SETTINGS_LAYOUT_DEFAULT : {
2016-01-11 21:23:45 +00:00
_load_docks_from_config ( default_layout , " docks " ) ;
2015-11-22 18:11:17 +00:00
_save_docks ( ) ;
} break ;
default : {
Ref < ConfigFile > config ;
2021-06-17 22:03:09 +00:00
config . instantiate ( ) ;
2017-11-17 20:48:24 +00:00
Error err = config - > load ( EditorSettings : : get_singleton ( ) - > get_editor_layouts_config ( ) ) ;
2017-03-05 15:44:50 +00:00
if ( err ! = OK ) {
2022-03-30 18:12:26 +00:00
return ; // No config.
2015-11-22 18:11:17 +00:00
}
2015-12-14 15:44:15 +00:00
_load_docks_from_config ( config , editor_layouts - > get_item_text ( p_id ) ) ;
2015-11-22 18:11:17 +00:00
_save_docks ( ) ;
}
}
2015-06-22 03:03:19 +00:00
}
2015-07-26 13:44:10 +00:00
void EditorNode : : _scene_tab_script_edited ( int p_tab ) {
2017-03-05 15:44:50 +00:00
Ref < Script > script = editor_data . get_scene_root_script ( p_tab ) ;
2020-05-14 14:41:43 +00:00
if ( script . is_valid ( ) ) {
2021-11-17 20:08:55 +00:00
InspectorDock : : get_singleton ( ) - > edit_resource ( script ) ;
2020-05-14 14:41:43 +00:00
}
2015-07-26 13:44:10 +00:00
}
2019-04-21 09:44:21 +00:00
void EditorNode : : _scene_tab_closed ( int p_tab , int option ) {
2022-03-30 18:12:26 +00:00
current_menu_option = option ;
tab_closing_idx = p_tab ;
2017-06-26 14:04:53 +00:00
Node * scene = editor_data . get_edited_scene_root ( p_tab ) ;
2017-07-09 18:48:39 +00:00
if ( ! scene ) {
_discard_changes ( ) ;
return ;
}
2016-05-02 11:40:44 +00:00
2021-10-28 13:57:41 +00:00
bool unsaved = ( p_tab = = editor_data . get_edited_scene ( ) )
? saved_version ! = editor_data . get_undo_redo ( ) . get_version ( )
: editor_data . get_scene_version ( p_tab ) ! = 0 ;
2016-05-02 11:40:44 +00:00
if ( unsaved ) {
2020-12-14 18:37:30 +00:00
save_confirmation - > get_ok_button ( ) - > set_text ( TTR ( " Save & Close " ) ) ;
2021-12-09 09:42:46 +00:00
save_confirmation - > set_text ( vformat ( TTR ( " Save changes to '%s' before closing? " ) , ! scene - > get_scene_file_path ( ) . is_empty ( ) ? scene - > get_scene_file_path ( ) : " unsaved scene " ) ) ;
2020-03-06 17:00:16 +00:00
save_confirmation - > popup_centered ( ) ;
2017-03-05 15:44:50 +00:00
} else {
2017-06-21 04:15:39 +00:00
_discard_changes ( ) ;
2015-11-19 13:15:17 +00:00
}
2017-11-24 23:32:54 +00:00
save_layout ( ) ;
2017-11-16 22:57:57 +00:00
_update_scene_tabs ( ) ;
2015-08-18 18:27:01 +00:00
}
2020-12-09 11:04:02 +00:00
void EditorNode : : _scene_tab_hovered ( int p_tab ) {
2018-10-06 20:20:41 +00:00
if ( ! bool ( EDITOR_GET ( " interface/scene_tabs/show_thumbnail_on_hover " ) ) ) {
2017-06-15 15:30:03 +00:00
return ;
}
int current_tab = scene_tabs - > get_current_tab ( ) ;
if ( p_tab = = current_tab | | p_tab < 0 ) {
tab_preview_panel - > hide ( ) ;
} else {
String path = editor_data . get_scene_path ( p_tab ) ;
2021-12-09 09:42:46 +00:00
if ( ! path . is_empty ( ) ) {
2018-10-21 14:38:01 +00:00
EditorResourcePreview : : get_singleton ( ) - > queue_resource_preview ( path , this , " _thumbnail_done " , p_tab ) ;
}
2017-06-15 15:30:03 +00:00
}
}
void EditorNode : : _scene_tab_exit ( ) {
tab_preview_panel - > hide ( ) ;
}
void EditorNode : : _scene_tab_input ( const Ref < InputEvent > & p_input ) {
Ref < InputEventMouseButton > mb = p_input ;
if ( mb . is_valid ( ) ) {
2017-07-01 16:23:16 +00:00
if ( scene_tabs - > get_hovered_tab ( ) > = 0 ) {
2021-08-13 21:31:57 +00:00
if ( mb - > get_button_index ( ) = = MouseButton : : MIDDLE & & mb - > is_pressed ( ) ) {
2017-07-01 16:23:16 +00:00
_scene_tab_closed ( scene_tabs - > get_hovered_tab ( ) ) ;
}
} else {
2021-08-13 21:31:57 +00:00
if ( ( mb - > get_button_index ( ) = = MouseButton : : LEFT & & mb - > is_double_click ( ) ) | | ( mb - > get_button_index ( ) = = MouseButton : : MIDDLE & & mb - > is_pressed ( ) ) ) {
2017-07-01 16:23:16 +00:00
_menu_option_confirm ( FILE_NEW_SCENE , true ) ;
}
2017-06-15 15:30:03 +00:00
}
2021-08-13 21:31:57 +00:00
if ( mb - > get_button_index ( ) = = MouseButton : : RIGHT & & mb - > is_pressed ( ) ) {
2022-03-30 18:12:26 +00:00
// Context menu.
2018-01-02 07:10:49 +00:00
scene_tabs_context_menu - > clear ( ) ;
2021-11-20 08:04:57 +00:00
scene_tabs_context_menu - > reset_size ( ) ;
2018-01-02 07:10:49 +00:00
scene_tabs_context_menu - > add_shortcut ( ED_GET_SHORTCUT ( " editor/new_scene " ) , FILE_NEW_SCENE ) ;
if ( scene_tabs - > get_hovered_tab ( ) > = 0 ) {
scene_tabs_context_menu - > add_shortcut ( ED_GET_SHORTCUT ( " editor/save_scene " ) , FILE_SAVE_SCENE ) ;
scene_tabs_context_menu - > add_shortcut ( ED_GET_SHORTCUT ( " editor/save_scene_as " ) , FILE_SAVE_AS_SCENE ) ;
}
scene_tabs_context_menu - > add_shortcut ( ED_GET_SHORTCUT ( " editor/save_all_scenes " ) , FILE_SAVE_ALL_SCENES ) ;
if ( scene_tabs - > get_hovered_tab ( ) > = 0 ) {
scene_tabs_context_menu - > add_separator ( ) ;
2018-10-26 19:11:36 +00:00
scene_tabs_context_menu - > add_item ( TTR ( " Show in FileSystem " ) , FILE_SHOW_IN_FILESYSTEM ) ;
2018-01-02 07:10:49 +00:00
scene_tabs_context_menu - > add_item ( TTR ( " Play This Scene " ) , RUN_PLAY_SCENE ) ;
2019-04-10 15:21:26 +00:00
2019-04-21 09:44:21 +00:00
scene_tabs_context_menu - > add_separator ( ) ;
2020-09-09 19:53:24 +00:00
Ref < Shortcut > close_tab_sc = ED_GET_SHORTCUT ( " editor/close_scene " ) ;
2019-04-10 15:21:26 +00:00
close_tab_sc - > set_name ( TTR ( " Close Tab " ) ) ;
scene_tabs_context_menu - > add_shortcut ( close_tab_sc , FILE_CLOSE ) ;
2020-09-09 19:53:24 +00:00
Ref < Shortcut > undo_close_tab_sc = ED_GET_SHORTCUT ( " editor/reopen_closed_scene " ) ;
2019-04-10 15:21:26 +00:00
undo_close_tab_sc - > set_name ( TTR ( " Undo Close Tab " ) ) ;
scene_tabs_context_menu - > add_shortcut ( undo_close_tab_sc , FILE_OPEN_PREV ) ;
2020-12-15 12:04:21 +00:00
if ( previous_scenes . is_empty ( ) ) {
2019-04-10 15:21:26 +00:00
scene_tabs_context_menu - > set_item_disabled ( scene_tabs_context_menu - > get_item_index ( FILE_OPEN_PREV ) , true ) ;
}
2019-04-21 09:44:21 +00:00
scene_tabs_context_menu - > add_item ( TTR ( " Close Other Tabs " ) , FILE_CLOSE_OTHERS ) ;
scene_tabs_context_menu - > add_item ( TTR ( " Close Tabs to the Right " ) , FILE_CLOSE_RIGHT ) ;
scene_tabs_context_menu - > add_item ( TTR ( " Close All Tabs " ) , FILE_CLOSE_ALL ) ;
2018-01-02 07:10:49 +00:00
}
2021-08-31 15:43:35 +00:00
scene_tabs_context_menu - > set_position ( scene_tabs - > get_screen_position ( ) + mb - > get_position ( ) ) ;
scene_tabs_context_menu - > reset_size ( ) ;
2018-01-02 07:10:49 +00:00
scene_tabs_context_menu - > popup ( ) ;
}
2021-08-13 21:31:57 +00:00
if ( mb - > get_button_index ( ) = = MouseButton : : WHEEL_UP & & mb - > is_pressed ( ) ) {
2021-04-07 13:25:44 +00:00
int previous_tab = editor_data . get_edited_scene ( ) - 1 ;
previous_tab = previous_tab > = 0 ? previous_tab : editor_data . get_edited_scene_count ( ) - 1 ;
_scene_tab_changed ( previous_tab ) ;
}
2021-08-13 21:31:57 +00:00
if ( mb - > get_button_index ( ) = = MouseButton : : WHEEL_DOWN & & mb - > is_pressed ( ) ) {
2021-04-07 13:25:44 +00:00
int next_tab = editor_data . get_edited_scene ( ) + 1 ;
next_tab % = editor_data . get_edited_scene_count ( ) ;
_scene_tab_changed ( next_tab ) ;
}
2017-06-15 15:30:03 +00:00
}
}
2017-07-05 13:44:53 +00:00
void EditorNode : : _reposition_active_tab ( int idx_to ) {
editor_data . move_edited_scene_to_index ( idx_to ) ;
_update_scene_tabs ( ) ;
}
2019-06-11 18:43:37 +00:00
void EditorNode : : _thumbnail_done ( const String & p_path , const Ref < Texture2D > & p_preview , const Ref < Texture2D > & p_small_preview , const Variant & p_udata ) {
2017-06-15 15:30:03 +00:00
int p_tab = p_udata . operator signed int ( ) ;
if ( p_preview . is_valid ( ) ) {
Rect2 rect = scene_tabs - > get_tab_rect ( p_tab ) ;
rect . position + = scene_tabs - > get_global_position ( ) ;
tab_preview - > set_texture ( p_preview ) ;
tab_preview_panel - > set_position ( rect . position + Vector2 ( 0 , rect . size . height ) ) ;
tab_preview_panel - > show ( ) ;
}
}
2015-06-22 03:03:19 +00:00
void EditorNode : : _scene_tab_changed ( int p_tab ) {
2017-06-15 15:30:03 +00:00
tab_preview_panel - > hide ( ) ;
2015-06-22 03:03:19 +00:00
2017-03-05 15:44:50 +00:00
bool unsaved = ( saved_version ! = editor_data . get_undo_redo ( ) . get_version ( ) ) ;
2015-06-22 03:03:19 +00:00
2020-05-14 14:41:43 +00:00
if ( p_tab = = editor_data . get_edited_scene ( ) ) {
2022-03-30 18:12:26 +00:00
return ; // Pointless.
2020-05-14 14:41:43 +00:00
}
2015-06-22 03:03:19 +00:00
uint64_t next_scene_version = editor_data . get_scene_version ( p_tab ) ;
2016-05-04 01:25:37 +00:00
editor_data . get_undo_redo ( ) . create_action ( TTR ( " Switch Scene Tab " ) ) ;
2017-03-05 15:44:50 +00:00
editor_data . get_undo_redo ( ) . add_do_method ( this , " set_current_version " , unsaved ? saved_version : 0 ) ;
editor_data . get_undo_redo ( ) . add_do_method ( this , " set_current_scene " , p_tab ) ;
editor_data . get_undo_redo ( ) . add_do_method ( this , " set_current_version " , next_scene_version = = 0 ? editor_data . get_undo_redo ( ) . get_version ( ) + 1 : next_scene_version ) ;
2015-06-22 03:03:19 +00:00
2017-03-05 15:44:50 +00:00
editor_data . get_undo_redo ( ) . add_undo_method ( this , " set_current_version " , next_scene_version ) ;
editor_data . get_undo_redo ( ) . add_undo_method ( this , " set_current_scene " , editor_data . get_edited_scene ( ) ) ;
editor_data . get_undo_redo ( ) . add_undo_method ( this , " set_current_version " , saved_version ) ;
2015-06-22 03:03:19 +00:00
editor_data . get_undo_redo ( ) . commit_action ( ) ;
2015-06-14 01:12:53 +00:00
}
2014-06-19 05:23:03 +00:00
2020-06-19 18:49:04 +00:00
Button * EditorNode : : add_bottom_panel_item ( String p_text , Control * p_item ) {
Button * tb = memnew ( Button ) ;
tb - > set_flat ( true ) ;
2020-02-21 17:28:45 +00:00
tb - > connect ( " toggled " , callable_mp ( this , & EditorNode : : _bottom_panel_switch ) , varray ( bottom_panel_items . size ( ) ) ) ;
2016-01-17 23:03:57 +00:00
tb - > set_text ( p_text ) ;
tb - > set_toggle_mode ( true ) ;
tb - > set_focus_mode ( Control : : FOCUS_NONE ) ;
bottom_panel_vb - > add_child ( p_item ) ;
bottom_panel_hb - > raise ( ) ;
2018-07-16 01:38:14 +00:00
bottom_panel_hb_editors - > add_child ( tb ) ;
2016-01-17 23:03:57 +00:00
p_item - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
p_item - > hide ( ) ;
BottomPanelItem bpi ;
2017-03-05 15:44:50 +00:00
bpi . button = tb ;
bpi . control = p_item ;
bpi . name = p_text ;
2016-01-17 23:03:57 +00:00
bottom_panel_items . push_back ( bpi ) ;
return tb ;
}
void EditorNode : : hide_bottom_panel ( ) {
2019-03-16 06:39:49 +00:00
for ( int i = 0 ; i < bottom_panel_items . size ( ) ; i + + ) {
if ( bottom_panel_items [ i ] . control - > is_visible ( ) ) {
_bottom_panel_switch ( false , i ) ;
break ;
}
}
2016-01-17 23:03:57 +00:00
}
void EditorNode : : make_bottom_panel_item_visible ( Control * p_item ) {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < bottom_panel_items . size ( ) ; i + + ) {
if ( bottom_panel_items [ i ] . control = = p_item ) {
_bottom_panel_switch ( true , i ) ;
2016-01-17 23:03:57 +00:00
break ;
}
}
}
void EditorNode : : raise_bottom_panel_item ( Control * p_item ) {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < bottom_panel_items . size ( ) ; i + + ) {
if ( bottom_panel_items [ i ] . control = = p_item ) {
2016-01-17 23:03:57 +00:00
bottom_panel_items [ i ] . button - > raise ( ) ;
2018-07-25 01:11:03 +00:00
SWAP ( bottom_panel_items . write [ i ] , bottom_panel_items . write [ bottom_panel_items . size ( ) - 1 ] ) ;
2016-01-17 23:03:57 +00:00
break ;
}
}
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < bottom_panel_items . size ( ) ; i + + ) {
2020-02-21 17:28:45 +00:00
bottom_panel_items [ i ] . button - > disconnect ( " toggled " , callable_mp ( this , & EditorNode : : _bottom_panel_switch ) ) ;
bottom_panel_items [ i ] . button - > connect ( " toggled " , callable_mp ( this , & EditorNode : : _bottom_panel_switch ) , varray ( i ) ) ;
2016-01-17 23:03:57 +00:00
}
}
2016-02-28 19:58:17 +00:00
void EditorNode : : remove_bottom_panel_item ( Control * p_item ) {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < bottom_panel_items . size ( ) ; i + + ) {
if ( bottom_panel_items [ i ] . control = = p_item ) {
2017-01-13 13:45:50 +00:00
if ( p_item - > is_visible_in_tree ( ) ) {
2019-03-16 06:39:49 +00:00
_bottom_panel_switch ( false , i ) ;
2016-02-28 19:58:17 +00:00
}
bottom_panel_vb - > remove_child ( bottom_panel_items [ i ] . control ) ;
2018-07-16 01:38:14 +00:00
bottom_panel_hb_editors - > remove_child ( bottom_panel_items [ i ] . button ) ;
2017-03-05 15:44:50 +00:00
memdelete ( bottom_panel_items [ i ] . button ) ;
2021-07-03 22:17:03 +00:00
bottom_panel_items . remove_at ( i ) ;
2016-02-28 19:58:17 +00:00
break ;
}
}
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < bottom_panel_items . size ( ) ; i + + ) {
2020-02-21 17:28:45 +00:00
bottom_panel_items [ i ] . button - > disconnect ( " toggled " , callable_mp ( this , & EditorNode : : _bottom_panel_switch ) ) ;
bottom_panel_items [ i ] . button - > connect ( " toggled " , callable_mp ( this , & EditorNode : : _bottom_panel_switch ) , varray ( i ) ) ;
2016-02-28 19:58:17 +00:00
}
}
2017-03-05 15:44:50 +00:00
void EditorNode : : _bottom_panel_switch ( bool p_enable , int p_idx ) {
ERR_FAIL_INDEX ( p_idx , bottom_panel_items . size ( ) ) ;
2016-01-17 23:03:57 +00:00
2019-03-16 06:39:49 +00:00
if ( bottom_panel_items [ p_idx ] . control - > is_visible ( ) = = p_enable ) {
return ;
}
2016-01-17 23:03:57 +00:00
if ( p_enable ) {
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < bottom_panel_items . size ( ) ; i + + ) {
bottom_panel_items [ i ] . button - > set_pressed ( i = = p_idx ) ;
bottom_panel_items [ i ] . control - > set_visible ( i = = p_idx ) ;
2016-01-17 23:03:57 +00:00
}
2022-03-30 18:12:26 +00:00
if ( EditorDebuggerNode : : get_singleton ( ) = = bottom_panel_items [ p_idx ] . control ) {
// This is the debug panel which uses tabs, so the top section should be smaller.
2022-02-08 09:14:58 +00:00
bottom_panel - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " BottomPanelDebuggerOverride " ) , SNAME ( " EditorStyles " ) ) ) ;
2017-09-18 19:06:55 +00:00
} else {
2022-02-08 09:14:58 +00:00
bottom_panel - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " panel " ) , SNAME ( " TabContainer " ) ) ) ;
2017-09-18 19:06:55 +00:00
}
2016-01-17 23:03:57 +00:00
center_split - > set_dragger_visibility ( SplitContainer : : DRAGGER_VISIBLE ) ;
center_split - > set_collapsed ( false ) ;
2018-07-16 01:38:14 +00:00
if ( bottom_panel_raise - > is_pressed ( ) ) {
top_split - > hide ( ) ;
}
bottom_panel_raise - > show ( ) ;
2016-01-17 23:03:57 +00:00
} else {
2022-02-08 09:14:58 +00:00
bottom_panel - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " panel " ) , SNAME ( " TabContainer " ) ) ) ;
2019-03-16 06:39:49 +00:00
bottom_panel_items [ p_idx ] . button - > set_pressed ( false ) ;
bottom_panel_items [ p_idx ] . control - > set_visible ( false ) ;
2016-01-17 23:03:57 +00:00
center_split - > set_dragger_visibility ( SplitContainer : : DRAGGER_HIDDEN ) ;
center_split - > set_collapsed ( true ) ;
2018-07-16 01:38:14 +00:00
bottom_panel_raise - > hide ( ) ;
if ( bottom_panel_raise - > is_pressed ( ) ) {
top_split - > show ( ) ;
}
2016-01-17 23:03:57 +00:00
}
}
2016-05-30 18:29:43 +00:00
void EditorNode : : set_docks_visible ( bool p_show ) {
docks_visible = p_show ;
_update_dock_slots_visibility ( ) ;
}
bool EditorNode : : get_docks_visible ( ) const {
return docks_visible ;
}
2016-09-13 12:46:17 +00:00
void EditorNode : : _toggle_distraction_free_mode ( ) {
2017-09-29 16:52:56 +00:00
if ( EditorSettings : : get_singleton ( ) - > get ( " interface/editor/separate_distraction_mode " ) ) {
2017-04-25 11:48:35 +00:00
int screen = - 1 ;
for ( int i = 0 ; i < editor_table . size ( ) ; i + + ) {
if ( editor_plugin_screen = = editor_table [ i ] ) {
screen = i ;
break ;
}
}
if ( screen = = EDITOR_SCRIPT ) {
2022-03-30 18:12:26 +00:00
script_distraction_free = ! script_distraction_free ;
set_distraction_free_mode ( script_distraction_free ) ;
2017-04-25 11:48:35 +00:00
} else {
2022-03-30 18:12:26 +00:00
scene_distraction_free = ! scene_distraction_free ;
set_distraction_free_mode ( scene_distraction_free ) ;
2017-04-25 11:48:35 +00:00
}
} else {
set_distraction_free_mode ( distraction_free - > is_pressed ( ) ) ;
}
2016-09-13 12:46:17 +00:00
}
2016-05-30 18:29:43 +00:00
void EditorNode : : set_distraction_free_mode ( bool p_enter ) {
2016-09-13 12:46:17 +00:00
distraction_free - > set_pressed ( p_enter ) ;
2016-05-30 18:29:43 +00:00
if ( p_enter ) {
if ( docks_visible ) {
set_docks_visible ( false ) ;
}
} else {
set_docks_visible ( true ) ;
}
}
2020-05-31 17:58:15 +00:00
bool EditorNode : : is_distraction_free_mode_enabled ( ) const {
2016-09-13 12:46:17 +00:00
return distraction_free - > is_pressed ( ) ;
2016-05-30 18:29:43 +00:00
}
2016-02-28 02:10:44 +00:00
2017-03-05 15:44:50 +00:00
void EditorNode : : add_control_to_dock ( DockSlot p_slot , Control * p_control ) {
ERR_FAIL_INDEX ( p_slot , DOCK_SLOT_MAX ) ;
2016-02-28 02:10:44 +00:00
dock_slot [ p_slot ] - > add_child ( p_control ) ;
_update_dock_slots_visibility ( ) ;
}
2017-03-05 15:44:50 +00:00
void EditorNode : : remove_control_from_dock ( Control * p_control ) {
2020-04-01 23:20:12 +00:00
Control * dock = nullptr ;
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
if ( p_control - > get_parent ( ) = = dock_slot [ i ] ) {
dock = dock_slot [ i ] ;
2016-02-28 02:10:44 +00:00
break ;
}
}
2019-08-15 02:57:49 +00:00
ERR_FAIL_COND_MSG ( ! dock , " Control was not in dock. " ) ;
2016-02-28 02:10:44 +00:00
dock - > remove_child ( p_control ) ;
_update_dock_slots_visibility ( ) ;
}
2017-03-05 15:44:50 +00:00
Variant EditorNode : : drag_resource ( const Ref < Resource > & p_res , Control * p_from ) {
Control * drag_control = memnew ( Control ) ;
TextureRect * drag_preview = memnew ( TextureRect ) ;
Label * label = memnew ( Label ) ;
2016-05-11 14:46:08 +00:00
2019-06-11 18:43:37 +00:00
Ref < Texture2D > preview ;
2016-05-11 14:46:08 +00:00
{
2022-03-30 18:12:26 +00:00
// TODO: make proper previews
2021-07-17 21:22:52 +00:00
Ref < ImageTexture > texture = gui_base - > get_theme_icon ( SNAME ( " FileBigThumb " ) , SNAME ( " EditorIcons " ) ) ;
2021-03-28 11:32:17 +00:00
Ref < Image > img = texture - > get_image ( ) ;
2017-05-17 10:36:47 +00:00
img = img - > duplicate ( ) ;
2021-10-17 16:55:44 +00:00
img - > resize ( 48 , 48 ) ; // meh
2017-03-05 15:44:50 +00:00
Ref < ImageTexture > resized_pic = Ref < ImageTexture > ( memnew ( ImageTexture ) ) ;
2016-05-11 14:46:08 +00:00
resized_pic - > create_from_image ( img ) ;
2017-03-05 15:44:50 +00:00
preview = resized_pic ;
2016-05-11 14:46:08 +00:00
}
drag_preview - > set_texture ( preview ) ;
drag_control - > add_child ( drag_preview ) ;
if ( p_res - > get_path ( ) . is_resource_file ( ) ) {
label - > set_text ( p_res - > get_path ( ) . get_file ( ) ) ;
2021-12-09 09:42:46 +00:00
} else if ( ! p_res - > get_name ( ) . is_empty ( ) ) {
2016-05-11 14:46:08 +00:00
label - > set_text ( p_res - > get_name ( ) ) ;
} else {
2017-01-03 02:03:46 +00:00
label - > set_text ( p_res - > get_class ( ) ) ;
2016-05-11 14:46:08 +00:00
}
drag_control - > add_child ( label ) ;
2022-03-30 18:12:26 +00:00
p_from - > set_drag_preview ( drag_control ) ; // Wait until it enters scene.
2016-05-11 14:46:08 +00:00
2017-03-29 15:29:38 +00:00
label - > set_position ( Point2 ( ( preview - > get_width ( ) - label - > get_minimum_size ( ) . width ) / 2 , preview - > get_height ( ) ) ) ;
2016-05-11 14:46:08 +00:00
Dictionary drag_data ;
2017-03-05 15:44:50 +00:00
drag_data [ " type " ] = " resource " ;
drag_data [ " resource " ] = p_res ;
drag_data [ " from " ] = p_from ;
2016-05-11 14:46:08 +00:00
return drag_data ;
}
2017-10-24 22:09:04 +00:00
Variant EditorNode : : drag_files_and_dirs ( const Vector < String > & p_paths , Control * p_from ) {
bool has_folder = false ;
bool has_file = false ;
for ( int i = 0 ; i < p_paths . size ( ) ; i + + ) {
bool is_folder = p_paths [ i ] . ends_with ( " / " ) ;
has_folder | = is_folder ;
has_file | = ! is_folder ;
}
int max_rows = 6 ;
2019-09-30 16:36:49 +00:00
int num_rows = p_paths . size ( ) > max_rows ? max_rows - 1 : p_paths . size ( ) ; // Don't waste a row to say "1 more file" - list it instead.
2017-10-24 22:09:04 +00:00
VBoxContainer * vbox = memnew ( VBoxContainer ) ;
for ( int i = 0 ; i < num_rows ; i + + ) {
HBoxContainer * hbox = memnew ( HBoxContainer ) ;
TextureRect * icon = memnew ( TextureRect ) ;
2017-03-05 15:44:50 +00:00
Label * label = memnew ( Label ) ;
2016-05-11 14:46:08 +00:00
2017-10-24 22:09:04 +00:00
if ( p_paths [ i ] . ends_with ( " / " ) ) {
label - > set_text ( p_paths [ i ] . substr ( 0 , p_paths [ i ] . length ( ) - 1 ) . get_file ( ) ) ;
2021-07-17 21:22:52 +00:00
icon - > set_texture ( gui_base - > get_theme_icon ( SNAME ( " Folder " ) , SNAME ( " EditorIcons " ) ) ) ;
2017-10-24 22:09:04 +00:00
} else {
label - > set_text ( p_paths [ i ] . get_file ( ) ) ;
2021-07-17 21:22:52 +00:00
icon - > set_texture ( gui_base - > get_theme_icon ( SNAME ( " File " ) , SNAME ( " EditorIcons " ) ) ) ;
2017-10-24 22:09:04 +00:00
}
2019-09-30 16:36:49 +00:00
icon - > set_stretch_mode ( TextureRect : : STRETCH_KEEP_CENTERED ) ;
2017-10-24 22:09:04 +00:00
icon - > set_size ( Size2 ( 16 , 16 ) ) ;
hbox - > add_child ( icon ) ;
hbox - > add_child ( label ) ;
vbox - > add_child ( hbox ) ;
2016-05-11 14:46:08 +00:00
}
2017-10-24 22:09:04 +00:00
if ( p_paths . size ( ) > num_rows ) {
2017-03-05 15:44:50 +00:00
Label * label = memnew ( Label ) ;
2017-10-24 22:09:04 +00:00
if ( has_file & & has_folder ) {
label - > set_text ( vformat ( TTR ( " %d more files or folders " ) , p_paths . size ( ) - num_rows ) ) ;
} else if ( has_folder ) {
label - > set_text ( vformat ( TTR ( " %d more folders " ) , p_paths . size ( ) - num_rows ) ) ;
} else {
label - > set_text ( vformat ( TTR ( " %d more files " ) , p_paths . size ( ) - num_rows ) ) ;
}
vbox - > add_child ( label ) ;
2016-05-11 14:46:08 +00:00
}
2022-03-30 18:12:26 +00:00
p_from - > set_drag_preview ( vbox ) ; // Wait until it enters scene.
2016-05-11 14:46:08 +00:00
Dictionary drag_data ;
2017-10-24 22:09:04 +00:00
drag_data [ " type " ] = has_folder ? " files_and_dirs " : " files " ;
drag_data [ " files " ] = p_paths ;
2017-03-05 15:44:50 +00:00
drag_data [ " from " ] = p_from ;
2016-05-11 14:46:08 +00:00
return drag_data ;
}
2020-12-15 23:04:21 +00:00
void EditorNode : : add_tool_menu_item ( const String & p_name , const Callable & p_callback ) {
2018-03-17 01:50:35 +00:00
int idx = tool_menu - > get_item_count ( ) ;
tool_menu - > add_item ( p_name , TOOLS_CUSTOM ) ;
2020-12-15 23:04:21 +00:00
tool_menu - > set_item_metadata ( idx , p_callback ) ;
2018-03-17 01:50:35 +00:00
}
void EditorNode : : add_tool_submenu_item ( const String & p_name , PopupMenu * p_submenu ) {
ERR_FAIL_NULL ( p_submenu ) ;
2020-04-01 23:20:12 +00:00
ERR_FAIL_COND ( p_submenu - > get_parent ( ) ! = nullptr ) ;
2018-03-17 01:50:35 +00:00
tool_menu - > add_child ( p_submenu ) ;
tool_menu - > add_submenu_item ( p_name , p_submenu - > get_name ( ) , TOOLS_CUSTOM ) ;
}
void EditorNode : : remove_tool_menu_item ( const String & p_name ) {
for ( int i = 0 ; i < tool_menu - > get_item_count ( ) ; i + + ) {
2020-05-14 14:41:43 +00:00
if ( tool_menu - > get_item_id ( i ) ! = TOOLS_CUSTOM ) {
2018-03-17 01:50:35 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2018-03-17 01:50:35 +00:00
if ( tool_menu - > get_item_text ( i ) = = p_name ) {
if ( tool_menu - > get_item_submenu ( i ) ! = " " ) {
Node * n = tool_menu - > get_node ( tool_menu - > get_item_submenu ( i ) ) ;
tool_menu - > remove_child ( n ) ;
memdelete ( n ) ;
}
tool_menu - > remove_item ( i ) ;
2022-03-05 23:57:42 +00:00
tool_menu - > reset_size ( ) ;
2018-03-17 01:50:35 +00:00
return ;
}
}
}
2022-04-06 12:41:04 +00:00
PopupMenu * EditorNode : : get_export_as_menu ( ) {
return export_as_menu ;
}
2020-03-07 16:02:54 +00:00
void EditorNode : : _global_menu_scene ( const Variant & p_tag ) {
int idx = ( int ) p_tag ;
scene_tabs - > set_current_tab ( idx ) ;
}
2019-02-06 13:57:06 +00:00
2020-03-07 16:02:54 +00:00
void EditorNode : : _global_menu_new_window ( const Variant & p_tag ) {
if ( OS : : get_singleton ( ) - > get_main_loop ( ) ) {
List < String > args ;
args . push_back ( " -p " ) ;
2021-11-01 09:12:52 +00:00
OS : : get_singleton ( ) - > create_instance ( args ) ;
2019-02-06 13:57:06 +00:00
}
}
2022-04-10 19:25:24 +00:00
void EditorNode : : _dropped_files ( const Vector < String > & p_files ) {
2021-11-17 20:08:55 +00:00
String to_path = ProjectSettings : : get_singleton ( ) - > globalize_path ( FileSystemDock : : get_singleton ( ) - > get_selected_path ( ) ) ;
2017-11-17 20:52:03 +00:00
2019-03-25 21:39:45 +00:00
_add_dropped_files_recursive ( p_files , to_path ) ;
EditorFileSystem : : get_singleton ( ) - > scan_changes ( ) ;
}
void EditorNode : : _add_dropped_files_recursive ( const Vector < String > & p_files , String to_path ) {
2022-03-23 09:08:58 +00:00
Ref < DirAccess > dir = DirAccess : : create ( DirAccess : : ACCESS_FILESYSTEM ) ;
2019-03-25 21:39:45 +00:00
2017-11-17 20:52:03 +00:00
for ( int i = 0 ; i < p_files . size ( ) ; i + + ) {
String from = p_files [ i ] ;
2019-03-25 21:39:45 +00:00
String to = to_path . plus_file ( from . get_file ( ) ) ;
if ( dir - > dir_exists ( from ) ) {
Vector < String > sub_files ;
2022-03-23 09:08:58 +00:00
Ref < DirAccess > sub_dir = DirAccess : : open ( from ) ;
2019-03-25 21:39:45 +00:00
sub_dir - > list_dir_begin ( ) ;
String next_file = sub_dir - > get_next ( ) ;
2021-12-09 09:42:46 +00:00
while ( ! next_file . is_empty ( ) ) {
2019-03-25 21:39:45 +00:00
if ( next_file = = " . " | | next_file = = " .. " ) {
next_file = sub_dir - > get_next ( ) ;
continue ;
}
sub_files . push_back ( from . plus_file ( next_file ) ) ;
next_file = sub_dir - > get_next ( ) ;
}
2020-12-15 12:04:21 +00:00
if ( ! sub_files . is_empty ( ) ) {
2019-03-25 21:39:45 +00:00
dir - > make_dir ( to ) ;
_add_dropped_files_recursive ( sub_files , to ) ;
}
continue ;
}
2017-11-17 20:52:03 +00:00
dir - > copy ( from , to ) ;
2017-08-26 15:46:49 +00:00
}
2016-05-27 17:18:40 +00:00
}
2017-08-26 15:46:49 +00:00
2017-03-05 15:44:50 +00:00
void EditorNode : : _file_access_close_error_notify ( const String & p_str ) {
2022-03-07 13:50:02 +00:00
add_io_error ( vformat ( TTR ( " Unable to write to file '%s', file in use, locked or lacking permissions. " ) , p_str ) ) ;
2016-06-13 13:10:50 +00:00
}
2016-05-27 17:18:40 +00:00
2017-03-05 15:44:50 +00:00
void EditorNode : : reload_scene ( const String & p_path ) {
int scene_idx = - 1 ;
for ( int i = 0 ; i < editor_data . get_edited_scene_count ( ) ; i + + ) {
if ( editor_data . get_scene_path ( i ) = = p_path ) {
scene_idx = i ;
2016-06-28 21:53:31 +00:00
break ;
}
}
int current_tab = editor_data . get_edited_scene ( ) ;
2017-03-05 15:44:50 +00:00
if ( scene_idx = = - 1 ) {
2016-06-28 21:53:31 +00:00
if ( get_edited_scene ( ) ) {
2022-03-30 18:12:26 +00:00
// Scene is not open, so at it might be instantiated. We'll refresh the whole scene later.
2016-06-28 21:53:31 +00:00
editor_data . get_undo_redo ( ) . clear_history ( ) ;
}
return ;
}
2017-03-05 15:44:50 +00:00
if ( current_tab = = scene_idx ) {
2016-06-28 21:53:31 +00:00
editor_data . apply_changes_in_editors ( ) ;
_set_scene_metadata ( p_path ) ;
}
2019-06-04 03:36:23 +00:00
2022-03-30 18:12:26 +00:00
// Reload scene.
2019-06-04 03:36:23 +00:00
_remove_scene ( scene_idx , false ) ;
2017-08-31 21:57:03 +00:00
load_scene ( p_path , true , false , true , true ) ;
2019-06-04 03:36:23 +00:00
2022-03-30 18:12:26 +00:00
// Adjust index so tab is back a the previous position.
2016-06-28 21:53:31 +00:00
editor_data . move_edited_scene_to_index ( scene_idx ) ;
get_undo_redo ( ) - > clear_history ( ) ;
2019-06-04 03:36:23 +00:00
2022-03-30 18:12:26 +00:00
// Recover the tab.
2016-06-28 21:53:31 +00:00
scene_tabs - > set_current_tab ( current_tab ) ;
}
2017-03-05 15:44:50 +00:00
int EditorNode : : plugin_init_callback_count = 0 ;
2016-08-06 22:00:54 +00:00
void EditorNode : : add_plugin_init_callback ( EditorPluginInitializeCallback p_callback ) {
2017-03-05 15:44:50 +00:00
ERR_FAIL_COND ( plugin_init_callback_count = = MAX_INIT_CALLBACKS ) ;
2016-08-06 22:00:54 +00:00
2017-03-05 15:44:50 +00:00
plugin_init_callbacks [ plugin_init_callback_count + + ] = p_callback ;
2016-08-06 22:00:54 +00:00
}
EditorPluginInitializeCallback EditorNode : : plugin_init_callbacks [ EditorNode : : MAX_INIT_CALLBACKS ] ;
2017-03-05 15:44:50 +00:00
int EditorNode : : build_callback_count = 0 ;
2016-09-14 22:37:37 +00:00
void EditorNode : : add_build_callback ( EditorBuildCallback p_callback ) {
2017-03-05 15:44:50 +00:00
ERR_FAIL_COND ( build_callback_count = = MAX_INIT_CALLBACKS ) ;
2016-09-14 22:37:37 +00:00
2017-03-05 15:44:50 +00:00
build_callbacks [ build_callback_count + + ] = p_callback ;
2016-09-14 22:37:37 +00:00
}
2017-08-29 21:59:20 +00:00
EditorBuildCallback EditorNode : : build_callbacks [ EditorNode : : MAX_BUILD_CALLBACKS ] ;
2016-09-14 22:37:37 +00:00
2018-02-14 15:23:04 +00:00
bool EditorNode : : call_build ( ) {
2018-01-08 15:55:22 +00:00
bool builds_successful = true ;
for ( int i = 0 ; i < build_callback_count & & builds_successful ; i + + ) {
if ( ! build_callbacks [ i ] ( ) ) {
ERR_PRINT ( " A Godot Engine build callback failed. " ) ;
builds_successful = false ;
}
2016-09-14 22:44:08 +00:00
}
2017-08-29 21:59:20 +00:00
2018-01-08 15:55:22 +00:00
if ( builds_successful & & ! editor_data . call_build ( ) ) {
ERR_PRINT ( " An EditorPlugin build callback failed. " ) ;
builds_successful = false ;
}
return builds_successful ;
2016-09-14 22:44:08 +00:00
}
2016-09-14 22:37:37 +00:00
2017-03-05 15:44:50 +00:00
void EditorNode : : _inherit_imported ( const String & p_action ) {
2017-02-04 23:31:15 +00:00
open_imported - > hide ( ) ;
2017-03-05 15:44:50 +00:00
load_scene ( open_import_request , true , true ) ;
2017-02-04 23:31:15 +00:00
}
void EditorNode : : _open_imported ( ) {
2017-03-05 15:44:50 +00:00
load_scene ( open_import_request , true , false , true , true ) ;
2017-02-04 23:31:15 +00:00
}
2021-05-28 23:58:03 +00:00
void EditorNode : : dim_editor ( bool p_dimming ) {
dimmed = p_dimming ;
gui_base - > set_modulate ( p_dimming ? Color ( 0.5 , 0.5 , 0.5 ) : Color ( 1 , 1 , 1 ) ) ;
2017-03-06 19:11:56 +00:00
}
2019-10-31 19:58:53 +00:00
bool EditorNode : : is_editor_dimmed ( ) const {
return dimmed ;
}
2017-03-21 02:31:41 +00:00
void EditorNode : : open_export_template_manager ( ) {
export_template_manager - > popup_manager ( ) ;
}
2017-09-22 12:20:28 +00:00
void EditorNode : : add_resource_conversion_plugin ( const Ref < EditorResourceConversionPlugin > & p_plugin ) {
resource_conversion_plugins . push_back ( p_plugin ) ;
}
void EditorNode : : remove_resource_conversion_plugin ( const Ref < EditorResourceConversionPlugin > & p_plugin ) {
resource_conversion_plugins . erase ( p_plugin ) ;
}
2020-03-17 06:33:00 +00:00
Vector < Ref < EditorResourceConversionPlugin > > EditorNode : : find_resource_conversion_plugin ( const Ref < Resource > & p_for_resource ) {
Vector < Ref < EditorResourceConversionPlugin > > ret ;
2017-09-22 12:20:28 +00:00
for ( int i = 0 ; i < resource_conversion_plugins . size ( ) ; i + + ) {
if ( resource_conversion_plugins [ i ] . is_valid ( ) & & resource_conversion_plugins [ i ] - > handles ( p_for_resource ) ) {
ret . push_back ( resource_conversion_plugins [ i ] ) ;
}
}
return ret ;
}
2018-07-16 01:38:14 +00:00
void EditorNode : : _bottom_panel_raise_toggled ( bool p_pressed ) {
2019-07-29 21:08:05 +00:00
top_split - > set_visible ( ! p_pressed ) ;
2018-07-16 01:38:14 +00:00
}
2020-11-18 18:11:30 +00:00
void EditorNode : : _update_rendering_driver_color ( ) {
2021-10-26 15:18:39 +00:00
if ( rendering_driver - > get_text ( ) = = " opengl3 " ) {
2022-02-08 09:14:58 +00:00
rendering_driver - > add_theme_color_override ( " font_color " , Color : : hex ( 0x5586a4ff ) ) ;
2021-09-26 23:07:10 +00:00
} else if ( rendering_driver - > get_text ( ) = = " vulkan " ) {
2022-02-08 09:14:58 +00:00
rendering_driver - > add_theme_color_override ( " font_color " , theme_base - > get_theme_color ( SNAME ( " vulkan_color " ) , SNAME ( " Editor " ) ) ) ;
2018-09-28 19:40:20 +00:00
}
}
2020-11-18 18:11:30 +00:00
void EditorNode : : _rendering_driver_selected ( int p_which ) {
String driver = rendering_driver - > get_item_metadata ( p_which ) ;
2018-07-19 21:58:15 +00:00
2022-03-30 18:12:26 +00:00
String current_driver = OS : : get_singleton ( ) - > get_current_rendering_driver_name ( ) ;
2018-07-19 21:58:15 +00:00
2022-03-30 18:12:26 +00:00
if ( driver = = current_driver ) {
2018-07-19 21:58:15 +00:00
return ;
}
2020-11-18 18:11:30 +00:00
rendering_driver_request = driver ;
2020-03-06 17:00:16 +00:00
video_restart_dialog - > popup_centered ( ) ;
2020-11-18 18:11:30 +00:00
rendering_driver - > select ( rendering_driver_current ) ;
_update_rendering_driver_color ( ) ;
2018-07-19 21:58:15 +00:00
}
2022-05-02 23:43:50 +00:00
void EditorNode : : _resource_saved ( Ref < Resource > p_resource , const String & p_path ) {
2018-10-29 19:36:31 +00:00
if ( EditorFileSystem : : get_singleton ( ) ) {
EditorFileSystem : : get_singleton ( ) - > update_file ( p_path ) ;
}
singleton - > editor_folding . save_resource_folding ( p_resource , p_path ) ;
}
2022-05-02 23:43:50 +00:00
void EditorNode : : _resource_loaded ( Ref < Resource > p_resource , const String & p_path ) {
2018-10-29 19:36:31 +00:00
singleton - > editor_folding . load_resource_folding ( p_resource , p_path ) ;
}
2019-04-08 22:18:03 +00:00
void EditorNode : : _feature_profile_changed ( ) {
Ref < EditorFeatureProfile > profile = feature_profile_manager - > get_current_profile ( ) ;
2021-11-17 20:08:55 +00:00
TabContainer * import_tabs = cast_to < TabContainer > ( ImportDock : : get_singleton ( ) - > get_parent ( ) ) ;
TabContainer * node_tabs = cast_to < TabContainer > ( NodeDock : : get_singleton ( ) - > get_parent ( ) ) ;
TabContainer * fs_tabs = cast_to < TabContainer > ( FileSystemDock : : get_singleton ( ) - > get_parent ( ) ) ;
2019-04-08 22:18:03 +00:00
if ( profile . is_valid ( ) ) {
2022-03-02 14:37:10 +00:00
node_tabs - > set_tab_hidden ( node_tabs - > get_tab_idx_from_control ( NodeDock : : get_singleton ( ) ) , profile - > is_feature_disabled ( EditorFeatureProfile : : FEATURE_NODE_DOCK ) ) ;
2020-05-08 19:51:42 +00:00
// The Import dock is useless without the FileSystem dock. Ensure the configuration is valid.
bool fs_dock_disabled = profile - > is_feature_disabled ( EditorFeatureProfile : : FEATURE_FILESYSTEM_DOCK ) ;
2022-03-02 14:37:10 +00:00
fs_tabs - > set_tab_hidden ( fs_tabs - > get_tab_idx_from_control ( FileSystemDock : : get_singleton ( ) ) , fs_dock_disabled ) ;
import_tabs - > set_tab_hidden ( import_tabs - > get_tab_idx_from_control ( ImportDock : : get_singleton ( ) ) , fs_dock_disabled | | profile - > is_feature_disabled ( EditorFeatureProfile : : FEATURE_IMPORT_DOCK ) ) ;
2019-04-08 22:18:03 +00:00
main_editor_buttons [ EDITOR_3D ] - > set_visible ( ! profile - > is_feature_disabled ( EditorFeatureProfile : : FEATURE_3D ) ) ;
main_editor_buttons [ EDITOR_SCRIPT ] - > set_visible ( ! profile - > is_feature_disabled ( EditorFeatureProfile : : FEATURE_SCRIPT ) ) ;
2020-05-14 14:41:43 +00:00
if ( StreamPeerSSL : : is_available ( ) ) {
2019-07-02 13:28:34 +00:00
main_editor_buttons [ EDITOR_ASSETLIB ] - > set_visible ( ! profile - > is_feature_disabled ( EditorFeatureProfile : : FEATURE_ASSET_LIB ) ) ;
2020-05-14 14:41:43 +00:00
}
2019-06-05 04:12:08 +00:00
if ( ( profile - > is_feature_disabled ( EditorFeatureProfile : : FEATURE_3D ) & & singleton - > main_editor_buttons [ EDITOR_3D ] - > is_pressed ( ) ) | |
( profile - > is_feature_disabled ( EditorFeatureProfile : : FEATURE_SCRIPT ) & & singleton - > main_editor_buttons [ EDITOR_SCRIPT ] - > is_pressed ( ) ) | |
2019-07-02 13:28:34 +00:00
( StreamPeerSSL : : is_available ( ) & & profile - > is_feature_disabled ( EditorFeatureProfile : : FEATURE_ASSET_LIB ) & & singleton - > main_editor_buttons [ EDITOR_ASSETLIB ] - > is_pressed ( ) ) ) {
2019-04-08 22:18:03 +00:00
_editor_select ( EDITOR_2D ) ;
}
} else {
2022-03-02 14:37:10 +00:00
import_tabs - > set_tab_hidden ( import_tabs - > get_tab_idx_from_control ( ImportDock : : get_singleton ( ) ) , false ) ;
node_tabs - > set_tab_hidden ( node_tabs - > get_tab_idx_from_control ( NodeDock : : get_singleton ( ) ) , false ) ;
fs_tabs - > set_tab_hidden ( fs_tabs - > get_tab_idx_from_control ( FileSystemDock : : get_singleton ( ) ) , false ) ;
2021-11-17 20:08:55 +00:00
ImportDock : : get_singleton ( ) - > set_visible ( true ) ;
NodeDock : : get_singleton ( ) - > set_visible ( true ) ;
FileSystemDock : : get_singleton ( ) - > set_visible ( true ) ;
2019-04-08 22:18:03 +00:00
main_editor_buttons [ EDITOR_3D ] - > set_visible ( true ) ;
2019-06-05 04:12:08 +00:00
main_editor_buttons [ EDITOR_SCRIPT ] - > set_visible ( true ) ;
2020-05-14 14:41:43 +00:00
if ( StreamPeerSSL : : is_available ( ) ) {
2019-07-02 13:28:34 +00:00
main_editor_buttons [ EDITOR_ASSETLIB ] - > set_visible ( true ) ;
2020-05-14 14:41:43 +00:00
}
2019-04-08 22:18:03 +00:00
}
_update_dock_slots_visibility ( ) ;
}
2016-01-17 23:03:57 +00:00
void EditorNode : : _bind_methods ( ) {
2021-09-12 11:21:24 +00:00
GLOBAL_DEF ( " editor/scene/scene_naming " , SCENE_NAME_CASING_SNAKE_CASE ) ;
ProjectSettings : : get_singleton ( ) - > set_custom_property_info ( " editor/scene/scene_naming " , PropertyInfo ( Variant : : INT , " editor/scene/scene_naming " , PROPERTY_HINT_ENUM , " Auto,PascalCase,snake_case " ) ) ;
2022-02-04 15:28:18 +00:00
ClassDB : : bind_method ( " edit_current " , & EditorNode : : edit_current ) ;
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( " _editor_select " , & EditorNode : : _editor_select ) ;
ClassDB : : bind_method ( " _node_renamed " , & EditorNode : : _node_renamed ) ;
ClassDB : : bind_method ( " edit_node " , & EditorNode : : edit_node ) ;
2018-12-31 08:52:09 +00:00
ClassDB : : bind_method ( D_METHOD ( " push_item " , " object " , " property " , " inspector_only " ) , & EditorNode : : push_item , DEFVAL ( " " ) , DEFVAL ( false ) ) ;
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( " _get_scene_metadata " , & EditorNode : : _get_scene_metadata ) ;
ClassDB : : bind_method ( " set_edited_scene " , & EditorNode : : set_edited_scene ) ;
ClassDB : : bind_method ( " open_request " , & EditorNode : : open_request ) ;
2022-03-25 00:17:30 +00:00
ClassDB : : bind_method ( " edit_foreign_resource " , & EditorNode : : edit_foreign_resource ) ;
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( " _close_messages " , & EditorNode : : _close_messages ) ;
ClassDB : : bind_method ( " _show_messages " , & EditorNode : : _show_messages ) ;
ClassDB : : bind_method ( " stop_child_process " , & EditorNode : : stop_child_process ) ;
ClassDB : : bind_method ( " set_current_scene " , & EditorNode : : set_current_scene ) ;
ClassDB : : bind_method ( " set_current_version " , & EditorNode : : set_current_version ) ;
2017-06-15 15:30:03 +00:00
ClassDB : : bind_method ( " _thumbnail_done " , & EditorNode : : _thumbnail_done ) ;
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( " _set_main_scene_state " , & EditorNode : : _set_main_scene_state ) ;
2017-10-12 02:35:15 +00:00
ClassDB : : bind_method ( " _update_recent_scenes " , & EditorNode : : _update_recent_scenes ) ;
2017-03-05 15:44:50 +00:00
ClassDB : : bind_method ( " _clear_undo_history " , & EditorNode : : _clear_undo_history ) ;
2020-03-07 16:02:54 +00:00
2019-02-22 20:42:29 +00:00
ClassDB : : bind_method ( " edit_item_resource " , & EditorNode : : edit_item_resource ) ;
2017-09-14 13:38:59 +00:00
2017-02-13 11:47:24 +00:00
ClassDB : : bind_method ( D_METHOD ( " get_gui_base " ) , & EditorNode : : get_gui_base ) ;
2018-11-21 00:47:48 +00:00
2020-02-21 22:26:13 +00:00
ClassDB : : bind_method ( D_METHOD ( " _on_plugin_ready " ) , & EditorNode : : _on_plugin_ready ) ; // Still used by some connect_compat.
2019-03-29 13:53:11 +00:00
ClassDB : : bind_method ( " _screenshot " , & EditorNode : : _screenshot ) ;
ClassDB : : bind_method ( " _save_screenshot " , & EditorNode : : _save_screenshot ) ;
2019-12-24 00:20:54 +00:00
ClassDB : : bind_method ( " _version_button_pressed " , & EditorNode : : _version_button_pressed ) ;
2017-03-05 15:44:50 +00:00
ADD_SIGNAL ( MethodInfo ( " play_pressed " ) ) ;
ADD_SIGNAL ( MethodInfo ( " pause_pressed " ) ) ;
ADD_SIGNAL ( MethodInfo ( " stop_pressed " ) ) ;
2017-05-16 19:26:32 +00:00
ADD_SIGNAL ( MethodInfo ( " request_help_search " ) ) ;
2020-02-17 21:06:54 +00:00
ADD_SIGNAL ( MethodInfo ( " script_add_function_request " , PropertyInfo ( Variant : : OBJECT , " obj " ) , PropertyInfo ( Variant : : STRING , " function " ) , PropertyInfo ( Variant : : PACKED_STRING_ARRAY , " args " ) ) ) ;
2017-03-05 15:44:50 +00:00
ADD_SIGNAL ( MethodInfo ( " resource_saved " , PropertyInfo ( Variant : : OBJECT , " obj " ) ) ) ;
2021-11-06 01:15:19 +00:00
ADD_SIGNAL ( MethodInfo ( " scene_saved " , PropertyInfo ( Variant : : STRING , " path " ) ) ) ;
2021-02-13 14:06:56 +00:00
ADD_SIGNAL ( MethodInfo ( " project_settings_changed " ) ) ;
2016-01-17 23:03:57 +00:00
}
2017-03-05 15:44:50 +00:00
static Node * _resource_get_edited_scene ( ) {
2017-01-10 04:04:31 +00:00
return EditorNode : : get_singleton ( ) - > get_edited_scene ( ) ;
}
2017-11-14 22:02:31 +00:00
void EditorNode : : _print_handler ( void * p_this , const String & p_string , bool p_error ) {
2022-04-05 10:40:26 +00:00
EditorNode * en = static_cast < EditorNode * > ( p_this ) ;
2018-08-13 15:04:38 +00:00
en - > log - > add_message ( p_string , p_error ? EditorLog : : MSG_TYPE_ERROR : EditorLog : : MSG_TYPE_STD ) ;
2017-11-14 22:02:31 +00:00
}
2019-04-07 18:46:52 +00:00
static void _execute_thread ( void * p_ud ) {
EditorNode : : ExecuteThreadArgs * eta = ( EditorNode : : ExecuteThreadArgs * ) p_ud ;
2020-12-18 18:49:13 +00:00
Error err = OS : : get_singleton ( ) - > execute ( eta - > path , eta - > args , & eta - > output , & eta - > exitcode , true , & eta - > execute_output_mutex ) ;
2019-04-07 18:46:52 +00:00
print_verbose ( " Thread exit status: " + itos ( eta - > exitcode ) ) ;
if ( err ! = OK ) {
eta - > exitcode = err ;
}
2021-02-10 18:22:13 +00:00
eta - > done . set ( ) ;
2019-04-07 18:46:52 +00:00
}
int EditorNode : : execute_and_show_output ( const String & p_title , const String & p_path , const List < String > & p_arguments , bool p_close_on_ok , bool p_close_on_errors ) {
execute_output_dialog - > set_title ( p_title ) ;
2020-12-14 18:37:30 +00:00
execute_output_dialog - > get_ok_button ( ) - > set_disabled ( true ) ;
2019-04-07 18:46:52 +00:00
execute_outputs - > clear ( ) ;
execute_outputs - > set_scroll_follow ( true ) ;
execute_output_dialog - > popup_centered_ratio ( ) ;
ExecuteThreadArgs eta ;
eta . path = p_path ;
eta . args = p_arguments ;
eta . exitcode = 255 ;
int prev_len = 0 ;
2021-01-19 12:29:41 +00:00
eta . execute_output_thread . start ( _execute_thread , & eta ) ;
2019-04-07 18:46:52 +00:00
2021-02-10 18:22:13 +00:00
while ( ! eta . done . is_set ( ) ) {
2020-02-26 10:28:13 +00:00
{
MutexLock lock ( eta . execute_output_mutex ) ;
if ( prev_len ! = eta . output . length ( ) ) {
String to_add = eta . output . substr ( prev_len , eta . output . length ( ) ) ;
prev_len = eta . output . length ( ) ;
execute_outputs - > add_text ( to_add ) ;
Main : : iteration ( ) ;
}
}
2019-04-07 18:46:52 +00:00
OS : : get_singleton ( ) - > delay_usec ( 1000 ) ;
}
2021-01-19 12:29:41 +00:00
eta . execute_output_thread . wait_to_finish ( ) ;
2019-04-07 18:46:52 +00:00
execute_outputs - > add_text ( " \n Exit Code: " + itos ( eta . exitcode ) ) ;
if ( p_close_on_errors & & eta . exitcode ! = 0 ) {
execute_output_dialog - > hide ( ) ;
}
if ( p_close_on_ok & & eta . exitcode = = 0 ) {
execute_output_dialog - > hide ( ) ;
}
2020-12-14 18:37:30 +00:00
execute_output_dialog - > get_ok_button ( ) - > set_disabled ( false ) ;
2019-04-07 18:46:52 +00:00
return eta . exitcode ;
}
2021-02-13 14:06:56 +00:00
void EditorNode : : notify_settings_changed ( ) {
settings_changed = true ;
}
2014-02-10 01:10:30 +00:00
EditorNode : : EditorNode ( ) {
2022-03-03 10:25:11 +00:00
EditorPropertyNameProcessor * epnp = memnew ( EditorPropertyNameProcessor ) ;
add_child ( epnp ) ;
2022-03-24 17:18:55 +00:00
PortableCompressedTexture2D : : set_keep_all_compressed_buffers ( true ) ;
2020-04-28 13:19:37 +00:00
Input : : get_singleton ( ) - > set_use_accumulated_input ( true ) ;
2017-03-05 15:44:50 +00:00
Resource : : _get_local_scene_func = _resource_get_edited_scene ;
2017-01-10 04:04:31 +00:00
2020-03-27 18:21:27 +00:00
RenderingServer : : get_singleton ( ) - > set_debug_generate_wireframes ( true ) ;
2016-12-23 03:37:38 +00:00
2022-03-30 18:12:26 +00:00
// No navigation server by default if in editor.
NavigationServer3D : : get_singleton ( ) - > set_active ( false ) ;
// No physics by default if in editor.
PhysicsServer3D : : get_singleton ( ) - > set_active ( false ) ;
PhysicsServer2D : : get_singleton ( ) - > set_active ( false ) ;
2020-01-10 11:22:34 +00:00
2022-03-30 18:12:26 +00:00
// No scripting by default if in editor.
ScriptServer : : set_scripting_enabled ( false ) ;
2018-08-21 00:55:01 +00:00
2022-03-30 18:12:26 +00:00
EditorHelp : : generate_doc ( ) ; // Before any editor classes are created.
2015-10-16 22:11:23 +00:00
SceneState : : set_disable_placeholders ( true ) ;
2022-03-30 18:12:26 +00:00
ResourceLoader : : clear_translation_remaps ( ) ; // Using no remaps if in editor.
2017-12-14 18:33:54 +00:00
ResourceLoader : : clear_path_remaps ( ) ;
2022-04-28 20:49:10 +00:00
ResourceLoader : : set_create_missing_resources_if_class_unavailable ( true ) ;
2014-02-10 01:10:30 +00:00
2020-04-28 13:19:37 +00:00
Input * id = Input : : get_singleton ( ) ;
2015-09-24 21:06:15 +00:00
if ( id ) {
2020-03-03 13:36:29 +00:00
bool found_touchscreen = false ;
for ( int i = 0 ; i < DisplayServer : : get_singleton ( ) - > get_screen_count ( ) ; i + + ) {
if ( DisplayServer : : get_singleton ( ) - > screen_is_touchscreen ( i ) ) {
found_touchscreen = true ;
}
}
2020-04-28 13:19:37 +00:00
if ( ! found_touchscreen & & Input : : get_singleton ( ) ) {
2022-03-30 18:12:26 +00:00
// Only if no touchscreen ui hint, disable emulation just in case.
id - > set_emulate_touch_from_mouse ( false ) ;
2015-09-24 21:06:15 +00:00
}
2022-05-02 23:43:50 +00:00
DisplayServer : : get_singleton ( ) - > cursor_set_custom_image ( Ref < Resource > ( ) ) ;
2015-08-29 20:16:11 +00:00
}
2017-03-05 15:44:50 +00:00
singleton = this ;
2017-04-25 11:48:35 +00:00
2014-02-10 01:10:30 +00:00
TranslationServer : : get_singleton ( ) - > set_enabled ( false ) ;
2022-03-30 18:12:26 +00:00
// Load settings.
2020-05-14 14:41:43 +00:00
if ( ! EditorSettings : : get_singleton ( ) ) {
2014-02-10 01:10:30 +00:00
EditorSettings : : create ( ) ;
2020-05-14 14:41:43 +00:00
}
2016-09-13 14:20:09 +00:00
2018-01-12 20:18:40 +00:00
FileAccess : : set_backup_save ( EDITOR_GET ( " filesystem/on_save/safe_save_on_backup_then_rename " ) ) ;
2016-06-05 21:43:45 +00:00
{
2018-03-22 19:20:42 +00:00
int display_scale = EditorSettings : : get_singleton ( ) - > get ( " interface/editor/display_scale " ) ;
switch ( display_scale ) {
2021-06-16 12:36:09 +00:00
case 0 :
2020-11-12 15:01:27 +00:00
// Try applying a suitable display scale automatically.
2021-06-16 12:36:09 +00:00
editor_set_scale ( EditorSettings : : get_singleton ( ) - > get_auto_display_scale ( ) ) ;
break ;
2020-11-12 15:01:27 +00:00
case 1 :
2018-03-22 19:20:42 +00:00
editor_set_scale ( 0.75 ) ;
2020-11-12 15:01:27 +00:00
break ;
case 2 :
2018-03-22 19:20:42 +00:00
editor_set_scale ( 1.0 ) ;
2020-11-12 15:01:27 +00:00
break ;
case 3 :
2018-03-22 19:20:42 +00:00
editor_set_scale ( 1.25 ) ;
2020-11-12 15:01:27 +00:00
break ;
case 4 :
2018-03-22 19:20:42 +00:00
editor_set_scale ( 1.5 ) ;
2020-11-12 15:01:27 +00:00
break ;
case 5 :
2018-03-22 19:20:42 +00:00
editor_set_scale ( 1.75 ) ;
2020-11-12 15:01:27 +00:00
break ;
case 6 :
2018-03-22 19:20:42 +00:00
editor_set_scale ( 2.0 ) ;
2020-11-12 15:01:27 +00:00
break ;
default :
editor_set_scale ( EditorSettings : : get_singleton ( ) - > get ( " interface/editor/custom_display_scale " ) ) ;
break ;
2016-06-05 21:43:45 +00:00
}
}
2022-03-30 18:12:26 +00:00
// Define a minimum window size to prevent UI elements from overlapping or being cut off.
2020-03-03 13:36:29 +00:00
DisplayServer : : get_singleton ( ) - > window_set_min_size ( Size2 ( 1024 , 600 ) * EDSCALE ) ;
2019-08-17 19:56:59 +00:00
2014-02-10 01:10:30 +00:00
ResourceLoader : : set_abort_on_missing_resources ( false ) ;
2017-01-05 22:41:36 +00:00
FileDialog : : set_default_show_hidden_files ( EditorSettings : : get_singleton ( ) - > get ( " filesystem/file_dialog/show_hidden_files " ) ) ;
EditorFileDialog : : set_default_show_hidden_files ( EditorSettings : : get_singleton ( ) - > get ( " filesystem/file_dialog/show_hidden_files " ) ) ;
EditorFileDialog : : set_default_display_mode ( ( EditorFileDialog : : DisplayMode ) EditorSettings : : get_singleton ( ) - > get ( " filesystem/file_dialog/display_mode " ) . operator int ( ) ) ;
2017-03-05 15:44:50 +00:00
ResourceLoader : : set_error_notify_func ( this , _load_error_notify ) ;
ResourceLoader : : set_dependency_error_notify_func ( this , _dependency_error_report ) ;
2014-02-10 01:10:30 +00:00
2022-03-30 18:12:26 +00:00
{
// Register importers at the beginning, so dialogs are created with the right extensions.
2017-02-01 12:45:45 +00:00
Ref < ResourceImporterTexture > import_texture ;
2021-06-17 22:03:09 +00:00
import_texture . instantiate ( ) ;
2017-02-01 12:45:45 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_texture ) ;
2017-02-01 23:41:05 +00:00
2020-05-01 12:34:23 +00:00
Ref < ResourceImporterLayeredTexture > import_cubemap ;
2021-06-17 22:03:09 +00:00
import_cubemap . instantiate ( ) ;
2019-06-11 18:43:37 +00:00
import_cubemap - > set_mode ( ResourceImporterLayeredTexture : : MODE_CUBEMAP ) ;
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_cubemap ) ;
2018-08-06 17:56:06 +00:00
Ref < ResourceImporterLayeredTexture > import_array ;
2021-06-17 22:03:09 +00:00
import_array . instantiate ( ) ;
2019-06-11 18:43:37 +00:00
import_array - > set_mode ( ResourceImporterLayeredTexture : : MODE_2D_ARRAY ) ;
2018-08-06 17:56:06 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_array ) ;
2019-06-11 18:43:37 +00:00
Ref < ResourceImporterLayeredTexture > import_cubemap_array ;
2021-06-17 22:03:09 +00:00
import_cubemap_array . instantiate ( ) ;
2019-06-11 18:43:37 +00:00
import_cubemap_array - > set_mode ( ResourceImporterLayeredTexture : : MODE_CUBEMAP_ARRAY ) ;
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_cubemap_array ) ;
2020-05-01 12:34:23 +00:00
2020-09-09 15:40:51 +00:00
Ref < ResourceImporterLayeredTexture > import_3d ;
2021-06-17 22:03:09 +00:00
import_3d . instantiate ( ) ;
2020-05-01 12:34:23 +00:00
import_3d - > set_mode ( ResourceImporterLayeredTexture : : MODE_3D ) ;
2020-09-09 15:40:51 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_3d ) ;
2020-05-01 12:34:23 +00:00
2018-07-29 19:45:23 +00:00
Ref < ResourceImporterImage > import_image ;
2021-06-17 22:03:09 +00:00
import_image . instantiate ( ) ;
2018-07-29 19:45:23 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_image ) ;
2019-04-19 18:54:33 +00:00
Ref < ResourceImporterTextureAtlas > import_texture_atlas ;
2021-06-17 22:03:09 +00:00
import_texture_atlas . instantiate ( ) ;
2019-04-19 18:54:33 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_texture_atlas ) ;
2020-12-27 13:30:33 +00:00
Ref < ResourceImporterDynamicFont > import_font_data_dynamic ;
import_font_data_dynamic . instantiate ( ) ;
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_font_data_dynamic ) ;
Ref < ResourceImporterBMFont > import_font_data_bmfont ;
import_font_data_bmfont . instantiate ( ) ;
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_font_data_bmfont ) ;
Ref < ResourceImporterImageFont > import_font_data_image ;
import_font_data_image . instantiate ( ) ;
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_font_data_image ) ;
2017-02-01 23:41:05 +00:00
Ref < ResourceImporterCSVTranslation > import_csv_translation ;
2021-06-17 22:03:09 +00:00
import_csv_translation . instantiate ( ) ;
2017-02-01 23:41:05 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_csv_translation ) ;
2017-02-03 01:51:26 +00:00
Ref < ResourceImporterWAV > import_wav ;
2021-06-17 22:03:09 +00:00
import_wav . instantiate ( ) ;
2017-02-03 01:51:26 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_wav ) ;
2017-09-29 23:38:27 +00:00
Ref < ResourceImporterOBJ > import_obj ;
2021-06-17 22:03:09 +00:00
import_obj . instantiate ( ) ;
2017-09-29 23:38:27 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_obj ) ;
2020-04-20 02:19:21 +00:00
Ref < ResourceImporterShaderFile > import_shader_file ;
2021-06-17 22:03:09 +00:00
import_shader_file . instantiate ( ) ;
2020-04-20 02:19:21 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_shader_file ) ;
2017-02-04 12:48:04 +00:00
Ref < ResourceImporterScene > import_scene ;
2021-06-17 22:03:09 +00:00
import_scene . instantiate ( ) ;
2017-02-04 12:48:04 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_scene ) ;
2022-04-12 14:07:09 +00:00
Ref < ResourceImporterScene > import_animation ;
import_animation = Ref < ResourceImporterScene > ( memnew ( ResourceImporterScene ( true ) ) ) ;
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_animation ) ;
2017-02-04 12:48:04 +00:00
{
2021-10-14 17:34:27 +00:00
Ref < EditorSceneFormatImporterCollada > import_collada ;
2021-06-17 22:03:09 +00:00
import_collada . instantiate ( ) ;
2022-04-12 14:07:09 +00:00
ResourceImporterScene : : add_importer ( import_collada ) ;
2017-07-18 00:05:38 +00:00
2019-02-12 20:10:08 +00:00
Ref < EditorOBJImporter > import_obj2 ;
2021-06-17 22:03:09 +00:00
import_obj2 . instantiate ( ) ;
2022-04-12 14:07:09 +00:00
ResourceImporterScene : : add_importer ( import_obj2 ) ;
2017-08-02 18:34:55 +00:00
2021-10-14 17:34:27 +00:00
Ref < EditorSceneFormatImporterESCN > import_escn ;
2021-06-17 22:03:09 +00:00
import_escn . instantiate ( ) ;
2022-04-12 14:07:09 +00:00
ResourceImporterScene : : add_importer ( import_escn ) ;
2017-02-04 12:48:04 +00:00
}
2018-01-06 19:36:49 +00:00
Ref < ResourceImporterBitMap > import_bitmap ;
2021-06-17 22:03:09 +00:00
import_bitmap . instantiate ( ) ;
2018-01-06 19:36:49 +00:00
ResourceFormatImporter : : get_singleton ( ) - > add_importer ( import_bitmap ) ;
2017-02-01 12:45:45 +00:00
}
2018-05-15 20:12:35 +00:00
{
Ref < EditorInspectorDefaultPlugin > eidp ;
2021-06-17 22:03:09 +00:00
eidp . instantiate ( ) ;
2018-05-15 20:12:35 +00:00
EditorInspector : : add_inspector_plugin ( eidp ) ;
2018-06-26 22:05:11 +00:00
Ref < EditorInspectorRootMotionPlugin > rmp ;
2021-06-17 22:03:09 +00:00
rmp . instantiate ( ) ;
2018-06-26 22:05:11 +00:00
EditorInspector : : add_inspector_plugin ( rmp ) ;
2018-07-14 21:15:42 +00:00
Ref < EditorInspectorShaderModePlugin > smp ;
2021-06-17 22:03:09 +00:00
smp . instantiate ( ) ;
2018-07-14 21:15:42 +00:00
EditorInspector : : add_inspector_plugin ( smp ) ;
2018-05-15 20:12:35 +00:00
}
2017-03-05 15:44:50 +00:00
editor_selection = memnew ( EditorSelection ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
EditorFileSystem * efs = memnew ( EditorFileSystem ) ;
2014-02-10 01:10:30 +00:00
add_child ( efs ) ;
2022-03-30 18:12:26 +00:00
// Used for previews.
2017-03-05 15:44:50 +00:00
FileDialog : : get_icon_func = _file_dialog_get_icon ;
FileDialog : : register_func = _file_dialog_register ;
FileDialog : : unregister_func = _file_dialog_unregister ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
EditorFileDialog : : get_icon_func = _file_dialog_get_icon ;
EditorFileDialog : : register_func = _editor_file_dialog_register ;
EditorFileDialog : : unregister_func = _editor_file_dialog_unregister ;
2015-05-31 04:59:42 +00:00
2017-03-05 15:44:50 +00:00
editor_export = memnew ( EditorExport ) ;
2017-02-20 02:19:30 +00:00
add_child ( editor_export ) ;
2022-03-30 18:12:26 +00:00
// Exporters might need the theme.
2019-10-11 11:21:24 +00:00
theme = create_custom_theme ( ) ;
2014-02-10 01:10:30 +00:00
register_exporters ( ) ;
2018-06-26 22:05:11 +00:00
ClassDB : : set_class_enabled ( " RootMotionView " , true ) ;
2014-02-10 01:10:30 +00:00
2021-04-11 13:39:31 +00:00
EDITOR_DEF ( " interface/editor/save_on_focus_loss " , false ) ;
2018-12-11 15:52:25 +00:00
EDITOR_DEF ( " interface/editor/show_update_spinner " , false ) ;
EDITOR_DEF ( " interface/editor/update_continuously " , false ) ;
2022-03-23 01:46:59 +00:00
EDITOR_DEF ( " interface/editor/localize_settings " , true ) ;
2021-09-12 14:11:56 +00:00
EDITOR_DEF_RST ( " interface/scene_tabs/restore_scenes_on_load " , true ) ;
2022-03-23 01:46:59 +00:00
EDITOR_DEF_RST ( " interface/inspector/default_property_name_style " , EditorPropertyNameProcessor : : STYLE_CAPITALIZED ) ;
EditorSettings : : get_singleton ( ) - > add_property_hint ( PropertyInfo ( Variant : : INT , " interface/inspector/default_property_name_style " , PROPERTY_HINT_ENUM , " Raw,Capitalized,Localized " ) ) ;
2019-07-23 15:27:55 +00:00
EDITOR_DEF_RST ( " interface/inspector/default_float_step " , 0.001 ) ;
Variant: Added 64-bit packed arrays, renamed Variant::REAL to FLOAT.
- Renames PackedIntArray to PackedInt32Array.
- Renames PackedFloatArray to PackedFloat32Array.
- Adds PackedInt64Array and PackedFloat64Array.
- Renames Variant::REAL to Variant::FLOAT for consistency.
Packed arrays are for storing large amount of data and creating stuff like
meshes, buffers. textures, etc. Forcing them to be 64 is a huge waste of
memory. That said, many users requested the ability to have 64 bits packed
arrays for their games, so this is just an optional added type.
For Variant, the float datatype is always 64 bits, and exposed as `float`.
We still have `real_t` which is the datatype that can change from 32 to 64
bits depending on a compile flag (not entirely working right now, but that's
the idea). It affects math related datatypes and code only.
Neither Variant nor PackedArray make use of real_t, which is only intended
for math precision, so the term is removed from there to keep only float.
2020-02-24 18:20:53 +00:00
EditorSettings : : get_singleton ( ) - > add_property_hint ( PropertyInfo ( Variant : : FLOAT , " interface/inspector/default_float_step " , PROPERTY_HINT_RANGE , " 0,1,0 " ) ) ;
2018-07-19 21:58:15 +00:00
EDITOR_DEF_RST ( " interface/inspector/disable_folding " , false ) ;
2018-11-25 13:46:26 +00:00
EDITOR_DEF_RST ( " interface/inspector/auto_unfold_foreign_scenes " , true ) ;
2018-08-07 15:19:19 +00:00
EDITOR_DEF ( " interface/inspector/horizontal_vector2_editing " , false ) ;
2018-09-23 03:20:36 +00:00
EDITOR_DEF ( " interface/inspector/horizontal_vector_types_editing " , true ) ;
2018-07-14 21:15:42 +00:00
EDITOR_DEF ( " interface/inspector/open_resources_in_current_inspector " , true ) ;
2021-05-07 13:41:39 +00:00
EDITOR_DEF ( " interface/inspector/resources_to_open_in_new_inspector " , " Script,MeshLibrary " ) ;
2019-08-30 20:25:15 +00:00
EDITOR_DEF ( " interface/inspector/default_color_picker_mode " , 0 ) ;
EditorSettings : : get_singleton ( ) - > add_property_hint ( PropertyInfo ( Variant : : INT , " interface/inspector/default_color_picker_mode " , PROPERTY_HINT_ENUM , " RGB,HSV,RAW " , PROPERTY_USAGE_DEFAULT ) ) ;
2021-02-23 10:22:46 +00:00
EDITOR_DEF ( " interface/inspector/default_color_picker_shape " , ( int32_t ) ColorPicker : : SHAPE_VHS_CIRCLE ) ;
EditorSettings : : get_singleton ( ) - > add_property_hint ( PropertyInfo ( Variant : : INT , " interface/inspector/default_color_picker_shape " , PROPERTY_HINT_ENUM , " HSV Rectangle,HSV Rectangle Wheel,VHS Circle " , PROPERTY_USAGE_DEFAULT ) ) ;
2022-01-19 18:59:12 +00:00
ED_SHORTCUT ( " canvas_item_editor/pan_view " , TTR ( " Pan View " ) , Key : : SPACE ) ;
2018-05-17 21:02:16 +00:00
2021-09-23 21:09:15 +00:00
const Vector < String > textfile_ext = ( ( String ) ( EditorSettings : : get_singleton ( ) - > get ( " docks/filesystem/textfile_extensions " ) ) ) . split ( " , " , false ) ;
for ( const String & E : textfile_ext ) {
textfile_extensions . insert ( E ) ;
}
2017-05-02 20:13:12 +00:00
theme_base = memnew ( Control ) ;
2016-06-17 04:13:23 +00:00
add_child ( theme_base ) ;
2020-12-22 16:24:29 +00:00
theme_base - > set_anchors_and_offsets_preset ( Control : : PRESET_WIDE ) ;
2016-06-17 04:13:23 +00:00
2017-03-05 15:44:50 +00:00
gui_base = memnew ( Panel ) ;
2016-06-17 04:13:23 +00:00
theme_base - > add_child ( gui_base ) ;
2020-12-22 16:24:29 +00:00
gui_base - > set_anchors_and_offsets_preset ( Control : : PRESET_WIDE ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
theme_base - > set_theme ( theme ) ;
2017-11-11 17:57:54 +00:00
gui_base - > set_theme ( theme ) ;
2022-02-08 09:14:58 +00:00
gui_base - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " Background " ) , SNAME ( " EditorStyles " ) ) ) ;
2016-06-17 04:13:23 +00:00
2017-03-05 15:44:50 +00:00
resource_preview = memnew ( EditorResourcePreview ) ;
2015-05-31 04:59:42 +00:00
add_child ( resource_preview ) ;
2017-03-05 15:44:50 +00:00
progress_dialog = memnew ( ProgressDialog ) ;
2014-02-10 01:10:30 +00:00
gui_base - > add_child ( progress_dialog ) ;
2022-03-30 18:12:26 +00:00
// Take up all screen.
2020-12-22 16:24:29 +00:00
gui_base - > set_anchor ( SIDE_RIGHT , Control : : ANCHOR_END ) ;
gui_base - > set_anchor ( SIDE_BOTTOM , Control : : ANCHOR_END ) ;
2017-03-05 15:44:50 +00:00
gui_base - > set_end ( Point2 ( 0 , 0 ) ) ;
2015-06-22 03:03:19 +00:00
2017-03-05 15:44:50 +00:00
main_vbox = memnew ( VBoxContainer ) ;
2014-02-10 01:10:30 +00:00
gui_base - > add_child ( main_vbox ) ;
2020-12-22 16:24:29 +00:00
main_vbox - > set_anchors_and_offsets_preset ( Control : : PRESET_WIDE , Control : : PRESET_MODE_MINSIZE , 8 ) ;
2022-02-08 09:14:58 +00:00
main_vbox - > add_theme_constant_override ( " separation " , 8 * EDSCALE ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
menu_hb = memnew ( HBoxContainer ) ;
2015-11-18 07:47:41 +00:00
main_vbox - > add_child ( menu_hb ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
left_l_hsplit = memnew ( HSplitContainer ) ;
2015-06-14 01:12:53 +00:00
main_vbox - > add_child ( left_l_hsplit ) ;
left_l_hsplit - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2017-03-05 15:44:50 +00:00
left_l_vsplit = memnew ( VSplitContainer ) ;
2015-06-14 01:12:53 +00:00
left_l_hsplit - > add_child ( left_l_vsplit ) ;
2017-03-05 15:44:50 +00:00
dock_slot [ DOCK_SLOT_LEFT_UL ] = memnew ( TabContainer ) ;
2015-06-14 01:12:53 +00:00
left_l_vsplit - > add_child ( dock_slot [ DOCK_SLOT_LEFT_UL ] ) ;
2017-03-05 15:44:50 +00:00
dock_slot [ DOCK_SLOT_LEFT_BL ] = memnew ( TabContainer ) ;
2015-06-14 01:12:53 +00:00
left_l_vsplit - > add_child ( dock_slot [ DOCK_SLOT_LEFT_BL ] ) ;
2017-03-05 15:44:50 +00:00
left_r_hsplit = memnew ( HSplitContainer ) ;
2015-06-14 01:12:53 +00:00
left_l_hsplit - > add_child ( left_r_hsplit ) ;
2017-03-05 15:44:50 +00:00
left_r_vsplit = memnew ( VSplitContainer ) ;
2015-06-14 01:12:53 +00:00
left_r_hsplit - > add_child ( left_r_vsplit ) ;
2017-03-05 15:44:50 +00:00
dock_slot [ DOCK_SLOT_LEFT_UR ] = memnew ( TabContainer ) ;
2015-06-14 01:12:53 +00:00
left_r_vsplit - > add_child ( dock_slot [ DOCK_SLOT_LEFT_UR ] ) ;
2017-03-05 15:44:50 +00:00
dock_slot [ DOCK_SLOT_LEFT_BR ] = memnew ( TabContainer ) ;
2015-06-14 01:12:53 +00:00
left_r_vsplit - > add_child ( dock_slot [ DOCK_SLOT_LEFT_BR ] ) ;
2017-03-05 15:44:50 +00:00
main_hsplit = memnew ( HSplitContainer ) ;
2015-06-14 01:12:53 +00:00
left_r_hsplit - > add_child ( main_hsplit ) ;
2017-03-05 15:44:50 +00:00
VBoxContainer * center_vb = memnew ( VBoxContainer ) ;
2015-11-18 07:47:41 +00:00
main_hsplit - > add_child ( center_vb ) ;
center_vb - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
center_split = memnew ( VSplitContainer ) ;
2015-11-18 07:47:41 +00:00
center_split - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2015-06-14 01:12:53 +00:00
center_split - > set_collapsed ( false ) ;
2015-11-18 07:47:41 +00:00
center_vb - > add_child ( center_split ) ;
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
right_hsplit = memnew ( HSplitContainer ) ;
2015-06-14 01:12:53 +00:00
main_hsplit - > add_child ( right_hsplit ) ;
2017-03-05 15:44:50 +00:00
right_l_vsplit = memnew ( VSplitContainer ) ;
2015-06-14 01:12:53 +00:00
right_hsplit - > add_child ( right_l_vsplit ) ;
2017-03-05 15:44:50 +00:00
dock_slot [ DOCK_SLOT_RIGHT_UL ] = memnew ( TabContainer ) ;
2015-06-14 01:12:53 +00:00
right_l_vsplit - > add_child ( dock_slot [ DOCK_SLOT_RIGHT_UL ] ) ;
2017-03-05 15:44:50 +00:00
dock_slot [ DOCK_SLOT_RIGHT_BL ] = memnew ( TabContainer ) ;
2015-06-14 01:12:53 +00:00
right_l_vsplit - > add_child ( dock_slot [ DOCK_SLOT_RIGHT_BL ] ) ;
2017-03-05 15:44:50 +00:00
right_r_vsplit = memnew ( VSplitContainer ) ;
2015-06-14 01:12:53 +00:00
right_hsplit - > add_child ( right_r_vsplit ) ;
2017-03-05 15:44:50 +00:00
dock_slot [ DOCK_SLOT_RIGHT_UR ] = memnew ( TabContainer ) ;
2015-06-14 01:12:53 +00:00
right_r_vsplit - > add_child ( dock_slot [ DOCK_SLOT_RIGHT_UR ] ) ;
2017-03-05 15:44:50 +00:00
dock_slot [ DOCK_SLOT_RIGHT_BR ] = memnew ( TabContainer ) ;
2015-06-14 01:12:53 +00:00
right_r_vsplit - > add_child ( dock_slot [ DOCK_SLOT_RIGHT_BR ] ) ;
2022-03-30 18:12:26 +00:00
// Store them for easier access.
2018-09-14 14:56:18 +00:00
vsplits . push_back ( left_l_vsplit ) ;
vsplits . push_back ( left_r_vsplit ) ;
vsplits . push_back ( right_l_vsplit ) ;
vsplits . push_back ( right_r_vsplit ) ;
hsplits . push_back ( left_l_hsplit ) ;
hsplits . push_back ( left_r_hsplit ) ;
hsplits . push_back ( main_hsplit ) ;
hsplits . push_back ( right_hsplit ) ;
2015-06-22 03:03:19 +00:00
2018-09-14 14:56:18 +00:00
for ( int i = 0 ; i < vsplits . size ( ) ; i + + ) {
2020-02-21 17:28:45 +00:00
vsplits [ i ] - > connect ( " dragged " , callable_mp ( this , & EditorNode : : _dock_split_dragged ) ) ;
hsplits [ i ] - > connect ( " dragged " , callable_mp ( this , & EditorNode : : _dock_split_dragged ) ) ;
2018-09-14 14:56:18 +00:00
}
2015-06-22 03:03:19 +00:00
2017-07-18 13:04:20 +00:00
dock_select_popup = memnew ( PopupPanel ) ;
gui_base - > add_child ( dock_select_popup ) ;
2017-03-05 15:44:50 +00:00
VBoxContainer * dock_vb = memnew ( VBoxContainer ) ;
2017-07-18 13:04:20 +00:00
dock_select_popup - > add_child ( dock_vb ) ;
2015-06-14 01:12:53 +00:00
2017-03-05 15:44:50 +00:00
HBoxContainer * dock_hb = memnew ( HBoxContainer ) ;
2020-06-19 18:49:04 +00:00
dock_tab_move_left = memnew ( Button ) ;
dock_tab_move_left - > set_flat ( true ) ;
2020-09-03 11:22:16 +00:00
if ( gui_base - > is_layout_rtl ( ) ) {
2022-02-06 14:53:53 +00:00
dock_tab_move_left - > set_icon ( theme - > get_icon ( SNAME ( " Forward " ) , SNAME ( " EditorIcons " ) ) ) ;
2020-09-03 11:22:16 +00:00
} else {
2022-02-06 14:53:53 +00:00
dock_tab_move_left - > set_icon ( theme - > get_icon ( SNAME ( " Back " ) , SNAME ( " EditorIcons " ) ) ) ;
2020-09-03 11:22:16 +00:00
}
2015-06-14 01:12:53 +00:00
dock_tab_move_left - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2020-02-21 17:28:45 +00:00
dock_tab_move_left - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _dock_move_left ) ) ;
2015-06-14 01:12:53 +00:00
dock_hb - > add_child ( dock_tab_move_left ) ;
2017-11-19 05:00:42 +00:00
Label * dock_label = memnew ( Label ) ;
dock_label - > set_text ( TTR ( " Dock Position " ) ) ;
dock_label - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2021-11-25 02:58:47 +00:00
dock_label - > set_horizontal_alignment ( HORIZONTAL_ALIGNMENT_CENTER ) ;
2017-11-19 05:00:42 +00:00
dock_hb - > add_child ( dock_label ) ;
2020-06-19 18:49:04 +00:00
dock_tab_move_right = memnew ( Button ) ;
dock_tab_move_right - > set_flat ( true ) ;
2020-09-03 11:22:16 +00:00
if ( gui_base - > is_layout_rtl ( ) ) {
2022-02-06 14:53:53 +00:00
dock_tab_move_right - > set_icon ( theme - > get_icon ( SNAME ( " Back " ) , SNAME ( " EditorIcons " ) ) ) ;
2021-09-24 00:32:48 +00:00
} else {
2022-02-06 14:53:53 +00:00
dock_tab_move_right - > set_icon ( theme - > get_icon ( SNAME ( " Forward " ) , SNAME ( " EditorIcons " ) ) ) ;
2020-09-03 11:22:16 +00:00
}
2015-06-14 01:12:53 +00:00
dock_tab_move_right - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2020-02-21 17:28:45 +00:00
dock_tab_move_right - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _dock_move_right ) ) ;
2015-06-14 03:41:08 +00:00
2015-06-14 01:12:53 +00:00
dock_hb - > add_child ( dock_tab_move_right ) ;
dock_vb - > add_child ( dock_hb ) ;
2017-03-05 15:44:50 +00:00
dock_select = memnew ( Control ) ;
2018-10-26 10:44:49 +00:00
dock_select - > set_custom_minimum_size ( Size2 ( 128 , 64 ) * EDSCALE ) ;
2020-02-21 17:28:45 +00:00
dock_select - > connect ( " gui_input " , callable_mp ( this , & EditorNode : : _dock_select_input ) ) ;
dock_select - > connect ( " draw " , callable_mp ( this , & EditorNode : : _dock_select_draw ) ) ;
dock_select - > connect ( " mouse_exited " , callable_mp ( this , & EditorNode : : _dock_popup_exit ) ) ;
2015-06-14 01:12:53 +00:00
dock_select - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
dock_vb - > add_child ( dock_select ) ;
2020-03-06 17:00:16 +00:00
dock_float = memnew ( Button ) ;
2020-03-27 19:48:42 +00:00
dock_float - > set_text ( TTR ( " Make Floating " ) ) ;
2020-03-06 17:00:16 +00:00
dock_float - > set_focus_mode ( Control : : FOCUS_NONE ) ;
dock_float - > set_h_size_flags ( Control : : SIZE_SHRINK_CENTER ) ;
dock_float - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _dock_make_float ) ) ;
dock_vb - > add_child ( dock_float ) ;
2022-03-05 23:57:42 +00:00
dock_select_popup - > reset_size ( ) ;
2022-03-30 18:12:26 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < DOCK_SLOT_MAX ; i + + ) {
2018-10-26 10:44:49 +00:00
dock_slot [ i ] - > set_custom_minimum_size ( Size2 ( 170 , 0 ) * EDSCALE ) ;
2015-06-14 01:12:53 +00:00
dock_slot [ i ] - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2017-07-18 13:04:20 +00:00
dock_slot [ i ] - > set_popup ( dock_select_popup ) ;
2020-02-21 17:28:45 +00:00
dock_slot [ i ] - > connect ( " pre_popup_pressed " , callable_mp ( this , & EditorNode : : _dock_pre_popup ) , varray ( i ) ) ;
2018-02-07 13:01:45 +00:00
dock_slot [ i ] - > set_drag_to_rearrange_enabled ( true ) ;
dock_slot [ i ] - > set_tabs_rearrange_group ( 1 ) ;
2020-02-21 17:28:45 +00:00
dock_slot [ i ] - > connect ( " tab_changed " , callable_mp ( this , & EditorNode : : _dock_tab_changed ) ) ;
2019-01-26 18:41:36 +00:00
dock_slot [ i ] - > set_use_hidden_tabs_for_min_size ( true ) ;
2015-06-14 01:12:53 +00:00
}
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
dock_drag_timer = memnew ( Timer ) ;
2015-06-14 01:12:53 +00:00
add_child ( dock_drag_timer ) ;
dock_drag_timer - > set_wait_time ( 0.5 ) ;
dock_drag_timer - > set_one_shot ( true ) ;
2020-02-21 17:28:45 +00:00
dock_drag_timer - > connect ( " timeout " , callable_mp ( this , & EditorNode : : _save_docks ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
top_split = memnew ( VSplitContainer ) ;
2015-06-14 01:12:53 +00:00
center_split - > add_child ( top_split ) ;
2014-02-10 01:10:30 +00:00
top_split - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
top_split - > set_collapsed ( true ) ;
2017-03-05 15:44:50 +00:00
VBoxContainer * srt = memnew ( VBoxContainer ) ;
2014-02-10 01:10:30 +00:00
srt - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
top_split - > add_child ( srt ) ;
2022-02-08 09:14:58 +00:00
srt - > add_theme_constant_override ( " separation " , 0 ) ;
2014-02-10 01:10:30 +00:00
2017-06-15 15:30:03 +00:00
tab_preview_panel = memnew ( Panel ) ;
tab_preview_panel - > set_size ( Size2 ( 100 , 100 ) * EDSCALE ) ;
tab_preview_panel - > hide ( ) ;
tab_preview_panel - > set_self_modulate ( Color ( 1 , 1 , 1 , 0.7 ) ) ;
gui_base - > add_child ( tab_preview_panel ) ;
tab_preview = memnew ( TextureRect ) ;
tab_preview - > set_stretch_mode ( TextureRect : : STRETCH_KEEP_ASPECT_CENTERED ) ;
tab_preview - > set_size ( Size2 ( 96 , 96 ) * EDSCALE ) ;
tab_preview - > set_position ( Point2 ( 2 , 2 ) * EDSCALE ) ;
tab_preview_panel - > add_child ( tab_preview ) ;
2022-01-23 15:42:52 +00:00
tabbar_container = memnew ( HBoxContainer ) ;
srt - > add_child ( tabbar_container ) ;
2021-10-17 16:55:44 +00:00
scene_tabs = memnew ( TabBar ) ;
2022-02-08 09:14:58 +00:00
scene_tabs - > add_theme_style_override ( " tab_selected " , gui_base - > get_theme_stylebox ( SNAME ( " SceneTabFG " ) , SNAME ( " EditorStyles " ) ) ) ;
scene_tabs - > add_theme_style_override ( " tab_unselected " , gui_base - > get_theme_stylebox ( SNAME ( " SceneTabBG " ) , SNAME ( " EditorStyles " ) ) ) ;
2018-01-02 07:10:49 +00:00
scene_tabs - > set_select_with_rmb ( true ) ;
2015-11-18 07:47:41 +00:00
scene_tabs - > add_tab ( " unsaved " ) ;
2022-03-13 01:03:26 +00:00
scene_tabs - > set_tab_close_display_policy ( ( TabBar : : CloseButtonDisplayPolicy ) EDITOR_GET ( " interface/scene_tabs/display_close_button " ) . operator int ( ) ) ;
2022-02-03 05:45:31 +00:00
scene_tabs - > set_max_tab_width ( int ( EDITOR_GET ( " interface/scene_tabs/maximum_width " ) ) * EDSCALE ) ;
2018-02-07 13:01:45 +00:00
scene_tabs - > set_drag_to_rearrange_enabled ( true ) ;
2020-02-21 17:28:45 +00:00
scene_tabs - > connect ( " tab_changed " , callable_mp ( this , & EditorNode : : _scene_tab_changed ) ) ;
2022-01-19 16:11:44 +00:00
scene_tabs - > connect ( " tab_button_pressed " , callable_mp ( this , & EditorNode : : _scene_tab_script_edited ) ) ;
2021-10-27 22:39:13 +00:00
scene_tabs - > connect ( " tab_close_pressed " , callable_mp ( this , & EditorNode : : _scene_tab_closed ) , varray ( SCENE_TAB_CLOSE ) ) ;
2020-12-09 11:04:02 +00:00
scene_tabs - > connect ( " tab_hovered " , callable_mp ( this , & EditorNode : : _scene_tab_hovered ) ) ;
2020-02-21 17:28:45 +00:00
scene_tabs - > connect ( " mouse_exited " , callable_mp ( this , & EditorNode : : _scene_tab_exit ) ) ;
scene_tabs - > connect ( " gui_input " , callable_mp ( this , & EditorNode : : _scene_tab_input ) ) ;
2021-09-30 23:18:23 +00:00
scene_tabs - > connect ( " active_tab_rearranged " , callable_mp ( this , & EditorNode : : _reposition_active_tab ) ) ;
2020-02-21 17:28:45 +00:00
scene_tabs - > connect ( " resized " , callable_mp ( this , & EditorNode : : _update_scene_tabs ) ) ;
2017-05-24 10:00:55 +00:00
scene_tabs - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2022-01-23 15:42:52 +00:00
tabbar_container - > add_child ( scene_tabs ) ;
2017-05-24 10:00:55 +00:00
2018-01-02 07:10:49 +00:00
scene_tabs_context_menu = memnew ( PopupMenu ) ;
tabbar_container - > add_child ( scene_tabs_context_menu ) ;
2020-02-21 17:28:45 +00:00
scene_tabs_context_menu - > connect ( " id_pressed " , callable_mp ( this , & EditorNode : : _menu_option ) ) ;
2018-01-02 07:10:49 +00:00
2022-01-23 15:42:52 +00:00
scene_tab_add = memnew ( Button ) ;
scene_tab_add - > set_flat ( true ) ;
scene_tab_add - > set_tooltip ( TTR ( " Add a new scene. " ) ) ;
scene_tab_add - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " Add " ) , SNAME ( " EditorIcons " ) ) ) ;
2022-02-08 09:14:58 +00:00
scene_tab_add - > add_theme_color_override ( " icon_normal_color " , Color ( 0.6f , 0.6f , 0.6f , 0.8f ) ) ;
2022-01-23 15:42:52 +00:00
scene_tabs - > add_child ( scene_tab_add ) ;
scene_tab_add - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _menu_option ) , make_binds ( FILE_NEW_SCENE ) ) ;
scene_tab_add_ph = memnew ( Control ) ;
scene_tab_add_ph - > set_mouse_filter ( Control : : MOUSE_FILTER_IGNORE ) ;
scene_tab_add_ph - > set_custom_minimum_size ( scene_tab_add - > get_minimum_size ( ) ) ;
tabbar_container - > add_child ( scene_tab_add_ph ) ;
2020-06-19 18:49:04 +00:00
distraction_free = memnew ( Button ) ;
distraction_free - > set_flat ( true ) ;
2021-08-13 21:31:57 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/distraction_free_mode " , TTR ( " Distraction Free Mode " ) , KeyModifierMask : : CMD | KeyModifierMask : : SHIFT | Key : : F11 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/distraction_free_mode " , " macos " , KeyModifierMask : : CMD | KeyModifierMask : : CTRL | Key : : D ) ;
2021-08-08 03:52:00 +00:00
distraction_free - > set_shortcut ( ED_GET_SHORTCUT ( " editor/distraction_free_mode " ) ) ;
2017-07-24 06:07:53 +00:00
distraction_free - > set_tooltip ( TTR ( " Toggle distraction-free mode. " ) ) ;
2020-02-21 17:28:45 +00:00
distraction_free - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _toggle_distraction_free_mode ) ) ;
2021-07-17 21:22:52 +00:00
distraction_free - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " DistractionFree " ) , SNAME ( " EditorIcons " ) ) ) ;
2017-05-24 10:00:55 +00:00
distraction_free - > set_toggle_mode ( true ) ;
2017-11-16 22:57:57 +00:00
tabbar_container - > add_child ( distraction_free ) ;
2017-03-05 15:44:50 +00:00
scene_root_parent = memnew ( PanelContainer ) ;
scene_root_parent - > set_custom_minimum_size ( Size2 ( 0 , 80 ) * EDSCALE ) ;
2022-02-08 09:14:58 +00:00
scene_root_parent - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " Content " ) , SNAME ( " EditorStyles " ) ) ) ;
2017-09-02 01:29:04 +00:00
scene_root_parent - > set_draw_behind_parent ( true ) ;
2014-02-10 01:10:30 +00:00
srt - > add_child ( scene_root_parent ) ;
scene_root_parent - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2020-03-04 01:51:12 +00:00
scene_root = memnew ( SubViewport ) ;
2022-03-13 15:18:44 +00:00
scene_root - > set_embedding_subwindows ( true ) ;
2021-06-29 16:36:32 +00:00
scene_root - > set_disable_3d ( true ) ;
2016-10-05 04:26:35 +00:00
2016-01-17 01:41:10 +00:00
scene_root - > set_disable_input ( true ) ;
2014-02-10 01:10:30 +00:00
scene_root - > set_as_audio_listener_2d ( true ) ;
2020-12-19 14:17:42 +00:00
main_control = memnew ( VBoxContainer ) ;
main_control - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2022-02-08 09:14:58 +00:00
main_control - > add_theme_constant_override ( " separation " , 0 ) ;
2020-12-19 14:17:42 +00:00
scene_root_parent - > add_child ( main_control ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
HBoxContainer * left_menu_hb = memnew ( HBoxContainer ) ;
2019-02-11 04:18:54 +00:00
menu_hb - > add_child ( left_menu_hb ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
file_menu = memnew ( MenuButton ) ;
2017-09-02 01:25:40 +00:00
file_menu - > set_flat ( false ) ;
2018-07-29 22:26:43 +00:00
file_menu - > set_switch_on_hover ( true ) ;
2016-05-04 01:25:37 +00:00
file_menu - > set_text ( TTR ( " Scene " ) ) ;
2022-02-08 09:14:58 +00:00
file_menu - > add_theme_style_override ( " hover " , gui_base - > get_theme_stylebox ( SNAME ( " MenuHover " ) , SNAME ( " EditorStyles " ) ) ) ;
2017-09-02 01:25:40 +00:00
left_menu_hb - > add_child ( file_menu ) ;
2014-02-10 01:10:30 +00:00
2020-06-19 18:49:04 +00:00
prev_scene = memnew ( Button ) ;
prev_scene - > set_flat ( true ) ;
2021-07-17 21:22:52 +00:00
prev_scene - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " PrevScene " ) , SNAME ( " EditorIcons " ) ) ) ;
2016-05-04 01:25:37 +00:00
prev_scene - > set_tooltip ( TTR ( " Go to previously opened scene. " ) ) ;
2014-02-10 01:10:30 +00:00
prev_scene - > set_disabled ( true ) ;
2020-02-21 17:28:45 +00:00
prev_scene - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _menu_option ) , make_binds ( FILE_OPEN_PREV ) ) ;
2015-04-20 22:38:02 +00:00
gui_base - > add_child ( prev_scene ) ;
2017-03-29 15:29:38 +00:00
prev_scene - > set_position ( Point2 ( 3 , 24 ) ) ;
2015-04-20 22:38:02 +00:00
prev_scene - > hide ( ) ;
2014-02-10 01:10:30 +00:00
2017-08-30 11:59:48 +00:00
accept = memnew ( AcceptDialog ) ;
gui_base - > add_child ( accept ) ;
2020-02-21 17:28:45 +00:00
accept - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _menu_confirm_current ) ) ;
2017-08-30 11:59:48 +00:00
2021-09-11 01:35:13 +00:00
save_accept = memnew ( AcceptDialog ) ;
gui_base - > add_child ( save_accept ) ;
save_accept - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _menu_option ) , make_binds ( ( int ) MenuOptions : : FILE_SAVE_AS_SCENE ) ) ;
2017-08-30 11:59:48 +00:00
project_export = memnew ( ProjectExportDialog ) ;
gui_base - > add_child ( project_export ) ;
dependency_error = memnew ( DependencyErrorDialog ) ;
gui_base - > add_child ( dependency_error ) ;
dependency_fixer = memnew ( DependencyEditor ) ;
gui_base - > add_child ( dependency_fixer ) ;
2022-01-31 23:19:01 +00:00
editor_settings_dialog = memnew ( EditorSettingsDialog ) ;
gui_base - > add_child ( editor_settings_dialog ) ;
2017-08-30 11:59:48 +00:00
2022-01-31 23:19:01 +00:00
project_settings_editor = memnew ( ProjectSettingsEditor ( & editor_data ) ) ;
gui_base - > add_child ( project_settings_editor ) ;
2017-08-30 11:59:48 +00:00
2021-03-19 12:57:52 +00:00
scene_import_settings = memnew ( SceneImportSettings ) ;
gui_base - > add_child ( scene_import_settings ) ;
2020-12-27 13:30:33 +00:00
fontdata_import_settings = memnew ( DynamicFontImportSettings ) ;
gui_base - > add_child ( fontdata_import_settings ) ;
2017-08-30 11:59:48 +00:00
export_template_manager = memnew ( ExportTemplateManager ) ;
gui_base - > add_child ( export_template_manager ) ;
2019-04-08 22:18:03 +00:00
feature_profile_manager = memnew ( EditorFeatureProfileManager ) ;
gui_base - > add_child ( feature_profile_manager ) ;
2017-08-30 11:59:48 +00:00
about = memnew ( EditorAbout ) ;
gui_base - > add_child ( about ) ;
2020-02-21 17:28:45 +00:00
feature_profile_manager - > connect ( " current_feature_profile_changed " , callable_mp ( this , & EditorNode : : _feature_profile_changed ) ) ;
2017-08-30 11:59:48 +00:00
warning = memnew ( AcceptDialog ) ;
2019-07-09 18:11:31 +00:00
warning - > add_button ( TTR ( " Copy Text " ) , true , " copy " ) ;
2017-08-30 11:59:48 +00:00
gui_base - > add_child ( warning ) ;
2020-02-21 17:28:45 +00:00
warning - > connect ( " custom_action " , callable_mp ( this , & EditorNode : : _copy_warning ) ) ;
2017-08-30 11:59:48 +00:00
2021-08-13 21:31:57 +00:00
ED_SHORTCUT ( " editor/next_tab " , TTR ( " Next Scene Tab " ) , KeyModifierMask : : CMD + Key : : TAB ) ;
ED_SHORTCUT ( " editor/prev_tab " , TTR ( " Previous Scene Tab " ) , KeyModifierMask : : CMD + KeyModifierMask : : SHIFT + Key : : TAB ) ;
ED_SHORTCUT ( " editor/filter_files " , TTR ( " Focus FileSystem Filter " ) , KeyModifierMask : : CMD + KeyModifierMask : : ALT + Key : : P ) ;
2021-05-29 13:28:16 +00:00
command_palette = EditorCommandPalette : : get_singleton ( ) ;
command_palette - > set_title ( TTR ( " Command Palette " ) ) ;
gui_base - > add_child ( command_palette ) ;
2017-06-22 21:04:03 +00:00
PopupMenu * p ;
2016-06-25 04:42:09 +00:00
2016-05-04 01:25:37 +00:00
file_menu - > set_tooltip ( TTR ( " Operations with scene files. " ) ) ;
2019-04-10 15:21:26 +00:00
2017-03-05 15:44:50 +00:00
p = file_menu - > get_popup ( ) ;
2020-03-12 12:37:40 +00:00
2021-08-13 21:31:57 +00:00
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/new_scene " , TTR ( " New Scene " ) , KeyModifierMask : : CMD + Key : : N ) , FILE_NEW_SCENE ) ;
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/new_inherited_scene " , TTR ( " New Inherited Scene... " ) , KeyModifierMask : : CMD + KeyModifierMask : : SHIFT + Key : : N ) , FILE_NEW_INHERITED_SCENE ) ;
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/open_scene " , TTR ( " Open Scene... " ) , KeyModifierMask : : CMD + Key : : O ) , FILE_OPEN_SCENE ) ;
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/reopen_closed_scene " , TTR ( " Reopen Closed Scene " ) , KeyModifierMask : : CMD + KeyModifierMask : : SHIFT + Key : : T ) , FILE_OPEN_PREV ) ;
2019-08-12 20:23:00 +00:00
p - > add_submenu_item ( TTR ( " Open Recent " ) , " RecentScenes " , FILE_OPEN_RECENT ) ;
2015-04-26 02:45:49 +00:00
p - > add_separator ( ) ;
2021-08-13 21:31:57 +00:00
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/save_scene " , TTR ( " Save Scene " ) , KeyModifierMask : : CMD + Key : : S ) , FILE_SAVE_SCENE ) ;
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/save_scene_as " , TTR ( " Save Scene As... " ) , KeyModifierMask : : CMD + KeyModifierMask : : SHIFT + Key : : S ) , FILE_SAVE_AS_SCENE ) ;
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/save_all_scenes " , TTR ( " Save All Scenes " ) , KeyModifierMask : : CMD + KeyModifierMask : : SHIFT + KeyModifierMask : : ALT + Key : : S ) , FILE_SAVE_ALL_SCENES ) ;
2019-08-12 20:23:00 +00:00
2014-02-10 01:10:30 +00:00
p - > add_separator ( ) ;
2019-05-11 04:03:30 +00:00
2021-08-13 21:31:57 +00:00
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/quick_open " , TTR ( " Quick Open... " ) , KeyModifierMask : : SHIFT + KeyModifierMask : : ALT + Key : : O ) , FILE_QUICK_OPEN ) ;
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/quick_open_scene " , TTR ( " Quick Open Scene... " ) , KeyModifierMask : : CMD + KeyModifierMask : : SHIFT + Key : : O ) , FILE_QUICK_OPEN_SCENE ) ;
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/quick_open_script " , TTR ( " Quick Open Script... " ) , KeyModifierMask : : CMD + KeyModifierMask : : ALT + Key : : O ) , FILE_QUICK_OPEN_SCRIPT ) ;
2019-08-12 20:23:00 +00:00
2014-02-10 01:10:30 +00:00
p - > add_separator ( ) ;
2022-04-06 12:41:04 +00:00
export_as_menu = memnew ( PopupMenu ) ;
export_as_menu - > set_name ( " Export " ) ;
p - > add_child ( export_as_menu ) ;
p - > add_submenu_item ( TTR ( " Export As... " ) , " Export " ) ;
export_as_menu - > add_shortcut ( ED_SHORTCUT ( " editor/export_as_mesh_library " , TTR ( " MeshLibrary... " ) ) , FILE_EXPORT_MESH_LIBRARY ) ;
export_as_menu - > connect ( " index_pressed " , callable_mp ( this , & EditorNode : : _export_as_menu_option ) ) ;
2014-02-10 01:10:30 +00:00
p - > add_separator ( ) ;
2020-12-07 11:32:00 +00:00
p - > add_shortcut ( ED_GET_SHORTCUT ( " ui_undo " ) , EDIT_UNDO , true ) ;
p - > add_shortcut ( ED_GET_SHORTCUT ( " ui_redo " ) , EDIT_REDO , true ) ;
2019-08-12 20:23:00 +00:00
2014-02-10 01:10:30 +00:00
p - > add_separator ( ) ;
2021-05-29 13:28:16 +00:00
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/reload_saved_scene " , TTR ( " Reload Saved Scene " ) ) , EDIT_RELOAD_SAVED_SCENE ) ;
2021-08-13 21:31:57 +00:00
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/close_scene " , TTR ( " Close Scene " ) , KeyModifierMask : : CMD + KeyModifierMask : : SHIFT + Key : : W ) , FILE_CLOSE ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
recent_scenes = memnew ( PopupMenu ) ;
2014-02-10 01:10:30 +00:00
recent_scenes - > set_name ( " RecentScenes " ) ;
p - > add_child ( recent_scenes ) ;
2020-02-21 17:28:45 +00:00
recent_scenes - > connect ( " id_pressed " , callable_mp ( this , & EditorNode : : _open_recent_scene ) ) ;
2014-02-10 01:10:30 +00:00
2017-06-22 21:04:03 +00:00
p - > add_separator ( ) ;
2021-08-13 21:31:57 +00:00
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/file_quit " , TTR ( " Quit " ) , KeyModifierMask : : CMD + Key : : Q ) , FILE_QUIT , true ) ;
2017-06-22 21:04:03 +00:00
project_menu = memnew ( MenuButton ) ;
2017-09-02 01:25:40 +00:00
project_menu - > set_flat ( false ) ;
2018-07-29 22:26:43 +00:00
project_menu - > set_switch_on_hover ( true ) ;
2017-06-22 21:04:03 +00:00
project_menu - > set_tooltip ( TTR ( " Miscellaneous project or scene-wide tools. " ) ) ;
project_menu - > set_text ( TTR ( " Project " ) ) ;
2022-02-08 09:14:58 +00:00
project_menu - > add_theme_style_override ( " hover " , gui_base - > get_theme_stylebox ( SNAME ( " MenuHover " ) , SNAME ( " EditorStyles " ) ) ) ;
2017-06-22 21:04:03 +00:00
left_menu_hb - > add_child ( project_menu ) ;
p = project_menu - > get_popup ( ) ;
2020-03-12 12:37:40 +00:00
2021-08-13 21:31:57 +00:00
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/project_settings " , TTR ( " Project Settings... " ) , Key : : NONE , TTR ( " Project Settings " ) ) , RUN_SETTINGS ) ;
2020-02-21 17:28:45 +00:00
p - > connect ( " id_pressed " , callable_mp ( this , & EditorNode : : _menu_option ) ) ;
2019-08-12 20:23:00 +00:00
2019-09-03 14:42:08 +00:00
vcs_actions_menu = VersionControlEditorPlugin : : get_singleton ( ) - > get_version_control_actions_panel ( ) ;
vcs_actions_menu - > set_name ( " Version Control " ) ;
2020-02-21 17:28:45 +00:00
vcs_actions_menu - > connect ( " index_pressed " , callable_mp ( this , & EditorNode : : _version_control_menu_option ) ) ;
2019-09-03 14:42:08 +00:00
p - > add_separator ( ) ;
p - > add_child ( vcs_actions_menu ) ;
p - > add_submenu_item ( TTR ( " Version Control " ) , " Version Control " ) ;
2020-09-29 19:01:26 +00:00
vcs_actions_menu - > add_item ( TTR ( " Create Version Control Metadata " ) , RUN_VCS_METADATA ) ;
2019-09-03 14:42:08 +00:00
vcs_actions_menu - > add_item ( TTR ( " Set Up Version Control " ) , RUN_VCS_SETTINGS ) ;
vcs_actions_menu - > add_item ( TTR ( " Shut Down Version Control " ) , RUN_VCS_SHUT_DOWN ) ;
2019-08-12 20:23:00 +00:00
p - > add_separator ( ) ;
2021-08-13 21:31:57 +00:00
p - > add_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/export " , TTR ( " Export... " ) , Key : : NONE , TTR ( " Export " ) ) , FILE_EXPORT_PROJECT ) ;
2019-08-12 20:23:00 +00:00
p - > add_item ( TTR ( " Install Android Build Template... " ) , FILE_INSTALL_ANDROID_SOURCE ) ;
2021-12-28 00:51:45 +00:00
p - > add_item ( TTR ( " Open User Data Folder " ) , RUN_USER_DATA_FOLDER ) ;
2017-06-22 21:04:03 +00:00
2018-07-19 15:34:22 +00:00
plugin_config_dialog = memnew ( PluginConfigDialog ) ;
2020-02-21 17:28:45 +00:00
plugin_config_dialog - > connect ( " plugin_ready " , callable_mp ( this , & EditorNode : : _on_plugin_ready ) ) ;
2018-07-19 15:34:22 +00:00
gui_base - > add_child ( plugin_config_dialog ) ;
2018-03-17 01:50:35 +00:00
tool_menu = memnew ( PopupMenu ) ;
2017-06-22 21:04:03 +00:00
tool_menu - > set_name ( " Tools " ) ;
2020-02-21 17:28:45 +00:00
tool_menu - > connect ( " index_pressed " , callable_mp ( this , & EditorNode : : _tool_menu_option ) ) ;
2017-06-22 21:04:03 +00:00
p - > add_child ( tool_menu ) ;
p - > add_submenu_item ( TTR ( " Tools " ) , " Tools " ) ;
2019-08-12 20:23:00 +00:00
tool_menu - > add_item ( TTR ( " Orphan Resource Explorer... " ) , TOOLS_ORPHAN_RESOURCES ) ;
2018-07-25 17:53:12 +00:00
2019-08-12 20:23:00 +00:00
p - > add_separator ( ) ;
2022-03-23 11:07:29 +00:00
p - > add_shortcut ( ED_SHORTCUT ( " editor/reload_current_project " , TTR ( " Reload Current Project " ) ) , RELOAD_CURRENT_PROJECT ) ;
2021-08-13 21:31:57 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/quit_to_project_list " , TTR ( " Quit to Project List " ) , KeyModifierMask : : CMD + KeyModifierMask : : SHIFT + Key : : Q ) ;
ED_SHORTCUT_OVERRIDE ( " editor/quit_to_project_list " , " macos " , KeyModifierMask : : SHIFT + KeyModifierMask : : ALT + Key : : Q ) ;
2021-08-08 03:52:00 +00:00
p - > add_shortcut ( ED_GET_SHORTCUT ( " editor/quit_to_project_list " ) , RUN_PROJECT_MANAGER , true ) ;
2015-11-18 07:47:41 +00:00
2017-05-24 10:00:55 +00:00
menu_hb - > add_spacer ( ) ;
2019-02-11 04:18:54 +00:00
main_editor_button_vb = memnew ( HBoxContainer ) ;
menu_hb - > add_child ( main_editor_button_vb ) ;
2016-09-13 12:46:17 +00:00
2022-03-30 18:12:26 +00:00
// Options are added and handled by DebuggerEditorPlugin.
2017-05-24 10:00:55 +00:00
debug_menu = memnew ( MenuButton ) ;
2017-09-02 01:25:40 +00:00
debug_menu - > set_flat ( false ) ;
2018-07-29 22:26:43 +00:00
debug_menu - > set_switch_on_hover ( true ) ;
2017-05-24 10:00:55 +00:00
debug_menu - > set_text ( TTR ( " Debug " ) ) ;
2022-02-08 09:14:58 +00:00
debug_menu - > add_theme_style_override ( " hover " , gui_base - > get_theme_stylebox ( SNAME ( " MenuHover " ) , SNAME ( " EditorStyles " ) ) ) ;
2017-05-24 10:00:55 +00:00
left_menu_hb - > add_child ( debug_menu ) ;
2020-03-12 12:37:40 +00:00
2017-05-24 10:00:55 +00:00
menu_hb - > add_spacer ( ) ;
2015-11-29 04:08:31 +00:00
2017-05-24 10:00:55 +00:00
settings_menu = memnew ( MenuButton ) ;
2017-09-02 01:25:40 +00:00
settings_menu - > set_flat ( false ) ;
2018-07-29 22:26:43 +00:00
settings_menu - > set_switch_on_hover ( true ) ;
2017-05-24 10:00:55 +00:00
settings_menu - > set_text ( TTR ( " Editor " ) ) ;
2022-02-08 09:14:58 +00:00
settings_menu - > add_theme_style_override ( " hover " , gui_base - > get_theme_stylebox ( SNAME ( " MenuHover " ) , SNAME ( " EditorStyles " ) ) ) ;
2017-09-02 01:25:40 +00:00
left_menu_hb - > add_child ( settings_menu ) ;
2015-11-29 04:08:31 +00:00
2018-01-02 07:10:49 +00:00
p = settings_menu - > get_popup ( ) ;
2021-08-08 03:52:00 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/editor_settings " , TTR ( " Editor Settings... " ) ) ;
2021-08-13 21:31:57 +00:00
ED_SHORTCUT_OVERRIDE ( " editor/editor_settings " , " macos " , KeyModifierMask : : CMD + Key : : COMMA ) ;
2021-08-08 03:52:00 +00:00
p - > add_shortcut ( ED_GET_SHORTCUT ( " editor/editor_settings " ) , SETTINGS_PREFERENCES ) ;
2021-08-13 21:31:57 +00:00
p - > add_shortcut ( ED_SHORTCUT ( " editor/command_palette " , TTR ( " Command Palette... " ) , KeyModifierMask : : CMD | KeyModifierMask : : SHIFT | Key : : P ) , HELP_COMMAND_PALETTE ) ;
2017-05-24 10:00:55 +00:00
p - > add_separator ( ) ;
2018-07-25 17:53:12 +00:00
2017-05-24 10:00:55 +00:00
editor_layouts = memnew ( PopupMenu ) ;
editor_layouts - > set_name ( " Layouts " ) ;
p - > add_child ( editor_layouts ) ;
2020-02-21 17:28:45 +00:00
editor_layouts - > connect ( " id_pressed " , callable_mp ( this , & EditorNode : : _layout_menu_option ) ) ;
2017-05-24 10:00:55 +00:00
p - > add_submenu_item ( TTR ( " Editor Layout " ) , " Layouts " ) ;
2019-07-23 05:05:29 +00:00
p - > add_separator ( ) ;
2021-08-08 03:52:00 +00:00
2021-08-13 21:31:57 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/take_screenshot " , TTR ( " Take Screenshot " ) , KeyModifierMask : : CTRL | Key : : F12 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/take_screenshot " , " macos " , KeyModifierMask : : CMD | Key : : F12 ) ;
2021-08-08 03:52:00 +00:00
p - > add_shortcut ( ED_GET_SHORTCUT ( " editor/take_screenshot " ) , EDITOR_SCREENSHOT ) ;
2022-03-12 00:06:45 +00:00
p - > set_item_tooltip ( - 1 , TTR ( " Screenshots are stored in the Editor Data/Settings Folder. " ) ) ;
2021-08-08 03:52:00 +00:00
2021-08-13 21:31:57 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/fullscreen_mode " , TTR ( " Toggle Fullscreen " ) , KeyModifierMask : : SHIFT | Key : : F11 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/fullscreen_mode " , " macos " , KeyModifierMask : : CMD | KeyModifierMask : : CTRL | Key : : F ) ;
2021-08-08 03:52:00 +00:00
p - > add_shortcut ( ED_GET_SHORTCUT ( " editor/fullscreen_mode " ) , SETTINGS_TOGGLE_FULLSCREEN ) ;
2017-05-24 10:00:55 +00:00
p - > add_separator ( ) ;
2018-07-25 17:53:12 +00:00
if ( OS : : get_singleton ( ) - > get_data_path ( ) = = OS : : get_singleton ( ) - > get_config_path ( ) ) {
2022-03-30 18:12:26 +00:00
// Configuration and data folders are located in the same place (Windows/MacOS).
2018-07-25 17:53:12 +00:00
p - > add_item ( TTR ( " Open Editor Data/Settings Folder " ) , SETTINGS_EDITOR_DATA_FOLDER ) ;
} else {
2022-03-30 18:12:26 +00:00
// Separate configuration and data folders (Linux).
2018-07-25 17:53:12 +00:00
p - > add_item ( TTR ( " Open Editor Data Folder " ) , SETTINGS_EDITOR_DATA_FOLDER ) ;
p - > add_item ( TTR ( " Open Editor Settings Folder " ) , SETTINGS_EDITOR_CONFIG_FOLDER ) ;
}
p - > add_separator ( ) ;
2019-08-12 20:23:00 +00:00
p - > add_item ( TTR ( " Manage Editor Features... " ) , SETTINGS_MANAGE_FEATURE_PROFILES ) ;
p - > add_item ( TTR ( " Manage Export Templates... " ) , SETTINGS_MANAGE_EXPORT_TEMPLATES ) ;
2017-05-26 14:34:41 +00:00
2017-09-02 01:25:40 +00:00
help_menu = memnew ( MenuButton ) ;
help_menu - > set_flat ( false ) ;
2018-07-29 22:26:43 +00:00
help_menu - > set_switch_on_hover ( true ) ;
2017-05-26 14:34:41 +00:00
help_menu - > set_text ( TTR ( " Help " ) ) ;
2022-02-08 09:14:58 +00:00
help_menu - > add_theme_style_override ( " hover " , gui_base - > get_theme_stylebox ( SNAME ( " MenuHover " ) , SNAME ( " EditorStyles " ) ) ) ;
2017-09-02 01:25:40 +00:00
left_menu_hb - > add_child ( help_menu ) ;
2017-05-26 14:34:41 +00:00
p = help_menu - > get_popup ( ) ;
2020-02-21 17:28:45 +00:00
p - > connect ( " id_pressed " , callable_mp ( this , & EditorNode : : _menu_option ) ) ;
2021-08-08 03:52:00 +00:00
2021-08-13 21:31:57 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/editor_help " , TTR ( " Search Help " ) , Key : : F1 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/editor_help " , " macos " , KeyModifierMask : : ALT | Key : : SPACE ) ;
2021-08-08 03:52:00 +00:00
p - > add_icon_shortcut ( gui_base - > get_theme_icon ( SNAME ( " HelpSearch " ) , SNAME ( " EditorIcons " ) ) , ED_GET_SHORTCUT ( " editor/editor_help " ) , HELP_SEARCH ) ;
2017-05-26 14:34:41 +00:00
p - > add_separator ( ) ;
2022-04-24 15:21:14 +00:00
p - > add_icon_shortcut ( gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) , ED_SHORTCUT_AND_COMMAND ( " editor/online_docs " , TTR ( " Online Documentation " ) ) , HELP_DOCS ) ;
p - > add_icon_shortcut ( gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) , ED_SHORTCUT_AND_COMMAND ( " editor/q&a " , TTR ( " Questions & Answers " ) ) , HELP_QA ) ;
p - > add_icon_shortcut ( gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) , ED_SHORTCUT_AND_COMMAND ( " editor/report_a_bug " , TTR ( " Report a Bug " ) ) , HELP_REPORT_A_BUG ) ;
p - > add_icon_shortcut ( gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) , ED_SHORTCUT_AND_COMMAND ( " editor/suggest_a_feature " , TTR ( " Suggest a Feature " ) ) , HELP_SUGGEST_A_FEATURE ) ;
p - > add_icon_shortcut ( gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) , ED_SHORTCUT_AND_COMMAND ( " editor/send_docs_feedback " , TTR ( " Send Docs Feedback " ) ) , HELP_SEND_DOCS_FEEDBACK ) ;
p - > add_icon_shortcut ( gui_base - > get_theme_icon ( SNAME ( " ExternalLink " ) , SNAME ( " EditorIcons " ) ) , ED_SHORTCUT_AND_COMMAND ( " editor/community " , TTR ( " Community " ) ) , HELP_COMMUNITY ) ;
2017-05-24 10:00:55 +00:00
p - > add_separator ( ) ;
2021-05-29 13:28:16 +00:00
p - > add_icon_shortcut ( gui_base - > get_theme_icon ( SNAME ( " Godot " ) , SNAME ( " EditorIcons " ) ) , ED_SHORTCUT_AND_COMMAND ( " editor/about " , TTR ( " About Godot " ) ) , HELP_ABOUT ) ;
p - > add_icon_shortcut ( gui_base - > get_theme_icon ( SNAME ( " Heart " ) , SNAME ( " EditorIcons " ) ) , ED_SHORTCUT_AND_COMMAND ( " editor/support_development " , TTR ( " Support Godot Development " ) ) , HELP_SUPPORT_GODOT_DEVELOPMENT ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
HBoxContainer * play_hb = memnew ( HBoxContainer ) ;
2019-02-11 04:18:54 +00:00
menu_hb - > add_child ( play_hb ) ;
2014-02-10 01:10:30 +00:00
2020-06-19 18:49:04 +00:00
play_button = memnew ( Button ) ;
play_button - > set_flat ( true ) ;
2014-02-10 01:10:30 +00:00
play_hb - > add_child ( play_button ) ;
play_button - > set_toggle_mode ( true ) ;
2021-07-17 21:22:52 +00:00
play_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " MainPlay " ) , SNAME ( " EditorIcons " ) ) ) ;
2014-02-10 01:10:30 +00:00
play_button - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2020-02-21 17:28:45 +00:00
play_button - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _menu_option ) , make_binds ( RUN_PLAY ) ) ;
2016-06-05 00:31:29 +00:00
play_button - > set_tooltip ( TTR ( " Play the project. " ) ) ;
2021-08-08 03:52:00 +00:00
2021-08-13 21:31:57 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/play " , TTR ( " Play " ) , Key : : F5 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/play " , " macos " , KeyModifierMask : : CMD | Key : : B ) ;
2021-08-08 03:52:00 +00:00
play_button - > set_shortcut ( ED_GET_SHORTCUT ( " editor/play " ) ) ;
2014-02-10 01:10:30 +00:00
2020-06-19 18:49:04 +00:00
pause_button = memnew ( Button ) ;
pause_button - > set_flat ( true ) ;
2014-02-10 01:10:30 +00:00
pause_button - > set_toggle_mode ( true ) ;
2021-07-17 21:22:52 +00:00
pause_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " Pause " ) , SNAME ( " EditorIcons " ) ) ) ;
2014-02-10 01:10:30 +00:00
pause_button - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2019-11-14 10:44:03 +00:00
pause_button - > set_tooltip ( TTR ( " Pause the scene execution for debugging. " ) ) ;
2016-05-22 00:18:16 +00:00
pause_button - > set_disabled ( true ) ;
play_hb - > add_child ( pause_button ) ;
2021-08-08 03:52:00 +00:00
2021-08-13 21:31:57 +00:00
ED_SHORTCUT ( " editor/pause_scene " , TTR ( " Pause Scene " ) , Key : : F7 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/pause_scene " , " macos " , KeyModifierMask : : CMD | KeyModifierMask : : CTRL | Key : : Y ) ;
2021-08-08 03:52:00 +00:00
pause_button - > set_shortcut ( ED_GET_SHORTCUT ( " editor/pause_scene " ) ) ;
2016-05-22 01:34:55 +00:00
2020-06-19 18:49:04 +00:00
stop_button = memnew ( Button ) ;
stop_button - > set_flat ( true ) ;
2014-02-10 01:10:30 +00:00
play_hb - > add_child ( stop_button ) ;
stop_button - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2021-07-17 21:22:52 +00:00
stop_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " Stop " ) , SNAME ( " EditorIcons " ) ) ) ;
2020-02-21 17:28:45 +00:00
stop_button - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _menu_option ) , make_binds ( RUN_STOP ) ) ;
2016-06-05 00:31:29 +00:00
stop_button - > set_tooltip ( TTR ( " Stop the scene. " ) ) ;
2017-12-04 19:48:46 +00:00
stop_button - > set_disabled ( true ) ;
2021-08-08 03:52:00 +00:00
2021-08-13 21:31:57 +00:00
ED_SHORTCUT ( " editor/stop " , TTR ( " Stop " ) , Key : : F8 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/stop " , " macos " , KeyModifierMask : : CMD | Key : : PERIOD ) ;
2021-08-08 03:52:00 +00:00
stop_button - > set_shortcut ( ED_GET_SHORTCUT ( " editor/stop " ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
run_native = memnew ( EditorRunNative ) ;
2014-02-10 01:10:30 +00:00
play_hb - > add_child ( run_native ) ;
2020-03-16 08:37:43 +00:00
run_native - > connect ( " native_run " , callable_mp ( this , & EditorNode : : _run_native ) ) ;
2014-02-10 01:10:30 +00:00
2020-06-19 18:49:04 +00:00
play_scene_button = memnew ( Button ) ;
play_scene_button - > set_flat ( true ) ;
2014-02-10 01:10:30 +00:00
play_hb - > add_child ( play_scene_button ) ;
play_scene_button - > set_toggle_mode ( true ) ;
play_scene_button - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2021-07-17 21:22:52 +00:00
play_scene_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " PlayScene " ) , SNAME ( " EditorIcons " ) ) ) ;
2020-02-21 17:28:45 +00:00
play_scene_button - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _menu_option ) , make_binds ( RUN_PLAY_SCENE ) ) ;
2016-06-05 00:31:29 +00:00
play_scene_button - > set_tooltip ( TTR ( " Play the edited scene. " ) ) ;
2021-08-08 03:52:00 +00:00
2021-08-13 21:31:57 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/play_scene " , TTR ( " Play Scene " ) , Key : : F6 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/play_scene " , " macos " , KeyModifierMask : : CMD | Key : : R ) ;
2021-08-08 03:52:00 +00:00
play_scene_button - > set_shortcut ( ED_GET_SHORTCUT ( " editor/play_scene " ) ) ;
2014-02-10 01:10:30 +00:00
2020-06-19 18:49:04 +00:00
play_custom_scene_button = memnew ( Button ) ;
play_custom_scene_button - > set_flat ( true ) ;
2014-02-10 01:10:30 +00:00
play_hb - > add_child ( play_custom_scene_button ) ;
play_custom_scene_button - > set_toggle_mode ( true ) ;
play_custom_scene_button - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2021-07-17 21:22:52 +00:00
play_custom_scene_button - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " PlayCustom " ) , SNAME ( " EditorIcons " ) ) ) ;
2020-02-21 17:28:45 +00:00
play_custom_scene_button - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _menu_option ) , make_binds ( RUN_PLAY_CUSTOM_SCENE ) ) ;
2016-07-11 17:46:41 +00:00
play_custom_scene_button - > set_tooltip ( TTR ( " Play custom scene " ) ) ;
2021-08-08 03:52:00 +00:00
2021-08-13 21:31:57 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/play_custom_scene " , TTR ( " Play Custom Scene " ) , KeyModifierMask : : CMD | KeyModifierMask : : SHIFT | Key : : F5 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/play_custom_scene " , " macos " , KeyModifierMask : : CMD | KeyModifierMask : : SHIFT | Key : : R ) ;
2021-08-08 03:52:00 +00:00
play_custom_scene_button - > set_shortcut ( ED_GET_SHORTCUT ( " editor/play_custom_scene " ) ) ;
2014-02-10 01:10:30 +00:00
2018-12-09 18:10:07 +00:00
HBoxContainer * right_menu_hb = memnew ( HBoxContainer ) ;
menu_hb - > add_child ( right_menu_hb ) ;
2020-11-18 18:11:30 +00:00
rendering_driver = memnew ( OptionButton ) ;
2021-10-26 15:18:39 +00:00
// Hide the renderer selection dropdown until OpenGL support is more mature.
// The renderer can still be changed in the project settings or using `--rendering-driver opengl3`.
rendering_driver - > set_visible ( false ) ;
2020-11-18 18:11:30 +00:00
rendering_driver - > set_flat ( true ) ;
rendering_driver - > set_focus_mode ( Control : : FOCUS_NONE ) ;
rendering_driver - > connect ( " item_selected " , callable_mp ( this , & EditorNode : : _rendering_driver_selected ) ) ;
2022-02-08 09:14:58 +00:00
rendering_driver - > add_theme_font_override ( " font " , gui_base - > get_theme_font ( SNAME ( " bold " ) , SNAME ( " EditorFonts " ) ) ) ;
rendering_driver - > add_theme_font_size_override ( " font_size " , gui_base - > get_theme_font_size ( SNAME ( " bold_size " ) , SNAME ( " EditorFonts " ) ) ) ;
2020-11-18 18:11:30 +00:00
right_menu_hb - > add_child ( rendering_driver ) ;
2021-10-26 15:18:39 +00:00
// Only display the render drivers that are available for this display driver.
2020-11-18 18:11:30 +00:00
int display_driver_idx = OS : : get_singleton ( ) - > get_display_driver_id ( ) ;
Vector < String > render_drivers = DisplayServer : : get_create_function_rendering_drivers ( display_driver_idx ) ;
String current_rendering_driver = OS : : get_singleton ( ) - > get_current_rendering_driver_name ( ) ;
2021-10-26 15:18:39 +00:00
// As we are doing string comparisons, keep in standard case to prevent problems with capitals
// "vulkan" in particular uses lowercase "v" in the code, and uppercase in the UI.
2020-11-18 18:11:30 +00:00
current_rendering_driver = current_rendering_driver . to_lower ( ) ;
for ( int i = 0 ; i < render_drivers . size ( ) ; i + + ) {
String driver = render_drivers [ i ] ;
2021-10-26 15:18:39 +00:00
// Add the driver to the UI.
2020-11-18 18:11:30 +00:00
rendering_driver - > add_item ( driver ) ;
rendering_driver - > set_item_metadata ( i , driver ) ;
2021-10-26 15:18:39 +00:00
// Lowercase for standard comparison.
2020-11-18 18:11:30 +00:00
driver = driver . to_lower ( ) ;
2018-07-19 21:58:15 +00:00
2020-11-18 18:11:30 +00:00
if ( current_rendering_driver = = driver ) {
rendering_driver - > select ( i ) ;
rendering_driver_current = i ;
2018-07-19 21:58:15 +00:00
}
}
2020-11-18 18:11:30 +00:00
_update_rendering_driver_color ( ) ;
2018-07-19 21:58:15 +00:00
video_restart_dialog = memnew ( ConfirmationDialog ) ;
video_restart_dialog - > set_text ( TTR ( " Changing the video driver requires restarting the editor. " ) ) ;
2020-12-14 18:37:30 +00:00
video_restart_dialog - > get_ok_button ( ) - > set_text ( TTR ( " Save & Restart " ) ) ;
2020-11-18 18:11:30 +00:00
video_restart_dialog - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _menu_option ) , varray ( SET_RENDERING_DRIVER_SAVE_AND_RESTART ) ) ;
2018-07-20 21:14:33 +00:00
gui_base - > add_child ( video_restart_dialog ) ;
2018-07-19 21:58:15 +00:00
2017-03-05 15:44:50 +00:00
progress_hb = memnew ( BackgroundProgress ) ;
2015-11-18 07:47:41 +00:00
2019-05-30 18:16:40 +00:00
layout_dialog = memnew ( EditorLayoutsDialog ) ;
2015-11-22 18:11:17 +00:00
gui_base - > add_child ( layout_dialog ) ;
layout_dialog - > set_hide_on_ok ( false ) ;
2019-05-30 18:16:40 +00:00
layout_dialog - > set_size ( Size2 ( 225 , 270 ) * EDSCALE ) ;
2020-02-21 17:28:45 +00:00
layout_dialog - > connect ( " name_confirmed " , callable_mp ( this , & EditorNode : : _dialog_action ) ) ;
2014-02-10 01:10:30 +00:00
2018-12-11 15:52:25 +00:00
update_spinner = memnew ( MenuButton ) ;
right_menu_hb - > add_child ( update_spinner ) ;
2021-07-17 21:22:52 +00:00
update_spinner - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " Progress1 " ) , SNAME ( " EditorIcons " ) ) ) ;
2020-02-21 17:28:45 +00:00
update_spinner - > get_popup ( ) - > connect ( " id_pressed " , callable_mp ( this , & EditorNode : : _menu_option ) ) ;
2018-12-11 15:52:25 +00:00
p = update_spinner - > get_popup ( ) ;
p - > add_radio_check_item ( TTR ( " Update Continuously " ) , SETTINGS_UPDATE_CONTINUOUSLY ) ;
p - > add_radio_check_item ( TTR ( " Update When Changed " ) , SETTINGS_UPDATE_WHEN_CHANGED ) ;
2017-03-05 15:44:50 +00:00
p - > add_separator ( ) ;
2018-12-11 15:52:25 +00:00
p - > add_item ( TTR ( " Hide Update Spinner " ) , SETTINGS_UPDATE_SPINNER_HIDE ) ;
_update_update_spinner ( ) ;
2015-11-18 07:47:41 +00:00
2022-03-30 18:12:26 +00:00
// Instantiate and place editor docks.
2014-02-10 01:10:30 +00:00
2022-01-27 09:36:51 +00:00
memnew ( SceneTreeDock ( scene_root , editor_selection , editor_data ) ) ;
memnew ( InspectorDock ( editor_data ) ) ;
2021-11-17 20:08:55 +00:00
memnew ( ImportDock ) ;
memnew ( NodeDock ) ;
2015-09-01 03:49:47 +00:00
2022-01-27 09:36:51 +00:00
FileSystemDock * filesystem_dock = memnew ( FileSystemDock ) ;
2020-02-21 17:28:45 +00:00
filesystem_dock - > connect ( " inherit " , callable_mp ( this , & EditorNode : : _inherit_request ) ) ;
2021-06-17 22:03:09 +00:00
filesystem_dock - > connect ( " instance " , callable_mp ( this , & EditorNode : : _instantiate_request ) ) ;
2020-02-21 17:28:45 +00:00
filesystem_dock - > connect ( " display_mode_changed " , callable_mp ( this , & EditorNode : : _save_docks ) ) ;
2015-09-01 03:49:47 +00:00
2022-03-30 18:12:26 +00:00
// Scene: Top left.
2021-11-17 20:08:55 +00:00
dock_slot [ DOCK_SLOT_LEFT_UR ] - > add_child ( SceneTreeDock : : get_singleton ( ) ) ;
2022-03-02 14:37:10 +00:00
dock_slot [ DOCK_SLOT_LEFT_UR ] - > set_tab_title ( dock_slot [ DOCK_SLOT_LEFT_UR ] - > get_tab_idx_from_control ( SceneTreeDock : : get_singleton ( ) ) , TTR ( " Scene " ) ) ;
2018-09-14 14:56:18 +00:00
2022-03-30 18:12:26 +00:00
// Import: Top left, behind Scene.
2021-11-17 20:08:55 +00:00
dock_slot [ DOCK_SLOT_LEFT_UR ] - > add_child ( ImportDock : : get_singleton ( ) ) ;
2022-03-02 14:37:10 +00:00
dock_slot [ DOCK_SLOT_LEFT_UR ] - > set_tab_title ( dock_slot [ DOCK_SLOT_LEFT_UR ] - > get_tab_idx_from_control ( ImportDock : : get_singleton ( ) ) , TTR ( " Import " ) ) ;
2018-09-14 14:56:18 +00:00
2022-03-30 18:12:26 +00:00
// FileSystem: Bottom left.
2021-11-17 20:08:55 +00:00
dock_slot [ DOCK_SLOT_LEFT_BR ] - > add_child ( FileSystemDock : : get_singleton ( ) ) ;
2022-03-02 14:37:10 +00:00
dock_slot [ DOCK_SLOT_LEFT_BR ] - > set_tab_title ( dock_slot [ DOCK_SLOT_LEFT_BR ] - > get_tab_idx_from_control ( FileSystemDock : : get_singleton ( ) ) , TTR ( " FileSystem " ) ) ;
2017-02-01 12:45:45 +00:00
2022-03-30 18:12:26 +00:00
// Inspector: Full height right.
2021-11-17 20:08:55 +00:00
dock_slot [ DOCK_SLOT_RIGHT_UL ] - > add_child ( InspectorDock : : get_singleton ( ) ) ;
2022-03-02 14:37:10 +00:00
dock_slot [ DOCK_SLOT_RIGHT_UL ] - > set_tab_title ( dock_slot [ DOCK_SLOT_RIGHT_UL ] - > get_tab_idx_from_control ( InspectorDock : : get_singleton ( ) ) , TTR ( " Inspector " ) ) ;
2017-03-24 16:39:16 +00:00
2022-03-30 18:12:26 +00:00
// Node: Full height right, behind Inspector.
2021-11-17 20:08:55 +00:00
dock_slot [ DOCK_SLOT_RIGHT_UL ] - > add_child ( NodeDock : : get_singleton ( ) ) ;
2022-03-02 14:37:10 +00:00
dock_slot [ DOCK_SLOT_RIGHT_UL ] - > set_tab_title ( dock_slot [ DOCK_SLOT_RIGHT_UL ] - > get_tab_idx_from_control ( NodeDock : : get_singleton ( ) ) , TTR ( " Node " ) ) ;
2016-06-04 00:03:09 +00:00
2022-03-30 18:12:26 +00:00
// Hide unused dock slots and vsplits.
2018-09-14 14:56:18 +00:00
dock_slot [ DOCK_SLOT_LEFT_UL ] - > hide ( ) ;
dock_slot [ DOCK_SLOT_LEFT_BL ] - > hide ( ) ;
2018-09-14 15:07:46 +00:00
dock_slot [ DOCK_SLOT_RIGHT_BL ] - > hide ( ) ;
2018-09-14 14:56:18 +00:00
dock_slot [ DOCK_SLOT_RIGHT_UR ] - > hide ( ) ;
dock_slot [ DOCK_SLOT_RIGHT_BR ] - > hide ( ) ;
left_l_vsplit - > hide ( ) ;
right_r_vsplit - > hide ( ) ;
2016-09-13 14:20:09 +00:00
2022-03-30 18:12:26 +00:00
// Add some offsets to left_r and main hsplits to make LEFT_R and RIGHT_L docks wider than minsize.
2018-10-26 10:44:49 +00:00
left_r_hsplit - > set_split_offset ( 70 * EDSCALE ) ;
main_hsplit - > set_split_offset ( - 70 * EDSCALE ) ;
2018-09-14 15:07:46 +00:00
2022-03-30 18:12:26 +00:00
// Define corresponding default layout.
2014-02-10 01:10:30 +00:00
2015-11-22 18:11:17 +00:00
const String docks_section = " docks " ;
2021-06-17 22:03:09 +00:00
default_layout . instantiate ( ) ;
2022-03-30 18:12:26 +00:00
// Dock numbers are based on DockSlot enum value + 1.
2018-09-14 15:07:46 +00:00
default_layout - > set_value ( docks_section , " dock_3 " , " Scene,Import " ) ;
default_layout - > set_value ( docks_section , " dock_4 " , " FileSystem " ) ;
default_layout - > set_value ( docks_section , " dock_5 " , " Inspector,Node " ) ;
2015-11-22 18:11:17 +00:00
2020-05-14 14:41:43 +00:00
for ( int i = 0 ; i < vsplits . size ( ) ; i + + ) {
2017-03-05 15:44:50 +00:00
default_layout - > set_value ( docks_section , " dock_split_ " + itos ( i + 1 ) , 0 ) ;
2020-05-14 14:41:43 +00:00
}
2018-09-14 15:07:46 +00:00
default_layout - > set_value ( docks_section , " dock_hsplit_1 " , 0 ) ;
2018-10-26 10:44:49 +00:00
default_layout - > set_value ( docks_section , " dock_hsplit_2 " , 70 * EDSCALE ) ;
default_layout - > set_value ( docks_section , " dock_hsplit_3 " , - 70 * EDSCALE ) ;
2018-09-14 15:07:46 +00:00
default_layout - > set_value ( docks_section , " dock_hsplit_4 " , 0 ) ;
2014-02-10 01:10:30 +00:00
2015-11-22 18:11:17 +00:00
_update_layouts_menu ( ) ;
2014-02-10 01:10:30 +00:00
2022-03-30 18:12:26 +00:00
// Bottom panels.
2018-09-14 14:56:18 +00:00
2017-03-05 15:44:50 +00:00
bottom_panel = memnew ( PanelContainer ) ;
2022-02-08 09:14:58 +00:00
bottom_panel - > add_theme_style_override ( " panel " , gui_base - > get_theme_stylebox ( SNAME ( " panel " ) , SNAME ( " TabContainer " ) ) ) ;
2016-01-17 23:03:57 +00:00
center_split - > add_child ( bottom_panel ) ;
center_split - > set_dragger_visibility ( SplitContainer : : DRAGGER_HIDDEN ) ;
2015-11-18 07:47:41 +00:00
2017-03-05 15:44:50 +00:00
bottom_panel_vb = memnew ( VBoxContainer ) ;
2016-01-17 23:03:57 +00:00
bottom_panel - > add_child ( bottom_panel_vb ) ;
2015-11-18 07:47:41 +00:00
2017-03-05 15:44:50 +00:00
bottom_panel_hb = memnew ( HBoxContainer ) ;
2019-01-26 21:07:32 +00:00
bottom_panel_hb - > set_custom_minimum_size ( Size2 ( 0 , 24 * EDSCALE ) ) ; // Adjust for the height of the "Expand Bottom Dock" icon.
2016-01-17 23:03:57 +00:00
bottom_panel_vb - > add_child ( bottom_panel_hb ) ;
2014-02-10 01:10:30 +00:00
2018-07-16 01:38:14 +00:00
bottom_panel_hb_editors = memnew ( HBoxContainer ) ;
bottom_panel_hb_editors - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
bottom_panel_hb - > add_child ( bottom_panel_hb_editors ) ;
2019-07-22 21:14:51 +00:00
2021-09-22 15:36:40 +00:00
editor_toaster = memnew ( EditorToaster ) ;
bottom_panel_hb - > add_child ( editor_toaster ) ;
2019-12-24 00:20:54 +00:00
VBoxContainer * version_info_vbc = memnew ( VBoxContainer ) ;
bottom_panel_hb - > add_child ( version_info_vbc ) ;
// Add a dummy control node for vertical spacing.
Control * v_spacer = memnew ( Control ) ;
version_info_vbc - > add_child ( v_spacer ) ;
version_btn = memnew ( LinkButton ) ;
version_btn - > set_text ( VERSION_FULL_CONFIG ) ;
String hash = String ( VERSION_HASH ) ;
if ( hash . length ( ) ! = 0 ) {
2021-06-07 21:51:18 +00:00
hash = " " + vformat ( " [%s] " , hash . left ( 9 ) ) ;
2019-12-24 00:20:54 +00:00
}
// Set the text to copy in metadata as it slightly differs from the button's text.
version_btn - > set_meta ( META_TEXT_TO_COPY , " v " VERSION_FULL_BUILD + hash ) ;
2022-03-30 18:12:26 +00:00
// Fade out the version label to be less prominent, but still readable.
2019-12-24 00:20:54 +00:00
version_btn - > set_self_modulate ( Color ( 1 , 1 , 1 , 0.65 ) ) ;
version_btn - > set_underline_mode ( LinkButton : : UNDERLINE_MODE_ON_HOVER ) ;
version_btn - > set_tooltip ( TTR ( " Click to copy. " ) ) ;
version_btn - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _version_button_pressed ) ) ;
version_info_vbc - > add_child ( version_btn ) ;
// Add a dummy control node for horizontal spacing.
Control * h_spacer = memnew ( Control ) ;
bottom_panel_hb - > add_child ( h_spacer ) ;
2019-07-22 21:14:51 +00:00
2020-06-19 18:49:04 +00:00
bottom_panel_raise = memnew ( Button ) ;
bottom_panel_raise - > set_flat ( true ) ;
2021-07-17 21:22:52 +00:00
bottom_panel_raise - > set_icon ( gui_base - > get_theme_icon ( SNAME ( " ExpandBottomDock " ) , SNAME ( " EditorIcons " ) ) ) ;
2018-07-16 01:38:14 +00:00
2021-08-13 21:31:57 +00:00
bottom_panel_raise - > set_shortcut ( ED_SHORTCUT_AND_COMMAND ( " editor/bottom_panel_expand " , TTR ( " Expand Bottom Panel " ) , KeyModifierMask : : SHIFT | Key : : F12 ) ) ;
2018-07-16 01:38:14 +00:00
bottom_panel_hb - > add_child ( bottom_panel_raise ) ;
bottom_panel_raise - > hide ( ) ;
bottom_panel_raise - > set_toggle_mode ( true ) ;
2020-02-21 17:28:45 +00:00
bottom_panel_raise - > connect ( " toggled " , callable_mp ( this , & EditorNode : : _bottom_panel_raise_toggled ) ) ;
2018-07-16 01:38:14 +00:00
2017-03-05 15:44:50 +00:00
log = memnew ( EditorLog ) ;
2020-06-19 18:49:04 +00:00
Button * output_button = add_bottom_panel_item ( TTR ( " Output " ) , log ) ;
2018-03-11 13:20:32 +00:00
log - > set_tool_button ( output_button ) ;
2014-02-10 01:10:30 +00:00
2020-02-21 17:28:45 +00:00
center_split - > connect ( " resized " , callable_mp ( this , & EditorNode : : _vp_resized ) ) ;
2014-02-10 01:10:30 +00:00
2021-01-05 23:01:50 +00:00
native_shader_source_visualizer = memnew ( EditorNativeShaderSourceVisualizer ) ;
gui_base - > add_child ( native_shader_source_visualizer ) ;
2017-03-05 15:44:50 +00:00
orphan_resources = memnew ( OrphanResourcesDialog ) ;
2015-11-29 04:08:31 +00:00
gui_base - > add_child ( orphan_resources ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
confirmation = memnew ( ConfirmationDialog ) ;
2014-02-10 01:10:30 +00:00
gui_base - > add_child ( confirmation ) ;
2020-02-21 17:28:45 +00:00
confirmation - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _menu_confirm_current ) ) ;
2014-02-10 01:10:30 +00:00
2017-06-21 04:15:39 +00:00
save_confirmation = memnew ( ConfirmationDialog ) ;
2020-07-08 23:02:38 +00:00
save_confirmation - > add_button ( TTR ( " Don't Save " ) , DisplayServer : : get_singleton ( ) - > get_swap_cancel_ok ( ) , " discard " ) ;
2017-06-21 04:15:39 +00:00
gui_base - > add_child ( save_confirmation ) ;
2020-02-21 17:28:45 +00:00
save_confirmation - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _menu_confirm_current ) ) ;
save_confirmation - > connect ( " custom_action " , callable_mp ( this , & EditorNode : : _discard_changes ) ) ;
2017-06-21 04:15:39 +00:00
2019-04-07 18:46:52 +00:00
custom_build_manage_templates = memnew ( ConfirmationDialog ) ;
custom_build_manage_templates - > set_text ( TTR ( " Android build template is missing, please install relevant templates. " ) ) ;
2020-12-14 18:37:30 +00:00
custom_build_manage_templates - > get_ok_button ( ) - > set_text ( TTR ( " Manage Templates " ) ) ;
2021-07-15 13:12:56 +00:00
custom_build_manage_templates - > add_button ( TTR ( " Install from file " ) ) - > connect ( " pressed " , callable_mp ( this , & EditorNode : : _menu_option ) , varray ( SETTINGS_INSTALL_ANDROID_BUILD_TEMPLATE ) ) ;
2020-02-21 17:28:45 +00:00
custom_build_manage_templates - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _menu_option ) , varray ( SETTINGS_MANAGE_EXPORT_TEMPLATES ) ) ;
2019-04-07 18:46:52 +00:00
gui_base - > add_child ( custom_build_manage_templates ) ;
2021-07-15 13:12:56 +00:00
file_android_build_source = memnew ( EditorFileDialog ) ;
2021-11-23 11:20:57 +00:00
file_android_build_source - > set_title ( TTR ( " Select Android sources file " ) ) ;
2021-07-15 13:12:56 +00:00
file_android_build_source - > set_access ( EditorFileDialog : : ACCESS_FILESYSTEM ) ;
file_android_build_source - > set_file_mode ( EditorFileDialog : : FILE_MODE_OPEN_FILE ) ;
file_android_build_source - > add_filter ( " *.zip " ) ;
file_android_build_source - > connect ( " file_selected " , callable_mp ( this , & EditorNode : : _android_build_source_selected ) ) ;
gui_base - > add_child ( file_android_build_source ) ;
2019-04-07 18:46:52 +00:00
install_android_build_template = memnew ( ConfirmationDialog ) ;
2019-08-27 11:07:24 +00:00
install_android_build_template - > set_text ( TTR ( " This will set up your project for custom Android builds by installing the source template to \" res://android/build \" . \n You can then apply modifications and build your own custom APK on export (adding modules, changing the AndroidManifest.xml, etc.). \n Note that in order to make custom builds instead of using pre-built APKs, the \" Use Custom Build \" option should be enabled in the Android export preset. " ) ) ;
2020-12-14 18:37:30 +00:00
install_android_build_template - > get_ok_button ( ) - > set_text ( TTR ( " Install " ) ) ;
2020-02-21 17:28:45 +00:00
install_android_build_template - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _menu_confirm_current ) ) ;
2019-04-07 18:46:52 +00:00
gui_base - > add_child ( install_android_build_template ) ;
remove_android_build_template = memnew ( ConfirmationDialog ) ;
2019-08-27 11:07:24 +00:00
remove_android_build_template - > set_text ( TTR ( " The Android build template is already installed in this project and it won't be overwritten. \n Remove the \" res://android/build \" directory manually before attempting this operation again. " ) ) ;
2020-12-14 18:37:30 +00:00
remove_android_build_template - > get_ok_button ( ) - > set_text ( TTR ( " Show in File Manager " ) ) ;
2020-02-21 17:28:45 +00:00
remove_android_build_template - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _menu_option ) , varray ( FILE_EXPLORE_ANDROID_BUILD_TEMPLATES ) ) ;
2019-04-07 18:46:52 +00:00
gui_base - > add_child ( remove_android_build_template ) ;
2017-11-10 22:45:08 +00:00
file_templates = memnew ( EditorFileDialog ) ;
2016-05-18 22:08:12 +00:00
file_templates - > set_title ( TTR ( " Import Templates From ZIP File " ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
gui_base - > add_child ( file_templates ) ;
2020-03-06 17:00:16 +00:00
file_templates - > set_file_mode ( EditorFileDialog : : FILE_MODE_OPEN_FILE ) ;
2017-11-10 22:45:08 +00:00
file_templates - > set_access ( EditorFileDialog : : ACCESS_FILESYSTEM ) ;
2014-02-10 01:10:30 +00:00
file_templates - > clear_filters ( ) ;
2019-12-16 05:18:44 +00:00
file_templates - > add_filter ( " *.tpz ; " + TTR ( " Template Package " ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
file = memnew ( EditorFileDialog ) ;
2014-02-10 01:10:30 +00:00
gui_base - > add_child ( file ) ;
file - > set_current_dir ( " res:// " ) ;
2017-11-10 22:45:08 +00:00
file_export_lib = memnew ( EditorFileDialog ) ;
2016-05-04 01:25:37 +00:00
file_export_lib - > set_title ( TTR ( " Export Library " ) ) ;
2020-03-06 17:00:16 +00:00
file_export_lib - > set_file_mode ( EditorFileDialog : : FILE_MODE_SAVE_FILE ) ;
2020-02-21 17:28:45 +00:00
file_export_lib - > connect ( " file_selected " , callable_mp ( this , & EditorNode : : _dialog_action ) ) ;
2019-07-04 15:30:44 +00:00
file_export_lib_merge = memnew ( CheckBox ) ;
2016-05-04 01:25:37 +00:00
file_export_lib_merge - > set_text ( TTR ( " Merge With Existing " ) ) ;
2021-11-21 20:29:34 +00:00
file_export_lib_merge - > set_h_size_flags ( Control : : SIZE_SHRINK_CENTER ) ;
2014-02-10 01:10:30 +00:00
file_export_lib_merge - > set_pressed ( true ) ;
file_export_lib - > get_vbox ( ) - > add_child ( file_export_lib_merge ) ;
2021-08-31 23:17:33 +00:00
file_export_lib_apply_xforms = memnew ( CheckBox ) ;
file_export_lib_apply_xforms - > set_text ( TTR ( " Apply MeshInstance Transforms " ) ) ;
2021-11-21 20:29:34 +00:00
file_export_lib_apply_xforms - > set_h_size_flags ( Control : : SIZE_SHRINK_CENTER ) ;
2021-08-31 23:17:33 +00:00
file_export_lib_apply_xforms - > set_pressed ( false ) ;
file_export_lib - > get_vbox ( ) - > add_child ( file_export_lib_apply_xforms ) ;
2014-02-10 01:10:30 +00:00
gui_base - > add_child ( file_export_lib ) ;
2017-11-10 22:45:08 +00:00
file_script = memnew ( EditorFileDialog ) ;
2016-05-04 01:25:37 +00:00
file_script - > set_title ( TTR ( " Open & Run a Script " ) ) ;
2017-11-10 22:45:08 +00:00
file_script - > set_access ( EditorFileDialog : : ACCESS_FILESYSTEM ) ;
2020-03-06 17:00:16 +00:00
file_script - > set_file_mode ( EditorFileDialog : : FILE_MODE_OPEN_FILE ) ;
2014-02-21 02:01:44 +00:00
List < String > sexts ;
2017-03-05 15:44:50 +00:00
ResourceLoader : : get_recognized_extensions_for_type ( " Script " , & sexts ) ;
2021-07-24 13:46:25 +00:00
for ( const String & E : sexts ) {
2021-07-16 03:45:57 +00:00
file_script - > add_filter ( " *. " + E ) ;
2014-02-21 02:01:44 +00:00
}
gui_base - > add_child ( file_script ) ;
2020-02-21 17:28:45 +00:00
file_script - > connect ( " file_selected " , callable_mp ( this , & EditorNode : : _dialog_action ) ) ;
2014-02-21 02:01:44 +00:00
2020-02-21 17:28:45 +00:00
file_menu - > get_popup ( ) - > connect ( " id_pressed " , callable_mp ( this , & EditorNode : : _menu_option ) ) ;
2020-03-12 12:37:40 +00:00
file_menu - > connect ( " about_to_popup " , callable_mp ( this , & EditorNode : : _update_file_menu_opened ) ) ;
2020-02-21 17:28:45 +00:00
file_menu - > get_popup ( ) - > connect ( " popup_hide " , callable_mp ( this , & EditorNode : : _update_file_menu_closed ) ) ;
2014-02-10 01:10:30 +00:00
2020-02-21 17:28:45 +00:00
settings_menu - > get_popup ( ) - > connect ( " id_pressed " , callable_mp ( this , & EditorNode : : _menu_option ) ) ;
2014-02-10 01:10:30 +00:00
2020-02-21 17:28:45 +00:00
file - > connect ( " file_selected " , callable_mp ( this , & EditorNode : : _dialog_action ) ) ;
file_templates - > connect ( " file_selected " , callable_mp ( this , & EditorNode : : _dialog_action ) ) ;
2016-01-17 23:03:57 +00:00
2022-03-30 18:12:26 +00:00
audio_preview_gen = memnew ( AudioStreamPreviewGenerator ) ;
add_child ( audio_preview_gen ) ;
2014-02-10 01:10:30 +00:00
2022-01-27 09:36:51 +00:00
add_editor_plugin ( memnew ( DebuggerEditorPlugin ( debug_menu ) ) ) ;
2021-06-04 18:39:38 +00:00
add_editor_plugin ( memnew ( DebugAdapterServer ( ) ) ) ;
2019-08-28 17:42:27 +00:00
disk_changed = memnew ( ConfirmationDialog ) ;
{
VBoxContainer * vbc = memnew ( VBoxContainer ) ;
disk_changed - > add_child ( vbc ) ;
Label * dl = memnew ( Label ) ;
dl - > set_text ( TTR ( " The following files are newer on disk. \n What action should be taken? " ) ) ;
vbc - > add_child ( dl ) ;
disk_changed_list = memnew ( Tree ) ;
vbc - > add_child ( disk_changed_list ) ;
disk_changed_list - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
disk_changed - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _reload_modified_scenes ) ) ;
2021-01-17 00:09:17 +00:00
disk_changed - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _reload_project_settings ) ) ;
2019-08-28 17:42:27 +00:00
disk_changed - > get_ok_button ( ) - > set_text ( TTR ( " Reload " ) ) ;
disk_changed - > add_button ( TTR ( " Resave " ) , ! DisplayServer : : get_singleton ( ) - > get_swap_cancel_ok ( ) , " resave " ) ;
disk_changed - > connect ( " custom_action " , callable_mp ( this , & EditorNode : : _resave_scenes ) ) ;
}
gui_base - > add_child ( disk_changed ) ;
2022-01-27 09:36:51 +00:00
add_editor_plugin ( memnew ( AnimationPlayerEditorPlugin ) ) ;
add_editor_plugin ( memnew ( CanvasItemEditorPlugin ) ) ;
add_editor_plugin ( memnew ( Node3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( ScriptEditorPlugin ) ) ;
2017-01-21 22:00:25 +00:00
2017-01-25 17:30:40 +00:00
EditorAudioBuses * audio_bus_editor = EditorAudioBuses : : register_editor ( ) ;
2017-01-21 22:00:25 +00:00
2022-03-30 18:12:26 +00:00
ScriptTextEditor : : register_editor ( ) ; // Register one for text scripts.
2018-05-28 15:52:28 +00:00
TextEditor : : register_editor ( ) ;
2016-08-02 22:11:05 +00:00
2022-05-25 12:19:01 +00:00
// Asset Library can't work on Web editor for now as most assets are sourced
// directly from GitHub which does not set CORS.
# ifndef JAVASCRIPT_ENABLED
2016-06-10 01:47:43 +00:00
if ( StreamPeerSSL : : is_available ( ) ) {
2022-01-27 09:36:51 +00:00
add_editor_plugin ( memnew ( AssetLibraryEditorPlugin ) ) ;
2016-06-10 01:47:43 +00:00
} else {
WARN_PRINT ( " Asset Library not available, as it requires SSL to work. " ) ;
}
2022-05-25 12:19:01 +00:00
# endif
2017-08-26 13:32:15 +00:00
2022-03-30 18:12:26 +00:00
// Add interface before adding plugins.
2017-08-26 13:32:15 +00:00
editor_interface = memnew ( EditorInterface ) ;
add_child ( editor_interface ) ;
2022-03-30 18:12:26 +00:00
// More visually meaningful to have this later.
2021-02-04 08:20:26 +00:00
raise_bottom_panel_item ( AnimationPlayerEditor : : get_singleton ( ) ) ;
2022-01-27 09:36:51 +00:00
add_editor_plugin ( memnew ( ReplicationEditorPlugin ) ) ;
2016-01-17 23:03:57 +00:00
2019-09-03 14:42:08 +00:00
add_editor_plugin ( VersionControlEditorPlugin : : get_singleton ( ) ) ;
2022-01-27 09:36:51 +00:00
add_editor_plugin ( memnew ( ShaderEditorPlugin ) ) ;
add_editor_plugin ( memnew ( ShaderFileEditorPlugin ) ) ;
add_editor_plugin ( memnew ( VisualShaderEditorPlugin ) ) ;
add_editor_plugin ( memnew ( Camera3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( ThemeEditorPlugin ) ) ;
add_editor_plugin ( memnew ( MultiMeshEditorPlugin ) ) ;
add_editor_plugin ( memnew ( MeshInstance3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( AnimationTreeEditorPlugin ) ) ;
add_editor_plugin ( memnew ( MeshLibraryEditorPlugin ) ) ;
add_editor_plugin ( memnew ( StyleBoxEditorPlugin ) ) ;
add_editor_plugin ( memnew ( Sprite2DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( Skeleton2DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( GPUParticles2DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( GPUParticles3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( CPUParticles2DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( CPUParticles3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( ResourcePreloaderEditorPlugin ) ) ;
add_editor_plugin ( memnew ( Polygon3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( CollisionPolygon2DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( TilesEditorPlugin ) ) ;
add_editor_plugin ( memnew ( SpriteFramesEditorPlugin ) ) ;
add_editor_plugin ( memnew ( TextureRegionEditorPlugin ) ) ;
add_editor_plugin ( memnew ( VoxelGIEditorPlugin ) ) ;
add_editor_plugin ( memnew ( LightmapGIEditorPlugin ) ) ;
add_editor_plugin ( memnew ( OccluderInstance3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( Path2DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( Path3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( Line2DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( Polygon2DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( LightOccluder2DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( NavigationPolygonEditorPlugin ) ) ;
add_editor_plugin ( memnew ( GradientEditorPlugin ) ) ;
add_editor_plugin ( memnew ( CollisionShape2DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( CurveEditorPlugin ) ) ;
add_editor_plugin ( memnew ( FontEditorPlugin ) ) ;
add_editor_plugin ( memnew ( OpenTypeFeaturesEditorPlugin ) ) ;
add_editor_plugin ( memnew ( TextureEditorPlugin ) ) ;
add_editor_plugin ( memnew ( TextureLayeredEditorPlugin ) ) ;
add_editor_plugin ( memnew ( Texture3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( AudioStreamEditorPlugin ) ) ;
add_editor_plugin ( memnew ( AudioStreamRandomizerEditorPlugin ) ) ;
2018-02-21 12:38:21 +00:00
add_editor_plugin ( memnew ( AudioBusesEditorPlugin ( audio_bus_editor ) ) ) ;
2022-01-27 09:36:51 +00:00
add_editor_plugin ( memnew ( Skeleton3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( SkeletonIK3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( PhysicalBone3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( MeshEditorPlugin ) ) ;
add_editor_plugin ( memnew ( MaterialEditorPlugin ) ) ;
add_editor_plugin ( memnew ( GPUParticlesCollisionSDF3DEditorPlugin ) ) ;
add_editor_plugin ( memnew ( InputEventEditorPlugin ) ) ;
add_editor_plugin ( memnew ( SubViewportPreviewEditorPlugin ) ) ;
add_editor_plugin ( memnew ( TextControlEditorPlugin ) ) ;
add_editor_plugin ( memnew ( ControlEditorPlugin ) ) ;
2022-02-22 04:35:20 +00:00
add_editor_plugin ( memnew ( GradientTexture2DEditorPlugin ) ) ;
2022-03-31 01:25:14 +00:00
add_editor_plugin ( memnew ( BitMapEditorPlugin ) ) ;
2022-03-18 19:22:41 +00:00
add_editor_plugin ( memnew ( RayCast2DEditorPlugin ) ) ;
2017-08-26 15:46:49 +00:00
2020-05-14 14:41:43 +00:00
for ( int i = 0 ; i < EditorPlugins : : get_plugin_count ( ) ; i + + ) {
2022-02-14 16:59:06 +00:00
add_editor_plugin ( EditorPlugins : : create ( i ) ) ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
for ( int i = 0 ; i < plugin_init_callback_count ; i + + ) {
2016-08-06 22:00:54 +00:00
plugin_init_callbacks [ i ] ( ) ;
}
2015-05-31 04:59:42 +00:00
2017-06-09 03:23:50 +00:00
resource_preview - > add_preview_generator ( Ref < EditorTexturePreviewPlugin > ( memnew ( EditorTexturePreviewPlugin ) ) ) ;
2020-06-27 20:03:20 +00:00
resource_preview - > add_preview_generator ( Ref < EditorImagePreviewPlugin > ( memnew ( EditorImagePreviewPlugin ) ) ) ;
2017-06-09 03:23:50 +00:00
resource_preview - > add_preview_generator ( Ref < EditorPackedScenePreviewPlugin > ( memnew ( EditorPackedScenePreviewPlugin ) ) ) ;
resource_preview - > add_preview_generator ( Ref < EditorMaterialPreviewPlugin > ( memnew ( EditorMaterialPreviewPlugin ) ) ) ;
resource_preview - > add_preview_generator ( Ref < EditorScriptPreviewPlugin > ( memnew ( EditorScriptPreviewPlugin ) ) ) ;
2018-06-07 15:46:14 +00:00
resource_preview - > add_preview_generator ( Ref < EditorAudioStreamPreviewPlugin > ( memnew ( EditorAudioStreamPreviewPlugin ) ) ) ;
2017-06-09 03:23:50 +00:00
resource_preview - > add_preview_generator ( Ref < EditorMeshPreviewPlugin > ( memnew ( EditorMeshPreviewPlugin ) ) ) ;
resource_preview - > add_preview_generator ( Ref < EditorBitmapPreviewPlugin > ( memnew ( EditorBitmapPreviewPlugin ) ) ) ;
2018-04-16 03:00:56 +00:00
resource_preview - > add_preview_generator ( Ref < EditorFontPreviewPlugin > ( memnew ( EditorFontPreviewPlugin ) ) ) ;
2022-04-20 22:08:35 +00:00
resource_preview - > add_preview_generator ( Ref < EditorGradientPreviewPlugin > ( memnew ( EditorGradientPreviewPlugin ) ) ) ;
2016-08-06 22:00:54 +00:00
2017-09-22 12:20:28 +00:00
{
2019-09-15 04:01:52 +00:00
Ref < StandardMaterial3DConversionPlugin > spatial_mat_convert ;
2021-06-17 22:03:09 +00:00
spatial_mat_convert . instantiate ( ) ;
2017-09-22 12:20:28 +00:00
resource_conversion_plugins . push_back ( spatial_mat_convert ) ;
2017-10-12 11:12:50 +00:00
2021-10-29 14:49:12 +00:00
Ref < ORMMaterial3DConversionPlugin > orm_mat_convert ;
orm_mat_convert . instantiate ( ) ;
resource_conversion_plugins . push_back ( orm_mat_convert ) ;
2017-11-14 18:44:51 +00:00
Ref < CanvasItemMaterialConversionPlugin > canvas_item_mat_convert ;
2021-06-17 22:03:09 +00:00
canvas_item_mat_convert . instantiate ( ) ;
2017-11-14 18:44:51 +00:00
resource_conversion_plugins . push_back ( canvas_item_mat_convert ) ;
2017-10-12 11:12:50 +00:00
Ref < ParticlesMaterialConversionPlugin > particles_mat_convert ;
2021-06-17 22:03:09 +00:00
particles_mat_convert . instantiate ( ) ;
2017-10-12 11:12:50 +00:00
resource_conversion_plugins . push_back ( particles_mat_convert ) ;
2019-06-28 11:51:51 +00:00
2020-03-20 00:32:19 +00:00
Ref < ProceduralSkyMaterialConversionPlugin > procedural_sky_mat_convert ;
2021-06-17 22:03:09 +00:00
procedural_sky_mat_convert . instantiate ( ) ;
2020-03-20 00:32:19 +00:00
resource_conversion_plugins . push_back ( procedural_sky_mat_convert ) ;
Ref < PanoramaSkyMaterialConversionPlugin > panorama_sky_mat_convert ;
2021-06-17 22:03:09 +00:00
panorama_sky_mat_convert . instantiate ( ) ;
2020-03-20 00:32:19 +00:00
resource_conversion_plugins . push_back ( panorama_sky_mat_convert ) ;
Ref < PhysicalSkyMaterialConversionPlugin > physical_sky_mat_convert ;
2021-06-17 22:03:09 +00:00
physical_sky_mat_convert . instantiate ( ) ;
2020-03-20 00:32:19 +00:00
resource_conversion_plugins . push_back ( physical_sky_mat_convert ) ;
2021-10-03 11:28:55 +00:00
Ref < FogMaterialConversionPlugin > fog_mat_convert ;
fog_mat_convert . instantiate ( ) ;
resource_conversion_plugins . push_back ( fog_mat_convert ) ;
2019-06-28 11:51:51 +00:00
Ref < VisualShaderConversionPlugin > vshader_convert ;
2021-06-17 22:03:09 +00:00
vshader_convert . instantiate ( ) ;
2019-06-28 11:51:51 +00:00
resource_conversion_plugins . push_back ( vshader_convert ) ;
2017-09-22 12:20:28 +00:00
}
2018-12-11 15:52:25 +00:00
update_spinner_step_msec = OS : : get_singleton ( ) - > get_ticks_msec ( ) ;
update_spinner_step_frame = Engine : : get_singleton ( ) - > get_frames_drawn ( ) ;
2014-02-10 01:10:30 +00:00
2020-04-01 23:20:12 +00:00
editor_plugin_screen = nullptr ;
2016-03-29 23:02:53 +00:00
editor_plugins_over = memnew ( EditorPluginList ) ;
2017-10-29 19:32:09 +00:00
editor_plugins_force_over = memnew ( EditorPluginList ) ;
2017-06-08 17:57:35 +00:00
editor_plugins_force_input_forwarding = memnew ( EditorPluginList ) ;
2014-02-10 01:10:30 +00:00
2017-12-15 11:38:24 +00:00
Ref < EditorExportTextSceneToBinaryPlugin > export_text_to_binary_plugin ;
2021-06-17 22:03:09 +00:00
export_text_to_binary_plugin . instantiate ( ) ;
2017-12-15 11:38:24 +00:00
EditorExport : : get_singleton ( ) - > add_export_plugin ( export_text_to_binary_plugin ) ;
2022-03-10 07:48:25 +00:00
Ref < GDExtensionExportPlugin > gdextension_export_plugin ;
gdextension_export_plugin . instantiate ( ) ;
EditorExport : : get_singleton ( ) - > add_export_plugin ( gdextension_export_plugin ) ;
2020-06-23 11:48:59 +00:00
Ref < PackedSceneEditorTranslationParserPlugin > packed_scene_translation_parser_plugin ;
2021-06-17 22:03:09 +00:00
packed_scene_translation_parser_plugin . instantiate ( ) ;
2020-06-23 11:48:59 +00:00
EditorTranslationParser : : get_singleton ( ) - > add_parser ( packed_scene_translation_parser_plugin , EditorTranslationParser : : STANDARD ) ;
2014-02-10 01:10:30 +00:00
_edit_current ( ) ;
2020-04-01 23:20:12 +00:00
current = nullptr ;
2018-11-18 14:17:04 +00:00
saving_resource = Ref < Resource > ( ) ;
2014-02-10 01:10:30 +00:00
set_process ( true ) ;
2017-03-05 15:44:50 +00:00
open_imported = memnew ( ConfirmationDialog ) ;
2020-12-14 18:37:30 +00:00
open_imported - > get_ok_button ( ) - > set_text ( TTR ( " Open Anyway " ) ) ;
2020-07-08 23:02:38 +00:00
new_inherited_button = open_imported - > add_button ( TTR ( " New Inherited " ) , ! DisplayServer : : get_singleton ( ) - > get_swap_cancel_ok ( ) , " inherit " ) ;
2020-02-21 17:28:45 +00:00
open_imported - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _open_imported ) ) ;
open_imported - > connect ( " custom_action " , callable_mp ( this , & EditorNode : : _inherit_imported ) ) ;
2017-02-04 23:31:15 +00:00
gui_base - > add_child ( open_imported ) ;
2017-03-05 15:44:50 +00:00
quick_open = memnew ( EditorQuickOpen ) ;
2014-02-10 01:10:30 +00:00
gui_base - > add_child ( quick_open ) ;
2020-02-21 17:28:45 +00:00
quick_open - > connect ( " quick_open " , callable_mp ( this , & EditorNode : : _quick_opened ) ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
quick_run = memnew ( EditorQuickOpen ) ;
2014-02-10 01:10:30 +00:00
gui_base - > add_child ( quick_run ) ;
2020-02-21 17:28:45 +00:00
quick_run - > connect ( " quick_open " , callable_mp ( this , & EditorNode : : _quick_run ) ) ;
2014-02-10 01:10:30 +00:00
_update_recent_scenes ( ) ;
editor_data . restore_editor_global_states ( ) ;
2022-01-11 13:59:52 +00:00
set_process_shortcut_input ( true ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
load_errors = memnew ( RichTextLabel ) ;
load_error_dialog = memnew ( AcceptDialog ) ;
2014-02-10 01:10:30 +00:00
load_error_dialog - > add_child ( load_errors ) ;
2016-05-04 01:25:37 +00:00
load_error_dialog - > set_title ( TTR ( " Load Errors " ) ) ;
2016-06-27 22:59:33 +00:00
gui_base - > add_child ( load_error_dialog ) ;
2014-02-10 01:10:30 +00:00
2019-04-07 18:46:52 +00:00
execute_outputs = memnew ( RichTextLabel ) ;
2020-06-04 12:38:55 +00:00
execute_outputs - > set_selection_enabled ( true ) ;
2019-04-07 18:46:52 +00:00
execute_output_dialog = memnew ( AcceptDialog ) ;
execute_output_dialog - > add_child ( execute_outputs ) ;
2019-06-16 19:57:34 +00:00
execute_output_dialog - > set_title ( " " ) ;
2019-04-07 18:46:52 +00:00
gui_base - > add_child ( execute_output_dialog ) ;
2020-02-21 17:28:45 +00:00
EditorFileSystem : : get_singleton ( ) - > connect ( " sources_changed " , callable_mp ( this , & EditorNode : : _sources_changed ) ) ;
EditorFileSystem : : get_singleton ( ) - > connect ( " filesystem_changed " , callable_mp ( this , & EditorNode : : _fs_changed ) ) ;
EditorFileSystem : : get_singleton ( ) - > connect ( " resources_reimported " , callable_mp ( this , & EditorNode : : _resources_reimported ) ) ;
EditorFileSystem : : get_singleton ( ) - > connect ( " resources_reload " , callable_mp ( this , & EditorNode : : _resources_changed ) ) ;
2014-02-10 01:10:30 +00:00
2018-02-25 16:04:16 +00:00
_build_icon_type_cache ( ) ;
2014-02-10 01:10:30 +00:00
2017-03-05 15:44:50 +00:00
pick_main_scene = memnew ( ConfirmationDialog ) ;
2016-06-27 22:59:33 +00:00
gui_base - > add_child ( pick_main_scene ) ;
2020-12-14 18:37:30 +00:00
pick_main_scene - > get_ok_button ( ) - > set_text ( TTR ( " Select " ) ) ;
2020-02-21 17:28:45 +00:00
pick_main_scene - > connect ( " confirmed " , callable_mp ( this , & EditorNode : : _menu_option ) , varray ( SETTINGS_PICK_MAIN_SCENE ) ) ;
2021-07-06 14:10:07 +00:00
select_current_scene_button = pick_main_scene - > add_button ( TTR ( " Select Current " ) , true , " select_current " ) ;
pick_main_scene - > connect ( " custom_action " , callable_mp ( this , & EditorNode : : _pick_main_scene_custom_action ) ) ;
2015-06-14 01:12:53 +00:00
2020-05-14 14:41:43 +00:00
for ( int i = 0 ; i < _init_callbacks . size ( ) ; i + + ) {
2014-02-25 12:31:47 +00:00
_init_callbacks [ i ] ( ) ;
2020-05-14 14:41:43 +00:00
}
2014-02-10 01:10:30 +00:00
2015-06-22 03:03:19 +00:00
editor_data . add_edited_scene ( - 1 ) ;
editor_data . set_edited_scene ( 0 ) ;
_update_scene_tabs ( ) ;
2021-11-17 20:08:55 +00:00
ImportDock : : get_singleton ( ) - > initialize_import_options ( ) ;
2017-07-23 14:44:42 +00:00
2016-06-13 13:10:50 +00:00
FileAccess : : set_file_close_fail_notify_callback ( _file_access_close_error_notify ) ;
2015-06-22 03:03:19 +00:00
2017-11-14 22:02:31 +00:00
print_handler . printfunc = _print_handler ;
print_handler . userdata = this ;
add_print_handler ( & print_handler ) ;
2018-10-29 19:36:31 +00:00
ResourceSaver : : set_save_callback ( _resource_saved ) ;
ResourceLoader : : set_load_callback ( _resource_loaded ) ;
2020-04-25 13:04:49 +00:00
// Use the Ctrl modifier so F2 can be used to rename nodes in the scene tree dock.
2021-08-13 21:31:57 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/editor_2d " , TTR ( " Open 2D Editor " ) , KeyModifierMask : : CTRL | Key : : F1 ) ;
ED_SHORTCUT_AND_COMMAND ( " editor/editor_3d " , TTR ( " Open 3D Editor " ) , KeyModifierMask : : CTRL | Key : : F2 ) ;
ED_SHORTCUT_AND_COMMAND ( " editor/editor_script " , TTR ( " Open Script Editor " ) , KeyModifierMask : : CTRL | Key : : F3 ) ;
ED_SHORTCUT_AND_COMMAND ( " editor/editor_assetlib " , TTR ( " Open Asset Library " ) , KeyModifierMask : : CTRL | Key : : F4 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/editor_2d " , " macos " , KeyModifierMask : : ALT | Key : : KEY_1 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/editor_3d " , " macos " , KeyModifierMask : : ALT | Key : : KEY_2 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/editor_script " , " macos " , KeyModifierMask : : ALT | Key : : KEY_3 ) ;
ED_SHORTCUT_OVERRIDE ( " editor/editor_assetlib " , " macos " , KeyModifierMask : : ALT | Key : : KEY_4 ) ;
2021-08-08 03:52:00 +00:00
ED_SHORTCUT_AND_COMMAND ( " editor/editor_next " , TTR ( " Open the next Editor " ) ) ;
ED_SHORTCUT_AND_COMMAND ( " editor/editor_prev " , TTR ( " Open the previous Editor " ) ) ;
2019-03-29 13:53:11 +00:00
screenshot_timer = memnew ( Timer ) ;
screenshot_timer - > set_one_shot ( true ) ;
screenshot_timer - > set_wait_time ( settings_menu - > get_popup ( ) - > get_submenu_popup_delay ( ) + 0.1f ) ;
2020-02-21 17:28:45 +00:00
screenshot_timer - > connect ( " timeout " , callable_mp ( this , & EditorNode : : _request_screenshot ) ) ;
2019-03-29 13:53:11 +00:00
add_child ( screenshot_timer ) ;
screenshot_timer - > set_owner ( get_owner ( ) ) ;
2020-03-12 12:59:48 +00:00
String exec = OS : : get_singleton ( ) - > get_executable_path ( ) ;
2022-03-30 18:12:26 +00:00
// Save editor executable path for third-party tools.
EditorSettings : : get_singleton ( ) - > set_project_metadata ( " editor_metadata " , " executable_path " , exec ) ;
2014-02-10 01:10:30 +00:00
}
2016-03-08 23:00:52 +00:00
EditorNode : : ~ EditorNode ( ) {
2018-05-15 20:12:35 +00:00
EditorInspector : : cleanup_plugins ( ) ;
2020-07-27 14:58:21 +00:00
EditorTranslationParser : : get_singleton ( ) - > clean_parsers ( ) ;
2022-04-12 14:07:09 +00:00
ResourceImporterScene : : clean_up_importer_plugins ( ) ;
2018-05-15 20:12:35 +00:00
2017-11-14 22:02:31 +00:00
remove_print_handler ( & print_handler ) ;
2021-07-25 17:44:03 +00:00
EditorHelp : : cleanup_doc ( ) ;
2014-02-10 01:10:30 +00:00
memdelete ( editor_selection ) ;
2016-03-29 23:02:53 +00:00
memdelete ( editor_plugins_over ) ;
2017-10-29 19:32:09 +00:00
memdelete ( editor_plugins_force_over ) ;
2017-06-08 17:57:35 +00:00
memdelete ( editor_plugins_force_input_forwarding ) ;
2017-08-24 16:51:28 +00:00
memdelete ( progress_hb ) ;
2018-11-08 14:30:02 +00:00
2014-02-10 01:10:30 +00:00
EditorSettings : : destroy ( ) ;
}
2016-03-29 23:02:53 +00:00
/*
* EDITOR PLUGIN LIST
*/
void EditorPluginList : : make_visible ( bool p_visible ) {
2016-09-10 19:44:03 +00:00
for ( int i = 0 ; i < plugins_list . size ( ) ; i + + ) {
plugins_list [ i ] - > make_visible ( p_visible ) ;
2016-03-29 23:02:53 +00:00
}
}
2017-03-05 15:44:50 +00:00
void EditorPluginList : : edit ( Object * p_object ) {
2016-09-10 19:44:03 +00:00
for ( int i = 0 ; i < plugins_list . size ( ) ; i + + ) {
plugins_list [ i ] - > edit ( p_object ) ;
2016-03-29 23:02:53 +00:00
}
}
2017-10-15 20:33:25 +00:00
bool EditorPluginList : : forward_gui_input ( const Ref < InputEvent > & p_event ) {
2016-03-29 23:02:53 +00:00
bool discard = false ;
2016-09-10 19:44:03 +00:00
for ( int i = 0 ; i < plugins_list . size ( ) ; i + + ) {
2017-10-15 20:33:25 +00:00
if ( plugins_list [ i ] - > forward_canvas_gui_input ( p_event ) ) {
2016-09-10 19:44:03 +00:00
discard = true ;
2016-03-29 23:02:53 +00:00
}
}
2016-09-10 19:44:03 +00:00
2016-03-29 23:02:53 +00:00
return discard ;
}
2021-02-04 08:20:26 +00:00
EditorPlugin : : AfterGUIInput EditorPluginList : : forward_spatial_gui_input ( Camera3D * p_camera , const Ref < InputEvent > & p_event , bool serve_when_force_input_enabled ) {
EditorPlugin : : AfterGUIInput after = EditorPlugin : : AFTER_GUI_INPUT_PASS ;
2016-09-10 19:44:03 +00:00
for ( int i = 0 ; i < plugins_list . size ( ) ; i + + ) {
2017-06-08 17:57:35 +00:00
if ( ( ! serve_when_force_input_enabled ) & & plugins_list [ i ] - > is_input_event_forwarding_always_enabled ( ) ) {
continue ;
}
2021-02-04 08:20:26 +00:00
EditorPlugin : : AfterGUIInput current_after = plugins_list [ i ] - > forward_spatial_gui_input ( p_camera , p_event ) ;
if ( current_after = = EditorPlugin : : AFTER_GUI_INPUT_STOP ) {
after = EditorPlugin : : AFTER_GUI_INPUT_STOP ;
}
if ( after ! = EditorPlugin : : AFTER_GUI_INPUT_STOP & & current_after = = EditorPlugin : : AFTER_GUI_INPUT_DESELECT ) {
after = EditorPlugin : : AFTER_GUI_INPUT_DESELECT ;
2016-03-29 23:02:53 +00:00
}
}
2016-09-10 19:44:03 +00:00
2021-02-04 08:20:26 +00:00
return after ;
2016-03-29 23:02:53 +00:00
}
2018-09-18 18:00:07 +00:00
void EditorPluginList : : forward_canvas_draw_over_viewport ( Control * p_overlay ) {
2016-09-10 19:44:03 +00:00
for ( int i = 0 ; i < plugins_list . size ( ) ; i + + ) {
2018-09-18 18:00:07 +00:00
plugins_list [ i ] - > forward_canvas_draw_over_viewport ( p_overlay ) ;
2017-10-29 19:32:09 +00:00
}
}
2018-09-18 18:00:07 +00:00
void EditorPluginList : : forward_canvas_force_draw_over_viewport ( Control * p_overlay ) {
2017-10-29 19:32:09 +00:00
for ( int i = 0 ; i < plugins_list . size ( ) ; i + + ) {
2018-09-18 18:00:07 +00:00
plugins_list [ i ] - > forward_canvas_force_draw_over_viewport ( p_overlay ) ;
}
}
void EditorPluginList : : forward_spatial_draw_over_viewport ( Control * p_overlay ) {
for ( int i = 0 ; i < plugins_list . size ( ) ; i + + ) {
plugins_list [ i ] - > forward_spatial_draw_over_viewport ( p_overlay ) ;
}
}
void EditorPluginList : : forward_spatial_force_draw_over_viewport ( Control * p_overlay ) {
for ( int i = 0 ; i < plugins_list . size ( ) ; i + + ) {
plugins_list [ i ] - > forward_spatial_force_draw_over_viewport ( p_overlay ) ;
2016-09-10 19:44:03 +00:00
}
}
2017-06-08 17:57:35 +00:00
void EditorPluginList : : add_plugin ( EditorPlugin * p_plugin ) {
plugins_list . push_back ( p_plugin ) ;
}
2019-02-25 15:49:06 +00:00
void EditorPluginList : : remove_plugin ( EditorPlugin * p_plugin ) {
plugins_list . erase ( p_plugin ) ;
}
2020-12-15 12:04:21 +00:00
bool EditorPluginList : : is_empty ( ) {
return plugins_list . is_empty ( ) ;
2016-03-29 23:02:53 +00:00
}
void EditorPluginList : : clear ( ) {
plugins_list . clear ( ) ;
}
EditorPluginList : : EditorPluginList ( ) {
}
EditorPluginList : : ~ EditorPluginList ( ) {
}