diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 346335a6dc..7c4c155be1 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -6776,6 +6776,8 @@ void EditorNode::set_distraction_free_mode(bool p_enter) { } else { editor_dock_manager->set_docks_visible(true); } + + emit_signal(SNAME("distraction_free_mode_changed"), p_enter); } bool EditorNode::is_distraction_free_mode_enabled() const { @@ -7797,6 +7799,7 @@ void EditorNode::_bind_methods() { ADD_SIGNAL(MethodInfo("scene_closed", PropertyInfo(Variant::STRING, "path"))); ADD_SIGNAL(MethodInfo("preview_locale_changed")); ADD_SIGNAL(MethodInfo("resource_counter_changed")); + ADD_SIGNAL(MethodInfo("distraction_free_mode_changed", PropertyInfo(Variant::BOOL, "enabled"))); } static Node *_resource_get_edited_scene() { diff --git a/platform/android/editor/editor_utils_jni.cpp b/platform/android/editor/editor_utils_jni.cpp index e2b6f3b4e9..9b2fcfc6ee 100644 --- a/platform/android/editor/editor_utils_jni.cpp +++ b/platform/android/editor/editor_utils_jni.cpp @@ -35,6 +35,8 @@ #ifdef TOOLS_ENABLED #include "editor/debugger/editor_debugger_node.h" #include "editor/debugger/script_editor_debugger.h" +#include "editor/editor_node.h" +#include "editor/gui/editor_title_bar.h" #include "editor/run/editor_run_bar.h" #include "main/main.h" #endif @@ -92,4 +94,13 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_editor_utils_EditorUtils_runSc } #endif } + +JNIEXPORT void JNICALL Java_org_godotengine_godot_editor_utils_EditorUtils_toggleTitleBar(JNIEnv *p_env, jclass, jboolean p_visible) { +#ifdef TOOLS_ENABLED + EditorTitleBar *title_bar = EditorNode::get_singleton()->get_title_bar(); + if (title_bar != nullptr) { + title_bar->call_deferred("set_visible", p_visible); + } +#endif +} } diff --git a/platform/android/editor/editor_utils_jni.h b/platform/android/editor/editor_utils_jni.h index 68d269617c..963b97b765 100644 --- a/platform/android/editor/editor_utils_jni.h +++ b/platform/android/editor/editor_utils_jni.h @@ -34,4 +34,5 @@ extern "C" { JNIEXPORT void JNICALL Java_org_godotengine_godot_editor_utils_EditorUtils_runScene(JNIEnv *p_env, jclass, jstring p_scene, jobjectArray p_scene_args); +JNIEXPORT void JNICALL Java_org_godotengine_godot_editor_utils_EditorUtils_toggleTitleBar(JNIEnv *p_env, jclass, jboolean p_enable); } diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt index 7328f17c19..e6f0684c60 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt @@ -37,7 +37,9 @@ import android.content.ComponentName import android.content.ContentResolver import android.content.Context import android.content.Intent +import android.content.pm.ActivityInfo import android.content.pm.PackageManager +import android.content.res.Configuration import android.os.Build import android.os.Bundle import android.os.Debug @@ -155,6 +157,7 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe internal const val GAME_MENU_ACTION_SET_TIME_SCALE = "setTimeScale" private const val GAME_WORKSPACE = "Game" + private const val SCRIPT_WORKSPACE = "Script" internal const val SNACKBAR_SHOW_DURATION_MS = 5000L @@ -203,6 +206,10 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe private val updatedCommandLineParams = ArrayList() + private var changingOrientationAllowed = false + private var distractionFreeModeEnabled = false + private var activeWorkspace: String? = null + override fun getGodotAppLayout() = R.layout.godot_editor_layout internal open fun getEditorWindowInfo() = EDITOR_MAIN_INFO @@ -269,6 +276,14 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe setupGameMenuBar() } + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + + // Show EditorTitleBar only in landscape due to width limitations in portrait. + // TODO: Enable for portrait once the title bar width is optimized. + EditorUtils.toggleTitleBar(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) + } + override fun onDestroy() { gradleBuildProvider.buildEnvDisconnect() super.onDestroy() @@ -696,7 +711,7 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe /** * The Godot Android Editor sets its own orientation via its AndroidManifest */ - protected open fun overrideOrientationRequest() = true + protected open fun overrideOrientationRequest() = !changingOrientationAllowed protected open fun overrideVolumeButtons() = false @@ -894,6 +909,8 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe } override fun onEditorWorkspaceSelected(workspace: String) { + activeWorkspace = workspace + if (workspace == GAME_WORKSPACE && shouldShowGameMenuBar()) { if (editorMessageDispatcher.bringEditorWindowToFront(EMBEDDED_RUN_GAME_INFO) || editorMessageDispatcher.bringEditorWindowToFront(RUN_GAME_INFO)) { return @@ -906,6 +923,23 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe embeddedGameViewContainerWindow?.isVisible = true } } + + toggleScriptEditorOrientation() + } + + override fun onDistractionFreeModeChanged(enabled: Boolean) { + distractionFreeModeEnabled = enabled + toggleScriptEditorOrientation() + } + + private fun toggleScriptEditorOrientation() { + if (activeWorkspace == SCRIPT_WORKSPACE && distractionFreeModeEnabled) { + changingOrientationAllowed = true + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER + } else if (changingOrientationAllowed) { + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE + changingOrientationAllowed = false + } } internal open fun bringSelfToFront() { diff --git a/platform/android/java/lib/src/main/java/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/main/java/org/godotengine/godot/Godot.kt index 99505baabb..921e083e8f 100644 --- a/platform/android/java/lib/src/main/java/org/godotengine/godot/Godot.kt +++ b/platform/android/java/lib/src/main/java/org/godotengine/godot/Godot.kt @@ -1308,6 +1308,11 @@ class Godot private constructor(val context: Context) { primaryHost?.onEditorWorkspaceSelected(workspace) } + @Keep + private fun nativeOnDistractionFreeModeChanged(enabled: Boolean) { + primaryHost?.onDistractionFreeModeChanged(enabled) + } + @Keep private fun nativeBuildEnvConnect(callback: GodotCallable): Boolean { try { diff --git a/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotFragment.java b/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotFragment.java index 1ecbc2acb5..4a08d97697 100644 --- a/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotFragment.java +++ b/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotFragment.java @@ -496,6 +496,13 @@ public class GodotFragment extends Fragment implements IDownloaderClient, GodotH } } + @Override + public void onDistractionFreeModeChanged(Boolean enabled) { + if (parentHost != null) { + parentHost.onDistractionFreeModeChanged(enabled); + } + } + @Override public BuildProvider getBuildProvider() { if (parentHost != null) { diff --git a/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotHost.java b/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotHost.java index e8be6e886a..40c268d4cf 100644 --- a/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotHost.java +++ b/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotHost.java @@ -153,6 +153,11 @@ public interface GodotHost { */ default void onEditorWorkspaceSelected(String workspace) {} + /** + * Triggered when the editor's distraction-free mode changes. + */ + default void onDistractionFreeModeChanged(Boolean enabled) {} + /** * Runs the specified action on a host provided thread. */ diff --git a/platform/android/java/lib/src/main/java/org/godotengine/godot/editor/utils/EditorUtils.kt b/platform/android/java/lib/src/main/java/org/godotengine/godot/editor/utils/EditorUtils.kt index 7c495e8537..478dbab705 100644 --- a/platform/android/java/lib/src/main/java/org/godotengine/godot/editor/utils/EditorUtils.kt +++ b/platform/android/java/lib/src/main/java/org/godotengine/godot/editor/utils/EditorUtils.kt @@ -38,4 +38,7 @@ package org.godotengine.godot.editor.utils object EditorUtils { @JvmStatic external fun runScene(scene: String, sceneArgs: Array) + + @JvmStatic + external fun toggleTitleBar(visible: Boolean) } diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp index 0eb9d12fdf..fb1f467c43 100644 --- a/platform/android/java_godot_wrapper.cpp +++ b/platform/android/java_godot_wrapper.cpp @@ -89,6 +89,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) { _is_in_immersive_mode = p_env->GetMethodID(godot_class, "isInImmersiveMode", "()Z"); _set_window_color = p_env->GetMethodID(godot_class, "setWindowColor", "(Ljava/lang/String;)V"); _on_editor_workspace_selected = p_env->GetMethodID(godot_class, "nativeOnEditorWorkspaceSelected", "(Ljava/lang/String;)V"); + _on_distraction_free_mode_changed = p_env->GetMethodID(godot_class, "nativeOnDistractionFreeModeChanged", "(Z)V"); _get_activity = p_env->GetMethodID(godot_class, "getActivity", "()Landroid/app/Activity;"); _build_env_connect = p_env->GetMethodID(godot_class, "nativeBuildEnvConnect", "(Lorg/godotengine/godot/variant/Callable;)Z"); _build_env_disconnect = p_env->GetMethodID(godot_class, "nativeBuildEnvDisconnect", "()V"); @@ -615,6 +616,15 @@ void GodotJavaWrapper::on_editor_workspace_selected(const String &p_workspace) { } } +void GodotJavaWrapper::on_distraction_free_mode_changed(bool p_enabled) { + if (_on_distraction_free_mode_changed) { + JNIEnv *env = get_jni_env(); + ERR_FAIL_NULL(env); + + env->CallVoidMethod(godot_instance, _on_distraction_free_mode_changed, p_enabled); + } +} + bool GodotJavaWrapper::build_env_connect(const Callable &p_callback) { if (_build_env_connect) { JNIEnv *env = get_jni_env(); diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h index 15367a1f33..dfa98e0cc2 100644 --- a/platform/android/java_godot_wrapper.h +++ b/platform/android/java_godot_wrapper.h @@ -83,6 +83,7 @@ private: jmethodID _is_in_immersive_mode = nullptr; jmethodID _set_window_color = nullptr; jmethodID _on_editor_workspace_selected = nullptr; + jmethodID _on_distraction_free_mode_changed = nullptr; jmethodID _get_activity = nullptr; jmethodID _build_env_connect = nullptr; jmethodID _build_env_disconnect = nullptr; @@ -146,6 +147,7 @@ public: void set_window_color(const Color &p_color); void on_editor_workspace_selected(const String &p_workspace); + void on_distraction_free_mode_changed(bool p_enabled); bool build_env_connect(const Callable &p_callback); void build_env_disconnect(); diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index a66139d3be..7f033f7b57 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -361,6 +361,10 @@ void OS_Android::main_loop_begin() { if (game_view_plugin != nullptr) { game_view_plugin->connect("main_screen_changed", callable_mp_static(&OS_Android::_on_main_screen_changed)); } + + if (EditorNode::get_singleton() != nullptr) { + EditorNode::get_singleton()->connect("distraction_free_mode_changed", callable_mp_static(&OS_Android::_on_distraction_free_mode_changed)); + } } #endif } @@ -393,6 +397,10 @@ void OS_Android::main_loop_end() { if (game_view_plugin != nullptr) { game_view_plugin->disconnect("main_screen_changed", callable_mp_static(&OS_Android::_on_main_screen_changed)); } + + if (EditorNode::get_singleton() != nullptr) { + EditorNode::get_singleton()->disconnect("distraction_free_mode_changed", callable_mp_static(&OS_Android::_on_distraction_free_mode_changed)); + } } #endif @@ -411,6 +419,12 @@ void OS_Android::_on_main_screen_changed(const String &p_screen_name) { OS_Android::get_singleton()->get_godot_java()->on_editor_workspace_selected(p_screen_name); } } + +void OS_Android::_on_distraction_free_mode_changed(bool p_enable) { + if (OS_Android::get_singleton() != nullptr && OS_Android::get_singleton()->get_godot_java() != nullptr) { + OS_Android::get_singleton()->get_godot_java()->on_distraction_free_mode_changed(p_enable); + } +} #endif void OS_Android::main_loop_focusout() { diff --git a/platform/android/os_android.h b/platform/android/os_android.h index b05069b852..fd487833ac 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -191,5 +191,6 @@ private: #ifdef TOOLS_ENABLED static void _on_main_screen_changed(const String &p_screen_name); + static void _on_distraction_free_mode_changed(bool p_enable); #endif };