74 changes: 58 additions & 16 deletions src/porting_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,22 +165,41 @@ bool setSystemPaths()
return true;
}

void showInputDialog(const std::string &acceptButton, const std::string &hint,
const std::string &current, int editType)
void showTextInputDialog(const std::string &hint, const std::string &current, int editType)
{
jmethodID showdialog = jnienv->GetMethodID(nativeActivity, "showDialog",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
jmethodID showdialog = jnienv->GetMethodID(nativeActivity, "showTextInputDialog",
"(Ljava/lang/String;Ljava/lang/String;I)V");

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 jcurrent = jnienv->NewStringUTF(current.c_str());
jint jeditType = editType;

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)
Expand All @@ -207,30 +226,53 @@ void shareFileAndroid(const std::string &path)
jnienv->CallVoidMethod(app_global->activity->clazz, url_open, jurl);
}

int getInputDialogState()
AndroidDialogType getLastInputDialogType()
{
jmethodID lastdialogtype = jnienv->GetMethodID(nativeActivity,
"getLastDialogType", "()I");

FATAL_ERROR_IF(lastdialogtype == nullptr,
"porting::getLastInputDialogType unable to find Java getLastDialogType method");

int dialogType = jnienv->CallIntMethod(app_global->activity->clazz, lastdialogtype);
return static_cast<AndroidDialogType>(dialogType);
}

AndroidDialogState getInputDialogState()
{
jmethodID dialogstate = jnienv->GetMethodID(nativeActivity,
"getDialogState", "()I");
jmethodID inputdialogstate = jnienv->GetMethodID(nativeActivity,
"getInputDialogState", "()I");

FATAL_ERROR_IF(dialogstate == nullptr,
"porting::getInputDialogState unable to find Java getDialogState method");
FATAL_ERROR_IF(inputdialogstate == nullptr,
"porting::getInputDialogState unable to find Java getInputDialogState method");

return jnienv->CallIntMethod(app_global->activity->clazz, dialogstate);
int dialogState = jnienv->CallIntMethod(app_global->activity->clazz, inputdialogstate);
return static_cast<AndroidDialogState>(dialogState);
}

std::string getInputDialogValue()
std::string getInputDialogMessage()
{
jmethodID dialogvalue = jnienv->GetMethodID(nativeActivity,
"getDialogValue", "()Ljava/lang/String;");
"getDialogMessage", "()Ljava/lang/String;");

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,
dialogvalue);
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
float getDisplayDensity()
{
Expand Down
75 changes: 56 additions & 19 deletions src/porting_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once

#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

#include <jni.h>
Expand All @@ -30,22 +30,28 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string>

namespace porting {
// java app
// Java app
extern android_app *app_global;

// java <-> c++ interaction interface
// Java <-> C++ interaction interface
extern JNIEnv *jnienv;

/**
* show text input dialog in java
* @param acceptButton text to display on accept button
* @param hint hint to show
* @param current initial value to display
* @param editType type of texfield
* (1==multiline text input; 2==single line text input; 3=password field)
* Show a text input dialog in Java
* @param hint Hint to be shown
* @param current Initial value to be displayed
* @param editType Type of the text field
* (1 = multi-line text input; 2 = single-line text input; 3 = password field)
*/
void showInputDialog(const std::string &acceptButton,
const std::string &hint, const std::string &current, int editType);
void showTextInputDialog(const std::string &hint, const std::string &current, 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
Expand All @@ -54,17 +60,48 @@ void showInputDialog(const std::string &acceptButton,
*/
void shareFileAndroid(const std::string &path);

/**
* WORKAROUND for not working callbacks from java -> c++
* get current state of input dialog
/*
* Types of Android 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++
* get text in current input dialog
/*
* WORKAROUND for not working callbacks from Java -> C++
* Get the type of the last input dialog
*/
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.
*/
std::string getInputDialogValue();
int getInputDialogSelection();

#ifndef SERVER
float getDisplayDensity();
Expand Down