From 533e072a592826df53b90491bcaa606dfddaf646 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 21 Jun 2012 19:43:59 +0200 Subject: NEWT: Add virtual on-screen keyboard visibility interface methods incl. Android implementation. Note: Currently only w/ Android implementation. Note: On Android there is no way to reliably be notified of the current keyboard state. It would be best, if your code does not rely on this information Window adds: - setKeyboardVisible(boolean) - isKeyboardVisible() // unreliable on Android --- src/newt/classes/com/jogamp/newt/Window.java | 35 ++++++++++++--- .../classes/com/jogamp/newt/opengl/GLWindow.java | 8 ++++ src/newt/classes/jogamp/newt/WindowImpl.java | 35 ++++++++++++++- .../jogamp/newt/driver/android/AndroidWindow.java | 50 ++++++++++++++++++++++ .../opengl/test/android/MovieCubeActivity0.java | 8 +--- .../opengl/test/android/NEWTGearsES2Activity.java | 8 +--- .../test/android/NEWTGearsES2ActivityLauncher.java | 2 +- 7 files changed, 122 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 3c5441bf7..136c19ff8 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -106,11 +106,11 @@ public interface Window extends NativeWindow, WindowClosingProtocol { void destroy(); /** - *

* setVisible makes the window and children visible if visible is true, - * otherwise the window and children becomes invisible.

+ * otherwise the window and children becomes invisible. *

- * The setVisible(true) is responsible to actual create the native window.

+ * The setVisible(true) is responsible to actual create the native window. + *

*

* Zero size semantics are respected, see {@link #setSize(int,int)}:
*

@@ -125,10 +125,11 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
      * }
      * 

*

- * In case this window is a child window and a parent {@link javax.media.nativewindow.NativeWindow} is being used,
- * the parent's {@link javax.media.nativewindow.NativeWindow} handle is retrieved via {@link javax.media.nativewindow.NativeWindow#getWindowHandle()}.
- * If this action fails, ie if the parent {@link javax.media.nativewindow.NativeWindow} is not valid yet,
- * no native window is created yet and setVisible(true) shall be repeated when it is.

+ * In case this window is a child window and has a {@link javax.media.nativewindow.NativeWindow} parent,
+ * setVisible(true) has no effect as long the parent's is not valid yet, + * i.e. {@link javax.media.nativewindow.NativeWindow#getWindowHandle()} returns null.
+ * setVisible(true) shall be repeated when the parent becomes valid. + *

*/ void setVisible(boolean visible); @@ -399,7 +400,27 @@ public interface Window extends NativeWindow, WindowClosingProtocol { // KeyListener // + /** + * In case the platform supports or even requires a virtual on-screen keyboard, + * this method shows or hide it depending on whether visible is true + * or false. + *

+ * One known platform where NEWT supports this feature is Android. + *

+ */ + void setKeyboardVisible(boolean visible); + /** + * Return true if the virtual on-screen keyboard is visible, otherwise false. + *

+ * Currently on Android, the only supported platform right now, + * there is no way to reliably be notified of the current keyboard state.
+ * It would be best, if your code does not rely on this information. + *

+ * @see #setKeyboardVisible(boolean) + */ + boolean isKeyboardVisible(); + /** * * Appends the given {@link com.jogamp.newt.event.KeyListener} to the end of diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index f89193754..a3adf5090 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -790,6 +790,14 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC window.addWindowListener(index, l); } + public final void setKeyboardVisible(boolean visible) { + window.setKeyboardVisible(visible); + } + + public final boolean isKeyboardVisible() { + return window.isKeyboardVisible(); + } + public final void addKeyListener(KeyListener l) { window.addKeyListener(l); } diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 074f635e4..68a2430f7 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -303,6 +303,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer setTitleImpl(title); setPointerVisibleImpl(pointerVisible); confinePointerImpl(pointerConfined); + setKeyboardVisible(keyboardVisible); if(waitForVisible(true, false)) { if(isFullscreen()) { synchronized(fullScreenAction) { @@ -2182,6 +2183,36 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer addKeyListener(-1, l); } + public final void setKeyboardVisible(boolean visible) { + if(isNativeValid()) { + // We don't skip the impl. if it seems that there is no state change, + // since we cannot assume the impl. reliably gives us it's current state. + final boolean n = setKeyboardVisibleImpl(visible); + if(DEBUG_IMPLEMENTATION || DEBUG_KEY_EVENT) { + System.err.println("setKeyboardVisible(native): visible "+keyboardVisible+" -> "+visible +" -> "+n); + } + keyboardVisible = n; + } else { + keyboardVisible = visible; // earmark for creation + } + } + public final boolean isKeyboardVisible() { + return keyboardVisible; + } + protected boolean setKeyboardVisibleImpl(boolean visible) { + return false; // nop + } + /** Triggered by implementation's WM events to update the virtual on-screen keyboard's visibility state. */ + protected void keyboardVisibilityChanged(boolean visible) { + if(keyboardVisible != visible) { + if(DEBUG_IMPLEMENTATION || DEBUG_KEY_EVENT) { + System.err.println("keyboardVisibilityChanged: "+keyboardVisible+" -> "+visible); + } + keyboardVisible = visible; + } + } + protected boolean keyboardVisible = false; + public void addKeyListener(int index, KeyListener l) { if(l == null) { return; @@ -2356,8 +2387,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer enqueueWindowEvent(false, evt); } } - } - + } + /** Triggered by implementation's WM events to update the visibility state. */ protected void visibleChanged(boolean defer, boolean visible) { if(this.visible != visible) { diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java index 63d5f7003..73192a07f 100644 --- a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java +++ b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java @@ -48,10 +48,14 @@ import jogamp.opengl.egl.EGLGraphicsConfigurationFactory; import android.content.Context; import android.graphics.PixelFormat; +import android.os.Bundle; +import android.os.IBinder; +import android.os.ResultReceiver; import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback2; +import android.view.inputmethod.InputMethodManager; import android.view.SurfaceView; import android.view.View; @@ -316,6 +320,52 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 { // nop .. } + //---------------------------------------------------------------------- + // Virtual On-Screen Keyboard / SoftInput + // + + private class KeyboardVisibleReceiver extends ResultReceiver { + public KeyboardVisibleReceiver() { + super(null); + } + + @Override + public void onReceiveResult(int r, Bundle data) { + boolean v = false; + + switch(r) { + case InputMethodManager.RESULT_UNCHANGED_SHOWN: + case InputMethodManager.RESULT_SHOWN: + v = true; + break; + case InputMethodManager.RESULT_HIDDEN: + case InputMethodManager.RESULT_UNCHANGED_HIDDEN: + v = false; + break; + } + Log.d(MD.TAG, "keyboardVisible: "+v); + keyboardVisibilityChanged(v); + } + } + private KeyboardVisibleReceiver keyboardVisibleReceiver = new KeyboardVisibleReceiver(); + + protected final boolean setKeyboardVisibleImpl(boolean visible) { + if(null != androidView) { + final InputMethodManager imm = (InputMethodManager) getAndroidView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + final IBinder winid = getAndroidView().getWindowToken(); + if(visible) { + // Show soft-keyboard: + imm.showSoftInput(androidView, 0, keyboardVisibleReceiver); + } else { + // hide keyboard : + imm.hideSoftInputFromWindow(winid, 0, keyboardVisibleReceiver); + } + return visible; + } else { + return false; // nop + } + } + //---------------------------------------------------------------------- // Surface Callbacks // diff --git a/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java b/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java index 59e78936d..a30262ee3 100644 --- a/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java +++ b/src/test/com/jogamp/opengl/test/android/MovieCubeActivity0.java @@ -34,7 +34,6 @@ import java.util.Arrays; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; -import jogamp.newt.driver.android.AndroidWindow; import jogamp.newt.driver.android.NewtBaseActivity; import com.jogamp.common.util.IOUtil; @@ -46,10 +45,8 @@ import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es2.av.MovieCube; import com.jogamp.opengl.util.Animator; -import android.content.Context; import android.os.Bundle; import android.util.Log; -import android.view.inputmethod.InputMethodManager; public class MovieCubeActivity0 extends NewtBaseActivity { static String TAG = "MovieCubeActivity0"; @@ -58,10 +55,7 @@ public class MovieCubeActivity0 extends NewtBaseActivity { @Override public void mousePressed(MouseEvent e) { if(e.getPressure()>2f) { - final AndroidWindow win = (AndroidWindow)e.getSource(); - InputMethodManager mgr = (InputMethodManager) win.getAndroidView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - mgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); // shows keyboard .. - win.getAndroidView().requestFocus(); + ((com.jogamp.newt.Window) e.getSource()).setKeyboardVisible(true); } } }; diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java index 592ecf5d6..4468868f6 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java @@ -30,7 +30,6 @@ package com.jogamp.opengl.test.android; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLProfile; -import jogamp.newt.driver.android.AndroidWindow; import jogamp.newt.driver.android.NewtBaseActivity; import com.jogamp.newt.ScreenMode; @@ -42,10 +41,8 @@ import com.jogamp.newt.opengl.GLWindow; import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2; import com.jogamp.opengl.util.Animator; -import android.content.Context; import android.os.Bundle; import android.util.Log; -import android.view.inputmethod.InputMethodManager; public class NEWTGearsES2Activity extends NewtBaseActivity { static String TAG = "NEWTGearsES2Activity"; @@ -65,10 +62,7 @@ public class NEWTGearsES2Activity extends NewtBaseActivity { @Override public void mousePressed(MouseEvent e) { if(e.getPressure()>2f) { // show Keyboard - final AndroidWindow win = (AndroidWindow)e.getSource(); - InputMethodManager mgr = (InputMethodManager) win.getAndroidView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - mgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); // shows keyboard .. - win.getAndroidView().requestFocus(); + ((com.jogamp.newt.Window) e.getSource()).setKeyboardVisible(true); } } }); diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java index 0454d543c..907be5092 100644 --- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java +++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2ActivityLauncher.java @@ -59,7 +59,7 @@ public class NEWTGearsES2ActivityLauncher extends LauncherUtil.BaseActivityLaunc // properties.setProperty("newt.debug", "all"); // props.setProperty("newt.debug.Window", "true"); // props.setProperty("newt.debug.Window.MouseEvent", "true"); - // props.setProperty("newt.debug.Window.KeyEvent", "true"); + props.setProperty("newt.debug.Window.KeyEvent", "true"); } @Override -- cgit v1.2.3