summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuslan Mustakov <r.mustakov@gmail.com>2017-10-04 15:39:31 +0700
committerRuslan Mustakov <r.mustakov@gmail.com>2017-10-04 17:21:05 +0700
commit275e537058ed870c4d37002f2110b7866d2ed1ae (patch)
tree150656cd97e9bae45098829d34d3fd34f1beadb0
parent6dc1025e6313d711939269e1578fff5ffc0cd30a (diff)
Allow to obtain virtual keyboard height
On mobile platforms virtual keyboards take up significant amount of screen space and UI containing a text box may need to be adjusted after the keyboard appears to keep the text box visible to user. This commit adds a way to obtain virtual keyabord height so that controls are aware of how much they need to move.
-rw-r--r--core/bind/core_bind.cpp5
-rw-r--r--core/bind/core_bind.h1
-rw-r--r--core/os/os.cpp4
-rw-r--r--core/os/os.h3
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java15
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotLib.java2
-rw-r--r--platform/android/java_glue.cpp14
-rw-r--r--platform/android/java_glue.h1
-rw-r--r--platform/android/os_android.cpp12
-rw-r--r--platform/android/os_android.h5
-rw-r--r--platform/iphone/gl_view.h2
-rw-r--r--platform/iphone/gl_view.mm40
-rw-r--r--platform/iphone/os_iphone.cpp9
-rw-r--r--platform/iphone/os_iphone.h4
14 files changed, 114 insertions, 3 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index f47d540351..f86c15f9a3 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -858,6 +858,10 @@ void _OS::hide_virtual_keyboard() {
OS::get_singleton()->hide_virtual_keyboard();
}
+int _OS::get_virtual_keyboard_height() {
+ return OS::get_singleton()->get_virtual_keyboard_height();
+}
+
void _OS::print_all_resources(const String &p_to_file) {
OS::get_singleton()->print_all_resources(p_to_file);
@@ -1064,6 +1068,7 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_virtual_keyboard"), &_OS::has_virtual_keyboard);
ClassDB::bind_method(D_METHOD("show_virtual_keyboard", "existing_text"), &_OS::show_virtual_keyboard, DEFVAL(""));
ClassDB::bind_method(D_METHOD("hide_virtual_keyboard"), &_OS::hide_virtual_keyboard);
+ ClassDB::bind_method(D_METHOD("get_virtual_keyboard_height"), &_OS::get_virtual_keyboard_height);
ClassDB::bind_method(D_METHOD("print_resources_in_use", "short"), &_OS::print_resources_in_use, DEFVAL(false));
ClassDB::bind_method(D_METHOD("print_all_resources", "tofile"), &_OS::print_all_resources, DEFVAL(""));
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index f12ab9f000..c6f61b0b37 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -204,6 +204,7 @@ public:
bool has_virtual_keyboard() const;
void show_virtual_keyboard(const String &p_existing_text = "");
void hide_virtual_keyboard();
+ int get_virtual_keyboard_height();
void print_resources_in_use(bool p_short = false);
void print_all_resources(const String &p_to_file);
diff --git a/core/os/os.cpp b/core/os/os.cpp
index ff17cdb508..fd1ded63d0 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -193,6 +193,10 @@ void OS::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_scr
void OS::hide_virtual_keyboard() {
}
+int OS::get_virtual_keyboard_height() const {
+ return 0;
+}
+
void OS::print_all_resources(String p_to_file) {
ERR_FAIL_COND(p_to_file != "" && _OSPRF);
diff --git a/core/os/os.h b/core/os/os.h
index c9d25792b9..b68cea1144 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -313,6 +313,9 @@ public:
virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2());
virtual void hide_virtual_keyboard();
+ // returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
+ virtual int get_virtual_keyboard_height() const;
+
virtual void set_cursor_shape(CursorShape p_shape) = 0;
virtual bool get_swap_ok_cancel() { return false; }
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 53a90e4cfe..053dfa631a 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -277,6 +277,21 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
edittext.setView(mView);
io.setEdit(edittext);
+ final Godot godot = this;
+ mView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ Point fullSize = new Point();
+ godot.getWindowManager().getDefaultDisplay().getSize(fullSize);
+ Rect gameSize = new Rect();
+ godot.mView.getWindowVisibleDisplayFrame(gameSize);
+
+ final int keyboardHeight = fullSize.y - gameSize.bottom;
+ Log.d("GODOT", "setVirtualKeyboardHeight: " + keyboardHeight);
+ GodotLib.setVirtualKeyboardHeight(keyboardHeight);
+ }
+ });
+
// Ad layout
adLayout = new RelativeLayout(this);
adLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java
index 47a690140f..e0ed4cd38c 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java
@@ -69,4 +69,6 @@ public class GodotLib {
public static native void callobject(int p_ID, String p_method, Object[] p_params);
public static native void calldeferred(int p_ID, String p_method, Object[] p_params);
+ public static native void setVirtualKeyboardHeight(int p_height);
+
}
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index 509d1bf123..f44b11ff63 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -754,6 +754,18 @@ static void _alert(const String &p_message, const String &p_title) {
env->CallVoidMethod(_godot_instance, _alertDialog, jStrMessage, jStrTitle);
}
+// volatile because it can be changed from non-main thread and we need to
+// ensure the change is immediately visible to other threads.
+static volatile int virtual_keyboard_height;
+
+static int _get_vk_height() {
+ return virtual_keyboard_height;
+}
+
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jobject obj, jint p_height) {
+ virtual_keyboard_height = p_height;
+}
+
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobject p_asset_manager, jboolean p_use_apk_expansion) {
__android_log_print(ANDROID_LOG_INFO, "godot", "**INIT EVENT! - %p\n", env);
@@ -824,7 +836,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
AudioDriverAndroid::setup(gob);
}
- os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion);
+ os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion);
os_android->set_need_reload_hooks(p_need_reload_hook);
char wd[500];
diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h
index ec8ae9a0a6..0aa2489813 100644
--- a/platform/android/java_glue.h
+++ b/platform/android/java_glue.h
@@ -59,6 +59,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_method(JNIEnv *env, j
JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getGlobal(JNIEnv *env, jobject obj, jstring path);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jobject p_obj, jint ID, jstring method, jobjectArray params);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jobject p_obj, jint ID, jstring method, jobjectArray params);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jobject obj, jint p_height);
}
#endif
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 0eb14f6af3..473a093077 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -519,6 +519,15 @@ bool OS_Android::has_virtual_keyboard() const {
return true;
}
+int OS_Android::get_virtual_keyboard_height() const {
+ if (get_virtual_keyboard_height_func) {
+ return get_virtual_keyboard_height_func();
+ }
+
+ ERR_PRINT("Cannot obtain virtual keyboard height.");
+ return 0;
+}
+
void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) {
if (show_virtual_keyboard_func) {
@@ -704,7 +713,7 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) {
return p_feature == "mobile" || p_feature == "etc" || p_feature == "etc2"; //TODO support etc2 only if GLES3 driver is selected
}
-OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion) {
+OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion) {
use_apk_expansion = p_use_apk_expansion;
default_videomode.width = 800;
@@ -734,6 +743,7 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI
show_virtual_keyboard_func = p_show_vk;
hide_virtual_keyboard_func = p_hide_vk;
+ get_virtual_keyboard_height_func = p_vk_height_func;
set_screen_orientation_func = p_screen_orient;
set_keep_screen_on_func = p_set_keep_screen_on_func;
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index a614bb8067..0c78c198a8 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -67,6 +67,7 @@ typedef void (*VideoPauseFunc)();
typedef void (*VideoStopFunc)();
typedef void (*SetKeepScreenOnFunc)(bool p_enabled);
typedef void (*AlertFunc)(const String &, const String &);
+typedef int (*VirtualKeyboardHeightFunc)();
class OS_Android : public OS_Unix {
public:
@@ -126,6 +127,7 @@ private:
GetScreenDPIFunc get_screen_dpi_func;
ShowVirtualKeyboardFunc show_virtual_keyboard_func;
HideVirtualKeyboardFunc hide_virtual_keyboard_func;
+ VirtualKeyboardHeightFunc get_virtual_keyboard_height_func;
SetScreenOrientationFunc set_screen_orientation_func;
GetUniqueIDFunc get_unique_id_func;
GetSystemDirFunc get_system_dir_func;
@@ -201,6 +203,7 @@ public:
virtual bool has_virtual_keyboard() const;
virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2());
virtual void hide_virtual_keyboard();
+ virtual int get_virtual_keyboard_height() const;
void set_opengl_extensions(const char *p_gl_extensions);
void set_display_size(Size2 p_size);
@@ -240,7 +243,7 @@ public:
void joy_connection_changed(int p_device, bool p_connected, String p_name);
virtual bool _check_internal_feature_support(const String &p_feature);
- OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion);
+ OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion);
~OS_Android();
};
diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h
index a9fd8d5711..f7309396c6 100644
--- a/platform/iphone/gl_view.h
+++ b/platform/iphone/gl_view.h
@@ -100,6 +100,8 @@
- (void)destroyFramebuffer;
- (void)audioRouteChangeListenerCallback:(NSNotification *)notification;
+- (void)keyboardOnScreen:(NSNotification *)notification;
+- (void)keyboardHidden:(NSNotification *)notification;
@property NSTimeInterval animationInterval;
@property(nonatomic, assign) BOOL useCADisplayLink;
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index 3e206c3a2c..02da706cc5 100644
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -63,6 +63,7 @@ void _pause_video();
void _focus_out_video();
void _unpause_video();
void _stop_video();
+CGFloat _points_to_pixels(CGFloat);
void _show_keyboard(String p_existing) {
keyboard_text = p_existing;
@@ -174,6 +175,19 @@ void _stop_video() {
video_playing = false;
}
+CGFloat _points_to_pixels(CGFloat points) {
+ float pixelPerInch;
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ pixelPerInch = 132;
+ } else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
+ pixelPerInch = 163;
+ } else {
+ pixelPerInch = 160;
+ }
+ CGFloat pointsPerInch = 72.0;
+ return (points / pointsPerInch * pixelPerInch);
+}
+
@implementation GLView
@synthesize animationInterval;
@@ -537,6 +551,20 @@ static void clear_touches() {
[self resignFirstResponder];
};
+- (void)keyboardOnScreen:(NSNotification *)notification {
+ NSDictionary *info = notification.userInfo;
+ NSValue *value = info[UIKeyboardFrameEndUserInfoKey];
+
+ CGRect rawFrame = [value CGRectValue];
+ CGRect keyboardFrame = [self convertRect:rawFrame fromView:nil];
+
+ OSIPhone::get_singleton()->set_virtual_keyboard_height(_points_to_pixels(keyboardFrame.size.height));
+}
+
+- (void)keyboardHidden:(NSNotification *)notification {
+ OSIPhone::get_singleton()->set_virtual_keyboard_height(0);
+}
+
- (void)deleteBackward {
if (keyboard_text.length())
keyboard_text.erase(keyboard_text.length() - 1, 1);
@@ -606,6 +634,18 @@ static void clear_touches() {
name:AVAudioSessionRouteChangeNotification
object:nil];
+ printf("******** adding observer for keyboard show/hide\n");
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(keyboardOnScreen:)
+ name:UIKeyboardDidShowNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(keyboardHidden:)
+ name:UIKeyboardDidHideNotification
+ object:nil];
+
//self.autoresizesSubviews = YES;
//[self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index 5009f7d8ae..219e93facf 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -463,6 +463,14 @@ void OSIPhone::hide_virtual_keyboard() {
_hide_keyboard();
};
+void OSIPhone::set_virtual_keyboard_height(int p_height) {
+ virtual_keyboard_height = p_height;
+}
+
+int OSIPhone::get_virtual_keyboard_height() const {
+ return virtual_keyboard_height;
+}
+
Error OSIPhone::shell_open(String p_uri) {
return _shell_open(p_uri);
};
@@ -576,6 +584,7 @@ OSIPhone::OSIPhone(int width, int height) {
vm.resizable = false;
set_video_mode(vm);
event_count = 0;
+ virtual_keyboard_height = 0;
_set_logger(memnew(SyslogLogger));
};
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 11f4eed5e7..cf2396e87b 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -124,6 +124,8 @@ private:
InputDefault *input;
+ int virtual_keyboard_height;
+
public:
bool iterate();
@@ -133,6 +135,7 @@ public:
void mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, bool p_use_as_mouse);
void touches_cancelled();
void key(uint32_t p_key, bool p_pressed);
+ void set_virtual_keyboard_height(int p_height);
int set_base_framebuffer(int p_fb);
@@ -168,6 +171,7 @@ public:
virtual bool has_virtual_keyboard() const;
virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2());
virtual void hide_virtual_keyboard();
+ virtual int get_virtual_keyboard_height() const;
virtual void set_cursor_shape(CursorShape p_shape);