diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 1f495b87117..f4b8523b01f 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -123,7 +123,7 @@
Shows a text dialog which uses the operating system's native look-and-feel. [param callback] should accept a single [int] parameter which corresponds to the index of the pressed button.
- [b]Note:[/b] This method is implemented if the display server has the [constant FEATURE_NATIVE_DIALOG] feature. Supported platforms include macOS and Windows.
+ [b]Note:[/b] This method is implemented if the display server has the [constant FEATURE_NATIVE_DIALOG] feature. Supported platforms include macOS, Windows, and Android.
diff --git a/platform/android/SCsub b/platform/android/SCsub
index 66c955252bd..d0928a937b3 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -29,6 +29,7 @@ android_files = [
"plugin/godot_plugin_jni.cpp",
"rendering_context_driver_vulkan_android.cpp",
"variant/callable_jni.cpp",
+ "dialog_utils_jni.cpp",
]
env_android = env.Clone()
diff --git a/platform/android/dialog_utils_jni.cpp b/platform/android/dialog_utils_jni.cpp
new file mode 100644
index 00000000000..c1f8cea06d6
--- /dev/null
+++ b/platform/android/dialog_utils_jni.cpp
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/* dialog_utils_jni.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "dialog_utils_jni.h"
+
+#include "display_server_android.h"
+#include "jni_utils.h"
+
+extern "C" {
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_DialogUtils_dialogCallback(JNIEnv *env, jclass clazz, jint p_button_index) {
+ DisplayServerAndroid *ds = (DisplayServerAndroid *)DisplayServer::get_singleton();
+ if (ds) {
+ ds->emit_dialog_callback(p_button_index);
+ }
+}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_DialogUtils_inputDialogCallback(JNIEnv *env, jclass clazz, jstring p_text) {
+ DisplayServerAndroid *ds = (DisplayServerAndroid *)DisplayServer::get_singleton();
+ if (ds) {
+ String text = jstring_to_string(p_text, env);
+ ds->emit_input_dialog_callback(text);
+ }
+}
+}
diff --git a/platform/android/dialog_utils_jni.h b/platform/android/dialog_utils_jni.h
new file mode 100644
index 00000000000..7b2da46dc57
--- /dev/null
+++ b/platform/android/dialog_utils_jni.h
@@ -0,0 +1,41 @@
+/**************************************************************************/
+/* dialog_utils_jni.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef DIALOG_UTILS_JNI_H
+#define DIALOG_UTILS_JNI_H
+
+#include
+
+extern "C" {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_DialogUtils_dialogCallback(JNIEnv *env, jclass clazz, jint p_button_index);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_utils_DialogUtils_inputDialogCallback(JNIEnv *env, jclass clazz, jstring p_text);
+}
+
+#endif // DIALOG_UTILS_JNI_H
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index d624bbbeb2c..3a0323176d9 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -70,7 +70,7 @@ bool DisplayServerAndroid::has_feature(Feature p_feature) const {
//case FEATURE_IME:
case FEATURE_MOUSE:
//case FEATURE_MOUSE_WARP:
- //case FEATURE_NATIVE_DIALOG:
+ case FEATURE_NATIVE_DIALOG:
case FEATURE_NATIVE_DIALOG_INPUT:
case FEATURE_NATIVE_DIALOG_FILE:
//case FEATURE_NATIVE_DIALOG_FILE_EXTRA:
@@ -177,6 +177,19 @@ bool DisplayServerAndroid::clipboard_has() const {
}
}
+Error DisplayServerAndroid::dialog_show(String p_title, String p_description, Vector p_buttons, const Callable &p_callback) {
+ GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
+ ERR_FAIL_NULL_V(godot_java, FAILED);
+ dialog_callback = p_callback;
+ return godot_java->show_dialog(p_title, p_description, p_buttons);
+}
+
+void DisplayServerAndroid::emit_dialog_callback(int p_button_index) {
+ if (dialog_callback.is_valid()) {
+ dialog_callback.call_deferred(p_button_index);
+ }
+}
+
Error DisplayServerAndroid::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) {
GodotJavaWrapper *godot_java = OS_Android::get_singleton()->get_godot_java();
ERR_FAIL_NULL_V(godot_java, FAILED);
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index 582f722fa5b..0d2caa07b7c 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -87,7 +87,9 @@ class DisplayServerAndroid : public DisplayServer {
Callable system_theme_changed;
+ Callable dialog_callback;
Callable input_dialog_callback;
+
Callable file_picker_callback;
void _window_callback(const Callable &p_callable, const Variant &p_arg, bool p_deferred = false) const;
@@ -119,6 +121,9 @@ public:
virtual String clipboard_get() const override;
virtual bool clipboard_has() const override;
+ virtual Error dialog_show(String p_title, String p_description, Vector p_buttons, const Callable &p_callback) override;
+ void emit_dialog_callback(int p_button_index);
+
virtual Error dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) override;
void emit_input_dialog_callback(String p_text);
diff --git a/platform/android/java/lib/res/values/dimens.xml b/platform/android/java/lib/res/values/dimens.xml
index 287d1c89204..cc0f0788aff 100644
--- a/platform/android/java/lib/res/values/dimens.xml
+++ b/platform/android/java/lib/res/values/dimens.xml
@@ -1,6 +1,8 @@
48dp
- 10dp
- 5dp
+ 48dp
+ 10dp
+ 16dp
+ 8dp
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
index fcbb8830f90..3fc3caed911 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
@@ -44,7 +44,6 @@ import android.os.*
import android.util.Log
import android.util.TypedValue
import android.view.*
-import android.widget.EditText
import android.widget.FrameLayout
import androidx.annotation.Keep
import androidx.annotation.StringRes
@@ -65,6 +64,7 @@ import org.godotengine.godot.plugin.GodotPlugin
import org.godotengine.godot.plugin.GodotPluginRegistry
import org.godotengine.godot.tts.GodotTTS
import org.godotengine.godot.utils.CommandLineFileParser
+import org.godotengine.godot.utils.DialogUtils
import org.godotengine.godot.utils.GodotNetUtils
import org.godotengine.godot.utils.PermissionsUtil
import org.godotengine.godot.utils.PermissionsUtil.requestPermission
@@ -903,27 +903,27 @@ class Godot(private val context: Context) {
}
/**
- * Popup a dialog to input text.
+ * This method shows a dialog with multiple buttons.
+ *
+ * @param title The title of the dialog.
+ * @param message The message displayed in the dialog.
+ * @param buttons An array of button labels to display.
+ */
+ @Keep
+ private fun showDialog(title: String, message: String, buttons: Array) {
+ getActivity()?.let { DialogUtils.showDialog(it, title, message, buttons) }
+ }
+
+ /**
+ * This method shows a dialog with a text input field, allowing the user to input text.
+ *
+ * @param title The title of the input dialog.
+ * @param message The message displayed in the input dialog.
+ * @param existingText The existing text that will be pre-filled in the input field.
*/
@Keep
private fun showInputDialog(title: String, message: String, existingText: String) {
- val activity: Activity = getActivity() ?: return
- val inputField = EditText(activity)
- val paddingHorizontal = activity.resources.getDimensionPixelSize(R.dimen.input_dialog_padding_horizontal)
- val paddingVertical = activity.resources.getDimensionPixelSize(R.dimen.input_dialog_padding_vertical)
- inputField.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical)
- inputField.setText(existingText)
- runOnUiThread {
- val builder = AlertDialog.Builder(activity)
- builder.setMessage(message).setTitle(title).setView(inputField)
- builder.setPositiveButton(R.string.dialog_ok) {
- dialog: DialogInterface, id: Int ->
- GodotLib.inputDialogCallback(inputField.text.toString())
- dialog.dismiss()
- }
- val dialog = builder.create()
- dialog.show()
- }
+ getActivity()?.let { DialogUtils.showInputDialog(it, title, message, existingText) }
}
@Keep
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 9af91924704..67aa3283be5 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -235,11 +235,6 @@ public class GodotLib {
*/
public static native void onNightModeChanged();
- /**
- * Invoked on the input dialog submitted.
- */
- public static native void inputDialogCallback(String p_text);
-
/**
* Invoked on the file picker closed.
*/
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/DialogUtils.kt b/platform/android/java/lib/src/org/godotengine/godot/utils/DialogUtils.kt
new file mode 100644
index 00000000000..45ec72b7433
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/DialogUtils.kt
@@ -0,0 +1,185 @@
+/**************************************************************************/
+/* DialogUtils.kt */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+package org.godotengine.godot.utils
+
+import android.app.Activity
+import android.app.AlertDialog
+import android.content.DialogInterface
+import android.widget.Button
+import android.widget.EditText
+import android.widget.LinearLayout
+
+import org.godotengine.godot.R
+
+/**
+ * Utility class for managing dialogs.
+ */
+internal class DialogUtils {
+ companion object {
+ private val TAG = DialogUtils::class.java.simpleName
+
+ /**
+ * Invoked on dialog button press.
+ */
+ @JvmStatic
+ private external fun dialogCallback(buttonIndex: Int)
+
+ /**
+ * Invoked on the input dialog submitted.
+ */
+ @JvmStatic
+ private external fun inputDialogCallback(text: String)
+
+ /**
+ * Displays a dialog with dynamically arranged buttons based on their text length.
+ *
+ * The buttons are laid out in rows, with a maximum of 2 buttons per row. If a button's text
+ * is too long to fit within half the screen width, it occupies the entire row.
+ *
+ * @param activity The activity where the dialog will be displayed.
+ * @param title The title of the dialog.
+ * @param message The message displayed in the dialog.
+ * @param buttons An array of button labels to display.
+ */
+ fun showDialog(activity: Activity, title: String, message: String, buttons: Array) {
+ var dismissDialog: () -> Unit = {} // Helper to dismiss the Dialog when a button is clicked.
+ activity.runOnUiThread {
+ val builder = AlertDialog.Builder(activity)
+ builder.setTitle(title)
+ builder.setMessage(message)
+
+ val buttonHeight = activity.resources.getDimensionPixelSize(R.dimen.button_height)
+ val paddingHorizontal = activity.resources.getDimensionPixelSize(R.dimen.dialog_padding_horizontal)
+ val paddingVertical = activity.resources.getDimensionPixelSize(R.dimen.dialog_padding_vertical)
+ val buttonPadding = activity.resources.getDimensionPixelSize(R.dimen.button_padding)
+
+ // Create a vertical parent layout to hold all rows of buttons.
+ val parentLayout = LinearLayout(activity)
+ parentLayout.orientation = LinearLayout.VERTICAL
+ parentLayout.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical)
+
+ // Horizontal row layout for arranging buttons.
+ var rowLayout = LinearLayout(activity)
+ rowLayout.orientation = LinearLayout.HORIZONTAL
+ rowLayout.layoutParams = LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ )
+
+ // Calculate the maximum width for a button to allow two buttons per row.
+ val screenWidth = activity.resources.displayMetrics.widthPixels
+ val availableWidth = screenWidth - (2 * paddingHorizontal)
+ val maxButtonWidth = availableWidth / 2
+
+ buttons.forEachIndexed { index, buttonLabel ->
+ val button = Button(activity)
+ button.text = buttonLabel
+ button.isSingleLine = true
+ button.setPadding(buttonPadding, buttonPadding, buttonPadding, buttonPadding)
+
+ // Measure the button to determine its width.
+ button.measure(0, 0)
+ val buttonWidth = button.measuredWidth
+
+ val params = LinearLayout.LayoutParams(
+ if (buttonWidth > maxButtonWidth) LinearLayout.LayoutParams.MATCH_PARENT else 0,
+ buttonHeight
+ )
+ params.weight = if (buttonWidth > maxButtonWidth) 0f else 1f
+ button.layoutParams = params
+
+ // Handle full-width buttons by finalizing the current row, if needed.
+ if (buttonWidth > maxButtonWidth) {
+ if (rowLayout.childCount > 0) {
+ parentLayout.addView(rowLayout)
+ rowLayout = LinearLayout(activity)
+ rowLayout.orientation = LinearLayout.HORIZONTAL
+ }
+ // Add the full-width button directly to the parent layout.
+ parentLayout.addView(button)
+ } else {
+ rowLayout.addView(button)
+
+ // Finalize the row if it reaches 2 buttons.
+ if (rowLayout.childCount == 2) {
+ parentLayout.addView(rowLayout)
+ rowLayout = LinearLayout(activity)
+ rowLayout.orientation = LinearLayout.HORIZONTAL
+ }
+
+ // Handle the last button with incomplete row.
+ if (index == buttons.size - 1 && rowLayout.childCount > 0) {
+ parentLayout.addView(rowLayout)
+ }
+ }
+
+ button.setOnClickListener {
+ dialogCallback(index)
+ dismissDialog()
+ }
+ }
+
+ // Attach the parent layout to the dialog.
+ builder.setView(parentLayout)
+ val dialog = builder.create()
+ dismissDialog = {dialog.dismiss()}
+ dialog.show()
+ }
+ }
+
+ /**
+ * This method shows a dialog with a text input field, allowing the user to input text.
+ *
+ * @param activity The activity where the input dialog will be displayed.
+ * @param title The title of the input dialog.
+ * @param message The message displayed in the input dialog.
+ * @param existingText The existing text that will be pre-filled in the input field.
+ */
+ fun showInputDialog(activity: Activity, title: String, message: String, existingText: String) {
+ val inputField = EditText(activity)
+ val paddingHorizontal = activity.resources.getDimensionPixelSize(R.dimen.dialog_padding_horizontal)
+ val paddingVertical = activity.resources.getDimensionPixelSize(R.dimen.dialog_padding_vertical)
+ inputField.setPadding(paddingHorizontal, paddingVertical, paddingHorizontal, paddingVertical)
+ inputField.setText(existingText)
+ activity.runOnUiThread {
+ val builder = AlertDialog.Builder(activity)
+ builder.setMessage(message).setTitle(title).setView(inputField)
+ builder.setPositiveButton(R.string.dialog_ok) {
+ dialog: DialogInterface, id: Int ->
+ inputDialogCallback(inputField.text.toString())
+ dialog.dismiss()
+ }
+ val dialog = builder.create()
+ dialog.show()
+ }
+ }
+ }
+}
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index 023832a2d34..b291473e29d 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -494,14 +494,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onNightModeChanged(JN
}
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_inputDialogCallback(JNIEnv *env, jclass clazz, jstring p_text) {
- DisplayServerAndroid *ds = (DisplayServerAndroid *)DisplayServer::get_singleton();
- if (ds) {
- String text = jstring_to_string(p_text, env);
- ds->emit_input_dialog_callback(text);
- }
-}
-
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_filePickerCallback(JNIEnv *env, jclass clazz, jboolean p_ok, jobjectArray p_selected_paths) {
DisplayServerAndroid *ds = (DisplayServerAndroid *)DisplayServer::get_singleton();
if (ds) {
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index 48d91795c7b..6feaec47c59 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -65,7 +65,6 @@ JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getEditorSetting(J
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jclass clazz, jint p_height);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResult(JNIEnv *env, jclass clazz, jstring p_permission, jboolean p_result);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onNightModeChanged(JNIEnv *env, jclass clazz);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_inputDialogCallback(JNIEnv *env, jclass clazz, jstring p_text);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_filePickerCallback(JNIEnv *env, jclass clazz, jboolean p_ok, jobjectArray p_selected_paths);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererPaused(JNIEnv *env, jclass clazz);
diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp
index 69d7ac37ea6..19d31547975 100644
--- a/platform/android/java_godot_wrapper.cpp
+++ b/platform/android/java_godot_wrapper.cpp
@@ -69,6 +69,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_
_get_clipboard = p_env->GetMethodID(godot_class, "getClipboard", "()Ljava/lang/String;");
_set_clipboard = p_env->GetMethodID(godot_class, "setClipboard", "(Ljava/lang/String;)V");
_has_clipboard = p_env->GetMethodID(godot_class, "hasClipboard", "()Z");
+ _show_dialog = p_env->GetMethodID(godot_class, "showDialog", "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V");
_show_input_dialog = p_env->GetMethodID(godot_class, "showInputDialog", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
_show_file_picker = p_env->GetMethodID(godot_class, "showFilePicker", "(Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;)V");
_request_permission = p_env->GetMethodID(godot_class, "requestPermission", "(Ljava/lang/String;)Z");
@@ -303,6 +304,28 @@ bool GodotJavaWrapper::has_clipboard() {
}
}
+Error GodotJavaWrapper::show_dialog(const String &p_title, const String &p_description, const Vector &p_buttons) {
+ if (_show_input_dialog) {
+ JNIEnv *env = get_jni_env();
+ ERR_FAIL_NULL_V(env, ERR_UNCONFIGURED);
+ jstring j_title = env->NewStringUTF(p_title.utf8().get_data());
+ jstring j_description = env->NewStringUTF(p_description.utf8().get_data());
+ jobjectArray j_buttons = env->NewObjectArray(p_buttons.size(), env->FindClass("java/lang/String"), nullptr);
+ for (int i = 0; i < p_buttons.size(); ++i) {
+ jstring j_button = env->NewStringUTF(p_buttons[i].utf8().get_data());
+ env->SetObjectArrayElement(j_buttons, i, j_button);
+ env->DeleteLocalRef(j_button);
+ }
+ env->CallVoidMethod(godot_instance, _show_dialog, j_title, j_description, j_buttons);
+ env->DeleteLocalRef(j_title);
+ env->DeleteLocalRef(j_description);
+ env->DeleteLocalRef(j_buttons);
+ return OK;
+ } else {
+ return ERR_UNCONFIGURED;
+ }
+}
+
Error GodotJavaWrapper::show_input_dialog(const String &p_title, const String &p_message, const String &p_existing_text) {
if (_show_input_dialog) {
JNIEnv *env = get_jni_env();
diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h
index 50612abf94a..1c74072e1a8 100644
--- a/platform/android/java_godot_wrapper.h
+++ b/platform/android/java_godot_wrapper.h
@@ -60,6 +60,7 @@ private:
jmethodID _get_clipboard = nullptr;
jmethodID _set_clipboard = nullptr;
jmethodID _has_clipboard = nullptr;
+ jmethodID _show_dialog = nullptr;
jmethodID _show_input_dialog = nullptr;
jmethodID _show_file_picker = nullptr;
jmethodID _request_permission = nullptr;
@@ -109,6 +110,7 @@ public:
void set_clipboard(const String &p_text);
bool has_has_clipboard();
bool has_clipboard();
+ Error show_dialog(const String &p_title, const String &p_description, const Vector &p_buttons);
Error show_input_dialog(const String &p_title, const String &p_message, const String &p_existing_text);
Error show_file_picker(const String &p_current_directory, const String &p_filename, int p_mode, const Vector &p_filters);
bool request_permission(const String &p_name);