Add support for embedding game process in the Android Editor

- Implement Android editor specific `EmbeddedGodotGame` to support embedding the game window in the Android editor
This commit is contained in:
Fredia Huya-Kouadio
2025-01-07 21:31:53 -08:00
parent 296de7da83
commit 7495a8a02e
71 changed files with 2497 additions and 301 deletions

View File

@@ -614,6 +614,10 @@ void GameView::_notification(int p_what) {
// Embedding available.
int game_mode = EDITOR_GET("run/window_placement/game_embed_mode");
switch (game_mode) {
case -1: { // Disabled.
embed_on_play = false;
make_floating_on_play = false;
} break;
case 1: { // Embed.
embed_on_play = true;
make_floating_on_play = false;
@@ -622,10 +626,6 @@ void GameView::_notification(int p_what) {
embed_on_play = true;
make_floating_on_play = true;
} break;
case 3: { // Disabled.
embed_on_play = false;
make_floating_on_play = false;
} break;
default: {
embed_on_play = EditorSettings::get_singleton()->get_project_metadata("game_view", "embed_on_play", true);
make_floating_on_play = EditorSettings::get_singleton()->get_project_metadata("game_view", "make_floating_on_play", true);
@@ -1027,6 +1027,18 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
///////
void GameViewPlugin::selected_notify() {
if (_is_window_wrapper_enabled()) {
#ifdef ANDROID_ENABLED
notify_main_screen_changed(get_plugin_name());
#else
window_wrapper->grab_window_focus();
#endif
_focus_another_editor();
}
}
#ifndef ANDROID_ENABLED
void GameViewPlugin::make_visible(bool p_visible) {
if (p_visible) {
window_wrapper->show();
@@ -1035,13 +1047,6 @@ void GameViewPlugin::make_visible(bool p_visible) {
}
}
void GameViewPlugin::selected_notify() {
if (window_wrapper->get_window_enabled()) {
window_wrapper->grab_window_focus();
_focus_another_editor();
}
}
void GameViewPlugin::set_window_layout(Ref<ConfigFile> p_layout) {
game_view->set_window_layout(p_layout);
}
@@ -1058,6 +1063,11 @@ Dictionary GameViewPlugin::get_state() const {
return game_view->get_state();
}
void GameViewPlugin::_window_visibility_changed(bool p_visible) {
_focus_another_editor();
}
#endif
void GameViewPlugin::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
@@ -1082,13 +1092,11 @@ void GameViewPlugin::_feature_profile_changed() {
debugger->set_is_feature_enabled(is_feature_enabled);
}
#ifndef ANDROID_ENABLED
if (game_view) {
game_view->set_is_feature_enabled(is_feature_enabled);
}
}
void GameViewPlugin::_window_visibility_changed(bool p_visible) {
_focus_another_editor();
#endif
}
void GameViewPlugin::_save_last_editor(const String &p_editor) {
@@ -1098,7 +1106,7 @@ void GameViewPlugin::_save_last_editor(const String &p_editor) {
}
void GameViewPlugin::_focus_another_editor() {
if (window_wrapper->get_window_enabled()) {
if (_is_window_wrapper_enabled()) {
if (last_editor.is_empty()) {
EditorNode::get_singleton()->get_editor_main_screen()->select(EditorMainScreen::EDITOR_2D);
} else {
@@ -1107,13 +1115,22 @@ void GameViewPlugin::_focus_another_editor() {
}
}
bool GameViewPlugin::_is_window_wrapper_enabled() const {
#ifdef ANDROID_ENABLED
return true;
#else
return window_wrapper->get_window_enabled();
#endif
}
GameViewPlugin::GameViewPlugin() {
debugger.instantiate();
#ifndef ANDROID_ENABLED
window_wrapper = memnew(WindowWrapper);
window_wrapper->set_window_title(vformat(TTR("%s - Godot Engine"), TTR("Game Workspace")));
window_wrapper->set_margins_enabled(true);
debugger.instantiate();
game_view = memnew(GameView(debugger, window_wrapper));
game_view->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -1123,6 +1140,7 @@ GameViewPlugin::GameViewPlugin() {
window_wrapper->set_v_size_flags(Control::SIZE_EXPAND_FILL);
window_wrapper->hide();
window_wrapper->connect("window_visibility_changed", callable_mp(this, &GameViewPlugin::_window_visibility_changed));
#endif
EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &GameViewPlugin::_feature_profile_changed));
}