|
@@ -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"
|
|
@@ -805,20 +808,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")));
|
|
@@ -1197,7 +1186,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;
|
|
@@ -1207,8 +1196,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));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1817,7 +1806,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);
|
|
|
|
|
@@ -1879,7 +1868,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();
|
|
|
}
|
|
|
|
|
@@ -1893,11 +1882,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;
|
|
@@ -1945,7 +1956,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() {
|
|
@@ -1985,11 +1996,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:
|
|
@@ -2010,7 +2017,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();
|
|
@@ -2024,9 +2031,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;
|
|
|
|
|
@@ -2035,13 +2042,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;
|
|
|
|
|
@@ -2253,7 +2256,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()) {
|
|
@@ -2499,157 +2502,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);
|
|
|
}
|
|
@@ -2816,6 +2668,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;
|
|
@@ -2919,45 +2775,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: {
|
|
@@ -2967,15 +2784,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;
|
|
@@ -3299,12 +3107,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();
|
|
|
|
|
@@ -3587,14 +3395,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;
|
|
@@ -4263,14 +4063,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) {
|
|
@@ -4308,13 +4125,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 {
|
|
@@ -5277,45 +5093,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;
|
|
|
}
|
|
@@ -5536,7 +5313,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);
|
|
@@ -6549,8 +6326,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")));
|
|
@@ -6934,8 +6709,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);
|
|
@@ -7175,11 +6950,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);
|
|
@@ -7355,7 +7130,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);
|
|
@@ -7370,7 +7145,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);
|
|
@@ -7455,104 +7230,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);
|
|
|
-
|
|
|
- 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));
|
|
|
+ title_bar->add_child(right_spacer);
|
|
|
+
|
|
|
+ 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);
|
|
@@ -7570,7 +7256,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");
|
|
@@ -8007,10 +7693,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);
|
|
@@ -8082,14 +7764,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();
|