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.
This commit is contained in:
Yuri Sizov 2023-04-12 21:02:28 +02:00
parent 27253f3eb2
commit 8a74d8438f
37 changed files with 771 additions and 538 deletions

View File

@ -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.

View File

@ -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();

View File

@ -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));

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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();

View File

@ -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 {

View File

@ -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: {

View File

@ -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"

View File

@ -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();

View File

@ -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);

View File

@ -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();
};

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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));
}

115
editor/gui/editor_run_bar.h Normal file
View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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"

View File

@ -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();

View File

@ -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: {

View File

@ -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() {

View File

@ -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"

View File

@ -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);

View File

@ -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";

View File

@ -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() {

View File

@ -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.

View File

@ -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"

View File

@ -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() {

View File

@ -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() {

View File

@ -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"

View File

@ -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"