forked from Mirrorlandia_minetest/minetest
Android: Add selection dialog (drop down/combo box) (#13814)
- The handling of IGUIComboBox uses the new setAndSendSelected() method. - getDialogState() is now getInputDialogState() and returns the state of the input dialog. - getLastDialogType() is added and returns current/last shown dialog's type. - getInputDialogState() now returns an enum instead of int. - getAndroidUIInput() now returns void instead of bool. - New data types (enum) are added: (1) GameActivity.DialogType (Java) and porting::AndroidDialogType (C++) (2) GameActivity.DialogState (Java) and porting::AndroidDialogState (C++) - When showing a text input dialog, there is no custom accept button text any more. - showDialog()/showDialogUI() for text input is now showTextInputDialog()/showTextInputDialogUI(). - showInputDialog()/showDialogUI() for text input is now showTextInputDialog()/showTextInputDialogUI(). - getDialogValue()/getInputDialogValue() is now getDialogMessage()/getInputDialogMessage(). Co-authored-by: Gregor Parzefall <82708541+grorp@users.noreply.github.com>
This commit is contained in:
parent
bd42cc2c77
commit
171f911237
@ -51,8 +51,13 @@ public class GameActivity extends NativeActivity {
|
|||||||
System.loadLibrary("minetest");
|
System.loadLibrary("minetest");
|
||||||
}
|
}
|
||||||
|
|
||||||
private int messageReturnCode = -1;
|
enum DialogType { TEXT_INPUT, SELECTION_INPUT }
|
||||||
|
enum DialogState { DIALOG_SHOWN, DIALOG_INPUTTED, DIALOG_CANCELED }
|
||||||
|
|
||||||
|
private DialogType lastDialogType = DialogType.TEXT_INPUT;
|
||||||
|
private DialogState inputDialogState = DialogState.DIALOG_CANCELED;
|
||||||
private String messageReturnValue = "";
|
private String messageReturnValue = "";
|
||||||
|
private int selectionReturnValue = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@ -85,11 +90,17 @@ public class GameActivity extends NativeActivity {
|
|||||||
// Ignore the back press so Minetest can handle it
|
// Ignore the back press so Minetest can handle it
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showDialog(String acceptButton, String hint, String current, int editType) {
|
public void showTextInputDialog(String hint, String current, int editType) {
|
||||||
runOnUiThread(() -> showDialogUI(hint, current, editType));
|
runOnUiThread(() -> showTextInputDialogUI(hint, current, editType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showDialogUI(String hint, String current, int editType) {
|
public void showSelectionInputDialog(String[] optionList, int selectedIdx) {
|
||||||
|
runOnUiThread(() -> showSelectionInputDialogUI(optionList, selectedIdx));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showTextInputDialogUI(String hint, String current, int editType) {
|
||||||
|
lastDialogType = DialogType.TEXT_INPUT;
|
||||||
|
inputDialogState = DialogState.DIALOG_SHOWN;
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
LinearLayout container = new LinearLayout(this);
|
LinearLayout container = new LinearLayout(this);
|
||||||
container.setOrientation(LinearLayout.VERTICAL);
|
container.setOrientation(LinearLayout.VERTICAL);
|
||||||
@ -114,7 +125,7 @@ public class GameActivity extends NativeActivity {
|
|||||||
// For multi-line, do not submit the text after pressing Enter key
|
// For multi-line, do not submit the text after pressing Enter key
|
||||||
if (keyCode == KeyEvent.KEYCODE_ENTER && editType != 1) {
|
if (keyCode == KeyEvent.KEYCODE_ENTER && editType != 1) {
|
||||||
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
|
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
|
||||||
messageReturnCode = 0;
|
inputDialogState = DialogState.DIALOG_INPUTTED;
|
||||||
messageReturnValue = editText.getText().toString();
|
messageReturnValue = editText.getText().toString();
|
||||||
alertDialog.dismiss();
|
alertDialog.dismiss();
|
||||||
return true;
|
return true;
|
||||||
@ -128,29 +139,55 @@ public class GameActivity extends NativeActivity {
|
|||||||
doneButton.setText(R.string.ime_dialog_done);
|
doneButton.setText(R.string.ime_dialog_done);
|
||||||
doneButton.setOnClickListener((view -> {
|
doneButton.setOnClickListener((view -> {
|
||||||
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
|
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
|
||||||
messageReturnCode = 0;
|
inputDialogState = DialogState.DIALOG_INPUTTED;
|
||||||
messageReturnValue = editText.getText().toString();
|
messageReturnValue = editText.getText().toString();
|
||||||
alertDialog.dismiss();
|
alertDialog.dismiss();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
alertDialog.setOnCancelListener(dialog -> {
|
alertDialog.setOnCancelListener(dialog -> {
|
||||||
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
||||||
|
inputDialogState = DialogState.DIALOG_CANCELED;
|
||||||
messageReturnValue = current;
|
messageReturnValue = current;
|
||||||
messageReturnCode = -1;
|
|
||||||
});
|
});
|
||||||
alertDialog.show();
|
alertDialog.show();
|
||||||
editText.requestFocusTryShow();
|
editText.requestFocusTryShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDialogState() {
|
public void showSelectionInputDialogUI(String[] optionList, int selectedIdx) {
|
||||||
return messageReturnCode;
|
lastDialogType = DialogType.SELECTION_INPUT;
|
||||||
|
inputDialogState = DialogState.DIALOG_SHOWN;
|
||||||
|
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
|
builder.setSingleChoiceItems(optionList, selectedIdx, (dialog, selection) -> {
|
||||||
|
inputDialogState = DialogState.DIALOG_INPUTTED;
|
||||||
|
selectionReturnValue = selection;
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
builder.setOnCancelListener(dialog -> {
|
||||||
|
inputDialogState = DialogState.DIALOG_CANCELED;
|
||||||
|
selectionReturnValue = selectedIdx;
|
||||||
|
});
|
||||||
|
AlertDialog alertDialog = builder.create();
|
||||||
|
alertDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDialogValue() {
|
public int getLastDialogType() {
|
||||||
messageReturnCode = -1;
|
return lastDialogType.ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInputDialogState() {
|
||||||
|
return inputDialogState.ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDialogMessage() {
|
||||||
|
inputDialogState = DialogState.DIALOG_CANCELED;
|
||||||
return messageReturnValue;
|
return messageReturnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getDialogSelection() {
|
||||||
|
inputDialogState = DialogState.DIALOG_CANCELED;
|
||||||
|
return selectionReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
public float getDensity() {
|
public float getDensity() {
|
||||||
return getResources().getDisplayMetrics().density;
|
return getResources().getDisplayMetrics().density;
|
||||||
}
|
}
|
||||||
|
@ -2277,7 +2277,7 @@ void Game::openConsole(float scale, const wchar_t *line)
|
|||||||
assert(scale > 0.0f && scale <= 1.0f);
|
assert(scale > 0.0f && scale <= 1.0f);
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
porting::showInputDialog(gettext("ok"), "", "", 2);
|
porting::showTextInputDialog("", "", 2);
|
||||||
m_android_chat_open = true;
|
m_android_chat_open = true;
|
||||||
#else
|
#else
|
||||||
if (gui_chat_console->isOpenInhibited())
|
if (gui_chat_console->isOpenInhibited())
|
||||||
@ -2293,15 +2293,19 @@ void Game::openConsole(float scale, const wchar_t *line)
|
|||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
void Game::handleAndroidChatInput()
|
void Game::handleAndroidChatInput()
|
||||||
{
|
{
|
||||||
if (m_android_chat_open && porting::getInputDialogState() == 0) {
|
// It has to be a text input
|
||||||
std::string text = porting::getInputDialogValue();
|
if (m_android_chat_open && porting::getLastInputDialogType() == porting::TEXT_INPUT) {
|
||||||
client->typeChatMessage(utf8_to_wide(text));
|
porting::AndroidDialogState dialogState = porting::getInputDialogState();
|
||||||
m_android_chat_open = false;
|
if (dialogState == porting::DIALOG_INPUTTED) {
|
||||||
|
std::string text = porting::getInputDialogMessage();
|
||||||
|
client->typeChatMessage(utf8_to_wide(text));
|
||||||
|
}
|
||||||
|
if (dialogState != porting::DIALOG_SHOWN)
|
||||||
|
m_android_chat_open = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void Game::toggleFreeMove()
|
void Game::toggleFreeMove()
|
||||||
{
|
{
|
||||||
bool free_move = !g_settings->getBool("free_move");
|
bool free_move = !g_settings->getBool("free_move");
|
||||||
|
@ -3497,46 +3497,58 @@ void GUIFormSpecMenu::legacySortElements(std::list<IGUIElement *>::iterator from
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
bool GUIFormSpecMenu::getAndroidUIInput()
|
void GUIFormSpecMenu::getAndroidUIInput()
|
||||||
{
|
{
|
||||||
if (!hasAndroidUIInput())
|
porting::AndroidDialogState dialogState = getAndroidUIInputState();
|
||||||
return false;
|
if (dialogState == porting::DIALOG_SHOWN) {
|
||||||
|
return;
|
||||||
|
} else if (dialogState == porting::DIALOG_CANCELED) {
|
||||||
|
m_jni_field_name.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// still waiting
|
porting::AndroidDialogType dialog_type = porting::getLastInputDialogType();
|
||||||
if (porting::getInputDialogState() == -1)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
std::string fieldname = m_jni_field_name;
|
std::string fieldname = m_jni_field_name;
|
||||||
m_jni_field_name.clear();
|
m_jni_field_name.clear();
|
||||||
|
|
||||||
for (const FieldSpec &field : m_fields) {
|
for (const FieldSpec &field : m_fields) {
|
||||||
if (field.fname != fieldname)
|
if (field.fname != fieldname)
|
||||||
continue;
|
continue; // Iterate until found
|
||||||
|
|
||||||
IGUIElement *element = getElementFromId(field.fid, true);
|
IGUIElement *element = getElementFromId(field.fid, true);
|
||||||
|
|
||||||
if (!element || element->getType() != irr::gui::EGUIET_EDIT_BOX)
|
if (!element)
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
gui::IGUIEditBox *editbox = (gui::IGUIEditBox *)element;
|
auto element_type = element->getType();
|
||||||
std::string text = porting::getInputDialogValue();
|
if (dialog_type == porting::TEXT_INPUT && element_type == irr::gui::EGUIET_EDIT_BOX) {
|
||||||
editbox->setText(utf8_to_wide(text).c_str());
|
gui::IGUIEditBox *editbox = (gui::IGUIEditBox *)element;
|
||||||
|
std::string text = porting::getInputDialogMessage();
|
||||||
|
editbox->setText(utf8_to_wide(text).c_str());
|
||||||
|
|
||||||
bool enter_after_edit = false;
|
bool enter_after_edit = false;
|
||||||
auto iter = field_enter_after_edit.find(fieldname);
|
auto iter = field_enter_after_edit.find(fieldname);
|
||||||
if (iter != field_enter_after_edit.end()) {
|
if (iter != field_enter_after_edit.end()) {
|
||||||
enter_after_edit = iter->second;
|
enter_after_edit = iter->second;
|
||||||
}
|
}
|
||||||
if (enter_after_edit && editbox->getParent()) {
|
if (enter_after_edit && editbox->getParent()) {
|
||||||
SEvent enter;
|
SEvent enter;
|
||||||
enter.EventType = EET_GUI_EVENT;
|
enter.EventType = EET_GUI_EVENT;
|
||||||
enter.GUIEvent.Caller = editbox;
|
enter.GUIEvent.Caller = editbox;
|
||||||
enter.GUIEvent.Element = nullptr;
|
enter.GUIEvent.Element = nullptr;
|
||||||
enter.GUIEvent.EventType = gui::EGET_EDITBOX_ENTER;
|
enter.GUIEvent.EventType = gui::EGET_EDITBOX_ENTER;
|
||||||
editbox->getParent()->OnEvent(enter);
|
editbox->getParent()->OnEvent(enter);
|
||||||
|
}
|
||||||
|
} else if (dialog_type == porting::SELECTION_INPUT &&
|
||||||
|
element_type == irr::gui::EGUIET_COMBO_BOX) {
|
||||||
|
auto dropdown = (gui::IGUIComboBox *) element;
|
||||||
|
int selected = porting::getInputDialogSelection();
|
||||||
|
dropdown->setAndSendSelected(selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return; // Early-return after found
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ public:
|
|||||||
core::rect<s32> getAbsoluteRect();
|
core::rect<s32> getAbsoluteRect();
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
bool getAndroidUIInput();
|
void getAndroidUIInput();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -264,14 +264,19 @@ std::string GUIPasswordChange::getNameByID(s32 id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
bool GUIPasswordChange::getAndroidUIInput()
|
void GUIPasswordChange::getAndroidUIInput()
|
||||||
{
|
{
|
||||||
if (!hasAndroidUIInput())
|
porting::AndroidDialogState dialogState = getAndroidUIInputState();
|
||||||
return false;
|
if (dialogState == porting::DIALOG_SHOWN) {
|
||||||
|
return;
|
||||||
|
} else if (dialogState == porting::DIALOG_CANCELED) {
|
||||||
|
m_jni_field_name.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// still waiting
|
// It has to be a text input
|
||||||
if (porting::getInputDialogState() == -1)
|
if (porting::getLastInputDialogType() != porting::TEXT_INPUT)
|
||||||
return true;
|
return;
|
||||||
|
|
||||||
gui::IGUIElement *e = nullptr;
|
gui::IGUIElement *e = nullptr;
|
||||||
if (m_jni_field_name == "old_password")
|
if (m_jni_field_name == "old_password")
|
||||||
@ -283,10 +288,10 @@ bool GUIPasswordChange::getAndroidUIInput()
|
|||||||
m_jni_field_name.clear();
|
m_jni_field_name.clear();
|
||||||
|
|
||||||
if (!e || e->getType() != irr::gui::EGUIET_EDIT_BOX)
|
if (!e || e->getType() != irr::gui::EGUIET_EDIT_BOX)
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
std::string text = porting::getInputDialogValue();
|
std::string text = porting::getInputDialogMessage();
|
||||||
e->setText(utf8_to_wide(text).c_str());
|
e->setText(utf8_to_wide(text).c_str());
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,7 +45,7 @@ public:
|
|||||||
|
|
||||||
bool OnEvent(const SEvent &event);
|
bool OnEvent(const SEvent &event);
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
bool getAndroidUIInput();
|
void getAndroidUIInput();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -268,11 +268,34 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
|
|||||||
if (((gui::IGUIEditBox *)hovered)->isPasswordBox())
|
if (((gui::IGUIEditBox *)hovered)->isPasswordBox())
|
||||||
type = 3;
|
type = 3;
|
||||||
|
|
||||||
porting::showInputDialog(gettext("OK"), "",
|
porting::showTextInputDialog("",
|
||||||
wide_to_utf8(((gui::IGUIEditBox *)hovered)->getText()), type);
|
wide_to_utf8(((gui::IGUIEditBox *) hovered)->getText()), type);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event.EventType == EET_GUI_EVENT) {
|
||||||
|
if (event.GUIEvent.EventType == gui::EGET_LISTBOX_OPENED) {
|
||||||
|
gui::IGUIComboBox *dropdown = (gui::IGUIComboBox *) event.GUIEvent.Caller;
|
||||||
|
|
||||||
|
std::string field_name = getNameByID(dropdown->getID());
|
||||||
|
if (field_name.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_jni_field_name = field_name;
|
||||||
|
|
||||||
|
s32 selected_idx = dropdown->getSelected();
|
||||||
|
s32 option_size = dropdown->getItemCount();
|
||||||
|
std::string list_of_options[option_size];
|
||||||
|
|
||||||
|
for (s32 i = 0; i < option_size; i++) {
|
||||||
|
list_of_options[i] = wide_to_utf8(dropdown->getItem(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
porting::showComboBoxDialog(list_of_options, option_size, selected_idx);
|
||||||
|
return true; // Prevent the Irrlicht dropdown from opening.
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Convert touch events into mouse events.
|
// Convert touch events into mouse events.
|
||||||
@ -347,22 +370,12 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
bool GUIModalMenu::hasAndroidUIInput()
|
porting::AndroidDialogState GUIModalMenu::getAndroidUIInputState()
|
||||||
{
|
{
|
||||||
// no dialog shown
|
// No dialog is shown
|
||||||
if (m_jni_field_name.empty())
|
if (m_jni_field_name.empty())
|
||||||
return false;
|
return porting::DIALOG_CANCELED;
|
||||||
|
|
||||||
// still waiting
|
return porting::getInputDialogState();
|
||||||
if (porting::getInputDialogState() == -1)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// no value abort dialog processing
|
|
||||||
if (porting::getInputDialogState() != 0) {
|
|
||||||
m_jni_field_name.clear();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,6 +22,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "irrlichttypes_extrabloated.h"
|
#include "irrlichttypes_extrabloated.h"
|
||||||
#include "irr_ptr.h"
|
#include "irr_ptr.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include <porting_android.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
enum class PointerType {
|
enum class PointerType {
|
||||||
Mouse,
|
Mouse,
|
||||||
@ -59,8 +62,8 @@ public:
|
|||||||
virtual bool OnEvent(const SEvent &event) { return false; };
|
virtual bool OnEvent(const SEvent &event) { return false; };
|
||||||
virtual bool pausesGame() { return false; } // Used for pause menu
|
virtual bool pausesGame() { return false; } // Used for pause menu
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
virtual bool getAndroidUIInput() { return false; }
|
virtual void getAndroidUIInput() {};
|
||||||
bool hasAndroidUIInput();
|
porting::AndroidDialogState getAndroidUIInputState();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PointerType getPointerType() { return m_pointer_type; };
|
PointerType getPointerType() { return m_pointer_type; };
|
||||||
|
@ -165,22 +165,41 @@ bool setSystemPaths()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void showInputDialog(const std::string &acceptButton, const std::string &hint,
|
void showTextInputDialog(const std::string &hint, const std::string ¤t, int editType)
|
||||||
const std::string ¤t, int editType)
|
|
||||||
{
|
{
|
||||||
jmethodID showdialog = jnienv->GetMethodID(nativeActivity, "showDialog",
|
jmethodID showdialog = jnienv->GetMethodID(nativeActivity, "showTextInputDialog",
|
||||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
|
"(Ljava/lang/String;Ljava/lang/String;I)V");
|
||||||
|
|
||||||
FATAL_ERROR_IF(showdialog == nullptr,
|
FATAL_ERROR_IF(showdialog == nullptr,
|
||||||
"porting::showInputDialog unable to find Java showDialog method");
|
"porting::showTextInputDialog unable to find Java showTextInputDialog method");
|
||||||
|
|
||||||
jstring jacceptButton = jnienv->NewStringUTF(acceptButton.c_str());
|
|
||||||
jstring jhint = jnienv->NewStringUTF(hint.c_str());
|
jstring jhint = jnienv->NewStringUTF(hint.c_str());
|
||||||
jstring jcurrent = jnienv->NewStringUTF(current.c_str());
|
jstring jcurrent = jnienv->NewStringUTF(current.c_str());
|
||||||
jint jeditType = editType;
|
jint jeditType = editType;
|
||||||
|
|
||||||
jnienv->CallVoidMethod(app_global->activity->clazz, showdialog,
|
jnienv->CallVoidMethod(app_global->activity->clazz, showdialog,
|
||||||
jacceptButton, jhint, jcurrent, jeditType);
|
jhint, jcurrent, jeditType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showComboBoxDialog(const std::string optionList[], s32 listSize, s32 selectedIdx)
|
||||||
|
{
|
||||||
|
jmethodID showdialog = jnienv->GetMethodID(nativeActivity, "showSelectionInputDialog",
|
||||||
|
"([Ljava/lang/String;I)V");
|
||||||
|
|
||||||
|
FATAL_ERROR_IF(showdialog == nullptr,
|
||||||
|
"porting::showComboBoxDialog unable to find Java showSelectionInputDialog method");
|
||||||
|
|
||||||
|
jclass jStringClass = jnienv->FindClass("java/lang/String");
|
||||||
|
jobjectArray jOptionList = jnienv->NewObjectArray(listSize, jStringClass, NULL);
|
||||||
|
jint jselectedIdx = selectedIdx;
|
||||||
|
|
||||||
|
for (s32 i = 0; i < listSize; i ++) {
|
||||||
|
jnienv->SetObjectArrayElement(jOptionList, i,
|
||||||
|
jnienv->NewStringUTF(optionList[i].c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
jnienv->CallVoidMethod(app_global->activity->clazz, showdialog, jOptionList,
|
||||||
|
jselectedIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void openURIAndroid(const char *url)
|
void openURIAndroid(const char *url)
|
||||||
@ -207,30 +226,53 @@ void shareFileAndroid(const std::string &path)
|
|||||||
jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl);
|
jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getInputDialogState()
|
AndroidDialogType getLastInputDialogType()
|
||||||
{
|
{
|
||||||
jmethodID dialogstate = jnienv->GetMethodID(nativeActivity,
|
jmethodID lastdialogtype = jnienv->GetMethodID(nativeActivity,
|
||||||
"getDialogState", "()I");
|
"getLastDialogType", "()I");
|
||||||
|
|
||||||
FATAL_ERROR_IF(dialogstate == nullptr,
|
FATAL_ERROR_IF(lastdialogtype == nullptr,
|
||||||
"porting::getInputDialogState unable to find Java getDialogState method");
|
"porting::getLastInputDialogType unable to find Java getLastDialogType method");
|
||||||
|
|
||||||
return jnienv->CallIntMethod(app_global->activity->clazz, dialogstate);
|
int dialogType = jnienv->CallIntMethod(app_global->activity->clazz, lastdialogtype);
|
||||||
|
return static_cast<AndroidDialogType>(dialogType);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getInputDialogValue()
|
AndroidDialogState getInputDialogState()
|
||||||
|
{
|
||||||
|
jmethodID inputdialogstate = jnienv->GetMethodID(nativeActivity,
|
||||||
|
"getInputDialogState", "()I");
|
||||||
|
|
||||||
|
FATAL_ERROR_IF(inputdialogstate == nullptr,
|
||||||
|
"porting::getInputDialogState unable to find Java getInputDialogState method");
|
||||||
|
|
||||||
|
int dialogState = jnienv->CallIntMethod(app_global->activity->clazz, inputdialogstate);
|
||||||
|
return static_cast<AndroidDialogState>(dialogState);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getInputDialogMessage()
|
||||||
{
|
{
|
||||||
jmethodID dialogvalue = jnienv->GetMethodID(nativeActivity,
|
jmethodID dialogvalue = jnienv->GetMethodID(nativeActivity,
|
||||||
"getDialogValue", "()Ljava/lang/String;");
|
"getDialogMessage", "()Ljava/lang/String;");
|
||||||
|
|
||||||
FATAL_ERROR_IF(dialogvalue == nullptr,
|
FATAL_ERROR_IF(dialogvalue == nullptr,
|
||||||
"porting::getInputDialogValue unable to find Java getDialogValue method");
|
"porting::getInputDialogMessage unable to find Java getDialogMessage method");
|
||||||
|
|
||||||
jobject result = jnienv->CallObjectMethod(app_global->activity->clazz,
|
jobject result = jnienv->CallObjectMethod(app_global->activity->clazz,
|
||||||
dialogvalue);
|
dialogvalue);
|
||||||
return readJavaString((jstring) result);
|
return readJavaString((jstring) result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getInputDialogSelection()
|
||||||
|
{
|
||||||
|
jmethodID dialogvalue = jnienv->GetMethodID(nativeActivity, "getDialogSelection", "()I");
|
||||||
|
|
||||||
|
FATAL_ERROR_IF(dialogvalue == nullptr,
|
||||||
|
"porting::getInputDialogSelection unable to find Java getDialogSelection method");
|
||||||
|
|
||||||
|
return jnienv->CallIntMethod(app_global->activity->clazz, dialogvalue);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
float getDisplayDensity()
|
float getDisplayDensity()
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef __ANDROID__
|
#ifndef __ANDROID__
|
||||||
#error this include has to be included on android port only!
|
#error This header has to be included on Android port only!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
@ -30,22 +30,28 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace porting {
|
namespace porting {
|
||||||
// java app
|
// Java app
|
||||||
extern android_app *app_global;
|
extern android_app *app_global;
|
||||||
|
|
||||||
// java <-> c++ interaction interface
|
// Java <-> C++ interaction interface
|
||||||
extern JNIEnv *jnienv;
|
extern JNIEnv *jnienv;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show text input dialog in java
|
* Show a text input dialog in Java
|
||||||
* @param acceptButton text to display on accept button
|
* @param hint Hint to be shown
|
||||||
* @param hint hint to show
|
* @param current Initial value to be displayed
|
||||||
* @param current initial value to display
|
* @param editType Type of the text field
|
||||||
* @param editType type of texfield
|
* (1 = multi-line text input; 2 = single-line text input; 3 = password field)
|
||||||
* (1==multiline text input; 2==single line text input; 3=password field)
|
|
||||||
*/
|
*/
|
||||||
void showInputDialog(const std::string &acceptButton,
|
void showTextInputDialog(const std::string &hint, const std::string ¤t, int editType);
|
||||||
const std::string &hint, const std::string ¤t, int editType);
|
|
||||||
|
/**
|
||||||
|
* Show a selection dialog in Java
|
||||||
|
* @param optionList The list of options
|
||||||
|
* @param listSize Size of the list
|
||||||
|
* @param selectedIdx Selected index
|
||||||
|
*/
|
||||||
|
void showComboBoxDialog(const std::string optionList[], s32 listSize, s32 selectedIdx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a share intent to the file at path
|
* Opens a share intent to the file at path
|
||||||
@ -54,17 +60,48 @@ void showInputDialog(const std::string &acceptButton,
|
|||||||
*/
|
*/
|
||||||
void shareFileAndroid(const std::string &path);
|
void shareFileAndroid(const std::string &path);
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* WORKAROUND for not working callbacks from java -> c++
|
* Types of Android input dialog:
|
||||||
* get current state of input dialog
|
* 1. Text input (single/multi-line text and password field)
|
||||||
|
* 2. Selection input (combo box)
|
||||||
*/
|
*/
|
||||||
int getInputDialogState();
|
enum AndroidDialogType { TEXT_INPUT, SELECTION_INPUT };
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* WORKAROUND for not working callbacks from java -> c++
|
* WORKAROUND for not working callbacks from Java -> C++
|
||||||
* get text in current input dialog
|
* Get the type of the last input dialog
|
||||||
*/
|
*/
|
||||||
std::string getInputDialogValue();
|
AndroidDialogType getLastInputDialogType();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* States of Android input dialog:
|
||||||
|
* 1. The dialog is currently shown.
|
||||||
|
* 2. The dialog has its input sent.
|
||||||
|
* 3. The dialog is canceled/dismissed.
|
||||||
|
*/
|
||||||
|
enum AndroidDialogState { DIALOG_SHOWN, DIALOG_INPUTTED, DIALOG_CANCELED };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WORKAROUND for not working callbacks from Java -> C++
|
||||||
|
* Get the state of the input dialog
|
||||||
|
*/
|
||||||
|
AndroidDialogState getInputDialogState();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WORKAROUND for not working callbacks from Java -> C++
|
||||||
|
* Get the text in the current/last input dialog
|
||||||
|
* This function clears the dialog state (set to canceled). Make sure to save
|
||||||
|
* the dialog state before calling this function.
|
||||||
|
*/
|
||||||
|
std::string getInputDialogMessage();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WORKAROUND for not working callbacks from Java -> C++
|
||||||
|
* Get the selection in the current/last input dialog
|
||||||
|
* This function clears the dialog state (set to canceled). Make sure to save
|
||||||
|
* the dialog state before calling this function.
|
||||||
|
*/
|
||||||
|
int getInputDialogSelection();
|
||||||
|
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
float getDisplayDensity();
|
float getDisplayDensity();
|
||||||
|
Loading…
Reference in New Issue
Block a user