Add gestures to bring up the software keyboard - Long press start or tap with 3 fingers

This commit is contained in:
Cameron Gutman 2015-01-25 22:55:12 -05:00
parent 4d24c654b9
commit bcc67269ab
3 changed files with 71 additions and 9 deletions

View File

@ -16,6 +16,7 @@ import com.limelight.nvstream.av.video.VideoDecoderRenderer;
import com.limelight.nvstream.input.KeyboardPacket;
import com.limelight.nvstream.input.MouseButtonPacket;
import com.limelight.preferences.PreferenceConfiguration;
import com.limelight.ui.GameGestures;
import com.limelight.utils.Dialog;
import com.limelight.utils.SpinnerDialog;
@ -30,6 +31,7 @@ import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.view.Display;
import android.view.InputDevice;
@ -44,6 +46,7 @@ import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;
import java.util.Locale;
@ -51,7 +54,7 @@ import java.util.Locale;
public class Game extends Activity implements SurfaceHolder.Callback,
OnGenericMotionListener, OnTouchListener, NvConnectionListener, EvdevListener,
OnSystemUiVisibilityChangeListener
OnSystemUiVisibilityChangeListener, GameGestures
{
private int lastMouseX = Integer.MIN_VALUE;
private int lastMouseY = Integer.MIN_VALUE;
@ -59,6 +62,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// Only 2 touches are supported
private TouchContext[] touchContextMap = new TouchContext[2];
private long threeFingerDownTime = 0;
private static final int THREE_FINGER_TAP_THRESHOLD = 300;
private ControllerHandler controllerHandler;
private KeyboardTranslator keybTranslator;
@ -189,7 +195,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// Initialize the connection
conn = new NvConnection(host, uniqueId, Game.this, config, PlatformBinding.getCryptoProvider(this));
keybTranslator = new KeyboardTranslator(conn);
controllerHandler = new ControllerHandler(conn, prefConfig.deadzonePercentage);
controllerHandler = new ControllerHandler(conn, this, prefConfig.deadzonePercentage);
SurfaceHolder sh = sv.getHolder();
if (prefConfig.stretchVideo || !decoderRenderer.isHardwareAccelerated()) {
@ -480,6 +486,13 @@ public class Game extends Activity implements SurfaceHolder.Callback,
}
}
@Override
public void showKeyboard() {
LimeLog.info("Showing keyboard overlay");
InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
// Returns true if the event was consumed
private boolean handleMotionEvent(MotionEvent event) {
// Pass through keyboard input if we're not grabbing
@ -501,7 +514,22 @@ public class Game extends Activity implements SurfaceHolder.Callback,
int actionIndex = event.getActionIndex();
int eventX = (int)event.getX(actionIndex);
int eventY = (int)event.getY(actionIndex);
int eventY = (int)event.getY(actionIndex);
// Special handling for 3 finger gesture
if (event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN &&
event.getPointerCount() == 3) {
// Three fingers down
threeFingerDownTime = SystemClock.uptimeMillis();
// Cancel the first and second touches to avoid
// erroneous events
for (TouchContext aTouchContext : touchContextMap) {
aTouchContext.cancelTouch();
}
return true;
}
TouchContext context = getTouchContext(actionIndex);
if (context == null) {
@ -516,8 +544,16 @@ public class Game extends Activity implements SurfaceHolder.Callback,
break;
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_UP:
if (event.getPointerCount() == 1) {
// All fingers up
if (SystemClock.uptimeMillis() - threeFingerDownTime < THREE_FINGER_TAP_THRESHOLD) {
// This is a 3 finger tap to bring up the keyboard
showKeyboard();
return true;
}
}
context.touchUpEvent(eventX, eventY);
if (actionIndex == 0 && event.getPointerCount() > 1) {
if (actionIndex == 0 && event.getPointerCount() > 1 && !context.isCancelled()) {
// The original secondary touch now becomes primary
context.touchDownEvent((int)event.getX(1), (int)event.getY(1));
}

View File

@ -10,6 +10,7 @@ import android.view.MotionEvent;
import com.limelight.LimeLog;
import com.limelight.nvstream.NvConnection;
import com.limelight.nvstream.input.ControllerPacket;
import com.limelight.ui.GameGestures;
import com.limelight.utils.Vector2d;
public class ControllerHandler {
@ -30,6 +31,9 @@ public class ControllerHandler {
private long lastLbUpTime = 0;
private long lastRbUpTime = 0;
private static final int MAXIMUM_BUMPER_UP_DELAY_MS = 100;
private long startDownTime = 0;
private static final int START_DOWN_TIME_KEYB_MS = 750;
private static final int MINIMUM_BUTTON_DOWN_TIME_MS = 25;
@ -46,10 +50,12 @@ public class ControllerHandler {
private NvConnection conn;
private double stickDeadzone;
private final ControllerMapping defaultMapping = new ControllerMapping();
private GameGestures gestures;
private boolean hasGameController;
public ControllerHandler(NvConnection conn, int deadzonePercentage) {
public ControllerHandler(NvConnection conn, GameGestures gestures, int deadzonePercentage) {
this.conn = conn;
this.gestures = gestures;
// HACK: For now we're hardcoding a 10% deadzone. Some deadzone
// is required for controller batching support to work.
@ -513,6 +519,9 @@ public class ControllerHandler {
break;
case KeyEvent.KEYCODE_BUTTON_START:
case KeyEvent.KEYCODE_MENU:
if (SystemClock.uptimeMillis() - startDownTime > ControllerHandler.START_DOWN_TIME_KEYB_MS) {
gestures.showKeyboard();
}
inputMap &= ~ControllerPacket.PLAY_FLAG;
break;
case KeyEvent.KEYCODE_BACK:
@ -621,6 +630,9 @@ public class ControllerHandler {
break;
case KeyEvent.KEYCODE_BUTTON_START:
case KeyEvent.KEYCODE_MENU:
if (event.getRepeatCount() == 0) {
startDownTime = SystemClock.uptimeMillis();
}
inputMap |= ControllerPacket.PLAY_FLAG;
break;
case KeyEvent.KEYCODE_BACK:

View File

@ -9,6 +9,7 @@ public class TouchContext {
private int originalTouchX = 0;
private int originalTouchY = 0;
private long originalTouchTime = 0;
private boolean cancelled;
private NvConnection conn;
private int actionIndex;
@ -56,12 +57,17 @@ public class TouchContext {
originalTouchX = lastTouchX = eventX;
originalTouchY = lastTouchY = eventY;
originalTouchTime = System.currentTimeMillis();
return true;
cancelled = false;
return true;
}
public void touchUpEvent(int eventX, int eventY)
{
if (cancelled) {
return;
}
if (isTap())
{
byte buttonIndex = getMouseButtonIndex();
@ -81,8 +87,8 @@ public class TouchContext {
}
public boolean touchMoveEvent(int eventX, int eventY)
{
if (eventX != lastTouchX || eventY != lastTouchY)
{
if (eventX != lastTouchX || eventY != lastTouchY)
{
// We only send moves for the primary touch point
if (actionIndex == 0) {
@ -102,4 +108,12 @@ public class TouchContext {
return true;
}
public void cancelTouch() {
cancelled = true;
}
public boolean isCancelled() {
return cancelled;
}
}