mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-19 19:13:03 +00:00
Add gestures to bring up the software keyboard - Long press start or tap with 3 fingers
This commit is contained in:
parent
4d24c654b9
commit
bcc67269ab
@ -16,6 +16,7 @@ import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
|||||||
import com.limelight.nvstream.input.KeyboardPacket;
|
import com.limelight.nvstream.input.KeyboardPacket;
|
||||||
import com.limelight.nvstream.input.MouseButtonPacket;
|
import com.limelight.nvstream.input.MouseButtonPacket;
|
||||||
import com.limelight.preferences.PreferenceConfiguration;
|
import com.limelight.preferences.PreferenceConfiguration;
|
||||||
|
import com.limelight.ui.GameGestures;
|
||||||
import com.limelight.utils.Dialog;
|
import com.limelight.utils.Dialog;
|
||||||
import com.limelight.utils.SpinnerDialog;
|
import com.limelight.utils.SpinnerDialog;
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ import android.net.ConnectivityManager;
|
|||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.InputDevice;
|
import android.view.InputDevice;
|
||||||
@ -44,6 +46,7 @@ import android.view.View.OnTouchListener;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -51,7 +54,7 @@ import java.util.Locale;
|
|||||||
|
|
||||||
public class Game extends Activity implements SurfaceHolder.Callback,
|
public class Game extends Activity implements SurfaceHolder.Callback,
|
||||||
OnGenericMotionListener, OnTouchListener, NvConnectionListener, EvdevListener,
|
OnGenericMotionListener, OnTouchListener, NvConnectionListener, EvdevListener,
|
||||||
OnSystemUiVisibilityChangeListener
|
OnSystemUiVisibilityChangeListener, GameGestures
|
||||||
{
|
{
|
||||||
private int lastMouseX = Integer.MIN_VALUE;
|
private int lastMouseX = Integer.MIN_VALUE;
|
||||||
private int lastMouseY = 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
|
// Only 2 touches are supported
|
||||||
private TouchContext[] touchContextMap = new TouchContext[2];
|
private TouchContext[] touchContextMap = new TouchContext[2];
|
||||||
|
private long threeFingerDownTime = 0;
|
||||||
|
|
||||||
|
private static final int THREE_FINGER_TAP_THRESHOLD = 300;
|
||||||
|
|
||||||
private ControllerHandler controllerHandler;
|
private ControllerHandler controllerHandler;
|
||||||
private KeyboardTranslator keybTranslator;
|
private KeyboardTranslator keybTranslator;
|
||||||
@ -189,7 +195,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
// Initialize the connection
|
// Initialize the connection
|
||||||
conn = new NvConnection(host, uniqueId, Game.this, config, PlatformBinding.getCryptoProvider(this));
|
conn = new NvConnection(host, uniqueId, Game.this, config, PlatformBinding.getCryptoProvider(this));
|
||||||
keybTranslator = new KeyboardTranslator(conn);
|
keybTranslator = new KeyboardTranslator(conn);
|
||||||
controllerHandler = new ControllerHandler(conn, prefConfig.deadzonePercentage);
|
controllerHandler = new ControllerHandler(conn, this, prefConfig.deadzonePercentage);
|
||||||
|
|
||||||
SurfaceHolder sh = sv.getHolder();
|
SurfaceHolder sh = sv.getHolder();
|
||||||
if (prefConfig.stretchVideo || !decoderRenderer.isHardwareAccelerated()) {
|
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
|
// Returns true if the event was consumed
|
||||||
private boolean handleMotionEvent(MotionEvent event) {
|
private boolean handleMotionEvent(MotionEvent event) {
|
||||||
// Pass through keyboard input if we're not grabbing
|
// Pass through keyboard input if we're not grabbing
|
||||||
@ -503,6 +516,21 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
int eventX = (int)event.getX(actionIndex);
|
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);
|
TouchContext context = getTouchContext(actionIndex);
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
return false;
|
return false;
|
||||||
@ -516,8 +544,16 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_POINTER_UP:
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
case MotionEvent.ACTION_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);
|
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
|
// The original secondary touch now becomes primary
|
||||||
context.touchDownEvent((int)event.getX(1), (int)event.getY(1));
|
context.touchDownEvent((int)event.getX(1), (int)event.getY(1));
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import android.view.MotionEvent;
|
|||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
import com.limelight.nvstream.NvConnection;
|
import com.limelight.nvstream.NvConnection;
|
||||||
import com.limelight.nvstream.input.ControllerPacket;
|
import com.limelight.nvstream.input.ControllerPacket;
|
||||||
|
import com.limelight.ui.GameGestures;
|
||||||
import com.limelight.utils.Vector2d;
|
import com.limelight.utils.Vector2d;
|
||||||
|
|
||||||
public class ControllerHandler {
|
public class ControllerHandler {
|
||||||
@ -31,6 +32,9 @@ public class ControllerHandler {
|
|||||||
private long lastRbUpTime = 0;
|
private long lastRbUpTime = 0;
|
||||||
private static final int MAXIMUM_BUMPER_UP_DELAY_MS = 100;
|
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;
|
private static final int MINIMUM_BUTTON_DOWN_TIME_MS = 25;
|
||||||
|
|
||||||
private static final int EMULATING_SPECIAL = 0x1;
|
private static final int EMULATING_SPECIAL = 0x1;
|
||||||
@ -46,10 +50,12 @@ public class ControllerHandler {
|
|||||||
private NvConnection conn;
|
private NvConnection conn;
|
||||||
private double stickDeadzone;
|
private double stickDeadzone;
|
||||||
private final ControllerMapping defaultMapping = new ControllerMapping();
|
private final ControllerMapping defaultMapping = new ControllerMapping();
|
||||||
|
private GameGestures gestures;
|
||||||
private boolean hasGameController;
|
private boolean hasGameController;
|
||||||
|
|
||||||
public ControllerHandler(NvConnection conn, int deadzonePercentage) {
|
public ControllerHandler(NvConnection conn, GameGestures gestures, int deadzonePercentage) {
|
||||||
this.conn = conn;
|
this.conn = conn;
|
||||||
|
this.gestures = gestures;
|
||||||
|
|
||||||
// HACK: For now we're hardcoding a 10% deadzone. Some deadzone
|
// HACK: For now we're hardcoding a 10% deadzone. Some deadzone
|
||||||
// is required for controller batching support to work.
|
// is required for controller batching support to work.
|
||||||
@ -513,6 +519,9 @@ public class ControllerHandler {
|
|||||||
break;
|
break;
|
||||||
case KeyEvent.KEYCODE_BUTTON_START:
|
case KeyEvent.KEYCODE_BUTTON_START:
|
||||||
case KeyEvent.KEYCODE_MENU:
|
case KeyEvent.KEYCODE_MENU:
|
||||||
|
if (SystemClock.uptimeMillis() - startDownTime > ControllerHandler.START_DOWN_TIME_KEYB_MS) {
|
||||||
|
gestures.showKeyboard();
|
||||||
|
}
|
||||||
inputMap &= ~ControllerPacket.PLAY_FLAG;
|
inputMap &= ~ControllerPacket.PLAY_FLAG;
|
||||||
break;
|
break;
|
||||||
case KeyEvent.KEYCODE_BACK:
|
case KeyEvent.KEYCODE_BACK:
|
||||||
@ -621,6 +630,9 @@ public class ControllerHandler {
|
|||||||
break;
|
break;
|
||||||
case KeyEvent.KEYCODE_BUTTON_START:
|
case KeyEvent.KEYCODE_BUTTON_START:
|
||||||
case KeyEvent.KEYCODE_MENU:
|
case KeyEvent.KEYCODE_MENU:
|
||||||
|
if (event.getRepeatCount() == 0) {
|
||||||
|
startDownTime = SystemClock.uptimeMillis();
|
||||||
|
}
|
||||||
inputMap |= ControllerPacket.PLAY_FLAG;
|
inputMap |= ControllerPacket.PLAY_FLAG;
|
||||||
break;
|
break;
|
||||||
case KeyEvent.KEYCODE_BACK:
|
case KeyEvent.KEYCODE_BACK:
|
||||||
|
@ -9,6 +9,7 @@ public class TouchContext {
|
|||||||
private int originalTouchX = 0;
|
private int originalTouchX = 0;
|
||||||
private int originalTouchY = 0;
|
private int originalTouchY = 0;
|
||||||
private long originalTouchTime = 0;
|
private long originalTouchTime = 0;
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
private NvConnection conn;
|
private NvConnection conn;
|
||||||
private int actionIndex;
|
private int actionIndex;
|
||||||
@ -56,12 +57,17 @@ public class TouchContext {
|
|||||||
originalTouchX = lastTouchX = eventX;
|
originalTouchX = lastTouchX = eventX;
|
||||||
originalTouchY = lastTouchY = eventY;
|
originalTouchY = lastTouchY = eventY;
|
||||||
originalTouchTime = System.currentTimeMillis();
|
originalTouchTime = System.currentTimeMillis();
|
||||||
|
cancelled = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void touchUpEvent(int eventX, int eventY)
|
public void touchUpEvent(int eventX, int eventY)
|
||||||
{
|
{
|
||||||
|
if (cancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isTap())
|
if (isTap())
|
||||||
{
|
{
|
||||||
byte buttonIndex = getMouseButtonIndex();
|
byte buttonIndex = getMouseButtonIndex();
|
||||||
@ -102,4 +108,12 @@ public class TouchContext {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void cancelTouch() {
|
||||||
|
cancelled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user