Skip to content

Commit e03942a

Browse files
Add editor setting to collapse main menu
1 parent 64b4598 commit e03942a

File tree

5 files changed

+157
-30
lines changed

5 files changed

+157
-30
lines changed

doc/classes/EditorSettings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,11 @@
836836
<member name="interface/editor/code_font_size" type="int" setter="" getter="">
837837
The size of the font in the script editor. This setting does not impact the font size of the Output panel (see [member run/output/font_size]).
838838
</member>
839+
<member name="interface/editor/collapse_main_menu" type="bool" setter="" getter="">
840+
If [code]true[/code], the main menu collapses into a [MenuButton].
841+
[b]Note:[/b] This setting is only applicable on macOS when [member interface/editor/use_embedded_menu] is [code]true[/code].
842+
[b]Note:[/b] Defaults to [code]true[/code] on the Android editor.
843+
</member>
839844
<member name="interface/editor/custom_display_scale" type="float" setter="" getter="">
840845
The custom editor scale factor to use. This can be used for displays with very high DPI where a scale factor of 200% is not sufficient.
841846
[b]Note:[/b] Only effective if [member interface/editor/display_scale] is set to [b]Custom[/b].

editor/editor_node.cpp

Lines changed: 130 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,10 @@ void EditorNode::_update_theme(bool p_skip_creation) {
573573
main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, theme->get_constant(SNAME("window_border_margin"), EditorStringName(Editor)));
574574
main_vbox->add_theme_constant_override("separation", theme->get_constant(SNAME("top_bar_separation"), EditorStringName(Editor)));
575575

576+
if (main_menu_button != nullptr) {
577+
main_menu_button->set_button_icon(theme->get_icon(SNAME("TripleBar"), EditorStringName(EditorIcons)));
578+
}
579+
576580
editor_main_screen->add_theme_style_override(SceneStringName(panel), theme->get_stylebox(SNAME("Content"), EditorStringName(EditorStyles)));
577581
bottom_panel->add_theme_style_override(SceneStringName(panel), theme->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles)));
578582
distraction_free->set_button_icon(theme->get_icon(SNAME("DistractionFree"), EditorStringName(EditorIcons)));
@@ -934,6 +938,7 @@ void EditorNode::_notification(int p_what) {
934938
if (EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor")) {
935939
_update_update_spinner();
936940
_update_vsync_mode();
941+
_update_main_menu_type();
937942
DisplayServer::get_singleton()->screen_set_keep_on(EDITOR_GET("interface/editor/keep_screen_on"));
938943
}
939944

@@ -7080,6 +7085,112 @@ void EditorNode::set_unfocused_low_processor_usage_mode_enabled(bool p_enabled)
70807085
unfocused_low_processor_usage_mode_enabled = p_enabled;
70817086
}
70827087

7088+
void EditorNode::_update_main_menu_type() {
7089+
bool use_menu_button = EDITOR_GET("interface/editor/collapse_main_menu");
7090+
bool global_menu = !bool(EDITOR_GET("interface/editor/use_embedded_menu")) && NativeMenu::get_singleton()->has_feature(NativeMenu::FEATURE_GLOBAL_MENU);
7091+
7092+
bool already_using_button = main_menu_button != nullptr;
7093+
bool already_using_bar = main_menu_bar != nullptr;
7094+
if ((use_menu_button && already_using_button) || (!use_menu_button && already_using_bar)) {
7095+
return; // Already correctly configured.
7096+
}
7097+
7098+
if (use_menu_button && !global_menu) {
7099+
main_menu_button = memnew(MenuButton);
7100+
main_menu_button->set_text(TTRC("Main Menu"));
7101+
main_menu_button->set_theme_type_variation("MainScreenButton");
7102+
main_menu_button->set_focus_mode(Control::FOCUS_NONE);
7103+
if (is_inside_tree()) {
7104+
main_menu_button->set_button_icon(theme->get_icon(SNAME("TripleBar"), EditorStringName(EditorIcons)));
7105+
}
7106+
main_menu_button->set_switch_on_hover(true);
7107+
7108+
if (main_menu_bar != nullptr) {
7109+
Vector<PopupMenu *> menus_to_move;
7110+
for (int i = 0; i < main_menu_bar->get_child_count(); i++) {
7111+
PopupMenu *menu = Object::cast_to<PopupMenu>(main_menu_bar->get_child(i));
7112+
if (menu != nullptr) {
7113+
menus_to_move.push_back(menu);
7114+
}
7115+
}
7116+
for (PopupMenu *menu : menus_to_move) {
7117+
main_menu_bar->remove_child(menu);
7118+
main_menu_button->get_popup()->add_submenu_node_item(menu->get_name(), menu);
7119+
}
7120+
}
7121+
7122+
#ifdef ANDROID_ENABLED
7123+
// Align main menu icon visually with TouchActionsPanel buttons.
7124+
main_menu_button->get_popup()->add_theme_constant_override("v_separation", 16 * EDSCALE);
7125+
menu_btn_spacer = memnew(Control);
7126+
menu_btn_spacer->set_custom_minimum_size(Vector2(8, 0) * EDSCALE);
7127+
title_bar->add_child(menu_btn_spacer);
7128+
title_bar->move_child(menu_btn_spacer, 0);
7129+
#endif
7130+
title_bar->add_child(main_menu_button);
7131+
if (menu_btn_spacer == nullptr) {
7132+
title_bar->move_child(main_menu_button, 0);
7133+
} else {
7134+
title_bar->move_child(main_menu_button, 1);
7135+
}
7136+
memdelete_notnull(main_menu_bar);
7137+
main_menu_bar = nullptr;
7138+
7139+
if (project_run_bar != nullptr) {
7140+
// Adjust spacers to center 2D / 3D / Script buttons.
7141+
int max_w = MAX(project_run_bar->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu_button->get_minimum_size().x);
7142+
left_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - main_menu_button->get_minimum_size().x), 0));
7143+
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));
7144+
}
7145+
} else {
7146+
main_menu_bar = memnew(MenuBar);
7147+
main_menu_bar->set_mouse_filter(Control::MOUSE_FILTER_STOP);
7148+
main_menu_bar->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
7149+
main_menu_bar->set_theme_type_variation("MainMenuBar");
7150+
main_menu_bar->set_start_index(0); // Main menu, add to the start of global menu.
7151+
main_menu_bar->set_prefer_global_menu(global_menu);
7152+
main_menu_bar->set_switch_on_hover(true);
7153+
7154+
if (main_menu_button != nullptr) {
7155+
Vector<PopupMenu *> menus_to_move;
7156+
for (int i = 0; i < main_menu_button->get_item_count(); i++) {
7157+
PopupMenu *menu = main_menu_button->get_popup()->get_item_submenu_node(i);
7158+
if (menu != nullptr) {
7159+
menus_to_move.push_back(menu);
7160+
}
7161+
}
7162+
for (PopupMenu *menu : menus_to_move) {
7163+
menu->get_parent()->remove_child(menu);
7164+
main_menu_bar->add_child(menu);
7165+
}
7166+
}
7167+
7168+
title_bar->add_child(main_menu_bar);
7169+
title_bar->move_child(main_menu_bar, 0);
7170+
7171+
memdelete_notnull(menu_btn_spacer);
7172+
memdelete_notnull(main_menu_button);
7173+
menu_btn_spacer = nullptr;
7174+
main_menu_button = nullptr;
7175+
7176+
if (project_run_bar != nullptr) {
7177+
// Adjust spacers to center 2D / 3D / Script buttons.
7178+
int max_w = MAX(project_run_bar->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu_bar->get_minimum_size().x);
7179+
left_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - main_menu_bar->get_minimum_size().x), 0));
7180+
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));
7181+
}
7182+
}
7183+
}
7184+
7185+
void EditorNode::_add_to_main_menu(const String &p_name, PopupMenu *p_menu) {
7186+
p_menu->set_name(p_name);
7187+
if (main_menu_button != nullptr) {
7188+
main_menu_button->get_popup()->add_submenu_node_item(p_name, p_menu);
7189+
} else {
7190+
main_menu_bar->add_child(p_menu);
7191+
}
7192+
}
7193+
70837194
#ifdef ANDROID_ENABLED
70847195
void EditorNode::_touch_actions_panel_mode_changed() {
70857196
int panel_mode = EDITOR_GET("interface/touchscreen/touch_actions_panel");
@@ -7601,19 +7712,10 @@ EditorNode::EditorNode() {
76017712
title_bar->add_child(left_menu_spacer);
76027713
}
76037714

7604-
main_menu = memnew(MenuBar);
7605-
main_menu->set_mouse_filter(Control::MOUSE_FILTER_STOP);
7606-
title_bar->add_child(main_menu);
7607-
main_menu->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
7608-
main_menu->set_theme_type_variation("MainMenuBar");
7609-
main_menu->set_start_index(0); // Main menu, add to the start of global menu.
7610-
main_menu->set_prefer_global_menu(global_menu);
7611-
main_menu->set_switch_on_hover(true);
7715+
_update_main_menu_type();
76127716

76137717
file_menu = memnew(PopupMenu);
7614-
file_menu->set_name(TTRC("Scene"));
7615-
main_menu->add_child(file_menu);
7616-
main_menu->set_menu_tooltip(0, TTR("Operations with scene files."));
7718+
_add_to_main_menu(TTRC("Scene"), file_menu);
76177719

76187720
accept = memnew(AcceptDialog);
76197721
accept->set_autowrap(true);
@@ -7728,7 +7830,7 @@ EditorNode::EditorNode() {
77287830
if (global_menu && NativeMenu::get_singleton()->has_system_menu(NativeMenu::APPLICATION_MENU_ID)) {
77297831
apple_menu = memnew(PopupMenu);
77307832
apple_menu->set_system_menu(NativeMenu::APPLICATION_MENU_ID);
7731-
main_menu->add_child(apple_menu);
7833+
main_menu_bar->add_child(apple_menu);
77327834

77337835
apple_menu->add_shortcut(ED_GET_SHORTCUT("editor/editor_settings"), EDITOR_OPEN_SETTINGS);
77347836
apple_menu->add_separator();
@@ -7737,8 +7839,7 @@ EditorNode::EditorNode() {
77377839
#endif
77387840

77397841
project_menu = memnew(PopupMenu);
7740-
project_menu->set_name(TTRC("Project"));
7741-
main_menu->add_child(project_menu);
7842+
_add_to_main_menu(TTRC("Project"), project_menu);
77427843

77437844
project_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/project_settings", TTRC("Project Settings..."), Key::NONE, TTRC("Project Settings")), PROJECT_OPEN_SETTINGS);
77447845
project_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option));
@@ -7770,7 +7871,7 @@ EditorNode::EditorNode() {
77707871
project_menu->add_shortcut(ED_GET_SHORTCUT("editor/quit_to_project_list"), PROJECT_QUIT_TO_PROJECT_MANAGER, true);
77717872

77727873
// Spacer to center 2D / 3D / Script buttons.
7773-
HBoxContainer *left_spacer = memnew(HBoxContainer);
7874+
left_spacer = memnew(HBoxContainer);
77747875
left_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS);
77757876
left_spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL);
77767877
title_bar->add_child(left_spacer);
@@ -7794,12 +7895,10 @@ EditorNode::EditorNode() {
77947895

77957896
// Options are added and handled by DebuggerEditorPlugin.
77967897
debug_menu = memnew(PopupMenu);
7797-
debug_menu->set_name(TTRC("Debug"));
7798-
main_menu->add_child(debug_menu);
7898+
_add_to_main_menu(TTRC("Debug"), debug_menu);
77997899

78007900
settings_menu = memnew(PopupMenu);
7801-
settings_menu->set_name(TTRC("Editor"));
7802-
main_menu->add_child(settings_menu);
7901+
_add_to_main_menu(TTRC("Editor"), settings_menu);
78037902

78047903
#ifdef MACOS_ENABLED
78057904
if (!global_menu) {
@@ -7848,11 +7947,10 @@ EditorNode::EditorNode() {
78487947
#endif
78497948

78507949
help_menu = memnew(PopupMenu);
7851-
help_menu->set_name(TTRC("Help"));
78527950
if (global_menu && NativeMenu::get_singleton()->has_system_menu(NativeMenu::HELP_MENU_ID)) {
78537951
help_menu->set_system_menu(NativeMenu::HELP_MENU_ID);
78547952
}
7855-
main_menu->add_child(help_menu);
7953+
_add_to_main_menu(TTRC("Help"), help_menu);
78567954

78577955
help_menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_menu_option));
78587956

@@ -7877,7 +7975,7 @@ EditorNode::EditorNode() {
78777975
help_menu->add_icon_shortcut(_get_editor_theme_native_menu_icon(SNAME("Heart"), global_menu, dark_mode), ED_SHORTCUT_AND_COMMAND("editor/support_development", TTRC("Support Godot Development")), HELP_SUPPORT_GODOT_DEVELOPMENT);
78787976

78797977
// Spacer to center 2D / 3D / Script buttons.
7880-
Control *right_spacer = memnew(Control);
7978+
right_spacer = memnew(Control);
78817979
right_spacer->set_mouse_filter(Control::MOUSE_FILTER_PASS);
78827980
right_spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL);
78837981
title_bar->add_child(right_spacer);
@@ -7888,7 +7986,7 @@ EditorNode::EditorNode() {
78887986
project_run_bar->connect("play_pressed", callable_mp(this, &EditorNode::_project_run_started));
78897987
project_run_bar->connect("stop_pressed", callable_mp(this, &EditorNode::_project_run_stopped));
78907988

7891-
HBoxContainer *right_menu_hb = memnew(HBoxContainer);
7989+
right_menu_hb = memnew(HBoxContainer);
78927990
right_menu_hb->set_mouse_filter(Control::MOUSE_FILTER_STOP);
78937991
title_bar->add_child(right_menu_hb);
78947992

@@ -8415,10 +8513,15 @@ EditorNode::EditorNode() {
84158513
screenshot_timer->set_owner(get_owner());
84168514

84178515
// Adjust spacers to center 2D / 3D / Script buttons.
8418-
int max_w = MAX(project_run_bar->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu->get_minimum_size().x);
8419-
left_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - main_menu->get_minimum_size().x), 0));
8420-
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));
8421-
8516+
if (main_menu_button != nullptr) {
8517+
int max_w = MAX(project_run_bar->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu_button->get_minimum_size().x);
8518+
left_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - main_menu_button->get_minimum_size().x), 0));
8519+
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));
8520+
} else {
8521+
int max_w = MAX(project_run_bar->get_minimum_size().x + right_menu_hb->get_minimum_size().x, main_menu_bar->get_minimum_size().x);
8522+
left_spacer->set_custom_minimum_size(Size2(MAX(0, max_w - main_menu_bar->get_minimum_size().x), 0));
8523+
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));
8524+
}
84228525
// Extend menu bar to window title.
84238526
if (can_expand) {
84248527
DisplayServer::get_singleton()->process_events();

editor/editor_node.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class ColorPicker;
4545
class ConfirmationDialog;
4646
class Control;
4747
class FileDialog;
48+
class HBoxContainer;
4849
class MenuBar;
4950
class MenuButton;
5051
class OptionButton;
@@ -100,7 +101,6 @@ class SceneImportSettingsDialog;
100101
class ProjectUpgradeTool;
101102

102103
#ifdef ANDROID_ENABLED
103-
class HBoxContainer;
104104
class TouchActionsPanel;
105105
#endif
106106

@@ -325,7 +325,16 @@ class EditorNode : public Node {
325325
Control *right_menu_spacer = nullptr;
326326
EditorTitleBar *title_bar = nullptr;
327327
EditorRunBar *project_run_bar = nullptr;
328-
MenuBar *main_menu = nullptr;
328+
HBoxContainer *right_menu_hb = nullptr;
329+
330+
// Spacers to center 2D / 3D / Script buttons.
331+
HBoxContainer *left_spacer = nullptr;
332+
Control *right_spacer = nullptr;
333+
334+
Control *menu_btn_spacer = nullptr;
335+
MenuButton *main_menu_button = nullptr;
336+
MenuBar *main_menu_bar = nullptr;
337+
329338
PopupMenu *apple_menu = nullptr;
330339
PopupMenu *file_menu = nullptr;
331340
PopupMenu *project_menu = nullptr;
@@ -689,6 +698,9 @@ class EditorNode : public Node {
689698

690699
bool _is_project_data_missing();
691700

701+
void _update_main_menu_type();
702+
void _add_to_main_menu(const String &p_name, PopupMenu *p_menu);
703+
692704
protected:
693705
friend class FileSystemDock;
694706

editor/editor_settings.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,14 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
529529
EDITOR_SETTING_BASIC(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/vsync_mode", 1, "Disabled,Enabled,Adaptive,Mailbox")
530530
EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/update_continuously", false, "")
531531

532+
bool is_android_editor = false;
533+
#ifdef ANDROID_ENABLED
534+
if (!OS::get_singleton()->has_feature("xr_editor")) {
535+
is_android_editor = true;
536+
}
537+
#endif
538+
EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "interface/editor/collapse_main_menu", is_android_editor, "")
539+
532540
_initial_set("interface/editors/show_scene_tree_root_selection", true);
533541
_initial_set("interface/editors/derive_script_globals_by_name", true);
534542
_initial_set("docks/scene_tree/ask_before_revoking_unique_name", true);

editor/gui/touch_actions_panel.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ TouchActionsPanel::TouchActionsPanel() {
240240
}
241241

242242
box = memnew(BoxContainer);
243-
box->set_alignment(BoxContainer::ALIGNMENT_CENTER);
244243
box->add_theme_constant_override("separation", 20);
245244
if (is_floating) {
246245
box->set_vertical(EDITOR_DEF("_touch_actions_panel_vertical_layout", false));

0 commit comments

Comments
 (0)