From 8a74d8438f5dee92927d953a7954ad3c3022cbd9 Mon Sep 17 00:00:00 2001 From: Yuri Sizov <yuris@humnom.net> Date: Wed, 12 Apr 2023 21:02:28 +0200 Subject: [PATCH] Extract editor run toolbar into its own component - Simplify and update its logic. - Simplify EditorScript. - Improve EditorNode and other relevant includes. - Fix scene-based path in the movie writer when reloading a scene. --- doc/classes/EditorScript.xml | 4 +- .../debug_adapter/debug_adapter_parser.cpp | 17 +- .../debug_adapter/debug_adapter_protocol.cpp | 6 +- editor/debugger/editor_debugger_node.cpp | 16 +- editor/editor_data.cpp | 10 + editor/editor_data.h | 3 + editor/editor_interface.cpp | 17 +- editor/editor_node.cpp | 498 ++++-------------- editor/editor_node.h | 59 +-- editor/editor_plugin.cpp | 4 +- editor/editor_plugin_settings.cpp | 1 + editor/editor_run.h | 1 + editor/editor_run_native.cpp | 7 +- editor/editor_run_native.h | 6 +- ...ditor_run_script.cpp => editor_script.cpp} | 33 +- .../{editor_run_script.h => editor_script.h} | 21 +- editor/editor_settings.h | 3 +- editor/export/editor_export_platform.cpp | 1 + editor/gui/editor_run_bar.cpp | 442 ++++++++++++++++ editor/gui/editor_run_bar.h | 115 ++++ editor/plugins/canvas_item_editor_plugin.cpp | 5 +- editor/plugins/curve_editor_plugin.cpp | 1 + editor/plugins/curve_editor_plugin.h | 2 + editor/plugins/material_editor_plugin.cpp | 1 + editor/plugins/node_3d_editor_plugin.cpp | 5 +- editor/plugins/script_editor_plugin.cpp | 11 +- editor/plugins/script_text_editor.cpp | 1 + editor/project_settings_editor.cpp | 1 + editor/register_editor_types.cpp | 6 +- .../editor_scene_exporter_gltf_plugin.cpp | 1 + modules/mono/editor/editor_internal_calls.cpp | 5 +- platform/ios/export/export_plugin.cpp | 1 + platform/linuxbsd/export/export_plugin.cpp | 1 + platform/uwp/export/export.cpp | 1 + platform/web/export/export.cpp | 1 + platform/web/export/export_plugin.cpp | 1 + platform/windows/export/export_plugin.cpp | 1 + 37 files changed, 771 insertions(+), 538 deletions(-) rename editor/{editor_run_script.cpp => editor_script.cpp} (87%) rename editor/{editor_run_script.h => editor_script.h} (88%) create mode 100644 editor/gui/editor_run_bar.cpp create mode 100644 editor/gui/editor_run_bar.h diff --git a/doc/classes/EditorScript.xml b/doc/classes/EditorScript.xml index ecaa21efb3c..d77d11857b5 100644 --- a/doc/classes/EditorScript.xml +++ b/doc/classes/EditorScript.xml @@ -48,13 +48,13 @@ [b]Warning:[/b] The implementation of this method is currently disabled. </description> </method> - <method name="get_editor_interface"> + <method name="get_editor_interface" qualifiers="const"> <return type="EditorInterface" /> <description> Returns the [EditorInterface] singleton instance. </description> </method> - <method name="get_scene"> + <method name="get_scene" qualifiers="const"> <return type="Node" /> <description> Returns the Editor's currently active scene. diff --git a/editor/debugger/debug_adapter/debug_adapter_parser.cpp b/editor/debugger/debug_adapter/debug_adapter_parser.cpp index fc806ded5ec..e3686a0217d 100644 --- a/editor/debugger/debug_adapter/debug_adapter_parser.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_parser.cpp @@ -32,9 +32,8 @@ #include "editor/debugger/editor_debugger_node.h" #include "editor/debugger/script_editor_debugger.h" -#include "editor/editor_node.h" -#include "editor/editor_run_native.h" #include "editor/export/editor_export_platform.h" +#include "editor/gui/editor_run_bar.h" #include "editor/plugins/script_editor_plugin.h" void DebugAdapterParser::_bind_methods() { @@ -162,7 +161,7 @@ Dictionary DebugAdapterParser::req_initialize(const Dictionary &p_params) const Dictionary DebugAdapterParser::req_disconnect(const Dictionary &p_params) const { if (!DebugAdapterProtocol::get_singleton()->get_current_peer()->attached) { - EditorNode::get_singleton()->run_stop(); + EditorRunBar::get_singleton()->stop_playing(); } return prepare_success_response(p_params); @@ -188,7 +187,7 @@ Dictionary DebugAdapterParser::req_launch(const Dictionary &p_params) const { String platform_string = args.get("platform", "host"); if (platform_string == "host") { - EditorNode::get_singleton()->run_play(); + EditorRunBar::get_singleton()->play_main_scene(); } else { int device = args.get("device", -1); int idx = -1; @@ -212,8 +211,8 @@ Dictionary DebugAdapterParser::req_launch(const Dictionary &p_params) const { return prepare_error_response(p_params, DAP::ErrorType::UNKNOWN_PLATFORM); } - EditorNode *editor = EditorNode::get_singleton(); - Error err = platform_string == "android" ? editor->run_play_native(device * 10000 + idx) : editor->run_play_native(idx); + EditorRunBar *run_bar = EditorRunBar::get_singleton(); + Error err = platform_string == "android" ? run_bar->start_native_device(device * 10000 + idx) : run_bar->start_native_device(idx); if (err) { if (err == ERR_INVALID_PARAMETER && platform_string == "android") { return prepare_error_response(p_params, DAP::ErrorType::MISSING_DEVICE); @@ -257,13 +256,13 @@ Dictionary DebugAdapterParser::req_restart(const Dictionary &p_params) const { } Dictionary DebugAdapterParser::req_terminate(const Dictionary &p_params) const { - EditorNode::get_singleton()->run_stop(); + EditorRunBar::get_singleton()->stop_playing(); return prepare_success_response(p_params); } Dictionary DebugAdapterParser::req_pause(const Dictionary &p_params) const { - EditorNode::get_singleton()->get_pause_button()->set_pressed(true); + EditorRunBar::get_singleton()->get_pause_button()->set_pressed(true); EditorDebuggerNode::get_singleton()->_paused(); DebugAdapterProtocol::get_singleton()->notify_stopped_paused(); @@ -272,7 +271,7 @@ Dictionary DebugAdapterParser::req_pause(const Dictionary &p_params) const { } Dictionary DebugAdapterParser::req_continue(const Dictionary &p_params) const { - EditorNode::get_singleton()->get_pause_button()->set_pressed(false); + EditorRunBar::get_singleton()->get_pause_button()->set_pressed(false); EditorDebuggerNode::get_singleton()->_paused(); DebugAdapterProtocol::get_singleton()->notify_continued(); diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp index f85163cd6ae..26fb73570e4 100644 --- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp +++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp @@ -38,6 +38,7 @@ #include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_run_bar.h" DebugAdapterProtocol *DebugAdapterProtocol::singleton = nullptr; @@ -812,7 +813,7 @@ Array DebugAdapterProtocol::update_breakpoints(const String &p_path, const Array } void DebugAdapterProtocol::on_debug_paused() { - if (EditorNode::get_singleton()->get_pause_button()->is_pressed()) { + if (EditorRunBar::get_singleton()->get_pause_button()->is_pressed()) { notify_stopped_paused(); } else { notify_continued(); @@ -1017,8 +1018,7 @@ DebugAdapterProtocol::DebugAdapterProtocol() { reset_ids(); - EditorNode *node = EditorNode::get_singleton(); - node->get_pause_button()->connect("pressed", callable_mp(this, &DebugAdapterProtocol::on_debug_paused)); + EditorRunBar::get_singleton()->get_pause_button()->connect("pressed", callable_mp(this, &DebugAdapterProtocol::on_debug_paused)); EditorDebuggerNode *debugger_node = EditorDebuggerNode::get_singleton(); debugger_node->connect("breakpoint_toggled", callable_mp(this, &DebugAdapterProtocol::on_debug_breakpoint_toggled)); diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index a368cacf56a..7083640b247 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -37,6 +37,7 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_run_bar.h" #include "editor/inspector_dock.h" #include "editor/plugins/editor_debugger_plugin.h" #include "editor/plugins/script_editor_plugin.h" @@ -87,8 +88,7 @@ EditorDebuggerNode::EditorDebuggerNode() { remote_scene_tree_timeout = EDITOR_DEF("debugger/remote_scene_tree_refresh_interval", 1.0); inspect_edited_object_timeout = EDITOR_DEF("debugger/remote_inspect_refresh_interval", 0.2); - EditorNode *editor = EditorNode::get_singleton(); - editor->get_pause_button()->connect("pressed", callable_mp(this, &EditorDebuggerNode::_paused)); + EditorRunBar::get_singleton()->get_pause_button()->connect("pressed", callable_mp(this, &EditorDebuggerNode::_paused)); } ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() { @@ -260,7 +260,7 @@ void EditorDebuggerNode::stop(bool p_force) { server->stop(); EditorNode::get_log()->add_message("--- Debugging process stopped ---", EditorLog::MSG_TYPE_EDITOR); - if (EditorNode::get_singleton()->is_movie_maker_enabled()) { + if (EditorRunBar::get_singleton()->is_movie_maker_enabled()) { // Request attention in case the user was doing something else when movie recording is finished. DisplayServer::get_singleton()->window_request_attention(); } @@ -344,7 +344,7 @@ void EditorDebuggerNode::_notification(int p_what) { } } - EditorNode::get_singleton()->get_pause_button()->set_disabled(false); + EditorRunBar::get_singleton()->get_pause_button()->set_disabled(false); // Switch to remote tree view if so desired. auto_switch_remote_scene_tree = (bool)EDITOR_GET("debugger/auto_switch_to_remote_scene_tree"); if (auto_switch_remote_scene_tree) { @@ -413,8 +413,8 @@ void EditorDebuggerNode::_debugger_stopped(int p_id) { } }); if (!found) { - EditorNode::get_singleton()->get_pause_button()->set_pressed(false); - EditorNode::get_singleton()->get_pause_button()->set_disabled(true); + EditorRunBar::get_singleton()->get_pause_button()->set_pressed(false); + EditorRunBar::get_singleton()->get_pause_button()->set_disabled(true); SceneTreeDock::get_singleton()->hide_remote_tree(); SceneTreeDock::get_singleton()->hide_tab_buttons(); EditorNode::get_singleton()->notify_all_debug_sessions_exited(); @@ -509,7 +509,7 @@ void EditorDebuggerNode::_update_debug_options() { } void EditorDebuggerNode::_paused() { - const bool paused = EditorNode::get_singleton()->get_pause_button()->is_pressed(); + const bool paused = EditorRunBar::get_singleton()->get_pause_button()->is_pressed(); _for_all(tabs, [&](ScriptEditorDebugger *dbg) { if (paused && !dbg->is_breaked()) { dbg->debug_break(); @@ -527,7 +527,7 @@ void EditorDebuggerNode::_breaked(bool p_breaked, bool p_can_debug, String p_mes tabs->set_current_tab(p_debugger); } _break_state_changed(); - EditorNode::get_singleton()->get_pause_button()->set_pressed(p_breaked); + EditorRunBar::get_singleton()->get_pause_button()->set_pressed(p_breaked); emit_signal(SNAME("breaked"), p_breaked, p_can_debug); } diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 1421db42ec7..1f9d7541855 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -713,6 +713,16 @@ int EditorData::get_edited_scene() const { return current_edited_scene; } +int EditorData::get_edited_scene_from_path(const String &p_path) const { + for (int i = 0; i < edited_scene.size(); i++) { + if (edited_scene[i].path == p_path) { + return i; + } + } + + return -1; +} + void EditorData::set_edited_scene(int p_idx) { ERR_FAIL_INDEX(p_idx, edited_scene.size()); current_edited_scene = p_idx; diff --git a/editor/editor_data.h b/editor/editor_data.h index 370963074c5..d4a2f534cdb 100644 --- a/editor/editor_data.h +++ b/editor/editor_data.h @@ -196,9 +196,11 @@ public: void set_edited_scene(int p_idx); void set_edited_scene_root(Node *p_root); int get_edited_scene() const; + int get_edited_scene_from_path(const String &p_path) const; Node *get_edited_scene_root(int p_idx = -1); int get_edited_scene_count() const; Vector<EditedScene> get_edited_scenes() const; + String get_scene_title(int p_idx, bool p_always_strip_extension = false) const; String get_scene_path(int p_idx) const; String get_scene_type(int p_idx) const; @@ -211,6 +213,7 @@ public: NodePath get_edited_scene_live_edit_root(); bool check_and_update_scene(int p_idx); void move_edited_scene_to_index(int p_idx); + bool call_build(); void set_scene_as_saved(int p_idx); diff --git a/editor/editor_interface.cpp b/editor/editor_interface.cpp index 99803fd82da..167a5a3dba3 100644 --- a/editor/editor_interface.cpp +++ b/editor/editor_interface.cpp @@ -37,6 +37,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/filesystem_dock.h" +#include "editor/gui/editor_run_bar.h" #include "editor/inspector_dock.h" #include "main/main.h" #include "scene/gui/box_container.h" @@ -317,35 +318,35 @@ void EditorInterface::save_scene_as(const String &p_scene, bool p_with_preview) // Scene playback. void EditorInterface::play_main_scene() { - EditorNode::get_singleton()->run_play(); + EditorRunBar::get_singleton()->play_main_scene(); } void EditorInterface::play_current_scene() { - EditorNode::get_singleton()->run_play_current(); + EditorRunBar::get_singleton()->play_current_scene(); } void EditorInterface::play_custom_scene(const String &scene_path) { - EditorNode::get_singleton()->run_play_custom(scene_path); + EditorRunBar::get_singleton()->play_custom_scene(scene_path); } void EditorInterface::stop_playing_scene() { - EditorNode::get_singleton()->run_stop(); + EditorRunBar::get_singleton()->stop_playing(); } bool EditorInterface::is_playing_scene() const { - return EditorNode::get_singleton()->is_run_playing(); + return EditorRunBar::get_singleton()->is_playing(); } String EditorInterface::get_playing_scene() const { - return EditorNode::get_singleton()->get_run_playing_scene(); + return EditorRunBar::get_singleton()->get_playing_scene(); } void EditorInterface::set_movie_maker_enabled(bool p_enabled) { - EditorNode::get_singleton()->set_movie_maker_enabled(p_enabled); + EditorRunBar::get_singleton()->set_movie_maker_enabled(p_enabled); } bool EditorInterface::is_movie_maker_enabled() const { - return EditorNode::get_singleton()->is_movie_maker_enabled(); + return EditorRunBar::get_singleton()->is_movie_maker_enabled(); } // Base. diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index f2f12857999..fc1ab9ef18c 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -53,6 +53,8 @@ #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "scene/gui/panel_container.h" +#include "scene/gui/popup.h" +#include "scene/gui/rich_text_label.h" #include "scene/gui/split_container.h" #include "scene/gui/tab_bar.h" #include "scene/gui/tab_container.h" @@ -99,6 +101,7 @@ #include "editor/fbx_importer_manager.h" #include "editor/filesystem_dock.h" #include "editor/gui/editor_file_dialog.h" +#include "editor/gui/editor_run_bar.h" #include "editor/gui/editor_title_bar.h" #include "editor/gui/editor_toaster.h" #include "editor/history_dock.h" @@ -802,20 +805,6 @@ void EditorNode::_notification(int p_what) { _build_icon_type_cache(); - if (write_movie_button->is_pressed()) { - launch_pad->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("LaunchPadMovieMode"), SNAME("EditorStyles"))); - write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonPressed"), SNAME("EditorStyles"))); - } else { - launch_pad->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("LaunchPadNormal"), SNAME("EditorStyles"))); - write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles"))); - } - - 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"))); - 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"))); @@ -1194,7 +1183,7 @@ void EditorNode::_vp_resized() { } void EditorNode::_titlebar_resized() { - DisplayServer::get_singleton()->window_set_window_buttons_offset(Vector2i(menu_hb->get_global_position().y + menu_hb->get_size().y / 2, menu_hb->get_global_position().y + menu_hb->get_size().y / 2), DisplayServer::MAIN_WINDOW_ID); + DisplayServer::get_singleton()->window_set_window_buttons_offset(Vector2i(title_bar->get_global_position().y + title_bar->get_size().y / 2, title_bar->get_global_position().y + title_bar->get_size().y / 2), DisplayServer::MAIN_WINDOW_ID); const Vector3i &margin = DisplayServer::get_singleton()->window_get_safe_title_margins(DisplayServer::MAIN_WINDOW_ID); if (left_menu_spacer) { int w = (gui_base->is_layout_rtl()) ? margin.y : margin.x; @@ -1204,8 +1193,8 @@ void EditorNode::_titlebar_resized() { int w = (gui_base->is_layout_rtl()) ? margin.x : margin.y; right_menu_spacer->set_custom_minimum_size(Size2(w, 0)); } - if (menu_hb) { - menu_hb->set_custom_minimum_size(Size2(0, margin.z - menu_hb->get_global_position().y)); + if (title_bar) { + title_bar->set_custom_minimum_size(Size2(0, margin.z - title_bar->get_global_position().y)); } } @@ -1814,7 +1803,7 @@ void EditorNode::_save_scene(String p_file, int idx) { editor_data.apply_changes_in_editors(); List<Ref<AnimatedValuesBackup>> anim_backups; _reset_animation_players(scene, &anim_backups); - _save_default_environment(); + save_default_environment(); _set_scene_metadata(p_file, idx); @@ -1876,7 +1865,7 @@ void EditorNode::_save_scene(String p_file, int idx) { } void EditorNode::save_all_scenes() { - _menu_option_confirm(RUN_STOP, true); + project_run_bar->stop_playing(); _save_all_scenes(); } @@ -1890,11 +1879,33 @@ void EditorNode::save_scene_list(Vector<String> p_scene_filenames) { } } +void EditorNode::save_before_run() { + current_menu_option = FILE_SAVE_AND_RUN; + _menu_option_confirm(FILE_SAVE_AS_SCENE, true); + file->set_title(TTR("Save scene before running...")); +} + +void EditorNode::try_autosave() { + if (!bool(EDITOR_GET("run/auto_save/save_before_running"))) { + return; + } + + if (unsaved_cache) { + Node *scene = editor_data.get_edited_scene_root(); + + if (scene && !scene->get_scene_file_path().is_empty()) { // Only autosave if there is a scene and if it has a path. + _save_scene_with_preview(scene->get_scene_file_path()); + } + } + _menu_option(FILE_SAVE_ALL_SCENES); + editor_data.save_editor_external_data(); +} + void EditorNode::restart_editor() { exiting = true; - if (editor_run.get_status() != EditorRun::STATUS_STOP) { - editor_run.stop(); + if (project_run_bar->is_playing()) { + project_run_bar->stop_playing(); } String to_reopen; @@ -1942,7 +1953,7 @@ void EditorNode::_save_all_scenes() { if (!all_saved) { show_warning(TTR("Could not save one or more scenes!"), TTR("Save All Scenes")); } - _save_default_environment(); + save_default_environment(); } void EditorNode::_mark_unsaved_scenes() { @@ -1982,11 +1993,7 @@ void EditorNode::_dialog_action(String p_file) { ProjectSettings::get_singleton()->save(); // TODO: Would be nice to show the project manager opened with the highlighted field. - if ((bool)pick_main_scene->get_meta("from_native", false)) { - run_native->resume_run_native(); - } else { - _run(false, ""); // Automatically run the project. - } + project_run_bar->play_main_scene((bool)pick_main_scene->get_meta("from_native", false)); } break; case FILE_CLOSE: case SCENE_TAB_CLOSE: @@ -2007,7 +2014,7 @@ void EditorNode::_dialog_action(String p_file) { return; } - _save_default_environment(); + save_default_environment(); _save_scene_with_preview(p_file, scene_idx); _add_to_recent_scenes(p_file); save_layout(); @@ -2021,9 +2028,9 @@ void EditorNode::_dialog_action(String p_file) { case FILE_SAVE_AND_RUN: { if (file->get_file_mode() == EditorFileDialog::FILE_MODE_SAVE_FILE) { - _save_default_environment(); + save_default_environment(); _save_scene_with_preview(p_file); - _run(false, p_file); + project_run_bar->play_custom_scene(p_file); } } break; @@ -2032,13 +2039,9 @@ void EditorNode::_dialog_action(String p_file) { ProjectSettings::get_singleton()->save(); if (file->get_file_mode() == EditorFileDialog::FILE_MODE_SAVE_FILE) { - _save_default_environment(); + save_default_environment(); _save_scene_with_preview(p_file); - if ((bool)pick_main_scene->get_meta("from_native", false)) { - run_native->resume_run_native(); - } else { - _run(false, p_file); - } + project_run_bar->play_main_scene((bool)pick_main_scene->get_meta("from_native", false)); } } break; @@ -2250,7 +2253,7 @@ void EditorNode::push_item(Object *p_object, const String &p_property, bool p_in _edit_current(); } -void EditorNode::_save_default_environment() { +void EditorNode::save_default_environment() { Ref<Environment> fallback = get_tree()->get_root()->get_world_3d()->get_fallback_environment(); if (fallback.is_valid() && fallback->get_path().is_resource_file()) { @@ -2496,157 +2499,6 @@ void EditorNode::_edit_current(bool p_skip_foreign) { InspectorDock::get_singleton()->update(current_obj); } -void EditorNode::_write_movie_toggled(bool p_enabled) { - if (p_enabled) { - launch_pad->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("LaunchPadMovieMode"), SNAME("EditorStyles"))); - write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonPressed"), SNAME("EditorStyles"))); - } else { - launch_pad->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("LaunchPadNormal"), SNAME("EditorStyles"))); - write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles"))); - } -} - -void EditorNode::_run(bool p_current, const String &p_custom) { - if (editor_run.get_status() == EditorRun::STATUS_PLAY) { - play_button->set_pressed(!_playing_edited); - play_scene_button->set_pressed(_playing_edited); - return; - } - - play_button->set_pressed(false); - play_button->set_icon(gui_base->get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); - play_scene_button->set_pressed(false); - play_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons"))); - play_custom_scene_button->set_pressed(false); - play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons"))); - - String write_movie_file; - if (write_movie_button->is_pressed()) { - if (p_current && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->has_meta("movie_file")) { - // If the scene file has a movie_file metadata set, use this as file. Quick workaround if you want to have multiple scenes that write to multiple movies. - write_movie_file = get_tree()->get_edited_scene_root()->get_meta("movie_file"); - } else { - write_movie_file = GLOBAL_GET("editor/movie_writer/movie_file"); - } - if (write_movie_file == String()) { - show_accept(TTR("Movie Maker mode is enabled, but no movie file path has been specified.\nA default movie file path can be specified in the project settings under the Editor > Movie Writer category.\nAlternatively, for running single scenes, a `movie_file` string metadata can be added to the root node,\nspecifying the path to a movie file that will be used when recording that scene."), TTR("OK")); - return; - } - } - - String run_filename; - - if ((p_current && p_custom.is_empty()) || (editor_data.get_edited_scene_root() && !p_custom.is_empty() && p_custom == editor_data.get_edited_scene_root()->get_scene_file_path())) { - Node *scene = editor_data.get_edited_scene_root(); - - if (!scene) { - show_accept(TTR("There is no defined scene to run."), TTR("OK")); - return; - } - - if (scene->get_scene_file_path().is_empty()) { - current_menu_option = FILE_SAVE_AND_RUN; - _menu_option_confirm(FILE_SAVE_AS_SCENE, true); - file->set_title(TTR("Save scene before running...")); - return; - } - - run_filename = scene->get_scene_file_path(); - } else if (!p_custom.is_empty()) { - run_filename = p_custom; - } - - if (run_filename.is_empty()) { - // Evidently, run the scene. - if (!ensure_main_scene(false)) { - return; - } - run_filename = GLOBAL_DEF_BASIC("application/run/main_scene", ""); - } - - if (bool(EDITOR_GET("run/auto_save/save_before_running"))) { - if (unsaved_cache) { - Node *scene = editor_data.get_edited_scene_root(); - - if (scene && !scene->get_scene_file_path().is_empty()) { // Only autosave if there is a scene and if it has a path. - _save_scene_with_preview(scene->get_scene_file_path()); - } - } - _menu_option(FILE_SAVE_ALL_SCENES); - editor_data.save_editor_external_data(); - } - - if (!call_build()) { - return; - } - - if (bool(EDITOR_GET("run/output/always_clear_output_on_play"))) { - log->clear(); - } - - if (bool(EDITOR_GET("run/output/always_open_output_on_play"))) { - make_bottom_panel_item_visible(log); - } - - EditorDebuggerNode::get_singleton()->start(); - Error error = editor_run.run(run_filename, write_movie_file); - if (error != OK) { - EditorDebuggerNode::get_singleton()->stop(); - show_accept(TTR("Could not start subprocess(es)!"), TTR("OK")); - return; - } - - emit_signal(SNAME("play_pressed")); - if (p_current) { - run_current_filename = run_filename; - play_scene_button->set_pressed(true); - play_scene_button->set_icon(gui_base->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); - play_scene_button->set_tooltip_text(TTR("Reload the played scene.")); - } else if (!p_custom.is_empty()) { - run_custom_filename = p_custom; - play_custom_scene_button->set_pressed(true); - play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); - play_custom_scene_button->set_tooltip_text(TTR("Reload the played scene.")); - } else { - play_button->set_pressed(true); - play_button->set_icon(gui_base->get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); - play_button->set_tooltip_text(TTR("Reload the played scene.")); - } - stop_button->set_disabled(false); - - _playing_edited = p_current; -} - -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); - - if (!call_build()) { - return; // Build failed. - } - - EditorDebuggerNode::get_singleton()->start(p_preset->get_platform()->get_debug_protocol()); - emit_signal(SNAME("play_pressed")); - editor_run.run_native_notify(); - } -} - -void EditorNode::_reset_play_buttons() { - play_button->set_pressed(false); - play_button->set_icon(gui_base->get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); - play_button->set_tooltip_text(TTR("Play the project.")); - play_scene_button->set_pressed(false); - play_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons"))); - play_scene_button->set_tooltip_text(TTR("Play the edited scene.")); - play_custom_scene_button->set_pressed(false); - play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons"))); - play_custom_scene_button->set_tooltip_text(TTR("Play a custom scene.")); -} - void EditorNode::_android_build_source_selected(const String &p_file) { export_template_manager->install_android_template_from_file(p_file); } @@ -2813,6 +2665,10 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { _save_all_scenes(); } break; + case FILE_RUN_SCENE: { + project_run_bar->play_current_scene(); + } break; + case FILE_EXPORT_PROJECT: { project_export->popup_export(); } break; @@ -2916,45 +2772,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { EditorUndoRedoManager::get_singleton()->clear_history(false, editor_data.get_current_edited_scene_history_id()); scene_tabs->set_current_tab(cur_idx); - } break; - case RUN_PLAY: { - run_play(); - - } break; - case RUN_PLAY_CUSTOM_SCENE: { - if (run_custom_filename.is_empty() || editor_run.get_status() == EditorRun::STATUS_STOP) { - _menu_option_confirm(RUN_STOP, true); - quick_run->popup_dialog("PackedScene", true); - quick_run->set_title(TTR("Quick Run Scene...")); - play_custom_scene_button->set_pressed(false); - } else { - String last_custom_scene = run_custom_filename; // This is necessary to have a copy of the string. - run_play_custom(last_custom_scene); - } - - } break; - case RUN_STOP: { - if (editor_run.get_status() == EditorRun::STATUS_STOP) { - break; - } - - editor_run.stop(); - run_custom_filename.clear(); - run_current_filename.clear(); - stop_button->set_disabled(true); - _reset_play_buttons(); - - if (bool(EDITOR_GET("run/output/always_close_output_on_stop"))) { - for (int i = 0; i < bottom_panel_items.size(); i++) { - if (bottom_panel_items[i].control == log) { - _bottom_panel_switch(false, i); - break; - } - } - } - EditorDebuggerNode::get_singleton()->stop(); - emit_signal(SNAME("stop_pressed")); - } break; case FILE_SHOW_IN_FILESYSTEM: { @@ -2964,15 +2781,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } } break; - case RUN_PLAY_SCENE: { - if (run_current_filename.is_empty() || editor_run.get_status() == EditorRun::STATUS_STOP) { - run_play_current(); - } else { - String last_current_scene = run_current_filename; // This is necessary to have a copy of the string. - run_play_custom(last_current_scene); - } - - } break; case RUN_SETTINGS: { project_settings_editor->popup_project_settings(); } break; @@ -3296,12 +3104,12 @@ void EditorNode::_discard_changes(const String &p_str) { _proceed_closing_scene_tabs(); } break; case FILE_QUIT: { - _menu_option_confirm(RUN_STOP, true); + project_run_bar->stop_playing(); _exit_editor(EXIT_SUCCESS); } break; case RUN_PROJECT_MANAGER: { - _menu_option_confirm(RUN_STOP, true); + project_run_bar->stop_playing(); _exit_editor(EXIT_SUCCESS); String exec = OS::get_singleton()->get_executable_path(); @@ -3584,14 +3392,6 @@ bool EditorNode::is_addon_plugin_enabled(const String &p_addon) const { return addon_name_to_plugin.has("res://addons/" + p_addon + "/plugin.cfg"); } -void EditorNode::set_movie_maker_enabled(bool p_enabled) { - write_movie_button->set_pressed(p_enabled); -} - -bool EditorNode::is_movie_maker_enabled() const { - return write_movie_button->is_pressed(); -} - void EditorNode::_remove_edited_scene(bool p_change_tab) { int new_index = editor_data.get_edited_scene(); int old_index = new_index; @@ -4260,14 +4060,31 @@ void EditorNode::_quick_opened() { } } -void EditorNode::_quick_run() { - _run(false, quick_run->get_selected()); +void EditorNode::_project_run_started() { + if (bool(EDITOR_GET("run/output/always_clear_output_on_play"))) { + log->clear(); + } + + if (bool(EDITOR_GET("run/output/always_open_output_on_play"))) { + make_bottom_panel_item_visible(log); + } +} + +void EditorNode::_project_run_stopped() { + if (!bool(EDITOR_GET("run/output/always_close_output_on_stop"))) { + return; + } + + for (int i = 0; i < bottom_panel_items.size(); i++) { + if (bottom_panel_items[i].control == log) { + _bottom_panel_switch(false, i); + break; + } + } } void EditorNode::notify_all_debug_sessions_exited() { - _menu_option_confirm(RUN_STOP, false); - stop_button->set_pressed(false); - editor_run.stop(); + project_run_bar->stop_playing(); } void EditorNode::add_io_error(const String &p_error) { @@ -4305,13 +4122,12 @@ bool EditorNode::is_scene_in_use(const String &p_path) { return false; } +OS::ProcessID EditorNode::has_child_process(OS::ProcessID p_pid) const { + return project_run_bar->has_child_process(p_pid); +} + void EditorNode::stop_child_process(OS::ProcessID p_pid) { - if (has_child_process(p_pid)) { - editor_run.stop_child_process(p_pid); - if (!editor_run.get_child_process_count()) { // All children stopped. Closing. - _menu_option_confirm(RUN_STOP, false); - } - } + project_run_bar->stop_child_process(p_pid); } Ref<Script> EditorNode::get_object_custom_type_base(const Object *p_object) const { @@ -5274,45 +5090,6 @@ bool EditorNode::ensure_main_scene(bool p_from_native) { return true; } -Error EditorNode::run_play_native(int p_id) { - return run_native->run_native(p_id); -} - -void EditorNode::run_play() { - _menu_option_confirm(RUN_STOP, true); - _run(false); -} - -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) { - bool is_current = !run_current_filename.is_empty(); - _menu_option_confirm(RUN_STOP, true); - _run(is_current, p_custom); -} - -void EditorNode::run_stop() { - _menu_option_confirm(RUN_STOP, false); -} - -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(); - if (run_filename.is_empty() && is_run_playing()) { - run_filename = GLOBAL_GET("application/run/main_scene"); // Must be the main scene then. - } - - return run_filename; -} - void EditorNode::_immediate_dialog_confirmed() { immediate_dialog_confirmed = true; } @@ -5533,7 +5310,7 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) { if (scene_tabs->get_hovered_tab() >= 0) { scene_tabs_context_menu->add_separator(); scene_tabs_context_menu->add_item(TTR("Show in FileSystem"), FILE_SHOW_IN_FILESYSTEM); - scene_tabs_context_menu->add_item(TTR("Play This Scene"), RUN_PLAY_SCENE); + scene_tabs_context_menu->add_item(TTR("Play This Scene"), FILE_RUN_SCENE); scene_tabs_context_menu->add_separator(); scene_tabs_context_menu->add_shortcut(ED_GET_SHORTCUT("editor/close_scene"), FILE_CLOSE); @@ -6546,8 +6323,6 @@ void EditorNode::_bind_methods() { ClassDB::bind_method(D_METHOD("get_gui_base"), &EditorNode::get_gui_base); - ADD_SIGNAL(MethodInfo("play_pressed")); - ADD_SIGNAL(MethodInfo("stop_pressed")); ADD_SIGNAL(MethodInfo("request_help_search")); ADD_SIGNAL(MethodInfo("script_add_function_request", PropertyInfo(Variant::OBJECT, "obj"), PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::PACKED_STRING_ARRAY, "args"))); ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj"))); @@ -6931,8 +6706,8 @@ EditorNode::EditorNode() { main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, 8); main_vbox->add_theme_constant_override("separation", 8 * EDSCALE); - menu_hb = memnew(EditorTitleBar); - main_vbox->add_child(menu_hb); + title_bar = memnew(EditorTitleBar); + main_vbox->add_child(title_bar); left_l_hsplit = memnew(HSplitContainer); main_vbox->add_child(left_l_hsplit); @@ -7172,11 +6947,11 @@ EditorNode::EditorNode() { // Add spacer to avoid other controls under window minimize/maximize/close buttons (left side). left_menu_spacer = memnew(Control); left_menu_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); - menu_hb->add_child(left_menu_spacer); + title_bar->add_child(left_menu_spacer); } main_menu = memnew(MenuBar); - menu_hb->add_child(main_menu); + title_bar->add_child(main_menu); main_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles"))); main_menu->set_flat(true); @@ -7352,7 +7127,7 @@ EditorNode::EditorNode() { HBoxContainer *left_spacer = memnew(HBoxContainer); left_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); left_spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL); - menu_hb->add_child(left_spacer); + title_bar->add_child(left_spacer); if (can_expand && global_menu) { project_title = memnew(Label); @@ -7367,7 +7142,7 @@ EditorNode::EditorNode() { } main_editor_button_hb = memnew(HBoxContainer); - menu_hb->add_child(main_editor_button_hb); + title_bar->add_child(main_editor_button_hb); // Options are added and handled by DebuggerEditorPlugin. debug_menu = memnew(PopupMenu); @@ -7452,104 +7227,15 @@ EditorNode::EditorNode() { Control *right_spacer = memnew(Control); right_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); right_spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL); - menu_hb->add_child(right_spacer); + title_bar->add_child(right_spacer); - launch_pad = memnew(PanelContainer); - launch_pad->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("LaunchPadNormal"), SNAME("EditorStyles"))); - menu_hb->add_child(launch_pad); - - HBoxContainer *launch_pad_hb = memnew(HBoxContainer); - launch_pad->add_child(launch_pad_hb); - - play_button = memnew(Button); - play_button->set_flat(true); - launch_pad_hb->add_child(play_button); - play_button->set_toggle_mode(true); - play_button->set_focus_mode(Control::FOCUS_NONE); - play_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY)); - play_button->set_tooltip_text(TTR("Run the project's default scene.")); - - ED_SHORTCUT_AND_COMMAND("editor/run_project", TTR("Run Project"), Key::F5); - ED_SHORTCUT_OVERRIDE("editor/run_project", "macos", KeyModifierMask::META | Key::B); - play_button->set_shortcut(ED_GET_SHORTCUT("editor/run_project")); - - pause_button = memnew(Button); - pause_button->set_flat(true); - pause_button->set_toggle_mode(true); - pause_button->set_icon(gui_base->get_theme_icon(SNAME("Pause"), SNAME("EditorIcons"))); - pause_button->set_focus_mode(Control::FOCUS_NONE); - pause_button->set_tooltip_text(TTR("Pause the running project's execution for debugging.")); - pause_button->set_disabled(true); - launch_pad_hb->add_child(pause_button); - - ED_SHORTCUT("editor/pause_running_project", TTR("Pause Running Project"), Key::F7); - ED_SHORTCUT_OVERRIDE("editor/pause_running_project", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::Y); - pause_button->set_shortcut(ED_GET_SHORTCUT("editor/pause_running_project")); - - stop_button = memnew(Button); - stop_button->set_flat(true); - launch_pad_hb->add_child(stop_button); - stop_button->set_focus_mode(Control::FOCUS_NONE); - stop_button->set_icon(gui_base->get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"))); - stop_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_STOP)); - stop_button->set_tooltip_text(TTR("Stop the currently running project.")); - stop_button->set_disabled(true); - - ED_SHORTCUT("editor/stop_running_project", TTR("Stop Running Project"), Key::F8); - ED_SHORTCUT_OVERRIDE("editor/stop_running_project", "macos", KeyModifierMask::META | Key::PERIOD); - stop_button->set_shortcut(ED_GET_SHORTCUT("editor/stop_running_project")); - - run_native = memnew(EditorRunNative); - launch_pad_hb->add_child(run_native); - run_native->connect("native_run", callable_mp(this, &EditorNode::_run_native)); - - play_scene_button = memnew(Button); - play_scene_button->set_flat(true); - launch_pad_hb->add_child(play_scene_button); - play_scene_button->set_toggle_mode(true); - play_scene_button->set_focus_mode(Control::FOCUS_NONE); - play_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_SCENE)); - play_scene_button->set_tooltip_text(TTR("Run the currently edited scene.")); - - ED_SHORTCUT_AND_COMMAND("editor/run_current_scene", TTR("Run Current Scene"), Key::F6); - ED_SHORTCUT_OVERRIDE("editor/run_current_scene", "macos", KeyModifierMask::META | Key::R); - play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_current_scene")); - - play_custom_scene_button = memnew(Button); - play_custom_scene_button->set_flat(true); - launch_pad_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); - play_custom_scene_button->connect("pressed", callable_mp(this, &EditorNode::_menu_option).bind(RUN_PLAY_CUSTOM_SCENE)); - play_custom_scene_button->set_tooltip_text(TTR("Run a specific scene.")); - - _reset_play_buttons(); - - ED_SHORTCUT_AND_COMMAND("editor/run_specific_scene", TTR("Run Specific Scene"), KeyModifierMask::CTRL | KeyModifierMask::SHIFT | Key::F5); - ED_SHORTCUT_OVERRIDE("editor/run_specific_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R); - play_custom_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_specific_scene")); - - write_movie_panel = memnew(PanelContainer); - write_movie_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles"))); - launch_pad_hb->add_child(write_movie_panel); - - write_movie_button = memnew(Button); - write_movie_button->set_flat(true); - write_movie_button->set_toggle_mode(true); - write_movie_panel->add_child(write_movie_button); - write_movie_button->set_pressed(false); - write_movie_button->set_icon(gui_base->get_theme_icon(SNAME("MainMovieWrite"), SNAME("EditorIcons"))); - write_movie_button->set_focus_mode(Control::FOCUS_NONE); - write_movie_button->connect("toggled", callable_mp(this, &EditorNode::_write_movie_toggled)); - write_movie_button->set_tooltip_text(TTR("Enable Movie Maker mode.\nThe project will run at stable FPS and the visual and audio output will be recorded to a video file.")); - - // This button behaves differently, so color it as such. - write_movie_button->add_theme_color_override("icon_normal_color", Color(1, 1, 1, 0.7)); - write_movie_button->add_theme_color_override("icon_pressed_color", Color(0, 0, 0, 0.84)); - write_movie_button->add_theme_color_override("icon_hover_color", Color(1, 1, 1, 0.9)); + project_run_bar = memnew(EditorRunBar); + title_bar->add_child(project_run_bar); + project_run_bar->connect("play_pressed", callable_mp(this, &EditorNode::_project_run_started)); + project_run_bar->connect("stop_pressed", callable_mp(this, &EditorNode::_project_run_stopped)); HBoxContainer *right_menu_hb = memnew(HBoxContainer); - menu_hb->add_child(right_menu_hb); + title_bar->add_child(right_menu_hb); renderer = memnew(OptionButton); renderer->set_visible(true); @@ -7567,7 +7253,7 @@ EditorNode::EditorNode() { // Add spacer to avoid other controls under the window minimize/maximize/close buttons (right side). right_menu_spacer = memnew(Control); right_menu_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS); - menu_hb->add_child(right_menu_spacer); + title_bar->add_child(right_menu_spacer); } String current_renderer = GLOBAL_GET("rendering/renderer/rendering_method"); @@ -8004,10 +7690,6 @@ EditorNode::EditorNode() { gui_base->add_child(quick_open); quick_open->connect("quick_open", callable_mp(this, &EditorNode::_quick_opened)); - quick_run = memnew(EditorQuickOpen); - gui_base->add_child(quick_run); - quick_run->connect("quick_open", callable_mp(this, &EditorNode::_quick_run)); - _update_recent_scenes(); set_process_shortcut_input(true); @@ -8079,14 +7761,14 @@ EditorNode::EditorNode() { screenshot_timer->set_owner(get_owner()); // Adjust spacers to center 2D / 3D / Script buttons. - int max_w = MAX(launch_pad->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu->get_minimum_size().x); + int max_w = MAX(project_run_bar->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu->get_minimum_size().x); left_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - main_menu->get_minimum_size().x), 0)); - right_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - launch_pad->get_minimum_size().x - right_menu_hb->get_minimum_size().x), 0)); + right_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - project_run_bar->get_minimum_size().x - right_menu_hb->get_minimum_size().x), 0)); // Extend menu bar to window title. if (can_expand) { DisplayServer::get_singleton()->window_set_flag(DisplayServer::WINDOW_FLAG_EXTEND_TO_TITLE, true, DisplayServer::MAIN_WINDOW_ID); - menu_hb->set_can_move_window(true); + title_bar->set_can_move_window(true); } String exec = OS::get_singleton()->get_executable_path(); diff --git a/editor/editor_node.h b/editor/editor_node.h index 831e2989f59..0003fee3014 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -35,8 +35,6 @@ #include "editor/editor_data.h" #include "editor/editor_folding.h" #include "editor/editor_plugin.h" -#include "editor/editor_run.h" -#include "editor/export/editor_export.h" typedef void (*EditorNodeInitCallback)(); typedef void (*EditorPluginInitializeCallback)(); @@ -59,6 +57,8 @@ class Node2D; class OptionButton; class Panel; class PanelContainer; +class PopupPanel; +class RichTextLabel; class SubViewport; class TabBar; class TabContainer; @@ -92,6 +92,7 @@ class EditorQuickOpen; class EditorPropertyResource; class EditorResourcePreview; class EditorResourceConversionPlugin; +class EditorRunBar; class EditorRunNative; class EditorSelectionHistory; class EditorSettingsDialog; @@ -162,6 +163,7 @@ private: FILE_SAVE_ALL_SCENES, FILE_SAVE_AND_RUN, FILE_SAVE_AND_RUN_MAIN_SCENE, + FILE_RUN_SCENE, FILE_SHOW_IN_FILESYSTEM, FILE_EXPORT_PROJECT, FILE_EXPORT_MESH_LIBRARY, @@ -188,11 +190,7 @@ private: TOOLS_CUSTOM, RESOURCE_SAVE, RESOURCE_SAVE_AS, - RUN_PLAY, - RUN_STOP, - RUN_PLAY_SCENE, - RUN_PLAY_CUSTOM_SCENE, RUN_SETTINGS, RUN_USER_DATA_FOLDER, RELOAD_CURRENT_PROJECT, @@ -265,7 +263,6 @@ private: EditorData editor_data; EditorFolding editor_folding; - EditorRun editor_run; EditorSelectionHistory editor_history; EditorCommandPalette *command_palette = nullptr; @@ -277,9 +274,7 @@ private: EditorPluginList *editor_plugins_force_over = nullptr; EditorPluginList *editor_plugins_over = nullptr; EditorQuickOpen *quick_open = nullptr; - EditorQuickOpen *quick_run = nullptr; EditorResourcePreview *resource_preview = nullptr; - EditorRunNative *run_native = nullptr; EditorSelection *editor_selection = nullptr; EditorSettingsDialog *editor_settings_dialog = nullptr; HistoryDock *history_dock = nullptr; @@ -342,7 +337,8 @@ private: Label *project_title = nullptr; Control *left_menu_spacer = nullptr; Control *right_menu_spacer = nullptr; - EditorTitleBar *menu_hb = nullptr; + EditorTitleBar *title_bar = nullptr; + EditorRunBar *project_run_bar = nullptr; VBoxContainer *main_screen_vbox = nullptr; MenuBar *main_menu = nullptr; PopupMenu *file_menu = nullptr; @@ -357,15 +353,6 @@ private: Button *search_button = nullptr; TextureProgressBar *audio_vu = nullptr; - PanelContainer *launch_pad = nullptr; - Button *play_button = nullptr; - Button *pause_button = nullptr; - Button *stop_button = nullptr; - Button *play_scene_button = nullptr; - Button *play_custom_scene_button = nullptr; - PanelContainer *write_movie_panel = nullptr; - Button *write_movie_button = nullptr; - Timer *screenshot_timer = nullptr; PluginConfigDialog *plugin_config_dialog = nullptr; @@ -469,7 +456,6 @@ private: bool scene_distraction_free = false; bool script_distraction_free = false; - bool _playing_edited = false; bool changing_scene = false; bool cmdline_export_mode = false; bool convert_old = false; @@ -496,9 +482,6 @@ private: String external_file; String open_navigate; - String run_custom_filename; - String run_current_filename; - DynamicFontImportSettings *fontdata_import_settings = nullptr; SceneImportSettings *scene_import_settings = nullptr; AudioStreamImportSettings *audio_stream_import_settings = nullptr; @@ -600,14 +583,10 @@ private: void _instantiate_request(const Vector<String> &p_files); void _quick_opened(); - void _quick_run(); void _open_command_palette(); - void _write_movie_toggled(bool p_enabled); - - void _run(bool p_current = false, const String &p_custom = ""); - void _run_native(const Ref<EditorExportPreset> &p_preset); - void _reset_play_buttons(); + void _project_run_started(); + void _project_run_stopped(); void _add_to_recent_scenes(const String &p_scene); void _update_recent_scenes(); @@ -687,7 +666,6 @@ private: void _inherit_imported(const String &p_action); void _open_imported(); - void _save_default_environment(); void _update_update_spinner(); void _resources_changed(const Vector<String> &p_resources); @@ -717,7 +695,6 @@ protected: friend class FileSystemDock; static void _bind_methods(); - void _notification(int p_what); int get_current_tab(); @@ -738,7 +715,7 @@ public: static EditorData &get_editor_data() { return singleton->editor_data; } static EditorFolding &get_editor_folding() { return singleton->editor_folding; } - static EditorTitleBar *get_menu_hb() { return singleton->menu_hb; } + static EditorTitleBar *get_title_bar() { return singleton->title_bar; } static VSplitContainer *get_top_split() { return singleton->top_split; } static String adjust_scene_name_casing(const String &root_name); @@ -789,9 +766,6 @@ public: void set_addon_plugin_enabled(const String &p_addon, bool p_enabled, bool p_config_changed = false); bool is_addon_plugin_enabled(const String &p_addon) const; - void set_movie_maker_enabled(bool p_enabled); - bool is_movie_maker_enabled() const; - void edit_node(Node *p_node); void edit_resource(const Ref<Resource> &p_resource); @@ -874,7 +848,7 @@ public: void notify_all_debug_sessions_exited(); - OS::ProcessID has_child_process(OS::ProcessID p_pid) const { return editor_run.has_child_process(p_pid); } + OS::ProcessID has_child_process(OS::ProcessID p_pid) const; void stop_child_process(OS::ProcessID p_pid); Ref<Theme> get_editor_theme() const { return theme; } @@ -908,6 +882,7 @@ public: bool is_scene_in_use(const String &p_path); void save_layout(); + void save_default_environment(); void open_export_template_manager(); @@ -918,8 +893,6 @@ public: bool is_exiting() const { return exiting; } - Button *get_pause_button() { return pause_button; } - Button *add_bottom_panel_item(String p_text, Control *p_item); void make_bottom_panel_item_visible(Control *p_item); void raise_bottom_panel_item(Control *p_item); @@ -937,6 +910,8 @@ public: void save_all_scenes(); void save_scene_list(Vector<String> p_scene_filenames); + void save_before_run(); + void try_autosave(); void restart_editor(); void notify_settings_changed(); @@ -958,14 +933,6 @@ public: Vector<Ref<EditorResourceConversionPlugin>> find_resource_conversion_plugin(const Ref<Resource> &p_for_resource); bool ensure_main_scene(bool p_from_native); - - Error run_play_native(int p_id); - void run_play(); - void run_play_current(); - void run_play_custom(const String &p_custom); - void run_stop(); - bool is_run_playing() const; - String get_run_playing_scene() const; }; struct EditorProgress { diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 8ac5e77d351..442524d5792 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -94,7 +94,7 @@ void EditorPlugin::add_control_to_container(CustomControlContainer p_location, C switch (p_location) { case CONTAINER_TOOLBAR: { - EditorNode::get_menu_hb()->add_child(p_control); + EditorNode::get_title_bar()->add_child(p_control); } break; case CONTAINER_SPATIAL_EDITOR_MENU: { @@ -147,7 +147,7 @@ void EditorPlugin::remove_control_from_container(CustomControlContainer p_locati switch (p_location) { case CONTAINER_TOOLBAR: { - EditorNode::get_menu_hb()->remove_child(p_control); + EditorNode::get_title_bar()->remove_child(p_control); } break; case CONTAINER_SPATIAL_EDITOR_MENU: { diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp index 9bcb25e9c03..1e582992d18 100644 --- a/editor/editor_plugin_settings.cpp +++ b/editor/editor_plugin_settings.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/io/config_file.h" +#include "core/io/dir_access.h" #include "core/io/file_access.h" #include "core/os/main_loop.h" #include "editor/editor_node.h" diff --git a/editor/editor_run.h b/editor/editor_run.h index 68c8742f790..bd6770ae3db 100644 --- a/editor/editor_run.h +++ b/editor/editor_run.h @@ -50,6 +50,7 @@ private: public: Status get_status() const; String get_running_scene() const; + Error run(const String &p_scene, const String &p_write_movie = ""); void run_native_notify() { status = STATUS_PLAY; } void stop(); diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 815d4fab9c4..beccf0f2ec9 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -33,6 +33,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" #include "editor/export/editor_export_platform.h" void EditorRunNative::_notification(int p_what) { @@ -77,7 +78,7 @@ void EditorRunNative::_notification(int p_what) { } } -Error EditorRunNative::run_native(int p_id) { +Error EditorRunNative::start_run_native(int p_id) { if (p_id < 0) { return OK; } @@ -142,7 +143,7 @@ Error EditorRunNative::run_native(int p_id) { } void EditorRunNative::resume_run_native() { - run_native(resume_id); + start_run_native(resume_id); } void EditorRunNative::_bind_methods() { @@ -155,7 +156,7 @@ bool EditorRunNative::is_deploy_debug_remote_enabled() const { EditorRunNative::EditorRunNative() { remote_debug = memnew(MenuButton); - remote_debug->get_popup()->connect("id_pressed", callable_mp(this, &EditorRunNative::run_native)); + remote_debug->get_popup()->connect("id_pressed", callable_mp(this, &EditorRunNative::start_run_native)); remote_debug->set_tooltip_text(TTR("Remote Debug")); remote_debug->set_disabled(true); diff --git a/editor/editor_run_native.h b/editor/editor_run_native.h index 2a5431e54b9..f52a455bb2a 100644 --- a/editor/editor_run_native.h +++ b/editor/editor_run_native.h @@ -52,11 +52,11 @@ protected: void _notification(int p_what); public: - Error run_native(int p_id); - bool is_deploy_debug_remote_enabled() const; - + Error start_run_native(int p_id); void resume_run_native(); + bool is_deploy_debug_remote_enabled() const; + EditorRunNative(); }; diff --git a/editor/editor_run_script.cpp b/editor/editor_script.cpp similarity index 87% rename from editor/editor_run_script.cpp rename to editor/editor_script.cpp index a459943656a..4e8c5ad8b58 100644 --- a/editor/editor_run_script.cpp +++ b/editor/editor_script.cpp @@ -1,5 +1,5 @@ /**************************************************************************/ -/* editor_run_script.cpp */ +/* editor_script.cpp */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,18 +28,18 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#include "editor_run_script.h" +#include "editor_script.h" #include "editor/editor_interface.h" #include "editor/editor_node.h" void EditorScript::add_root_node(Node *p_node) { - if (!editor) { + if (!EditorNode::get_singleton()) { EditorNode::add_io_error("EditorScript::add_root_node: " + TTR("Write your logic in the _run() method.")); return; } - if (editor->get_edited_scene()) { + if (EditorNode::get_singleton()->get_edited_scene()) { EditorNode::add_io_error("EditorScript::add_root_node: " + TTR("There is an edited scene already.")); return; } @@ -47,36 +47,29 @@ void EditorScript::add_root_node(Node *p_node) { //editor->set_edited_scene(p_node); } -EditorInterface *EditorScript::get_editor_interface() { - return EditorInterface::get_singleton(); -} - -Node *EditorScript::get_scene() { - if (!editor) { +Node *EditorScript::get_scene() const { + if (!EditorNode::get_singleton()) { EditorNode::add_io_error("EditorScript::get_scene: " + TTR("Write your logic in the _run() method.")); return nullptr; } - return editor->get_edited_scene(); + return EditorNode::get_singleton()->get_edited_scene(); } -void EditorScript::_run() { +EditorInterface *EditorScript::get_editor_interface() const { + return EditorInterface::get_singleton(); +} + +void EditorScript::run() { if (!GDVIRTUAL_CALL(_run)) { EditorNode::add_io_error(TTR("Couldn't run editor script, did you forget to override the '_run' method?")); } } -void EditorScript::set_editor(EditorNode *p_editor) { - editor = p_editor; -} - void EditorScript::_bind_methods() { ClassDB::bind_method(D_METHOD("add_root_node", "node"), &EditorScript::add_root_node); ClassDB::bind_method(D_METHOD("get_scene"), &EditorScript::get_scene); ClassDB::bind_method(D_METHOD("get_editor_interface"), &EditorScript::get_editor_interface); + GDVIRTUAL_BIND(_run); } - -EditorScript::EditorScript() { - editor = nullptr; -} diff --git a/editor/editor_run_script.h b/editor/editor_script.h similarity index 88% rename from editor/editor_run_script.h rename to editor/editor_script.h index 8284d59110c..d7c813261d3 100644 --- a/editor/editor_run_script.h +++ b/editor/editor_script.h @@ -1,5 +1,5 @@ /**************************************************************************/ -/* editor_run_script.h */ +/* editor_script.h */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef EDITOR_RUN_SCRIPT_H -#define EDITOR_RUN_SCRIPT_H +#ifndef EDITOR_SCRIPT_H +#define EDITOR_SCRIPT_H #include "core/object/gdvirtual.gen.inc" #include "core/object/ref_counted.h" @@ -41,20 +41,19 @@ class EditorNode; class EditorScript : public RefCounted { GDCLASS(EditorScript, RefCounted); - EditorNode *editor = nullptr; - protected: static void _bind_methods(); + GDVIRTUAL0(_run) public: void add_root_node(Node *p_node); - Node *get_scene(); - EditorInterface *get_editor_interface(); - virtual void _run(); + Node *get_scene() const; + EditorInterface *get_editor_interface() const; - void set_editor(EditorNode *p_editor); - EditorScript(); + virtual void run(); + + EditorScript() {} }; -#endif // EDITOR_RUN_SCRIPT_H +#endif // EDITOR_SCRIPT_H diff --git a/editor/editor_settings.h b/editor/editor_settings.h index a21fb9fdfb3..660a9501a27 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -31,14 +31,13 @@ #ifndef EDITOR_SETTINGS_H #define EDITOR_SETTINGS_H +#include "core/input/shortcut.h" #include "core/io/config_file.h" #include "core/io/resource.h" #include "core/os/thread_safe.h" #include "core/templates/rb_set.h" class EditorPlugin; -class InputEvent; -class Shortcut; class EditorSettings : public Resource { GDCLASS(EditorSettings, Resource); diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index 4e173799115..121088f27a5 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -42,6 +42,7 @@ #include "editor/editor_paths.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" #include "editor/plugins/script_editor_plugin.h" #include "editor_export_plugin.h" #include "scene/resources/packed_scene.h" diff --git a/editor/gui/editor_run_bar.cpp b/editor/gui/editor_run_bar.cpp new file mode 100644 index 00000000000..3da4514d998 --- /dev/null +++ b/editor/gui/editor_run_bar.cpp @@ -0,0 +1,442 @@ +/**************************************************************************/ +/* editor_run_bar.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#include "editor_run_bar.h" + +#include "core/config/project_settings.h" +#include "editor/debugger/editor_debugger_node.h" +#include "editor/editor_command_palette.h" +#include "editor/editor_node.h" +#include "editor/editor_quick_open.h" +#include "editor/editor_run_native.h" +#include "editor/editor_settings.h" +#include "scene/gui/box_container.h" +#include "scene/gui/button.h" +#include "scene/gui/panel_container.h" + +EditorRunBar *EditorRunBar::singleton = nullptr; + +void EditorRunBar::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_THEME_CHANGED: { + _update_play_buttons(); + pause_button->set_icon(get_theme_icon(SNAME("Pause"), SNAME("EditorIcons"))); + stop_button->set_icon(get_theme_icon(SNAME("Stop"), SNAME("EditorIcons"))); + + if (is_movie_maker_enabled()) { + main_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadMovieMode"), SNAME("EditorStyles"))); + write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonPressed"), SNAME("EditorStyles"))); + } else { + main_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadNormal"), SNAME("EditorStyles"))); + write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles"))); + } + + write_movie_button->set_icon(get_theme_icon(SNAME("MainMovieWrite"), SNAME("EditorIcons"))); + // This button behaves differently, so color it as such. + write_movie_button->add_theme_color_override("icon_normal_color", Color(1, 1, 1, 0.7)); + write_movie_button->add_theme_color_override("icon_pressed_color", Color(0, 0, 0, 0.84)); + write_movie_button->add_theme_color_override("icon_hover_color", Color(1, 1, 1, 0.9)); + } break; + } +} + +void EditorRunBar::_reset_play_buttons() { + play_button->set_pressed(false); + play_button->set_icon(get_theme_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); + play_button->set_tooltip_text(TTR("Play the project.")); + + play_scene_button->set_pressed(false); + play_scene_button->set_icon(get_theme_icon(SNAME("PlayScene"), SNAME("EditorIcons"))); + play_scene_button->set_tooltip_text(TTR("Play the edited scene.")); + + play_custom_scene_button->set_pressed(false); + play_custom_scene_button->set_icon(get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons"))); + play_custom_scene_button->set_tooltip_text(TTR("Play a custom scene.")); +} + +void EditorRunBar::_update_play_buttons() { + _reset_play_buttons(); + if (!is_playing()) { + return; + } + + Button *active_button = nullptr; + if (current_mode == RUN_CURRENT) { + active_button = play_scene_button; + } else if (current_mode == RUN_CUSTOM) { + active_button = play_custom_scene_button; + } else { + active_button = play_button; + } + + if (active_button) { + active_button->set_pressed(true); + active_button->set_icon(get_theme_icon(SNAME("Reload"), SNAME("EditorIcons"))); + active_button->set_tooltip_text(TTR("Reload the played scene.")); + } +} + +void EditorRunBar::_write_movie_toggled(bool p_enabled) { + if (p_enabled) { + add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadMovieMode"), SNAME("EditorStyles"))); + write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonPressed"), SNAME("EditorStyles"))); + } else { + add_theme_style_override("panel", get_theme_stylebox(SNAME("LaunchPadNormal"), SNAME("EditorStyles"))); + write_movie_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("MovieWriterButtonNormal"), SNAME("EditorStyles"))); + } +} + +void EditorRunBar::_quick_run_selected() { + play_custom_scene(quick_run->get_selected()); +} + +void EditorRunBar::_play_custom_pressed() { + if (editor_run.get_status() == EditorRun::STATUS_STOP || current_mode != RunMode::RUN_CUSTOM) { + stop_playing(); + + quick_run->popup_dialog("PackedScene", true); + quick_run->set_title(TTR("Quick Run Scene...")); + play_custom_scene_button->set_pressed(false); + } else { + // Reload if already running a custom scene. + String last_custom_scene = run_custom_filename; // This is necessary to have a copy of the string. + play_custom_scene(last_custom_scene); + } +} + +void EditorRunBar::_play_current_pressed() { + if (editor_run.get_status() == EditorRun::STATUS_STOP || current_mode != RunMode::RUN_CURRENT) { + play_current_scene(); + } else { + // Reload if already running the current scene. + play_current_scene(true); + } +} + +void EditorRunBar::_run_scene(const String &p_scene_path) { + ERR_FAIL_COND_MSG(current_mode == RUN_CUSTOM && p_scene_path.is_empty(), "Attempting to run a custom scene with an empty path."); + + if (editor_run.get_status() == EditorRun::STATUS_PLAY) { + return; + } + + _reset_play_buttons(); + + String write_movie_file; + if (is_movie_maker_enabled()) { + if (current_mode == RUN_CURRENT) { + Node *scene_root = nullptr; + if (p_scene_path.is_empty()) { + scene_root = get_tree()->get_edited_scene_root(); + } else { + int scene_index = EditorNode::get_editor_data().get_edited_scene_from_path(p_scene_path); + if (scene_index >= 0) { + scene_root = EditorNode::get_editor_data().get_edited_scene_root(scene_index); + } + } + + if (scene_root && scene_root->has_meta("movie_file")) { + // If the scene file has a movie_file metadata set, use this as file. + // Quick workaround if you want to have multiple scenes that write to + // multiple movies. + write_movie_file = scene_root->get_meta("movie_file"); + } + } + + if (write_movie_file.is_empty()) { + write_movie_file = GLOBAL_GET("editor/movie_writer/movie_file"); + } + + if (write_movie_file.is_empty()) { + // TODO: Provide options to diretly resolve the issue with a custom dialog. + EditorNode::get_singleton()->show_accept(TTR("Movie Maker mode is enabled, but no movie file path has been specified.\nA default movie file path can be specified in the project settings under the Editor > Movie Writer category.\nAlternatively, for running single scenes, a `movie_file` string metadata can be added to the root node,\nspecifying the path to a movie file that will be used when recording that scene."), TTR("OK")); + return; + } + } + + String run_filename; + switch (current_mode) { + case RUN_CUSTOM: { + run_filename = p_scene_path; + run_custom_filename = run_filename; + } break; + + case RUN_CURRENT: { + if (!p_scene_path.is_empty()) { + run_filename = p_scene_path; + run_current_filename = run_filename; + break; + } + + Node *scene_root = get_tree()->get_edited_scene_root(); + if (!scene_root) { + EditorNode::get_singleton()->show_accept(TTR("There is no defined scene to run."), TTR("OK")); + return; + } + + if (scene_root->get_scene_file_path().is_empty()) { + EditorNode::get_singleton()->save_before_run(); + return; + } + + run_filename = scene_root->get_scene_file_path(); + run_current_filename = run_filename; + } break; + + default: { + if (!EditorNode::get_singleton()->ensure_main_scene(false)) { + return; + } + + run_filename = GLOBAL_DEF_BASIC("application/run/main_scene", ""); + } break; + } + + EditorNode::get_singleton()->try_autosave(); + if (!EditorNode::get_singleton()->call_build()) { + return; + } + + EditorDebuggerNode::get_singleton()->start(); + Error error = editor_run.run(run_filename, write_movie_file); + if (error != OK) { + EditorDebuggerNode::get_singleton()->stop(); + EditorNode::get_singleton()->show_accept(TTR("Could not start subprocess(es)!"), TTR("OK")); + return; + } + + _update_play_buttons(); + stop_button->set_disabled(false); + + emit_signal(SNAME("play_pressed")); +} + +void EditorRunBar::_run_native(const Ref<EditorExportPreset> &p_preset) { + EditorNode::get_singleton()->try_autosave(); + + if (run_native->is_deploy_debug_remote_enabled()) { + stop_playing(); + + if (!EditorNode::get_singleton()->call_build()) { + return; // Build failed. + } + + EditorDebuggerNode::get_singleton()->start(p_preset->get_platform()->get_debug_protocol()); + emit_signal(SNAME("play_pressed")); + editor_run.run_native_notify(); + } +} + +void EditorRunBar::play_main_scene(bool p_from_native) { + if (p_from_native) { + run_native->resume_run_native(); + } else { + stop_playing(); + + current_mode = RunMode::RUN_MAIN; + _run_scene(); + } +} + +void EditorRunBar::play_current_scene(bool p_reload) { + EditorNode::get_singleton()->save_default_environment(); + stop_playing(); + + current_mode = RunMode::RUN_CURRENT; + if (p_reload) { + String last_current_scene = run_current_filename; // This is necessary to have a copy of the string. + _run_scene(last_current_scene); + } else { + _run_scene(); + } +} + +void EditorRunBar::play_custom_scene(const String &p_custom) { + stop_playing(); + + current_mode = RunMode::RUN_CUSTOM; + _run_scene(p_custom); +} + +void EditorRunBar::stop_playing() { + if (editor_run.get_status() == EditorRun::STATUS_STOP) { + return; + } + + current_mode = RunMode::STOPPED; + editor_run.stop(); + EditorDebuggerNode::get_singleton()->stop(); + + run_custom_filename.clear(); + run_current_filename.clear(); + stop_button->set_pressed(false); + stop_button->set_disabled(true); + _reset_play_buttons(); + + emit_signal(SNAME("stop_pressed")); +} + +bool EditorRunBar::is_playing() const { + EditorRun::Status status = editor_run.get_status(); + return (status == EditorRun::STATUS_PLAY || status == EditorRun::STATUS_PAUSED); +} + +String EditorRunBar::get_playing_scene() const { + String run_filename = editor_run.get_running_scene(); + if (run_filename.is_empty() && is_playing()) { + run_filename = GLOBAL_GET("application/run/main_scene"); // Must be the main scene then. + } + + return run_filename; +} + +Error EditorRunBar::start_native_device(int p_device_id) { + return run_native->start_run_native(p_device_id); +} + +OS::ProcessID EditorRunBar::has_child_process(OS::ProcessID p_pid) const { + return editor_run.has_child_process(p_pid); +} + +void EditorRunBar::stop_child_process(OS::ProcessID p_pid) { + if (!has_child_process(p_pid)) { + return; + } + + editor_run.stop_child_process(p_pid); + if (!editor_run.get_child_process_count()) { // All children stopped. Closing. + stop_playing(); + } +} + +void EditorRunBar::set_movie_maker_enabled(bool p_enabled) { + write_movie_button->set_pressed(p_enabled); +} + +bool EditorRunBar::is_movie_maker_enabled() const { + return write_movie_button->is_pressed(); +} + +void EditorRunBar::_bind_methods() { + ADD_SIGNAL(MethodInfo("play_pressed")); + ADD_SIGNAL(MethodInfo("stop_pressed")); +} + +EditorRunBar::EditorRunBar() { + singleton = this; + + main_panel = memnew(PanelContainer); + add_child(main_panel); + + HBoxContainer *main_hbox = memnew(HBoxContainer); + main_panel->add_child(main_hbox); + + play_button = memnew(Button); + main_hbox->add_child(play_button); + play_button->set_flat(true); + play_button->set_toggle_mode(true); + play_button->set_focus_mode(Control::FOCUS_NONE); + play_button->set_tooltip_text(TTR("Run the project's default scene.")); + play_button->connect("pressed", callable_mp(this, &EditorRunBar::play_main_scene).bind(false)); + + ED_SHORTCUT_AND_COMMAND("editor/run_project", TTR("Run Project"), Key::F5); + ED_SHORTCUT_OVERRIDE("editor/run_project", "macos", KeyModifierMask::META | Key::B); + play_button->set_shortcut(ED_GET_SHORTCUT("editor/run_project")); + + pause_button = memnew(Button); + main_hbox->add_child(pause_button); + pause_button->set_flat(true); + pause_button->set_toggle_mode(true); + pause_button->set_focus_mode(Control::FOCUS_NONE); + pause_button->set_tooltip_text(TTR("Pause the running project's execution for debugging.")); + pause_button->set_disabled(true); + + ED_SHORTCUT("editor/pause_running_project", TTR("Pause Running Project"), Key::F7); + ED_SHORTCUT_OVERRIDE("editor/pause_running_project", "macos", KeyModifierMask::META | KeyModifierMask::CTRL | Key::Y); + pause_button->set_shortcut(ED_GET_SHORTCUT("editor/pause_running_project")); + + stop_button = memnew(Button); + main_hbox->add_child(stop_button); + stop_button->set_flat(true); + stop_button->set_focus_mode(Control::FOCUS_NONE); + stop_button->set_tooltip_text(TTR("Stop the currently running project.")); + stop_button->set_disabled(true); + stop_button->connect("pressed", callable_mp(this, &EditorRunBar::stop_playing)); + + ED_SHORTCUT("editor/stop_running_project", TTR("Stop Running Project"), Key::F8); + ED_SHORTCUT_OVERRIDE("editor/stop_running_project", "macos", KeyModifierMask::META | Key::PERIOD); + stop_button->set_shortcut(ED_GET_SHORTCUT("editor/stop_running_project")); + + run_native = memnew(EditorRunNative); + main_hbox->add_child(run_native); + run_native->connect("native_run", callable_mp(this, &EditorRunBar::_run_native)); + + play_scene_button = memnew(Button); + main_hbox->add_child(play_scene_button); + play_scene_button->set_flat(true); + play_scene_button->set_toggle_mode(true); + play_scene_button->set_focus_mode(Control::FOCUS_NONE); + play_scene_button->set_tooltip_text(TTR("Run the currently edited scene.")); + play_scene_button->connect("pressed", callable_mp(this, &EditorRunBar::_play_current_pressed)); + + ED_SHORTCUT_AND_COMMAND("editor/run_current_scene", TTR("Run Current Scene"), Key::F6); + ED_SHORTCUT_OVERRIDE("editor/run_current_scene", "macos", KeyModifierMask::META | Key::R); + play_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_current_scene")); + + play_custom_scene_button = memnew(Button); + main_hbox->add_child(play_custom_scene_button); + play_custom_scene_button->set_flat(true); + play_custom_scene_button->set_toggle_mode(true); + play_custom_scene_button->set_focus_mode(Control::FOCUS_NONE); + play_custom_scene_button->set_tooltip_text(TTR("Run a specific scene.")); + play_custom_scene_button->connect("pressed", callable_mp(this, &EditorRunBar::_play_custom_pressed)); + + ED_SHORTCUT_AND_COMMAND("editor/run_specific_scene", TTR("Run Specific Scene"), KeyModifierMask::CTRL | KeyModifierMask::SHIFT | Key::F5); + ED_SHORTCUT_OVERRIDE("editor/run_specific_scene", "macos", KeyModifierMask::META | KeyModifierMask::SHIFT | Key::R); + play_custom_scene_button->set_shortcut(ED_GET_SHORTCUT("editor/run_specific_scene")); + + write_movie_panel = memnew(PanelContainer); + main_hbox->add_child(write_movie_panel); + + write_movie_button = memnew(Button); + write_movie_panel->add_child(write_movie_button); + write_movie_button->set_flat(true); + write_movie_button->set_toggle_mode(true); + write_movie_button->set_pressed(false); + write_movie_button->set_focus_mode(Control::FOCUS_NONE); + write_movie_button->set_tooltip_text(TTR("Enable Movie Maker mode.\nThe project will run at stable FPS and the visual and audio output will be recorded to a video file.")); + write_movie_button->connect("toggled", callable_mp(this, &EditorRunBar::_write_movie_toggled)); + + _reset_play_buttons(); + + quick_run = memnew(EditorQuickOpen); + add_child(quick_run); + quick_run->connect("quick_open", callable_mp(this, &EditorRunBar::_quick_run_selected)); +} diff --git a/editor/gui/editor_run_bar.h b/editor/gui/editor_run_bar.h new file mode 100644 index 00000000000..b7e7db2bd6a --- /dev/null +++ b/editor/gui/editor_run_bar.h @@ -0,0 +1,115 @@ +/**************************************************************************/ +/* editor_run_bar.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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. */ +/**************************************************************************/ + +#ifndef EDITOR_RUN_BAR_H +#define EDITOR_RUN_BAR_H + +#include "editor/editor_run.h" +#include "editor/export/editor_export.h" +#include "scene/gui/margin_container.h" + +class Button; +class EditorRunNative; +class EditorQuickOpen; +class PanelContainer; + +class EditorRunBar : public MarginContainer { + GDCLASS(EditorRunBar, MarginContainer); + + static EditorRunBar *singleton; + + enum RunMode { + STOPPED = 0, + RUN_MAIN, + RUN_CURRENT, + RUN_CUSTOM, + }; + + PanelContainer *main_panel = nullptr; + + Button *play_button = nullptr; + Button *pause_button = nullptr; + Button *stop_button = nullptr; + Button *play_scene_button = nullptr; + Button *play_custom_scene_button = nullptr; + + EditorRun editor_run; + EditorRunNative *run_native = nullptr; + + PanelContainer *write_movie_panel = nullptr; + Button *write_movie_button = nullptr; + + EditorQuickOpen *quick_run = nullptr; + + RunMode current_mode = RunMode::STOPPED; + String run_custom_filename; + String run_current_filename; + + void _reset_play_buttons(); + void _update_play_buttons(); + + void _write_movie_toggled(bool p_enabled); + void _quick_run_selected(); + + void _play_current_pressed(); + void _play_custom_pressed(); + + void _run_scene(const String &p_scene_path = ""); + void _run_native(const Ref<EditorExportPreset> &p_preset); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + static EditorRunBar *get_singleton() { return singleton; } + + void play_main_scene(bool p_from_native = false); + void play_current_scene(bool p_reload = false); + void play_custom_scene(const String &p_custom); + + void stop_playing(); + bool is_playing() const; + String get_playing_scene() const; + + Error start_native_device(int p_device_id); + + OS::ProcessID has_child_process(OS::ProcessID p_pid) const; + void stop_child_process(OS::ProcessID p_pid); + + void set_movie_maker_enabled(bool p_enabled); + bool is_movie_maker_enabled() const; + + Button *get_pause_button() { return pause_button; } + + EditorRunBar(); +}; + +#endif // EDITOR_RUN_BAR_H diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index eef1fea11be..f9ab37dce22 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -38,6 +38,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_run_bar.h" #include "editor/gui/editor_toaster.h" #include "editor/gui/editor_zoom_widget.h" #include "editor/plugins/animation_player_editor_plugin.h" @@ -4975,8 +4976,8 @@ CanvasItemEditor::CanvasItemEditor() { SceneTreeDock::get_singleton()->connect("node_created", callable_mp(this, &CanvasItemEditor::_node_created)); SceneTreeDock::get_singleton()->connect("add_node_used", callable_mp(this, &CanvasItemEditor::_reset_create_position)); - EditorNode::get_singleton()->call_deferred(SNAME("connect"), "play_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(true)); - EditorNode::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(false)); + EditorRunBar::get_singleton()->call_deferred(SNAME("connect"), "play_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(true)); + EditorRunBar::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(false)); // A fluid container for all toolbars. HFlowContainer *main_flow = memnew(HFlowContainer); diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index a7ec4bfe33e..ba2d7e67bf0 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -39,6 +39,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "scene/gui/popup_menu.h" CurveEditor::CurveEditor() { _selected_point = -1; diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h index d5cc0cb66a6..ca1a824f0c7 100644 --- a/editor/plugins/curve_editor_plugin.h +++ b/editor/plugins/curve_editor_plugin.h @@ -36,6 +36,8 @@ #include "editor/editor_resource_preview.h" #include "scene/resources/curve.h" +class PopupMenu; + // Edits a y(x) curve class CurveEditor : public Control { GDCLASS(CurveEditor, Control); diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp index 328fe9b9508..2fdebc7c7fe 100644 --- a/editor/plugins/material_editor_plugin.cpp +++ b/editor/plugins/material_editor_plugin.cpp @@ -42,6 +42,7 @@ #include "scene/gui/color_rect.h" #include "scene/gui/subviewport_container.h" #include "scene/gui/texture_button.h" +#include "scene/main/viewport.h" #include "scene/resources/fog_material.h" #include "scene/resources/particle_process_material.h" #include "scene/resources/sky_material.h" diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 7225c1b6581..4fc3c5588d5 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -40,6 +40,7 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/gui/editor_run_bar.h" #include "editor/gui/editor_spin_slider.h" #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/node_3d_editor_gizmos.h" @@ -7487,8 +7488,8 @@ void Node3DEditor::_notification(int p_what) { SceneTreeDock::get_singleton()->get_tree_editor()->connect("node_changed", callable_mp(this, &Node3DEditor::_refresh_menu_icons)); editor_selection->connect("selection_changed", callable_mp(this, &Node3DEditor::_selection_changed)); - EditorNode::get_singleton()->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button).bind(false)); - EditorNode::get_singleton()->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button).bind(true)); + EditorRunBar::get_singleton()->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button).bind(false)); + EditorRunBar::get_singleton()->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button).bind(true)); _update_preview_environment(); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 736826c231c..7be4d76f1e2 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -43,12 +43,13 @@ #include "editor/editor_help_search.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" -#include "editor/editor_run_script.h" #include "editor/editor_scale.h" +#include "editor/editor_script.h" #include "editor/editor_settings.h" #include "editor/filesystem_dock.h" #include "editor/find_in_files.h" #include "editor/gui/editor_file_dialog.h" +#include "editor/gui/editor_run_bar.h" #include "editor/inspector_dock.h" #include "editor/node_dock.h" #include "editor/plugins/shader_editor_plugin.h" @@ -1375,9 +1376,7 @@ void ScriptEditor::_menu_option(int p_option) { Ref<EditorScript> es = memnew(EditorScript); es->set_script(scr); - es->set_editor(EditorNode::get_singleton()); - - es->_run(); + es->run(); } break; case FILE_CLOSE: { if (current->is_unsaved()) { @@ -1592,7 +1591,7 @@ void ScriptEditor::_tab_changed(int p_which) { void ScriptEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - EditorNode::get_singleton()->connect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop)); + EditorRunBar::get_singleton()->connect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop)); EditorNode::get_singleton()->connect("script_add_function_request", callable_mp(this, &ScriptEditor::_add_callback)); EditorNode::get_singleton()->connect("resource_saved", callable_mp(this, &ScriptEditor::_res_saved_callback)); EditorNode::get_singleton()->connect("scene_saved", callable_mp(this, &ScriptEditor::_scene_saved_callback)); @@ -1646,7 +1645,7 @@ void ScriptEditor::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - EditorNode::get_singleton()->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop)); + EditorRunBar::get_singleton()->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop)); } break; case NOTIFICATION_APPLICATION_FOCUS_IN: { diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 9b84c33ff27..63b63090842 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -38,6 +38,7 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "scene/gui/rich_text_label.h" #include "scene/gui/split_container.h" void ConnectionInfoDialog::ok_pressed() { diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 5c159d54ac1..671be80ed3e 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -36,6 +36,7 @@ #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/export/editor_export.h" #include "scene/gui/check_button.h" #include "servers/movie_writer/movie_writer.h" diff --git a/editor/register_editor_types.cpp b/editor/register_editor_types.cpp index 724d435f68e..1f35d63564e 100644 --- a/editor/register_editor_types.cpp +++ b/editor/register_editor_types.cpp @@ -40,11 +40,13 @@ #include "editor/editor_paths.h" #include "editor/editor_resource_picker.h" #include "editor/editor_resource_preview.h" -#include "editor/editor_run_script.h" +#include "editor/editor_script.h" #include "editor/editor_settings.h" #include "editor/editor_translation_parser.h" #include "editor/editor_undo_redo_manager.h" +#include "editor/export/editor_export_platform.h" #include "editor/export/editor_export_platform_pc.h" +#include "editor/export/editor_export_plugin.h" #include "editor/filesystem_dock.h" #include "editor/gui/editor_file_dialog.h" #include "editor/gui/editor_spin_slider.h" @@ -137,7 +139,9 @@ void register_editor_types() { GDREGISTER_CLASS(EditorExportPlugin); GDREGISTER_ABSTRACT_CLASS(EditorExportPlatform); GDREGISTER_ABSTRACT_CLASS(EditorExportPlatformPC); + register_exporter_types(); + GDREGISTER_CLASS(EditorResourceConversionPlugin); GDREGISTER_CLASS(EditorSceneFormatImporter); GDREGISTER_CLASS(EditorScenePostImportPlugin); diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp index 5f6ec5904cf..554fe5a4221 100644 --- a/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp +++ b/modules/gltf/editor/editor_scene_exporter_gltf_plugin.cpp @@ -37,6 +37,7 @@ #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/gui/editor_file_dialog.h" +#include "scene/gui/popup_menu.h" String SceneExporterGLTFPlugin::get_name() const { return "ConvertGLTF2"; diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp index ad9ab66cc91..34b9974d102 100644 --- a/modules/mono/editor/editor_internal_calls.cpp +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -42,6 +42,7 @@ #include "editor/editor_paths.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/gui/editor_run_bar.h" #include "editor/plugins/script_editor_plugin.h" #include "main/main.h" @@ -156,11 +157,11 @@ void godot_icall_Internal_EditorNodeShowScriptScreen() { } void godot_icall_Internal_EditorRunPlay() { - EditorNode::get_singleton()->run_play(); + EditorRunBar::get_singleton()->play_main_scene(); } void godot_icall_Internal_EditorRunStop() { - EditorNode::get_singleton()->run_stop(); + EditorRunBar::get_singleton()->stop_playing(); } void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts() { diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp index b6d70048e36..92ba4dba4e7 100644 --- a/platform/ios/export/export_plugin.cpp +++ b/platform/ios/export/export_plugin.cpp @@ -33,6 +33,7 @@ #include "core/string/translation.h" #include "editor/editor_node.h" #include "editor/editor_scale.h" +#include "editor/export/editor_export.h" #include "platform/ios/logo_svg.gen.h" #include "modules/modules_enabled.gen.h" // For svg. diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp index 317c6575b33..9544cc761df 100644 --- a/platform/linuxbsd/export/export_plugin.cpp +++ b/platform/linuxbsd/export/export_plugin.cpp @@ -34,6 +34,7 @@ #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_scale.h" +#include "editor/export/editor_export.h" #include "platform/linuxbsd/logo_svg.gen.h" #include "platform/linuxbsd/run_icon_svg.gen.h" diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 85964c53e6c..c20e3316a5a 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -31,6 +31,7 @@ #include "export.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" #include "export_plugin.h" void register_uwp_exporter_types() { diff --git a/platform/web/export/export.cpp b/platform/web/export/export.cpp index 54d9774da58..80c29024a84 100644 --- a/platform/web/export/export.cpp +++ b/platform/web/export/export.cpp @@ -31,6 +31,7 @@ #include "export.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" #include "export_plugin.h" void register_web_exporter_types() { diff --git a/platform/web/export/export_plugin.cpp b/platform/web/export/export_plugin.cpp index 7a62cd2a4ad..876efdf8643 100644 --- a/platform/web/export/export_plugin.cpp +++ b/platform/web/export/export_plugin.cpp @@ -33,6 +33,7 @@ #include "core/config/project_settings.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" +#include "editor/export/editor_export.h" #include "platform/web/logo_svg.gen.h" #include "platform/web/run_icon_svg.gen.h" diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp index 05b25eae031..1863a3083b7 100644 --- a/platform/windows/export/export_plugin.cpp +++ b/platform/windows/export/export_plugin.cpp @@ -35,6 +35,7 @@ #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_scale.h" +#include "editor/export/editor_export.h" #include "platform/windows/logo_svg.gen.h" #include "platform/windows/run_icon_svg.gen.h"