summaryrefslogtreecommitdiff
path: root/editor/editor_node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/editor_node.cpp')
-rw-r--r--editor/editor_node.cpp302
1 files changed, 186 insertions, 116 deletions
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 3853d18e17..8ed6cec779 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -135,6 +135,8 @@ void EditorNode::_update_scene_tabs() {
bool show_rb = EditorSettings::get_singleton()->get("interface/scene_tabs/show_script_button");
+ OS::get_singleton()->global_menu_clear("_dock");
+
scene_tabs->clear_tabs();
Ref<Texture> script_icon = gui_base->get_icon("Script", "EditorIcons");
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
@@ -149,11 +151,16 @@ void EditorNode::_update_scene_tabs() {
bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0;
scene_tabs->add_tab(editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), icon);
+ OS::get_singleton()->global_menu_add_item("_dock", editor_data.get_scene_title(i) + (unsaved ? "(*)" : ""), GLOBAL_SCENE, i);
+
if (show_rb && editor_data.get_scene_root_script(i).is_valid()) {
scene_tabs->set_tab_right_button(i, script_icon);
}
}
+ OS::get_singleton()->global_menu_add_separator("_dock");
+ OS::get_singleton()->global_menu_add_item("_dock", TTR("New Window"), GLOBAL_NEW_WINDOW, Variant());
+
scene_tabs->set_current_tab(editor_data.get_edited_scene());
if (scene_tabs->get_offset_buttons_visible()) {
@@ -290,6 +297,7 @@ void EditorNode::_notification(int p_what) {
get_tree()->get_root()->set_as_audio_listener_2d(false);
get_tree()->set_auto_accept_quit(false);
get_tree()->connect("files_dropped", this, "_dropped_files");
+ get_tree()->connect("global_menu_action", this, "_global_menu_action");
/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
} break;
@@ -334,6 +342,11 @@ void EditorNode::_notification(int p_what) {
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec")));
} break;
+ case MainLoop::NOTIFICATION_WM_ABOUT: {
+
+ show_about();
+ } break;
+
case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: {
_menu_option_confirm(FILE_QUIT, false);
@@ -397,6 +410,8 @@ void EditorNode::_notification(int p_what) {
distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons"));
scene_tab_add->set_icon(gui_base->get_icon("Add", "EditorIcons"));
+ bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons"));
+
// clear_button->set_icon(gui_base->get_icon("Close", "EditorIcons")); don't have access to that node. needs to become a class property
dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons"));
dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons"));
@@ -1574,6 +1589,7 @@ void EditorNode::push_item(Object *p_object, const String &p_property, bool p_in
get_inspector()->edit(NULL);
node_dock->set_node(NULL);
scene_tree_dock->set_selected(NULL);
+ inspector_dock->update(NULL);
return;
}
@@ -1662,9 +1678,10 @@ void EditorNode::_edit_current() {
Resource *current_res = Object::cast_to<Resource>(current_obj);
ERR_FAIL_COND(!current_res);
- scene_tree_dock->set_selected(NULL);
get_inspector()->edit(current_res);
+ scene_tree_dock->set_selected(NULL);
node_dock->set_node(NULL);
+ inspector_dock->update(NULL);
EditorNode::get_singleton()->get_import_dock()->set_edit_path(current_res->get_path());
int subr_idx = current_res->get_path().find("::");
@@ -1691,9 +1708,11 @@ void EditorNode::_edit_current() {
if (current_node->is_inside_tree()) {
node_dock->set_node(current_node);
scene_tree_dock->set_selected(current_node);
+ inspector_dock->update(current_node);
} else {
node_dock->set_node(NULL);
scene_tree_dock->set_selected(NULL);
+ inspector_dock->update(NULL);
}
if (get_edited_scene() && get_edited_scene()->get_filename() != String()) {
@@ -1713,6 +1732,8 @@ void EditorNode::_edit_current() {
get_inspector()->edit(current_obj);
node_dock->set_node(NULL);
+ scene_tree_dock->set_selected(NULL);
+ inspector_dock->update(NULL);
}
inspector_dock->set_warning(editable_warning);
@@ -1913,10 +1934,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
switch (p_option) {
case FILE_NEW_SCENE: {
- int idx = editor_data.add_edited_scene(-1);
- _scene_tab_changed(idx);
- editor_data.clear_editor_states();
- _update_scene_tabs();
+ new_scene();
} break;
case FILE_NEW_INHERITED_SCENE:
@@ -1963,6 +1981,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
break;
opening_prev = true;
open_request(previous_scenes.back()->get());
+ previous_scenes.pop_back();
} break;
case FILE_CLOSE_OTHERS:
@@ -2613,11 +2632,8 @@ void EditorNode::_exit_editor() {
resource_preview->stop(); //stop early to avoid crashes
_save_docks();
- // Dim the editor window while it's quitting to make it clearer that it's busy.
- // No transition is applied, as the effect needs to be visible immediately
- float c = 0.4f;
- Color dim_color = Color(c, c, c);
- gui_base->set_modulate(dim_color);
+ // Dim the editor window while it's quitting to make it clearer that it's busy
+ dim_editor(true, true);
get_tree()->quit();
}
@@ -2634,6 +2650,14 @@ void EditorNode::_discard_changes(const String &p_str) {
case FILE_CLOSE_ALL:
case SCENE_TAB_CLOSE: {
+ Node *scene = editor_data.get_edited_scene_root(tab_closing);
+ if (scene != NULL) {
+ String scene_filename = scene->get_filename();
+ if (scene_filename != "") {
+ previous_scenes.push_back(scene_filename);
+ }
+ }
+
_remove_scene(tab_closing);
_update_scene_tabs();
@@ -2699,6 +2723,21 @@ void EditorNode::_update_debug_options() {
if (check_reload_scripts) _menu_option_confirm(RUN_RELOAD_SCRIPTS, true);
}
+void EditorNode::_update_file_menu_opened() {
+
+ Ref<ShortCut> close_scene_sc = ED_GET_SHORTCUT("editor/close_scene");
+ close_scene_sc->set_name(TTR("Close Scene"));
+ Ref<ShortCut> reopen_closed_scene_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
+ reopen_closed_scene_sc->set_name(TTR("Reopen Closed Scene"));
+ PopupMenu *pop = file_menu->get_popup();
+ pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), previous_scenes.empty());
+}
+
+void EditorNode::_update_file_menu_closed() {
+ PopupMenu *pop = file_menu->get_popup();
+ pop->set_item_disabled(pop->get_item_index(FILE_OPEN_PREV), false);
+}
+
Control *EditorNode::get_viewport() {
return viewport;
@@ -2751,6 +2790,19 @@ void EditorNode::_editor_select(int p_which) {
}
}
+void EditorNode::select_editor_by_name(const String &p_name) {
+ ERR_FAIL_COND(p_name == "");
+
+ for (int i = 0; i < main_editor_buttons.size(); i++) {
+ if (main_editor_buttons[i]->get_text() == p_name) {
+ _editor_select(i);
+ return;
+ }
+ }
+
+ ERR_FAIL_MSG("The editor name '" + p_name + "' was not found.");
+}
+
void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed) {
if (p_editor->has_main_screen()) {
@@ -2874,36 +2926,39 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled,
return;
}
- String path = cf->get_value("plugin", "script");
- path = String("res://addons").plus_file(p_addon).plus_file(path);
+ String script_path = cf->get_value("plugin", "script");
+ Ref<Script> script; // We need to save it for creating "ep" below.
- Ref<Script> script = ResourceLoader::load(path);
+ // Only try to load the script if it has a name. Else, the plugin has no init script.
+ if (script_path.length() > 0) {
+ script_path = String("res://addons").plus_file(p_addon).plus_file(script_path);
+ script = ResourceLoader::load(script_path);
- if (script.is_null()) {
- show_warning(vformat(TTR("Unable to load addon script from path: '%s'."), path));
- return;
- }
+ if (script.is_null()) {
+ show_warning(vformat(TTR("Unable to load addon script from path: '%s'."), script_path));
+ return;
+ }
- //errors in the script cause the base_type to be ""
- if (String(script->get_instance_base_type()) == "") {
- show_warning(vformat(TTR("Unable to load addon script from path: '%s' There seems to be an error in the code, please check the syntax."), path));
- return;
- }
+ // Errors in the script cause the base_type to be an empty string.
+ if (String(script->get_instance_base_type()) == "") {
+ show_warning(vformat(TTR("Unable to load addon script from path: '%s' There seems to be an error in the code, please check the syntax."), script_path));
+ return;
+ }
- //could check inheritance..
- if (String(script->get_instance_base_type()) != "EditorPlugin") {
- show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), path));
- return;
- }
+ // Plugin init scripts must inherit from EditorPlugin and be tools.
+ if (String(script->get_instance_base_type()) != "EditorPlugin") {
+ show_warning(vformat(TTR("Unable to load addon script from path: '%s' Base type is not EditorPlugin."), script_path));
+ return;
+ }
- if (!script->is_tool()) {
- show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), path));
- return;
+ if (!script->is_tool()) {
+ show_warning(vformat(TTR("Unable to load addon script from path: '%s' Script is not in tool mode."), script_path));
+ return;
+ }
}
EditorPlugin *ep = memnew(EditorPlugin);
ep->set_script(script.get_ref_ptr());
- ep->set_dir_cache(p_addon);
plugin_addons[p_addon] = ep;
add_editor_plugin(ep, p_config_changed);
@@ -3111,6 +3166,14 @@ void EditorNode::fix_dependencies(const String &p_for_file) {
dependency_fixer->edit(p_for_file);
}
+int EditorNode::new_scene() {
+ int idx = editor_data.add_edited_scene(-1);
+ _scene_tab_changed(idx);
+ editor_data.clear_editor_states();
+ _update_scene_tabs();
+ return idx;
+}
+
Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported) {
if (!is_inside_tree()) {
@@ -3271,6 +3334,13 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
void EditorNode::open_request(const String &p_path) {
+ if (!opening_prev) {
+ List<String>::Element *prev_scene = previous_scenes.find(p_path);
+ if (prev_scene != NULL) {
+ prev_scene->erase();
+ }
+ }
+
load_scene(p_path); // as it will be opened in separate tab
}
@@ -3762,9 +3832,13 @@ void EditorNode::show_accept(const String &p_text, const String &p_title) {
void EditorNode::show_warning(const String &p_text, const String &p_title) {
- warning->set_text(p_text);
- warning->set_title(p_title);
- warning->popup_centered_minsize();
+ if (warning->is_inside_tree()) {
+ warning->set_text(p_text);
+ warning->set_title(p_title);
+ warning->popup_centered_minsize();
+ } else {
+ WARN_PRINTS(p_title + " " + p_text);
+ }
}
void EditorNode::_copy_warning(const String &p_str) {
@@ -4308,6 +4382,15 @@ bool EditorNode::ensure_main_scene(bool p_from_native) {
return true;
}
+void EditorNode::run_play() {
+ _menu_option_confirm(RUN_STOP, true);
+ _run(false);
+}
+
+void EditorNode::run_stop() {
+ _menu_option_confirm(RUN_STOP, false);
+}
+
int EditorNode::get_current_tab() {
return scene_tabs->get_current_tab();
}
@@ -4471,8 +4554,17 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
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_separator();
- scene_tabs_context_menu->add_item(TTR("Close Tab"), FILE_CLOSE);
+ Ref<ShortCut> close_tab_sc = ED_GET_SHORTCUT("editor/close_scene");
+ close_tab_sc->set_name(TTR("Close Tab"));
+ scene_tabs_context_menu->add_shortcut(close_tab_sc, FILE_CLOSE);
+ Ref<ShortCut> undo_close_tab_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
+ undo_close_tab_sc->set_name(TTR("Undo Close Tab"));
+ scene_tabs_context_menu->add_shortcut(undo_close_tab_sc, FILE_OPEN_PREV);
+ if (previous_scenes.empty()) {
+ scene_tabs_context_menu->set_item_disabled(scene_tabs_context_menu->get_item_index(FILE_OPEN_PREV), true);
+ }
scene_tabs_context_menu->add_item(TTR("Close Other Tabs"), FILE_CLOSE_OTHERS);
scene_tabs_context_menu->add_item(TTR("Close Tabs to the Right"), FILE_CLOSE_RIGHT);
scene_tabs_context_menu->add_item(TTR("Close All Tabs"), FILE_CLOSE_ALL);
@@ -4716,8 +4808,7 @@ void EditorNode::remove_control_from_dock(Control *p_control) {
}
}
- ERR_EXPLAIN("Control was not in dock");
- ERR_FAIL_COND(!dock);
+ ERR_FAIL_COND_MSG(!dock, "Control was not in dock.");
dock->remove_child(p_control);
_update_dock_slots_visibility();
@@ -4855,6 +4946,23 @@ void EditorNode::remove_tool_menu_item(const String &p_name) {
}
}
+void EditorNode::_global_menu_action(const Variant &p_id, const Variant &p_meta) {
+
+ int id = (int)p_id;
+ if (id == GLOBAL_NEW_WINDOW) {
+ if (OS::get_singleton()->get_main_loop()) {
+ List<String> args;
+ String exec = OS::get_singleton()->get_executable_path();
+
+ OS::ProcessID pid = 0;
+ OS::get_singleton()->execute(exec, args, false, &pid);
+ }
+ } else if (id == GLOBAL_SCENE) {
+ int idx = (int)p_meta;
+ scene_tabs->set_current_tab(idx);
+ }
+}
+
void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) {
String to_path = ProjectSettings::get_singleton()->globalize_path(get_filesystem_dock()->get_selected_path());
@@ -5022,46 +5130,12 @@ void EditorNode::_open_imported() {
load_scene(open_import_request, true, false, true, true);
}
-void EditorNode::dim_editor(bool p_dimming) {
- static int dim_count = 0;
- bool dim_ui = EditorSettings::get_singleton()->get("interface/editor/dim_editor_on_dialog_popup");
- if (p_dimming) {
- if (dim_ui && dim_count == 0) {
- _start_dimming(true);
- }
- dim_count++;
+void EditorNode::dim_editor(bool p_dimming, bool p_force_dim) {
+ // Dimming can be forced regardless of the editor setting, which is useful when quitting the editor
+ if ((p_force_dim || EditorSettings::get_singleton()->get("interface/editor/dim_editor_on_dialog_popup")) && p_dimming) {
+ gui_base->set_modulate(Color(0.5, 0.5, 0.5));
} else {
- if (dim_count == 1) {
- _start_dimming(false);
- }
- if (dim_count > 0) {
- dim_count--;
- } else {
- ERR_PRINT("Undimmed before dimming!");
- }
- }
-}
-
-void EditorNode::_start_dimming(bool p_dimming) {
- _dimming = p_dimming;
- _dim_time = 0.0f;
- _dim_timer->start();
-}
-
-void EditorNode::_dim_timeout() {
-
- _dim_time += _dim_timer->get_wait_time();
- float wait_time = 0.08f;
- float c = 0.4f;
-
- Color base = _dimming ? Color(1, 1, 1) : Color(c, c, c);
- Color final = _dimming ? Color(c, c, c) : Color(1, 1, 1);
-
- if (_dim_time + _dim_timer->get_wait_time() >= wait_time) {
- gui_base->set_modulate(final);
- _dim_timer->stop();
- } else {
- gui_base->set_modulate(base.linear_interpolate(final, _dim_time / wait_time));
+ gui_base->set_modulate(Color(1, 1, 1));
}
}
@@ -5093,18 +5167,12 @@ Vector<Ref<EditorResourceConversionPlugin> > EditorNode::find_resource_conversio
void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) {
- if (p_pressed) {
- top_split->hide();
- bottom_panel_raise->set_icon(gui_base->get_icon("ShrinkBottomDock", "EditorIcons"));
- } else {
- top_split->show();
- bottom_panel_raise->set_icon(gui_base->get_icon("ExpandBottomDock", "EditorIcons"));
- }
+ top_split->set_visible(!p_pressed);
}
void EditorNode::_update_video_driver_color() {
- //todo probably should de-harcode this and add to editor settings
+ // TODO: Probably should de-hardcode this and add to editor settings.
if (video_driver->get_text() == "GLES2") {
video_driver->add_color_override("font_color", Color::hex(0x5586a4ff));
} else if (video_driver->get_text() == "GLES3") {
@@ -5189,6 +5257,8 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("_node_renamed", &EditorNode::_node_renamed);
ClassDB::bind_method("edit_node", &EditorNode::edit_node);
ClassDB::bind_method("_unhandled_input", &EditorNode::_unhandled_input);
+ ClassDB::bind_method("_update_file_menu_opened", &EditorNode::_update_file_menu_opened);
+ ClassDB::bind_method("_update_file_menu_closed", &EditorNode::_update_file_menu_closed);
ClassDB::bind_method(D_METHOD("push_item", "object", "property", "inspector_only"), &EditorNode::push_item, DEFVAL(""), DEFVAL(false));
@@ -5240,6 +5310,7 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("_clear_undo_history", &EditorNode::_clear_undo_history);
ClassDB::bind_method("_dropped_files", &EditorNode::_dropped_files);
+ ClassDB::bind_method(D_METHOD("_global_menu_action"), &EditorNode::_global_menu_action, DEFVAL(Variant()));
ClassDB::bind_method("_toggle_distraction_free_mode", &EditorNode::_toggle_distraction_free_mode);
ClassDB::bind_method("edit_item_resource", &EditorNode::edit_item_resource);
@@ -5248,7 +5319,6 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("_open_imported"), &EditorNode::_open_imported);
ClassDB::bind_method(D_METHOD("_inherit_imported"), &EditorNode::_inherit_imported);
- ClassDB::bind_method(D_METHOD("_dim_timeout"), &EditorNode::_dim_timeout);
ClassDB::bind_method("_copy_warning", &EditorNode::_copy_warning);
@@ -5433,6 +5503,9 @@ EditorNode::EditorNode() {
}
}
+ // Define a minimum window size to prevent UI elements from overlapping or being cut off
+ OS::get_singleton()->set_min_window_size(Size2(1024, 600) * EDSCALE);
+
ResourceLoader::set_abort_on_missing_resources(false);
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
@@ -5707,6 +5780,7 @@ EditorNode::EditorNode() {
dock_slot[i]->set_drag_to_rearrange_enabled(true);
dock_slot[i]->set_tabs_rearrange_group(1);
dock_slot[i]->connect("tab_changed", this, "_dock_tab_changed");
+ dock_slot[i]->set_use_hidden_tabs_for_min_size(true);
}
dock_drag_timer = memnew(Timer);
@@ -5865,23 +5939,25 @@ EditorNode::EditorNode() {
PopupMenu *p;
file_menu->set_tooltip(TTR("Operations with scene files."));
+
p = file_menu->get_popup();
p->set_hide_on_window_lose_focus(true);
p->add_shortcut(ED_SHORTCUT("editor/new_scene", TTR("New Scene")), FILE_NEW_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/new_inherited_scene", TTR("New Inherited Scene...")), FILE_NEW_INHERITED_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/open_scene", TTR("Open Scene..."), KEY_MASK_CMD + KEY_O), FILE_OPEN_SCENE);
+ p->add_shortcut(ED_SHORTCUT("editor/reopen_closed_scene", TTR("Reopen Closed Scene"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_T), FILE_OPEN_PREV);
+ p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT);
+
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/save_scene", TTR("Save Scene"), KEY_MASK_CMD + KEY_S), FILE_SAVE_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/save_scene_as", TTR("Save Scene As..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_AS_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/save_all_scenes", TTR("Save All Scenes"), KEY_MASK_ALT + KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_ALL_SCENES);
- p->add_separator();
- p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE);
- p->add_separator();
- p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT);
+
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/quick_open", TTR("Quick Open..."), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_O), FILE_QUICK_OPEN);
p->add_shortcut(ED_SHORTCUT("editor/quick_open_scene", TTR("Quick Open Scene..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/quick_open_script", TTR("Quick Open Script..."), KEY_MASK_ALT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCRIPT);
+
p->add_separator();
PopupMenu *pm_export = memnew(PopupMenu);
pm_export->set_name("Export");
@@ -5894,8 +5970,10 @@ EditorNode::EditorNode() {
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true);
p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Z), EDIT_REDO, true);
+
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/revert_scene", TTR("Revert Scene")), EDIT_REVERT);
+ p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE);
recent_scenes = memnew(PopupMenu);
recent_scenes->set_name("RecentScenes");
@@ -5903,7 +5981,7 @@ EditorNode::EditorNode() {
recent_scenes->connect("id_pressed", this, "_open_recent_scene");
p->add_separator();
- p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q);
+ p->add_shortcut(ED_SHORTCUT("editor/file_quit", TTR("Quit"), KEY_MASK_CMD + KEY_Q), FILE_QUIT, true);
project_menu = memnew(MenuButton);
project_menu->set_flat(false);
@@ -5915,31 +5993,31 @@ EditorNode::EditorNode() {
p = project_menu->get_popup();
p->set_hide_on_window_lose_focus(true);
- p->add_shortcut(ED_SHORTCUT("editor/project_settings", TTR("Project Settings")), RUN_SETTINGS);
- p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("editor/project_settings", TTR("Project Settings...")), RUN_SETTINGS);
p->connect("id_pressed", this, "_menu_option");
- p->add_shortcut(ED_SHORTCUT("editor/export", TTR("Export")), FILE_EXPORT_PROJECT);
+
+ p->add_separator();
+ p->add_shortcut(ED_SHORTCUT("editor/export", TTR("Export...")), FILE_EXPORT_PROJECT);
+ p->add_item(TTR("Install Android Build Template..."), FILE_INSTALL_ANDROID_SOURCE);
+ p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
plugin_config_dialog = memnew(PluginConfigDialog);
plugin_config_dialog->connect("plugin_ready", this, "_on_plugin_ready");
gui_base->add_child(plugin_config_dialog);
+ p->add_separator();
tool_menu = memnew(PopupMenu);
tool_menu->set_name("Tools");
tool_menu->connect("index_pressed", this, "_tool_menu_option");
- p->add_separator();
p->add_child(tool_menu);
p->add_submenu_item(TTR("Tools"), "Tools");
- tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES);
- tool_menu->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
- p->add_separator();
- p->add_item(TTR("Install Android Build Template"), FILE_INSTALL_ANDROID_SOURCE);
- p->add_separator();
+ tool_menu->add_item(TTR("Orphan Resource Explorer..."), TOOLS_ORPHAN_RESOURCES);
+ p->add_separator();
#ifdef OSX_ENABLED
- p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
+ p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q), RUN_PROJECT_MANAGER, true);
#else
- p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q);
+ p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q), RUN_PROJECT_MANAGER, true);
#endif
menu_hb->add_spacer();
@@ -5987,7 +6065,7 @@ EditorNode::EditorNode() {
p = settings_menu->get_popup();
p->set_hide_on_window_lose_focus(true);
- p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings")), SETTINGS_PREFERENCES);
+ p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings...")), SETTINGS_PREFERENCES);
p->add_separator();
editor_layouts = memnew(PopupMenu);
@@ -6022,11 +6100,8 @@ EditorNode::EditorNode() {
}
p->add_separator();
- p->add_item(TTR("Manage Editor Features"), SETTINGS_MANAGE_FEATURE_PROFILES);
-
- p->add_separator();
-
- p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES);
+ p->add_item(TTR("Manage Editor Features..."), SETTINGS_MANAGE_FEATURE_PROFILES);
+ p->add_item(TTR("Manage Export Templates..."), SETTINGS_MANAGE_EXPORT_TEMPLATES);
// Help Menu
help_menu = memnew(MenuButton);
@@ -6299,13 +6374,13 @@ EditorNode::EditorNode() {
gui_base->add_child(custom_build_manage_templates);
install_android_build_template = memnew(ConfirmationDialog);
- install_android_build_template->set_text(TTR("This will install the Android project for custom builds.\nNote that, in order to use it, it needs to be enabled per export preset."));
+ install_android_build_template->set_text(TTR("This will set up your project for custom Android builds by installing the source template to \"res://android/build\".\nYou can then apply modifications and build your own custom APK on export (adding modules, changing the AndroidManifest.xml, etc.).\nNote that in order to make custom builds instead of using pre-built APKs, the \"Use Custom Build\" option should be enabled in the Android export preset."));
install_android_build_template->get_ok()->set_text(TTR("Install"));
install_android_build_template->connect("confirmed", this, "_menu_confirm_current");
gui_base->add_child(install_android_build_template);
remove_android_build_template = memnew(ConfirmationDialog);
- remove_android_build_template->set_text(TTR("Android build template is already installed and it won't be overwritten.\nRemove the \"build\" directory manually before attempting this operation again."));
+ remove_android_build_template->set_text(TTR("The Android build template is already installed in this project and it won't be overwritten.\nRemove the \"res://android/build\" directory manually before attempting this operation again."));
remove_android_build_template->get_ok()->set_text(TTR("Show in File Manager"));
remove_android_build_template->connect("confirmed", this, "_menu_option", varray(FILE_EXPLORE_ANDROID_BUILD_TEMPLATES));
gui_base->add_child(remove_android_build_template);
@@ -6357,6 +6432,8 @@ EditorNode::EditorNode() {
file_script->connect("file_selected", this, "_dialog_action");
file_menu->get_popup()->connect("id_pressed", this, "_menu_option");
+ file_menu->connect("about_to_show", this, "_update_file_menu_opened");
+ file_menu->get_popup()->connect("popup_hide", this, "_update_file_menu_closed");
settings_menu->get_popup()->connect("id_pressed", this, "_menu_option");
@@ -6573,13 +6650,6 @@ EditorNode::EditorNode() {
waiting_for_first_scan = true;
- _dimming = false;
- _dim_time = 0.0f;
- _dim_timer = memnew(Timer);
- _dim_timer->set_wait_time(0.01666f);
- _dim_timer->connect("timeout", this, "_dim_timeout");
- add_child(_dim_timer);
-
print_handler.printfunc = _print_handler;
print_handler.userdata = this;
add_print_handler(&print_handler);