Implement text input on iOS

This commit is contained in:
sfan5 2017-08-16 14:11:17 +02:00 committed by Maksim Gamarnik
parent 2fc840fb64
commit 39bec37923
10 changed files with 94 additions and 14 deletions

View File

@ -15,6 +15,8 @@ void ioswrap_log(const char *message);
void ioswrap_paths(int type, char *dest, size_t destlen);
void ioswrap_assets(void); // extracts assets.zip to PATH_LIBRARY_SUPPORT
void ioswrap_size(unsigned int *dest);
void ioswrap_show_dialog(void *uiviewcontroller, const char *accept, const char *hint, const char *current, int type);
int ioswrap_get_dialog(const char **text);
#ifdef __cplusplus
}

View File

@ -131,3 +131,45 @@ void ioswrap_size(unsigned int *dest)
dest[0] = bounds.width * scale;
dest[1] = bounds.height * scale;
}
/********/
static int dialog_state;
static char dialog_text[512];
#define DIALOG_MULTILINE 1
#define DIALOG_SINGLELINE 2
#define DIALOG_PASSWORD 3
void ioswrap_show_dialog(void *uiviewcontroller, const char *accept, const char *hint, const char *current, int type)
{
UIViewController *viewc = (__bridge UIViewController*) uiviewcontroller;
NSString *accept_ = [NSString stringWithUTF8String:accept];
(void) hint; // unused
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Text Input" message:nil preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
textField.text = [NSString stringWithUTF8String:current];
if(type == DIALOG_PASSWORD)
textField.secureTextEntry = YES;
}];
[alert addAction:[UIAlertAction actionWithTitle:accept_ style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
dialog_state = 0;
strncpy(dialog_text, alert.textFields[0].text.UTF8String, sizeof(dialog_text));
}]];
dialog_state = -1;
dialog_text[0] = 0;
[viewc presentViewController:alert animated:YES completion:nil];
}
int ioswrap_get_dialog(const char **text)
{
int ret = dialog_state;
if(text) {
*text = dialog_text;
dialog_state = -1; // reset
}
return ret;
}

View File

@ -39,6 +39,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#if 0 // toggle to 1 for ads
#define ADS
#include "ads.h"
#endif
#ifdef __IOS__
namespace irr {
class CIrrDeviceiOS : public IrrlichtDevice {
public:
@ -596,10 +599,14 @@ bool ClientLauncher::create_engine_device()
if (device)
porting::initIrrlicht(device);
#ifdef ADS
#ifdef __IOS__
if (device) {
CIrrDeviceiOS* dev = (CIrrDeviceiOS*) device;
porting::setViewController(dev->getViewController());
#ifdef ADS
ads_startup(dev->getViewController());
#endif
}
#endif

View File

@ -1353,7 +1353,7 @@ protected:
return input->wasKeyDown(keycache.key[k]) || input->joystick.wasKeyDown(k);
}
#ifdef __ANDROID__
#if defined(__ANDROID__) || defined(__IOS__)
void handleAndroidChatInput();
#endif
@ -1463,8 +1463,6 @@ private:
#if defined(__ANDROID__) || defined(__IOS__)
bool show_minimap;
bool m_cache_hold_aux1;
#endif
#ifdef __ANDROID__
bool m_android_chat_open;
#endif
};
@ -2547,7 +2545,7 @@ void Game::processUserInput(f32 dtime)
// Input handler step() (used by the random input generator)
input->step(dtime);
#ifdef __ANDROID__
#if defined(__ANDROID__) || defined(__IOS__)
if (current_formspec != NULL)
current_formspec->getAndroidUIInput();
else
@ -2758,7 +2756,7 @@ void Game::openConsole(float scale, const wchar_t *line)
{
assert(scale > 0.0f && scale <= 1.0f);
#ifdef __ANDROID__
#if defined(__ANDROID__) || defined(__IOS__)
porting::showInputDialog(gettext("ok"), "", "", 2);
m_android_chat_open = true;
#else
@ -2772,7 +2770,7 @@ void Game::openConsole(float scale, const wchar_t *line)
#endif
}
#ifdef __ANDROID__
#if defined(__ANDROID__) || defined(__IOS__)
void Game::handleAndroidChatInput()
{
if (m_android_chat_open && porting::getInputDialogState() == 0) {

View File

@ -309,7 +309,7 @@ void GUIEngine::run()
m_script->step();
#ifdef __ANDROID__
#if defined(__ANDROID__) || defined(__IOS__)
m_menu->getAndroidUIInput();
#endif
}

View File

@ -106,7 +106,7 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
current_field_enter_pending(""),
m_font(NULL),
m_remap_dbl_click(remap_dbl_click)
#ifdef __ANDROID__
#if defined(__ANDROID__) || defined(__IOS__)
, m_JavaDialogFieldName("")
#endif
{
@ -2227,7 +2227,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
skin->setFont(old_font);
}
#ifdef __ANDROID__
#if defined(__ANDROID__) || defined(__IOS__)
bool GUIFormSpecMenu::getAndroidUIInput()
{
/* no dialog shown */
@ -3051,7 +3051,7 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
}
}
#ifdef __ANDROID__
#if defined(__ANDROID__) || defined(__IOS__)
// display software keyboard when clicking edit boxes
if (event.EventType == EET_MOUSE_INPUT_EVENT
&& event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) {

View File

@ -365,7 +365,7 @@ public:
GUITable* getTable(const std::string &tablename);
std::vector<std::string>* getDropDownValues(const std::string &name);
#ifdef __ANDROID__
#if defined(__ANDROID__) || defined(__IOS__)
bool getAndroidUIInput();
#endif
@ -541,8 +541,6 @@ private:
std::string getNameByID(s32 id);
#if defined(__ANDROID__) || defined(__IOS__)
v2s32 m_down_pos;
#endif
#ifdef __ANDROID__
std::string m_JavaDialogFieldName;
#endif

View File

@ -4,6 +4,7 @@
#include "config.h"
#include "ioswrap.h"
static void *uiviewcontroller;
namespace porting {
void initializePathsiOS() {
@ -40,6 +41,26 @@ namespace porting {
return retval;
}
void setViewController(void *v) {
uiviewcontroller = v;
}
void showInputDialog(const std::string &acceptButton, const std::string &hint,
const std::string &current, int editType)
{
ioswrap_show_dialog(uiviewcontroller, acceptButton.c_str(), hint.c_str(), current.c_str(), editType);
}
int getInputDialogState() {
return ioswrap_get_dialog(NULL);
}
std::string getInputDialogValue() {
const char *str;
ioswrap_get_dialog(&str);
return std::string(str);
}
}

View File

@ -8,6 +8,12 @@
namespace porting {
void initializePathsiOS();
void copyAssets();
void setViewController(void *v);
void showInputDialog(const std::string &acceptButton, const std::string &hint,
const std::string &current, int editType);
int getInputDialogState();
std::string getInputDialogValue();
}
#endif

View File

@ -364,6 +364,12 @@ void TouchScreenGUI::init(ISimpleTextureSource* tsrc)
m_screensize.X / 2 + (button_size * 0.75),
(button_size * 0.75)),
L"far", false, SLOW_BUTTON_REPEAT);
/* init chat button */
initButton(chat_id,
rect<s32>(m_screensize.X / 2 + (button_size * 0.75), 0,
m_screensize.X / 2 + (button_size * 1.5),
(button_size * 0.75)),
L"Chat", false, SLOW_BUTTON_REPEAT);
#else
// Android and Windows bar