2009Scape-mobile/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java

202 lines
7.6 KiB
Java

package net.kdt.pojavlaunch;
import static net.kdt.pojavlaunch.MinecraftGLSurface.FINGER_SCROLL_THRESHOLD;
import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.DEFAULT_PREF;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.res.ResourcesCompat;
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import org.lwjgl.glfw.CallbackBridge;
/**
* Class dealing with the virtual mouse
*/
public class Touchpad extends FrameLayout implements GrabListener{
/* Whether the Touchpad should be displayed */
private boolean mDisplayState;
/* Mouse pointer icon used by the touchpad */
private final ImageView mMousePointerImageView = new ImageView(getContext());
/* Detect a classic android Tap */
private final GestureDetector mSingleTapDetector = new GestureDetector(getContext(), new SingleTapConfirm());
/* Resolution scaler option, allow downsizing a window */
private final float mScaleFactor = DEFAULT_PREF.getInt("resolutionRatio",100)/100f;
/* Current pointer ID to move the mouse */
private int mCurrentPointerID = -1000;
/* Previous MotionEvent position, not scale */
private float mPrevX, mPrevY;
/* Last first pointer positions non-scaled, used to scroll distance */
private float mScrollLastInitialX, mScrollLastInitialY;
/* Handler and message to check if we are grabbing */
public Touchpad(@NonNull Context context) {
this(context, null);
}
public Touchpad(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
@SuppressWarnings("accessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
// MotionEvent reports input details from the touch screen
// and other input controls. In this case, you are only
// interested in events where the touch position changed.
// int index = event.getActionIndex();
if(CallbackBridge.isGrabbing()) {
disable();
return false;
}
int action = event.getActionMasked();
float x = event.getX();
float y = event.getY();
float mouseX = mMousePointerImageView.getX();
float mouseY = mMousePointerImageView.getY();
if (mSingleTapDetector.onTouchEvent(event)) {
CallbackBridge.mouseX = (mouseX * mScaleFactor);
CallbackBridge.mouseY = (mouseY * mScaleFactor);
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
CallbackBridge.sendMouseKeycode(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT);
return true;
}
switch (action) {
case MotionEvent.ACTION_POINTER_DOWN: // 5
// Check if there are two fingers on the screen
if (event.getPointerCount() == 2) {
// Right-click event when a second finger touches the screen
// Simulating right-click by sending GLFW_MOUSE_BUTTON_RIGHT event
Log.i("downthecrop","Hi from a rightclick event!");
CallbackBridge.putMouseEventWithCoords(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, CallbackBridge.mouseX, CallbackBridge.mouseY);
}
mScrollLastInitialX = event.getX();
mScrollLastInitialY = event.getY();
break;
case MotionEvent.ACTION_DOWN:
mPrevX = x;
mPrevY = y;
mCurrentPointerID = event.getPointerId(0);
break;
case MotionEvent.ACTION_MOVE: // 2
//Scrolling feature
if (!LauncherPreferences.PREF_DISABLE_GESTURES && !CallbackBridge.isGrabbing() && event.getPointerCount() >= 2) {
int hScroll = ((int) (event.getX() - mScrollLastInitialX)) / FINGER_SCROLL_THRESHOLD;
int vScroll = ((int) (event.getY() - mScrollLastInitialY)) / FINGER_SCROLL_THRESHOLD;
if(vScroll != 0 || hScroll != 0){
CallbackBridge.sendScroll(hScroll, vScroll);
mScrollLastInitialX = event.getX();
mScrollLastInitialY = event.getY();
}
break;
}
// Mouse movement
if(mCurrentPointerID == event.getPointerId(0)) {
mouseX = Math.max(0, Math.min(currentDisplayMetrics.widthPixels, mouseX + (x - mPrevX) * LauncherPreferences.PREF_MOUSESPEED));
mouseY = Math.max(0, Math.min(currentDisplayMetrics.heightPixels, mouseY + (y - mPrevY) * LauncherPreferences.PREF_MOUSESPEED));
placeMouseAt(mouseX, mouseY);
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
}else mCurrentPointerID = event.getPointerId(0);
mPrevX = x;
mPrevY = y;
break;
case MotionEvent.ACTION_UP:
mPrevX = x;
mPrevY = y;
mCurrentPointerID = -1000;
break;
}
return true;
}
/** Enable the touchpad */
public void enable(){
setVisibility(VISIBLE);
placeMouseAt(currentDisplayMetrics.widthPixels / 2f, currentDisplayMetrics.heightPixels / 2f);
}
/** Disable the touchpad and hides the mouse */
public void disable(){
setVisibility(GONE);
}
/** @return The new state, enabled or disabled */
public boolean switchState(){
mDisplayState = !mDisplayState;
if(!CallbackBridge.isGrabbing()) {
if(mDisplayState) enable();
else disable();
}
return mDisplayState;
}
public void placeMouseAt(float x, float y) {
mMousePointerImageView.setX(x);
mMousePointerImageView.setY(y);
CallbackBridge.mouseX = (x * mScaleFactor);
CallbackBridge.mouseY = (y * mScaleFactor);
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
}
private void init(){
// Setup mouse pointer
mMousePointerImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_mouse_pointer, getContext().getTheme()));
mMousePointerImageView.post(() -> {
ViewGroup.LayoutParams params = mMousePointerImageView.getLayoutParams();
params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE);
params.height = (int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE);
});
addView(mMousePointerImageView);
setFocusable(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setDefaultFocusHighlightEnabled(false);
}
// When the game is grabbing, we should not display the mouse
disable();
mDisplayState = false;
}
@Override
public void onGrabState(boolean isGrabbing) {
post(()->updateGrabState(isGrabbing));
}
private void updateGrabState(boolean isGrabbing) {
if(!isGrabbing) {
if(mDisplayState && getVisibility() != VISIBLE) enable();
if(!mDisplayState && getVisibility() == VISIBLE) disable();
}else{
if(getVisibility() != View.GONE) disable();
}
}
}