Improve and reduce Game window sizing

This commit is contained in:
arkology
2025-03-21 07:00:49 +00:00
parent 2d86b69bf1
commit cb8e592b5e
4 changed files with 81 additions and 95 deletions

View File

@ -48,9 +48,9 @@
#include "editor/settings/editor_settings.h"
#include "editor/themes/editor_scale.h"
#include "scene/gui/button.h"
#include "scene/gui/flow_container.h"
#include "scene/gui/label.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/panel.h"
#include "scene/gui/separator.h"
void GameViewDebugger::_session_started(Ref<EditorDebuggerSession> p_session) {
@ -602,19 +602,19 @@ void GameView::_embed_options_menu_menu_id_pressed(int p_id) {
EditorSettings::get_singleton()->set_project_metadata("game_view", "make_floating_on_play", make_floating_on_play);
}
} break;
case SIZE_MODE_FIXED:
case SIZE_MODE_KEEP_ASPECT:
case SIZE_MODE_STRETCH: {
embed_size_mode = (EmbedSizeMode)p_id;
EditorSettings::get_singleton()->set_project_metadata("game_view", "embed_size_mode", p_id);
_update_embed_window_size();
} break;
}
_update_embed_menu_options();
_update_ui();
}
void GameView::_size_mode_button_pressed(int size_mode) {
embed_size_mode = (EmbedSizeMode)size_mode;
EditorSettings::get_singleton()->set_project_metadata("game_view", "embed_size_mode", size_mode);
_update_embed_menu_options();
_update_embed_window_size();
}
void GameView::_reset_time_scales() {
if (!is_visible_in_tree()) {
return;
@ -754,11 +754,11 @@ void GameView::_update_embed_menu_options() {
menu->set_item_checked(menu->get_item_index(EMBED_RUN_GAME_EMBEDDED), embed_on_play);
menu->set_item_checked(menu->get_item_index(EMBED_MAKE_FLOATING_ON_PLAY), make_floating_on_play && is_multi_window);
menu->set_item_disabled(menu->get_item_index(EMBED_MAKE_FLOATING_ON_PLAY), !embed_on_play || !is_multi_window);
menu->set_item_checked(menu->get_item_index(SIZE_MODE_FIXED), embed_size_mode == SIZE_MODE_FIXED);
menu->set_item_checked(menu->get_item_index(SIZE_MODE_KEEP_ASPECT), embed_size_mode == SIZE_MODE_KEEP_ASPECT);
menu->set_item_checked(menu->get_item_index(SIZE_MODE_STRETCH), embed_size_mode == SIZE_MODE_STRETCH);
fixed_size_button->set_pressed(embed_size_mode == SIZE_MODE_FIXED);
keep_aspect_button->set_pressed(embed_size_mode == SIZE_MODE_KEEP_ASPECT);
stretch_button->set_pressed(embed_size_mode == SIZE_MODE_STRETCH);
menu->set_item_disabled(menu->get_item_index(EMBED_MAKE_FLOATING_ON_PLAY), !embed_on_play || !is_multi_window);
}
void GameView::_update_embed_window_size() {
@ -863,10 +863,7 @@ void GameView::_notification(int p_what) {
select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]->set_button_icon(get_editor_theme_icon(SNAME("ListSelect")));
hide_selection->set_button_icon(get_editor_theme_icon(hide_selection->is_pressed() ? SNAME("GuiVisibilityHidden") : SNAME("GuiVisibilityVisible")));
fixed_size_button->set_button_icon(get_editor_theme_icon(SNAME("FixedSize")));
keep_aspect_button->set_button_icon(get_editor_theme_icon(SNAME("KeepAspect")));
stretch_button->set_button_icon(get_editor_theme_icon(SNAME("Stretch")));
embed_options_menu->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
embed_options_menu->set_button_icon(get_editor_theme_icon(SNAME("KeepAspect")));
debug_mute_audio_button->set_button_icon(get_editor_theme_icon(debug_mute_audio ? SNAME("AudioMute") : SNAME("AudioStreamPlayer")));
@ -900,7 +897,6 @@ void GameView::_notification(int p_what) {
} break;
}
embed_size_mode = (EmbedSizeMode)(int)EditorSettings::get_singleton()->get_project_metadata("game_view", "embed_size_mode", SIZE_MODE_FIXED);
keep_aspect_button->set_pressed(EditorSettings::get_singleton()->get_project_metadata("game_view", "keep_aspect", true));
_update_embed_menu_options();
EditorRunBar::get_singleton()->connect("play_pressed", callable_mp(this, &GameView::_play_pressed));
@ -913,11 +909,7 @@ void GameView::_notification(int p_what) {
EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &GameView::_editor_or_project_settings_changed));
} else {
// Embedding not available.
embedding_separator->hide();
embed_options_menu->hide();
fixed_size_button->hide();
keep_aspect_button->hide();
stretch_button->hide();
embedding_hb->hide();
}
_update_ui();
@ -1129,11 +1121,13 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
toolbar_margin->set_theme_type_variation("MainToolBarMargin");
add_child(toolbar_margin);
HBoxContainer *main_menu_hbox = memnew(HBoxContainer);
toolbar_margin->add_child(main_menu_hbox);
FlowContainer *main_menu_fc = memnew(FlowContainer);
toolbar_margin->add_child(main_menu_fc);
HBoxContainer *process_hb = memnew(HBoxContainer);
main_menu_fc->add_child(process_hb);
suspend_button = memnew(Button);
main_menu_hbox->add_child(suspend_button);
process_hb->add_child(suspend_button);
suspend_button->set_toggle_mode(true);
suspend_button->set_theme_type_variation(SceneStringName(FlatButton));
suspend_button->connect(SceneStringName(toggled), callable_mp(this, &GameView::_suspend_button_toggled));
@ -1142,14 +1136,14 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
suspend_button->set_tooltip_text(TTRC("Force pause at SceneTree level. Stops all processing, but you can still interact with the project."));
next_frame_button = memnew(Button);
main_menu_hbox->add_child(next_frame_button);
process_hb->add_child(next_frame_button);
next_frame_button->set_theme_type_variation(SceneStringName(FlatButton));
next_frame_button->connect(SceneStringName(pressed), callable_mp(*debugger, &GameViewDebugger::next_frame));
next_frame_button->set_accessibility_name(TTRC("Next Frame"));
next_frame_button->set_shortcut(ED_GET_SHORTCUT("editor/next_frame_embedded_project"));
speed_state_button = memnew(MenuButton);
main_menu_hbox->add_child(speed_state_button);
process_hb->add_child(speed_state_button);
speed_state_button->set_text(U"1.0×");
speed_state_button->set_theme_type_variation(SceneStringName(FlatButton));
speed_state_button->set_tooltip_text(TTRC("Change the game speed."));
@ -1162,16 +1156,19 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
}
reset_speed_button = memnew(Button);
main_menu_hbox->add_child(reset_speed_button);
process_hb->add_child(reset_speed_button);
reset_speed_button->set_theme_type_variation(SceneStringName(FlatButton));
reset_speed_button->set_tooltip_text(TTRC("Reset the game speed."));
reset_speed_button->set_accessibility_name(TTRC("Reset Speed"));
reset_speed_button->connect(SceneStringName(pressed), callable_mp(this, &GameView::_reset_time_scales));
main_menu_hbox->add_child(memnew(VSeparator));
process_hb->add_child(memnew(VSeparator));
HBoxContainer *input_hb = memnew(HBoxContainer);
main_menu_fc->add_child(input_hb);
node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE] = memnew(Button);
main_menu_hbox->add_child(node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]);
input_hb->add_child(node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]);
node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->set_text(TTRC("Input"));
node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->set_toggle_mode(true);
node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->set_pressed(true);
@ -1180,7 +1177,7 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
node_type_button[RuntimeNodeSelect::NODE_TYPE_NONE]->set_tooltip_text(TTRC("Allow game input."));
node_type_button[RuntimeNodeSelect::NODE_TYPE_2D] = memnew(Button);
main_menu_hbox->add_child(node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]);
input_hb->add_child(node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]);
node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]->set_text(TTRC("2D"));
node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]->set_toggle_mode(true);
node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]->set_theme_type_variation(SceneStringName(FlatButton));
@ -1188,27 +1185,20 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
node_type_button[RuntimeNodeSelect::NODE_TYPE_2D]->set_tooltip_text(TTRC("Disable game input and allow to select Node2Ds, Controls, and manipulate the 2D camera."));
node_type_button[RuntimeNodeSelect::NODE_TYPE_3D] = memnew(Button);
main_menu_hbox->add_child(node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]);
input_hb->add_child(node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]);
node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->set_text(TTRC("3D"));
node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->set_toggle_mode(true);
node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->set_theme_type_variation(SceneStringName(FlatButton));
node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->connect(SceneStringName(pressed), callable_mp(this, &GameView::_node_type_pressed).bind(RuntimeNodeSelect::NODE_TYPE_3D));
node_type_button[RuntimeNodeSelect::NODE_TYPE_3D]->set_tooltip_text(TTRC("Disable game input and allow to select Node3Ds and manipulate the 3D camera."));
main_menu_hbox->add_child(memnew(VSeparator));
input_hb->add_child(memnew(VSeparator));
hide_selection = memnew(Button);
main_menu_hbox->add_child(hide_selection);
hide_selection->set_toggle_mode(true);
hide_selection->set_theme_type_variation(SceneStringName(FlatButton));
hide_selection->connect(SceneStringName(toggled), callable_mp(this, &GameView::_hide_selection_toggled));
hide_selection->set_tooltip_text(TTRC("Toggle Selection Visibility"));
hide_selection->set_pressed(EditorSettings::get_singleton()->get_project_metadata("game_view", "hide_selection", false));
main_menu_hbox->add_child(memnew(VSeparator));
HBoxContainer *selection_hb = memnew(HBoxContainer);
main_menu_fc->add_child(selection_hb);
select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE] = memnew(Button);
main_menu_hbox->add_child(select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]);
selection_hb->add_child(select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]);
select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_toggle_mode(true);
select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_pressed(true);
select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_theme_type_variation(SceneStringName(FlatButton));
@ -1217,7 +1207,7 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
select_mode_button[RuntimeNodeSelect::SELECT_MODE_SINGLE]->set_shortcut_context(this);
select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST] = memnew(Button);
main_menu_hbox->add_child(select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]);
selection_hb->add_child(select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]);
select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]->set_toggle_mode(true);
select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]->set_theme_type_variation(SceneStringName(FlatButton));
select_mode_button[RuntimeNodeSelect::SELECT_MODE_LIST]->connect(SceneStringName(pressed), callable_mp(this, &GameView::_select_mode_pressed).bind(RuntimeNodeSelect::SELECT_MODE_LIST));
@ -1225,25 +1215,39 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
_select_mode_pressed(EditorSettings::get_singleton()->get_project_metadata("game_view", "select_mode", 0));
main_menu_hbox->add_child(memnew(VSeparator));
hide_selection = memnew(Button);
selection_hb->add_child(hide_selection);
hide_selection->set_toggle_mode(true);
hide_selection->set_theme_type_variation(SceneStringName(FlatButton));
hide_selection->connect(SceneStringName(toggled), callable_mp(this, &GameView::_hide_selection_toggled));
hide_selection->set_tooltip_text(TTRC("Toggle Selection Visibility"));
hide_selection->set_pressed(EditorSettings::get_singleton()->get_project_metadata("game_view", "hide_selection", false));
selection_hb->add_child(memnew(VSeparator));
HBoxContainer *audio_hb = memnew(HBoxContainer);
main_menu_fc->add_child(audio_hb);
debug_mute_audio_button = memnew(Button);
main_menu_hbox->add_child(debug_mute_audio_button);
audio_hb->add_child(debug_mute_audio_button);
debug_mute_audio_button->set_theme_type_variation("FlatButton");
debug_mute_audio_button->connect(SceneStringName(pressed), callable_mp(this, &GameView::_debug_mute_audio_button_pressed));
debug_mute_audio_button->set_tooltip_text(debug_mute_audio ? TTRC("Unmute game audio.") : TTRC("Mute game audio."));
main_menu_hbox->add_child(memnew(VSeparator));
audio_hb->add_child(memnew(VSeparator));
HBoxContainer *camera_hb = memnew(HBoxContainer);
main_menu_fc->add_child(camera_hb);
camera_override_button = memnew(Button);
main_menu_hbox->add_child(camera_override_button);
camera_hb->add_child(camera_override_button);
camera_override_button->set_toggle_mode(true);
camera_override_button->set_theme_type_variation(SceneStringName(FlatButton));
camera_override_button->set_tooltip_text(TTRC("Override the in-game camera."));
camera_override_button->connect(SceneStringName(toggled), callable_mp(this, &GameView::_camera_override_button_toggled));
camera_override_menu = memnew(MenuButton);
main_menu_hbox->add_child(camera_override_menu);
camera_hb->add_child(camera_override_menu);
camera_override_menu->set_flat(false);
camera_override_menu->set_theme_type_variation("FlatMenuButton");
camera_override_menu->set_h_size_flags(SIZE_SHRINK_END);
@ -1259,33 +1263,14 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
menu->add_radio_check_item(TTRC("Manipulate From Editors"), CAMERA_MODE_EDITORS);
_camera_override_menu_id_pressed(EditorSettings::get_singleton()->get_project_metadata("game_view", "camera_override_mode", 0));
embedding_separator = memnew(VSeparator);
main_menu_hbox->add_child(embedding_separator);
camera_hb->add_child(memnew(VSeparator));
fixed_size_button = memnew(Button);
main_menu_hbox->add_child(fixed_size_button);
fixed_size_button->set_toggle_mode(true);
fixed_size_button->set_theme_type_variation("FlatButton");
fixed_size_button->set_tooltip_text(TTRC("Embedded game size is based on project settings.\nThe 'Keep Aspect' mode is used when the Game Workspace is smaller than the desired size."));
fixed_size_button->set_accessibility_name(TTRC("Embedded game size is based on project settings."));
fixed_size_button->connect(SceneStringName(pressed), callable_mp(this, &GameView::_size_mode_button_pressed).bind(SIZE_MODE_FIXED));
keep_aspect_button = memnew(Button);
main_menu_hbox->add_child(keep_aspect_button);
keep_aspect_button->set_toggle_mode(true);
keep_aspect_button->set_theme_type_variation("FlatButton");
keep_aspect_button->set_tooltip_text(TTRC("Keep the aspect ratio of the embedded game."));
keep_aspect_button->connect(SceneStringName(pressed), callable_mp(this, &GameView::_size_mode_button_pressed).bind(SIZE_MODE_KEEP_ASPECT));
stretch_button = memnew(Button);
main_menu_hbox->add_child(stretch_button);
stretch_button->set_toggle_mode(true);
stretch_button->set_theme_type_variation("FlatButton");
stretch_button->set_tooltip_text(TTRC("Embedded game size stretches to fit the Game Workspace."));
stretch_button->connect(SceneStringName(pressed), callable_mp(this, &GameView::_size_mode_button_pressed).bind(SIZE_MODE_STRETCH));
embedding_hb = memnew(HBoxContainer);
embedding_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
main_menu_fc->add_child(embedding_hb);
embed_options_menu = memnew(MenuButton);
main_menu_hbox->add_child(embed_options_menu);
embedding_hb->add_child(embed_options_menu);
embed_options_menu->set_flat(false);
embed_options_menu->set_theme_type_variation("FlatMenuButton");
embed_options_menu->set_h_size_flags(SIZE_SHRINK_END);
@ -1295,22 +1280,32 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
menu->connect(SceneStringName(id_pressed), callable_mp(this, &GameView::_embed_options_menu_menu_id_pressed));
menu->add_check_item(TTRC("Embed Game on Next Play"), EMBED_RUN_GAME_EMBEDDED);
menu->add_check_item(TTRC("Make Game Workspace Floating on Next Play"), EMBED_MAKE_FLOATING_ON_PLAY);
menu->add_separator(TTRC("Embedded Window Sizing"));
main_menu_hbox->add_spacer();
menu->add_radio_check_item(TTRC("Fixed Size"), SIZE_MODE_FIXED);
menu->set_item_tooltip(menu->get_item_index(SIZE_MODE_FIXED), TTRC("Embedded game size is based on project settings.\nThe 'Keep Aspect' mode is used when the Game Workspace is smaller than the desired size."));
menu->add_radio_check_item(TTRC("Keep Aspect Ratio"), SIZE_MODE_KEEP_ASPECT);
menu->set_item_tooltip(menu->get_item_index(SIZE_MODE_KEEP_ASPECT), TTRC("Keep the aspect ratio of the embedded game."));
menu->add_radio_check_item(TTRC("Stretch to Fit"), SIZE_MODE_STRETCH);
menu->set_item_tooltip(menu->get_item_index(SIZE_MODE_STRETCH), TTRC("Embedded game size stretches to fit the Game Workspace."));
game_size_label = memnew(Label());
main_menu_hbox->add_child(game_size_label);
embedding_hb->add_child(game_size_label);
game_size_label->hide();
// Setting the minimum size prevents the game workspace from resizing indefinitely
// due to the label size oscillating by a few pixels when the game is in stretch mode
// and the game workspace is at its minimum size.
game_size_label->set_custom_minimum_size(Size2(80 * EDSCALE, 0));
game_size_label->set_h_size_flags(SIZE_EXPAND_FILL);
game_size_label->set_horizontal_alignment(HorizontalAlignment::HORIZONTAL_ALIGNMENT_RIGHT);
panel = memnew(Panel);
panel = memnew(PanelContainer);
add_child(panel);
panel->set_theme_type_variation("GamePanel");
panel->set_v_size_flags(SIZE_EXPAND_FILL);
#ifdef MACOS_ENABLED
panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
#endif
panel->add_child(embedded_process);
embedded_process->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
@ -1320,17 +1315,8 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, EmbeddedProcessBase *p_embe
embedded_process->connect("embedded_process_focused", callable_mp(this, &GameView::_embedded_process_focused));
embedded_process->set_custom_minimum_size(Size2i(100, 100));
MarginContainer *state_container = memnew(MarginContainer);
state_container->add_theme_constant_override("margin_left", 8 * EDSCALE);
state_container->add_theme_constant_override("margin_right", 8 * EDSCALE);
state_container->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
#ifdef MACOS_ENABLED
state_container->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
#endif
panel->add_child(state_container);
state_label = memnew(Label());
state_container->add_child(state_label);
panel->add_child(state_label);
state_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
state_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);
state_label->set_autowrap_mode(TextServer::AUTOWRAP_WORD);

View File

@ -165,13 +165,10 @@ class GameView : public VBoxContainer {
Button *camera_override_button = nullptr;
MenuButton *camera_override_menu = nullptr;
VSeparator *embedding_separator = nullptr;
Button *fixed_size_button = nullptr;
Button *keep_aspect_button = nullptr;
Button *stretch_button = nullptr;
HBoxContainer *embedding_hb = nullptr;
MenuButton *embed_options_menu = nullptr;
Label *game_size_label = nullptr;
Panel *panel = nullptr;
PanelContainer *panel = nullptr;
EmbeddedProcessBase *embedded_process = nullptr;
Label *state_label = nullptr;
@ -194,7 +191,6 @@ class GameView : public VBoxContainer {
void _node_type_pressed(int p_option);
void _select_mode_pressed(int p_option);
void _embed_options_menu_menu_id_pressed(int p_id);
void _size_mode_button_pressed(int size_mode);
void _reset_time_scales();
void _speed_state_menu_pressed(int p_id);

View File

@ -1587,9 +1587,11 @@ void ThemeClassic::populate_editor_styles(const Ref<EditorTheme> &p_theme, Edito
p_theme->set_stylebox("ScriptEditor", EditorStringName(EditorStyles), EditorThemeManager::make_empty_stylebox(0, 0, 0, 0));
// Game view.
p_theme->set_type_variation("GamePanel", "Panel");
p_theme->set_type_variation("GamePanel", "PanelContainer");
Ref<StyleBoxFlat> game_panel = p_theme->get_stylebox(SceneStringName(panel), SNAME("Panel"))->duplicate();
game_panel->set_corner_radius_all(0);
game_panel->set_content_margin_all(0);
game_panel->set_draw_center(true);
p_theme->set_stylebox(SceneStringName(panel), "GamePanel", game_panel);
// Main menu.

View File

@ -1576,9 +1576,11 @@ void ThemeModern::populate_editor_styles(const Ref<EditorTheme> &p_theme, Editor
p_theme->set_stylebox("ScriptEditor", EditorStringName(EditorStyles), EditorThemeManager::make_empty_stylebox(0, 0, 0, 0));
// Game view.
p_theme->set_type_variation("GamePanel", "Panel");
p_theme->set_type_variation("GamePanel", "PanelContainer");
Ref<StyleBoxFlat> game_panel = p_theme->get_stylebox(SceneStringName(panel), SNAME("Panel"))->duplicate();
game_panel->set_corner_radius_all(0);
game_panel->set_content_margin_all(0);
game_panel->set_draw_center(true);
p_theme->set_stylebox(SceneStringName(panel), "GamePanel", game_panel);
// Main menu.