mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-17 00:29:50 -04:00
- Move some BaseMainActivity to their respective classes
- Improved control onTouch performance
This commit is contained in:
parent
9198413f11
commit
3dd0e0331b
@ -12,7 +12,6 @@ import android.graphics.*;
|
|||||||
import android.os.*;
|
import android.os.*;
|
||||||
import android.util.*;
|
import android.util.*;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.view.View.*;
|
|
||||||
import android.widget.*;
|
import android.widget.*;
|
||||||
|
|
||||||
import androidx.drawerlayout.widget.*;
|
import androidx.drawerlayout.widget.*;
|
||||||
@ -36,18 +35,11 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
|
|
||||||
volatile public static boolean isInputStackCall;
|
volatile public static boolean isInputStackCall;
|
||||||
|
|
||||||
private static final int[] hotbarKeys = {
|
|
||||||
LWJGLGLFWKeycode.GLFW_KEY_1, LWJGLGLFWKeycode.GLFW_KEY_2, LWJGLGLFWKeycode.GLFW_KEY_3,
|
|
||||||
LWJGLGLFWKeycode.GLFW_KEY_4, LWJGLGLFWKeycode.GLFW_KEY_5, LWJGLGLFWKeycode.GLFW_KEY_6,
|
|
||||||
LWJGLGLFWKeycode.GLFW_KEY_7, LWJGLGLFWKeycode.GLFW_KEY_8, LWJGLGLFWKeycode.GLFW_KEY_9};
|
|
||||||
|
|
||||||
private Gamepad gamepad;
|
private Gamepad gamepad;
|
||||||
|
|
||||||
private static boolean rightOverride = false;
|
|
||||||
private DisplayMetrics displayMetrics;
|
private DisplayMetrics displayMetrics;
|
||||||
public float scaleFactor = 1;
|
public float scaleFactor = 1;
|
||||||
public double sensitivityFactor;
|
public double sensitivityFactor;
|
||||||
private final int fingerScrollThreshold = (int) Tools.dpToPx(6);
|
|
||||||
|
|
||||||
private boolean mIsResuming = false;
|
private boolean mIsResuming = false;
|
||||||
|
|
||||||
@ -58,7 +50,7 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
|
|
||||||
|
|
||||||
private static boolean isVirtualMouseEnabled;
|
private static boolean isVirtualMouseEnabled;
|
||||||
private static LinearLayout touchPad;
|
private static Touchpad touchpad;
|
||||||
private ImageView mousePointer;
|
private ImageView mousePointer;
|
||||||
private MinecraftAccount mProfile;
|
private MinecraftAccount mProfile;
|
||||||
|
|
||||||
@ -76,8 +68,6 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
|
|
||||||
protected volatile JMinecraftVersionList.Version mVersionInfo;
|
protected volatile JMinecraftVersionList.Version mVersionInfo;
|
||||||
|
|
||||||
private View.OnTouchListener glTouchListener;
|
|
||||||
|
|
||||||
private File logFile;
|
private File logFile;
|
||||||
private PrintStream logStream;
|
private PrintStream logStream;
|
||||||
private PerVersionConfig.VersionConfig config;
|
private PerVersionConfig.VersionConfig config;
|
||||||
@ -134,10 +124,6 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
windowHeight = Tools.getDisplayFriendlyRes(displayMetrics.heightPixels, scaleFactor);
|
windowHeight = Tools.getDisplayFriendlyRes(displayMetrics.heightPixels, scaleFactor);
|
||||||
System.out.println("WidthHeight: " + windowWidth + ":" + windowHeight);
|
System.out.println("WidthHeight: " + windowWidth + ":" + windowHeight);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
singleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH);
|
|
||||||
doubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN);
|
|
||||||
|
|
||||||
|
|
||||||
// Menu
|
// Menu
|
||||||
@ -165,15 +151,7 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
};
|
};
|
||||||
navDrawer.setNavigationItemSelectedListener(gameActionListener);
|
navDrawer.setNavigationItemSelectedListener(gameActionListener);
|
||||||
|
|
||||||
this.touchPad = findViewById(R.id.main_touchpad);
|
touchpad = findViewById(R.id.main_touchpad);
|
||||||
touchPad.setFocusable(false);
|
|
||||||
|
|
||||||
this.mousePointer = findViewById(R.id.main_mouse_pointer);
|
|
||||||
this.mousePointer.post(() -> {
|
|
||||||
ViewGroup.LayoutParams params = mousePointer.getLayoutParams();
|
|
||||||
params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE);
|
|
||||||
params.height = (int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.contentLog = findViewById(R.id.content_log_layout);
|
this.contentLog = findViewById(R.id.content_log_layout);
|
||||||
this.contentScroll = findViewById(R.id.content_log_scroll);
|
this.contentScroll = findViewById(R.id.content_log_scroll);
|
||||||
@ -192,119 +170,6 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
this.minecraftGLView = findViewById(R.id.main_game_render_view);
|
this.minecraftGLView = findViewById(R.id.main_game_render_view);
|
||||||
this.drawerLayout.closeDrawers();
|
this.drawerLayout.closeDrawers();
|
||||||
|
|
||||||
placeMouseAt(CallbackBridge.physicalWidth / 2, CallbackBridge.physicalHeight / 2);
|
|
||||||
Thread virtualMouseGrabThread = new Thread(() -> {
|
|
||||||
while (!isExited) {
|
|
||||||
if (lastGrab != CallbackBridge.isGrabbing())
|
|
||||||
mousePointer.post(() -> {
|
|
||||||
if (!CallbackBridge.isGrabbing() && isVirtualMouseEnabled) {
|
|
||||||
touchPad.setVisibility(View.VISIBLE);
|
|
||||||
placeMouseAt(displayMetrics.widthPixels / 2, displayMetrics.heightPixels / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CallbackBridge.isGrabbing() && touchPad.getVisibility() != View.GONE) {
|
|
||||||
touchPad.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastGrab = CallbackBridge.isGrabbing();
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}, "VirtualMouseGrabThread");
|
|
||||||
virtualMouseGrabThread.setPriority(Thread.MIN_PRIORITY);
|
|
||||||
virtualMouseGrabThread.start();
|
|
||||||
|
|
||||||
if (isAndroid8OrHigher()) {
|
|
||||||
touchPad.setDefaultFocusHighlightEnabled(false);
|
|
||||||
}
|
|
||||||
touchPad.setOnTouchListener((v, 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()) {
|
|
||||||
minecraftGLView.dispatchTouchEvent(MotionEvent.obtain(event));
|
|
||||||
System.out.println("Transitioned event" + event.hashCode() + " to MinecraftGLView");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int action = event.getActionMasked();
|
|
||||||
|
|
||||||
float x = event.getX();
|
|
||||||
float y = event.getY();
|
|
||||||
float mouseX = mousePointer.getX();
|
|
||||||
float mouseY = mousePointer.getY();
|
|
||||||
|
|
||||||
if (singleTapDetector.onTouchEvent(event)) {
|
|
||||||
mouse_x = (mouseX * scaleFactor);
|
|
||||||
mouse_y = (mouseY * scaleFactor);
|
|
||||||
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
|
||||||
CallbackBridge.sendMouseKeycode(rightOverride ? LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT : LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
|
||||||
switch (action) {
|
|
||||||
case MotionEvent.ACTION_POINTER_DOWN: // 5
|
|
||||||
scrollLastInitialX = event.getX();
|
|
||||||
scrollLastInitialY = event.getY();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MotionEvent.ACTION_DOWN:
|
|
||||||
prevX = x;
|
|
||||||
prevY = y;
|
|
||||||
currentPointerID = event.getPointerId(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MotionEvent.ACTION_MOVE: // 2
|
|
||||||
|
|
||||||
if (!CallbackBridge.isGrabbing() && event.getPointerCount() >= 2 && !LauncherPreferences.PREF_DISABLE_GESTURES) { //Scrolling feature
|
|
||||||
int hScroll = ((int) (event.getX() - scrollLastInitialX)) / fingerScrollThreshold;
|
|
||||||
int vScroll = ((int) (event.getY() - scrollLastInitialY)) / fingerScrollThreshold;
|
|
||||||
|
|
||||||
if(vScroll != 0 || hScroll != 0){
|
|
||||||
CallbackBridge.sendScroll(hScroll, vScroll);
|
|
||||||
scrollLastInitialX = event.getX();
|
|
||||||
scrollLastInitialY = event.getY();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(currentPointerID == event.getPointerId(0)) {
|
|
||||||
mouseX = Math.max(0, Math.min(displayMetrics.widthPixels, mouseX + (x - prevX) * LauncherPreferences.PREF_MOUSESPEED));
|
|
||||||
mouseY = Math.max(0, Math.min(displayMetrics.heightPixels, mouseY + (y - prevY) * LauncherPreferences.PREF_MOUSESPEED));
|
|
||||||
mouse_x = (mouseX * scaleFactor);
|
|
||||||
mouse_y = (mouseY * scaleFactor);
|
|
||||||
placeMouseAt(mouseX, mouseY);
|
|
||||||
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
|
||||||
}else currentPointerID = event.getPointerId(0);
|
|
||||||
|
|
||||||
prevX = x;
|
|
||||||
prevY = y;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
prevX = x;
|
|
||||||
prevY = y;
|
|
||||||
currentPointerID = -1000;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debugText.setText(CallbackBridge.DEBUG_STRING.toString());
|
|
||||||
CallbackBridge.DEBUG_STRING.setLength(0);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
glTouchListener = new OnTouchListener(){
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View p1, MotionEvent e) {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isAndroid8OrHigher()) {
|
if (isAndroid8OrHigher()) {
|
||||||
minecraftGLView.setDefaultFocusHighlightEnabled(false);
|
minecraftGLView.setDefaultFocusHighlightEnabled(false);
|
||||||
@ -372,58 +237,17 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
minecraftGLView.setOnTouchListener(glTouchListener);
|
|
||||||
minecraftGLView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener(){
|
|
||||||
|
|
||||||
private boolean isCalled = false;
|
|
||||||
@Override
|
|
||||||
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
|
|
||||||
scaleFactor = (LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f);
|
|
||||||
windowWidth = Tools.getDisplayFriendlyRes(width, scaleFactor);
|
|
||||||
windowHeight = Tools.getDisplayFriendlyRes(height, scaleFactor);
|
|
||||||
texture.setDefaultBufferSize(windowWidth, windowHeight);
|
|
||||||
|
|
||||||
//Load Minecraft options:
|
minecraftGLView.setSurfaceReadyListener(() -> {
|
||||||
MCOptionUtils.load();
|
try {
|
||||||
MCOptionUtils.set("overrideWidth", String.valueOf(windowWidth));
|
runCraft();
|
||||||
MCOptionUtils.set("overrideHeight", String.valueOf(windowHeight));
|
}catch (Throwable e){
|
||||||
MCOptionUtils.save();
|
Tools.showError(getApplicationContext(), e, true);
|
||||||
getMcScale();
|
}
|
||||||
// Should we do that?
|
});
|
||||||
if (!isCalled) {
|
|
||||||
isCalled = true;
|
|
||||||
|
|
||||||
JREUtils.setupBridgeWindow(new Surface(texture));
|
|
||||||
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
Thread.sleep(200);
|
|
||||||
runCraft();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
Tools.showError(BaseMainActivity.this, e, true);
|
|
||||||
}
|
|
||||||
}, "JVM Main thread").start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
minecraftGLView.init();
|
||||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
|
|
||||||
windowWidth = Tools.getDisplayFriendlyRes(width, scaleFactor);
|
|
||||||
windowHeight = Tools.getDisplayFriendlyRes(height, scaleFactor);
|
|
||||||
CallbackBridge.sendUpdateWindowSize(windowWidth, windowHeight);
|
|
||||||
getMcScale();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
|
|
||||||
texture.setDefaultBufferSize(windowWidth, windowHeight);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Tools.showError(this, e, true);
|
Tools.showError(this, e, true);
|
||||||
}
|
}
|
||||||
@ -692,10 +516,6 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public int mcscale(int input) {
|
|
||||||
return (int)((this.guiScale * input)/scaleFactor);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void toggleMenu(View v) {
|
public void toggleMenu(View v) {
|
||||||
drawerLayout.openDrawer(Gravity.RIGHT);
|
drawerLayout.openDrawer(Gravity.RIGHT);
|
||||||
@ -706,18 +526,13 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
this.mousePointer.setY(mousePointer.getY() + y);
|
this.mousePointer.setY(mousePointer.getY() + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void placeMouseAt(float x, float y) {
|
|
||||||
this.mousePointer.setX(x);
|
|
||||||
this.mousePointer.setY(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void toggleMouse(Context ctx) {
|
public static void toggleMouse(Context ctx) {
|
||||||
if (CallbackBridge.isGrabbing()) return;
|
if (CallbackBridge.isGrabbing()) return;
|
||||||
|
|
||||||
isVirtualMouseEnabled = !isVirtualMouseEnabled;
|
Toast.makeText(ctx, touchpad.switchState()
|
||||||
touchPad.setVisibility(isVirtualMouseEnabled ? View.VISIBLE : View.GONE);
|
? R.string.control_mouseon : R.string.control_mouseoff,
|
||||||
Toast.makeText(ctx,
|
|
||||||
isVirtualMouseEnabled ? R.string.control_mouseon : R.string.control_mouseoff,
|
|
||||||
Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -746,12 +561,6 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void setRightOverride(boolean val) {
|
|
||||||
rightOverride = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sendKeyPress(int keyCode, int modifiers, boolean status) {
|
public static void sendKeyPress(int keyCode, int modifiers, boolean status) {
|
||||||
sendKeyPress(keyCode, 0, modifiers, status);
|
sendKeyPress(keyCode, 0, modifiers, status);
|
||||||
}
|
}
|
||||||
@ -791,36 +600,8 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMcScale() {
|
|
||||||
//Get the scale stored in game files, used auto scale if found or if the stored scaled is bigger than the authorized size.
|
|
||||||
MCOptionUtils.load();
|
|
||||||
String str = MCOptionUtils.get("guiScale");
|
|
||||||
this.guiScale = (str == null ? 0 :Integer.parseInt(str));
|
|
||||||
|
|
||||||
|
|
||||||
int scale = Math.max(Math.min(windowWidth / 320, windowHeight / 240), 1);
|
|
||||||
if(scale < this.guiScale || guiScale == 0){
|
|
||||||
this.guiScale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(gamepad != null) gamepad.notifyGUISizeChange(this.guiScale);
|
|
||||||
return this.guiScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int handleGuiBar(int x, int y) {
|
|
||||||
if (!CallbackBridge.isGrabbing()) return -1;
|
|
||||||
|
|
||||||
int barHeight = mcscale(20);
|
|
||||||
int barWidth = mcscale(180);
|
|
||||||
int barX = (CallbackBridge.physicalWidth / 2) - (barWidth / 2);
|
|
||||||
int barY = CallbackBridge.physicalHeight - barHeight;
|
|
||||||
if (x < barX || x >= barX + barWidth || y < barY || y >= barY + barHeight) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return hotbarKeys[((x - barX) / mcscale(180 / 9)) % 9];
|
|
||||||
}
|
|
||||||
int tmpMouseSpeed;
|
int tmpMouseSpeed;
|
||||||
|
|
||||||
public void adjustMouseSpeedLive() {
|
public void adjustMouseSpeedLive() {
|
||||||
AlertDialog.Builder b = new AlertDialog.Builder(this);
|
AlertDialog.Builder b = new AlertDialog.Builder(this);
|
||||||
b.setTitle(R.string.mcl_setting_title_mousespeed);
|
b.setTitle(R.string.mcl_setting_title_mousespeed);
|
||||||
|
@ -2,32 +2,54 @@ package net.kdt.pojavlaunch;
|
|||||||
|
|
||||||
import static net.kdt.pojavlaunch.BaseMainActivity.sendKeyPress;
|
import static net.kdt.pojavlaunch.BaseMainActivity.sendKeyPress;
|
||||||
import static net.kdt.pojavlaunch.BaseMainActivity.sendMouseButton;
|
import static net.kdt.pojavlaunch.BaseMainActivity.sendMouseButton;
|
||||||
|
import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale;
|
||||||
|
|
||||||
|
import static org.lwjgl.glfw.CallbackBridge.windowHeight;
|
||||||
|
import static org.lwjgl.glfw.CallbackBridge.windowWidth;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.*;
|
import android.content.*;
|
||||||
|
import android.graphics.SurfaceTexture;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.util.*;
|
import android.util.*;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.google.android.material.math.MathUtils;
|
||||||
|
|
||||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||||
|
import net.kdt.pojavlaunch.utils.JREUtils;
|
||||||
|
import net.kdt.pojavlaunch.utils.MCOptionUtils;
|
||||||
|
|
||||||
import org.lwjgl.glfw.CallbackBridge;
|
import org.lwjgl.glfw.CallbackBridge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class dealing with showing minecraft surface and taking inputs and dispatching them to minecraft
|
||||||
|
*/
|
||||||
public class MinecraftGLView extends TextureView {
|
public class MinecraftGLView extends TextureView {
|
||||||
|
|
||||||
/* Resolution scaler option, allow downsizing a window */
|
/* Resolution scaler option, allow downsizing a window */
|
||||||
private float scaleFactor = 1f;
|
private final float scaleFactor = LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f;
|
||||||
/* Display properties, such as resolution and DPI */
|
/* Display properties, such as resolution and DPI */
|
||||||
private DisplayMetrics displayMetrics = Tools.getDisplayMetrics((Activity) getContext());
|
private final DisplayMetrics displayMetrics = Tools.getDisplayMetrics((Activity) getContext());
|
||||||
/* Sensitivity, adjusted according to screen size */
|
/* Sensitivity, adjusted according to screen size */
|
||||||
private double sensitivityFactor = (1.4 * (1080f/ displayMetrics.heightPixels));
|
private final double sensitivityFactor = (1.4 * (1080f/ displayMetrics.heightPixels));
|
||||||
/* Use to detect simple and double taps */
|
/* Use to detect simple and double taps */
|
||||||
private final TapDetector singleTapDetector;
|
private final TapDetector singleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH);
|
||||||
private final TapDetector doubleTapDetector;
|
private final TapDetector doubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN);
|
||||||
|
/* MC GUI scale, listened by MCOptionUtils */
|
||||||
|
private int GUIScale = getMcScale();
|
||||||
|
private MCOptionUtils.MCOptionListener GUIScaleListener = () -> GUIScale = getMcScale();
|
||||||
|
/* Surface ready listener, used by the activity to launch minecraft */
|
||||||
|
SurfaceReadyListener surfaceReadyListener = null;
|
||||||
|
|
||||||
|
/* List of hotbarKeys, used when clicking on the hotbar */
|
||||||
|
private static final int[] hotbarKeys = {
|
||||||
|
LWJGLGLFWKeycode.GLFW_KEY_1, LWJGLGLFWKeycode.GLFW_KEY_2, LWJGLGLFWKeycode.GLFW_KEY_3,
|
||||||
|
LWJGLGLFWKeycode.GLFW_KEY_4, LWJGLGLFWKeycode.GLFW_KEY_5, LWJGLGLFWKeycode.GLFW_KEY_6,
|
||||||
|
LWJGLGLFWKeycode.GLFW_KEY_7, LWJGLGLFWKeycode.GLFW_KEY_8, LWJGLGLFWKeycode.GLFW_KEY_9};
|
||||||
/* Last hotbar button (0-9) registered */
|
/* Last hotbar button (0-9) registered */
|
||||||
private int lastHotbarKey = -1;
|
private int lastHotbarKey = -1;
|
||||||
/* Events can start with only a move instead of an pointerDown due to mouse passthrough */
|
/* Events can start with only a move instead of an pointerDown due to mouse passthrough */
|
||||||
@ -45,9 +67,9 @@ public class MinecraftGLView extends TextureView {
|
|||||||
/* Last first pointer positions non-scaled, used to scroll distance */
|
/* Last first pointer positions non-scaled, used to scroll distance */
|
||||||
private float scrollLastInitialX, scrollLastInitialY;
|
private float scrollLastInitialX, scrollLastInitialY;
|
||||||
/* How much distance a finger has to go for touch sloppiness to be disabled */
|
/* How much distance a finger has to go for touch sloppiness to be disabled */
|
||||||
private final int fingerStillThreshold = (int) Tools.dpToPx(9);
|
public static final int FINGER_STILL_THRESHOLD = (int) Tools.dpToPx(9);
|
||||||
/* How much distance a finger has to go to scroll */
|
/* How much distance a finger has to go to scroll */
|
||||||
private final int fingerScrollThreshold = (int) Tools.dpToPx(6);
|
public static final int FINGER_SCROLL_THRESHOLD = (int) Tools.dpToPx(6);
|
||||||
/* Handle hotbar throw button and mouse mining button */
|
/* Handle hotbar throw button and mouse mining button */
|
||||||
public static final int MSG_LEFT_MOUSE_BUTTON_CHECK = 1028;
|
public static final int MSG_LEFT_MOUSE_BUTTON_CHECK = 1028;
|
||||||
public static final int MSG_DROP_ITEM_BUTTON_CHECK = 1029;
|
public static final int MSG_DROP_ITEM_BUTTON_CHECK = 1029;
|
||||||
@ -58,8 +80,8 @@ public class MinecraftGLView extends TextureView {
|
|||||||
float x = CallbackBridge.mouseX;
|
float x = CallbackBridge.mouseX;
|
||||||
float y = CallbackBridge.mouseY;
|
float y = CallbackBridge.mouseY;
|
||||||
if (CallbackBridge.isGrabbing() &&
|
if (CallbackBridge.isGrabbing() &&
|
||||||
Math.abs(initialX - x) < fingerStillThreshold &&
|
Math.abs(initialX - x) < FINGER_STILL_THRESHOLD &&
|
||||||
Math.abs(initialY - y) < fingerStillThreshold) {
|
Math.abs(initialY - y) < FINGER_STILL_THRESHOLD) {
|
||||||
triggeredLeftMouseButton = true;
|
triggeredLeftMouseButton = true;
|
||||||
sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, true);
|
sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, true);
|
||||||
}
|
}
|
||||||
@ -88,11 +110,63 @@ public class MinecraftGLView extends TextureView {
|
|||||||
setOpaque(false);
|
setOpaque(false);
|
||||||
setFocusable(true);
|
setFocusable(true);
|
||||||
|
|
||||||
singleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH);
|
MCOptionUtils.addMCOptionListener(GUIScaleListener);
|
||||||
doubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void init(){
|
||||||
|
setSurfaceTextureListener(new SurfaceTextureListener() {
|
||||||
|
private boolean isCalled = false;
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
|
||||||
|
windowWidth = Tools.getDisplayFriendlyRes(width, scaleFactor);
|
||||||
|
windowHeight = Tools.getDisplayFriendlyRes(height, scaleFactor);
|
||||||
|
texture.setDefaultBufferSize(windowWidth, windowHeight);
|
||||||
|
|
||||||
|
//Load Minecraft options:
|
||||||
|
MCOptionUtils.load();
|
||||||
|
MCOptionUtils.set("overrideWidth", String.valueOf(windowWidth));
|
||||||
|
MCOptionUtils.set("overrideHeight", String.valueOf(windowHeight));
|
||||||
|
MCOptionUtils.save();
|
||||||
|
getMcScale();
|
||||||
|
// Should we do that?
|
||||||
|
if(isCalled) return;
|
||||||
|
isCalled = true;
|
||||||
|
|
||||||
|
JREUtils.setupBridgeWindow(new Surface(texture));
|
||||||
|
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
Thread.sleep(200);
|
||||||
|
if(surfaceReadyListener != null){
|
||||||
|
surfaceReadyListener.isReady();
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Tools.showError(getContext(), e, true);
|
||||||
|
}
|
||||||
|
}, "JVM Main thread").start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
|
||||||
|
windowWidth = Tools.getDisplayFriendlyRes(width, scaleFactor);
|
||||||
|
windowHeight = Tools.getDisplayFriendlyRes(height, scaleFactor);
|
||||||
|
CallbackBridge.sendUpdateWindowSize(windowWidth, windowHeight);
|
||||||
|
getMcScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
|
||||||
|
texture.setDefaultBufferSize(windowWidth, windowHeight);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The touch event for both grabbed an non-grabbed mouse state
|
* The touch event for both grabbed an non-grabbed mouse state
|
||||||
@ -114,26 +188,77 @@ public class MinecraftGLView extends TextureView {
|
|||||||
|
|
||||||
//Getting scaled position from the event
|
//Getting scaled position from the event
|
||||||
/* Tells if a double tap happened [MOUSE GRAB ONLY]. Doesn't tell where though. */
|
/* Tells if a double tap happened [MOUSE GRAB ONLY]. Doesn't tell where though. */
|
||||||
boolean hasDoubleTapped = false;
|
|
||||||
if(!CallbackBridge.isGrabbing()) {
|
if(!CallbackBridge.isGrabbing()) {
|
||||||
mouse_x = (e.getX() * scaleFactor);
|
mouse_x = (e.getX() * scaleFactor);
|
||||||
mouse_y = (e.getY() * scaleFactor);
|
mouse_y = (e.getY() * scaleFactor);
|
||||||
//One android click = one MC click
|
//One android click = one MC click
|
||||||
if(singleTapDetector.onTouchEvent(e)){
|
if(singleTapDetector.onTouchEvent(e)){
|
||||||
CallbackBridge.putMouseEventWithCoords(rightOverride ? (byte) 1 : (byte) 0, (int)mouse_x, (int)mouse_y);
|
CallbackBridge.putMouseEventWithCoords(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, mouse_x, mouse_y);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
hasDoubleTapped = doubleTapDetector.onTouchEvent(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check double tap state, used for the hotbar
|
||||||
|
boolean hasDoubleTapped = doubleTapDetector.onTouchEvent(e);
|
||||||
|
|
||||||
switch (e.getActionMasked()) {
|
switch (e.getActionMasked()) {
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
int pointerCount = e.getPointerCount();
|
||||||
|
|
||||||
|
// In-menu interactions
|
||||||
|
if(!CallbackBridge.isGrabbing()){
|
||||||
|
|
||||||
|
// Touch hover
|
||||||
|
if(pointerCount == 1){
|
||||||
|
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
||||||
|
prevX = e.getX();
|
||||||
|
prevY = e.getY();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scrolling feature
|
||||||
|
if(LauncherPreferences.PREF_DISABLE_GESTURES) break;
|
||||||
|
// The pointer count can never be 0, and it is not 1, therefore it is >= 2
|
||||||
|
int hScroll = ((int) (e.getX() - scrollLastInitialX)) / FINGER_SCROLL_THRESHOLD;
|
||||||
|
int vScroll = ((int) (e.getY() - scrollLastInitialY)) / FINGER_SCROLL_THRESHOLD;
|
||||||
|
|
||||||
|
if(vScroll != 0 || hScroll != 0){
|
||||||
|
CallbackBridge.sendScroll(hScroll, vScroll);
|
||||||
|
scrollLastInitialX = e.getX();
|
||||||
|
scrollLastInitialY = e.getY();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Camera movement
|
||||||
|
int pointerIndex = e.findPointerIndex(currentPointerID);
|
||||||
|
int hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY());
|
||||||
|
// Start movement, due to new pointer or loss of pointer
|
||||||
|
if (pointerIndex == -1 || lastPointerCount != pointerCount || !shouldBeDown) {
|
||||||
|
if(hudKeyHandled != -1) break; //No pointer attribution on hotbar
|
||||||
|
|
||||||
|
shouldBeDown = true;
|
||||||
|
currentPointerID = e.getPointerId(0);
|
||||||
|
prevX = e.getX();
|
||||||
|
prevY = e.getY();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Continue movement as usual
|
||||||
|
if(hudKeyHandled == -1){ //No camera on hotbar
|
||||||
|
mouse_x += (e.getX(pointerIndex) - prevX) * sensitivityFactor;
|
||||||
|
mouse_y += (e.getY(pointerIndex) - prevY) * sensitivityFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
prevX = e.getX(pointerIndex);
|
||||||
|
prevY = e.getY(pointerIndex);
|
||||||
|
|
||||||
|
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
||||||
|
break;
|
||||||
|
|
||||||
case MotionEvent.ACTION_DOWN: // 0
|
case MotionEvent.ACTION_DOWN: // 0
|
||||||
//shouldBeDown = true;
|
|
||||||
CallbackBridge.sendPrepareGrabInitialPos();
|
CallbackBridge.sendPrepareGrabInitialPos();
|
||||||
|
|
||||||
|
hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY());
|
||||||
int hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY());
|
|
||||||
boolean isTouchInHotbar = hudKeyHandled != -1;
|
boolean isTouchInHotbar = hudKeyHandled != -1;
|
||||||
if (isTouchInHotbar) {
|
if (isTouchInHotbar) {
|
||||||
sendKeyPress(hudKeyHandled);
|
sendKeyPress(hudKeyHandled);
|
||||||
@ -169,25 +294,30 @@ public class MinecraftGLView extends TextureView {
|
|||||||
|
|
||||||
hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY());
|
hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY());
|
||||||
isTouchInHotbar = hudKeyHandled != -1;
|
isTouchInHotbar = hudKeyHandled != -1;
|
||||||
|
// We only treat in world events
|
||||||
|
if (!CallbackBridge.isGrabbing()) break;
|
||||||
|
|
||||||
if (CallbackBridge.isGrabbing()) {
|
// Stop the dropping of items
|
||||||
if (!isTouchInHotbar && !triggeredLeftMouseButton && Math.abs(initialX - mouse_x) < fingerStillThreshold && Math.abs(initialY - mouse_y) < fingerStillThreshold) {
|
if (isTouchInHotbar) {
|
||||||
if (!LauncherPreferences.PREF_DISABLE_GESTURES) {
|
sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_Q, 0, false);
|
||||||
sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, true);
|
theHandler.removeMessages(MSG_DROP_ITEM_BUTTON_CHECK);
|
||||||
sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, false);
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isTouchInHotbar) {
|
|
||||||
if (triggeredLeftMouseButton) sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, false);
|
|
||||||
|
|
||||||
triggeredLeftMouseButton = false;
|
|
||||||
theHandler.removeMessages(MSG_LEFT_MOUSE_BUTTON_CHECK);
|
|
||||||
} else {
|
|
||||||
sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_Q, 0, false);
|
|
||||||
theHandler.removeMessages(MSG_DROP_ITEM_BUTTON_CHECK);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the mouse left button
|
||||||
|
if(triggeredLeftMouseButton){
|
||||||
|
sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, false);
|
||||||
|
triggeredLeftMouseButton = false;
|
||||||
|
theHandler.removeMessages(MSG_LEFT_MOUSE_BUTTON_CHECK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case of a short click, just send a quick right click
|
||||||
|
if(!LauncherPreferences.PREF_DISABLE_GESTURES &&
|
||||||
|
MathUtils.dist(initialX, initialY, mouse_x, mouse_y) < FINGER_STILL_THRESHOLD){
|
||||||
|
sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, true);
|
||||||
|
sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, false);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionEvent.ACTION_POINTER_DOWN: // 5
|
case MotionEvent.ACTION_POINTER_DOWN: // 5
|
||||||
@ -195,7 +325,7 @@ public class MinecraftGLView extends TextureView {
|
|||||||
scrollLastInitialY = e.getY();
|
scrollLastInitialY = e.getY();
|
||||||
//Checking if we are pressing the hotbar to select the item
|
//Checking if we are pressing the hotbar to select the item
|
||||||
hudKeyHandled = handleGuiBar((int)e.getX(e.getPointerCount()-1), (int) e.getY(e.getPointerCount()-1));
|
hudKeyHandled = handleGuiBar((int)e.getX(e.getPointerCount()-1), (int) e.getY(e.getPointerCount()-1));
|
||||||
if(hudKeyHandled != -1){
|
if(hudKeyHandled == -1){
|
||||||
sendKeyPress(hudKeyHandled);
|
sendKeyPress(hudKeyHandled);
|
||||||
if(hasDoubleTapped && hudKeyHandled == lastHotbarKey){
|
if(hasDoubleTapped && hudKeyHandled == lastHotbarKey){
|
||||||
//Prevent double tapping Event on two different slots
|
//Prevent double tapping Event on two different slots
|
||||||
@ -206,60 +336,49 @@ public class MinecraftGLView extends TextureView {
|
|||||||
lastHotbarKey = hudKeyHandled;
|
lastHotbarKey = hudKeyHandled;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionEvent.ACTION_MOVE:
|
|
||||||
if (!CallbackBridge.isGrabbing() && e.getPointerCount() >= 2 && !LauncherPreferences.PREF_DISABLE_GESTURES) { //Scrolling feature
|
|
||||||
int hScroll = ((int) (e.getX() - scrollLastInitialX)) / fingerScrollThreshold;
|
|
||||||
int vScroll = ((int) (e.getY() - scrollLastInitialY)) / fingerScrollThreshold;
|
|
||||||
|
|
||||||
if(vScroll != 0 || hScroll != 0){
|
|
||||||
CallbackBridge.sendScroll(hScroll, vScroll);
|
|
||||||
scrollLastInitialX = e.getX();
|
|
||||||
scrollLastInitialY = e.getY();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else if (!CallbackBridge.isGrabbing() && e.getPointerCount() == 1) { //Touch hover
|
|
||||||
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
|
||||||
prevX = e.getX();
|
|
||||||
prevY = e.getY();
|
|
||||||
} else {
|
|
||||||
//Camera movement
|
|
||||||
if (CallbackBridge.isGrabbing()) {
|
|
||||||
int pointerIndex = e.findPointerIndex(currentPointerID);
|
|
||||||
if (pointerIndex == -1 || lastPointerCount != e.getPointerCount() || !shouldBeDown) {
|
|
||||||
shouldBeDown = true;
|
|
||||||
|
|
||||||
hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY());
|
|
||||||
if(hudKeyHandled != -1) break; //No camera movement on hotbar
|
|
||||||
|
|
||||||
currentPointerID = e.getPointerId(0);
|
|
||||||
prevX = e.getX();
|
|
||||||
prevY = e.getY();
|
|
||||||
} else {
|
|
||||||
hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY());
|
|
||||||
if(hudKeyHandled == -1){ //No camera on hotbar
|
|
||||||
mouse_x += (e.getX(pointerIndex) - prevX) * sensitivityFactor;
|
|
||||||
mouse_y += (e.getY(pointerIndex) - prevY) * sensitivityFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
prevX = e.getX(pointerIndex);
|
|
||||||
prevY = e.getY(pointerIndex);
|
|
||||||
|
|
||||||
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lastPointerCount = e.getPointerCount();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debugText.setText(CallbackBridge.DEBUG_STRING.toString());
|
// Actualise the pointer count
|
||||||
|
lastPointerCount = e.getPointerCount();
|
||||||
|
|
||||||
|
//debugText.setText(CallbackBridge.DEBUG_STRING.toString());
|
||||||
CallbackBridge.DEBUG_STRING.setLength(0);
|
CallbackBridge.DEBUG_STRING.setLength(0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return the hotbar key, given the position. -1 if no key are pressed */
|
||||||
|
public int handleGuiBar(int x, int y) {
|
||||||
|
if (!CallbackBridge.isGrabbing()) return -1;
|
||||||
|
|
||||||
|
int barHeight = mcscale(20);
|
||||||
|
int barY = CallbackBridge.physicalHeight - barHeight;
|
||||||
|
if(y < barY) return -1;
|
||||||
|
|
||||||
|
int barWidth = mcscale(180);
|
||||||
|
int barX = (CallbackBridge.physicalWidth / 2) - (barWidth / 2);
|
||||||
|
if(x < barX || x >= barX + barWidth) return -1;
|
||||||
|
|
||||||
|
return hotbarKeys[((x - barX) / barWidth / 9) % 9];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the size, given the UI scale size */
|
||||||
|
private int mcscale(int input) {
|
||||||
|
return (int)((GUIScale * input)/scaleFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||||
|
return super.dispatchKeyEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** A small interface called when the listener is ready for the first time */
|
||||||
|
public interface SurfaceReadyListener {
|
||||||
|
void isReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSurfaceReadyListener(SurfaceReadyListener listener){
|
||||||
|
surfaceReadyListener = listener;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,185 @@
|
|||||||
|
package net.kdt.pojavlaunch;
|
||||||
|
|
||||||
|
import static net.kdt.pojavlaunch.BaseMainActivity.isAndroid8OrHigher;
|
||||||
|
import static net.kdt.pojavlaunch.MinecraftGLView.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.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.LWJGLGLFWKeycode;
|
||||||
|
import net.kdt.pojavlaunch.MinecraftGLView;
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
import net.kdt.pojavlaunch.SingleTapConfirm;
|
||||||
|
import net.kdt.pojavlaunch.Tools;
|
||||||
|
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.CallbackBridge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class dealing with the virtual mouse
|
||||||
|
*/
|
||||||
|
public class Touchpad extends FrameLayout {
|
||||||
|
|
||||||
|
/* Mouse pointer icon used by the touchpad */
|
||||||
|
private final ImageView mousePointer = new ImageView(getContext());
|
||||||
|
/* Detect a classic android Tap */
|
||||||
|
private final GestureDetector singleTapDetector = new GestureDetector(getContext(), new SingleTapConfirm());
|
||||||
|
/* Mc mouse position, scaled by the scaleFactor */
|
||||||
|
float mouse_x, mouse_y;
|
||||||
|
/* Resolution scaler option, allow downsizing a window */
|
||||||
|
private final float scaleFactor = DEFAULT_PREF.getInt("resolutionRatio",100)/100f;
|
||||||
|
/* Current pointer ID to move the mouse */
|
||||||
|
private int currentPointerID = -1000;
|
||||||
|
/* Previous MotionEvent position, not scale */
|
||||||
|
private float prevX, prevY;
|
||||||
|
/* Last first pointer positions non-scaled, used to scroll distance */
|
||||||
|
private float scrollLastInitialX, scrollLastInitialY;
|
||||||
|
|
||||||
|
public Touchpad(@NonNull Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Touchpad(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(){
|
||||||
|
// Setup mouse pointer
|
||||||
|
mousePointer.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.mouse_pointer, getContext().getTheme()));
|
||||||
|
mousePointer.post(() -> {
|
||||||
|
ViewGroup.LayoutParams params = mousePointer.getLayoutParams();
|
||||||
|
params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE);
|
||||||
|
params.height = (int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE);
|
||||||
|
});
|
||||||
|
addView(mousePointer);
|
||||||
|
setFocusable(false);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
setDefaultFocusHighlightEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Enable the touchpad */
|
||||||
|
public void enable(){
|
||||||
|
setVisibility(VISIBLE);
|
||||||
|
placeMouseAt(currentDisplayMetrics.widthPixels / 2, currentDisplayMetrics.heightPixels / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Disable the touchpad and hides the mouse */
|
||||||
|
public void disable(){
|
||||||
|
setVisibility(GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return: The new state, enabled or disabled */
|
||||||
|
public boolean switchState(){
|
||||||
|
if(getVisibility() == VISIBLE){
|
||||||
|
disable();
|
||||||
|
return false;
|
||||||
|
} else{
|
||||||
|
enable();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 = mousePointer.getX();
|
||||||
|
float mouseY = mousePointer.getY();
|
||||||
|
|
||||||
|
if (singleTapDetector.onTouchEvent(event)) {
|
||||||
|
mouse_x = (mouseX * scaleFactor);
|
||||||
|
mouse_y = (mouseY * scaleFactor);
|
||||||
|
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
||||||
|
CallbackBridge.sendMouseKeycode(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case MotionEvent.ACTION_POINTER_DOWN: // 5
|
||||||
|
scrollLastInitialX = event.getX();
|
||||||
|
scrollLastInitialY = event.getY();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
prevX = x;
|
||||||
|
prevY = y;
|
||||||
|
currentPointerID = 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() - scrollLastInitialX)) / FINGER_SCROLL_THRESHOLD;
|
||||||
|
int vScroll = ((int) (event.getY() - scrollLastInitialY)) / FINGER_SCROLL_THRESHOLD;
|
||||||
|
|
||||||
|
if(vScroll != 0 || hScroll != 0){
|
||||||
|
CallbackBridge.sendScroll(hScroll, vScroll);
|
||||||
|
scrollLastInitialX = event.getX();
|
||||||
|
scrollLastInitialY = event.getY();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mouse movement
|
||||||
|
if(currentPointerID == event.getPointerId(0)) {
|
||||||
|
mouseX = Math.max(0, Math.min(currentDisplayMetrics.widthPixels, mouseX + (x - prevX) * LauncherPreferences.PREF_MOUSESPEED));
|
||||||
|
mouseY = Math.max(0, Math.min(currentDisplayMetrics.heightPixels, mouseY + (y - prevY) * LauncherPreferences.PREF_MOUSESPEED));
|
||||||
|
|
||||||
|
placeMouseAt(mouseX, mouseY);
|
||||||
|
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
||||||
|
}else currentPointerID = event.getPointerId(0);
|
||||||
|
|
||||||
|
prevX = x;
|
||||||
|
prevY = y;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
prevX = x;
|
||||||
|
prevY = y;
|
||||||
|
currentPointerID = -1000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//debugText.setText(CallbackBridge.DEBUG_STRING.toString());
|
||||||
|
CallbackBridge.DEBUG_STRING.setLength(0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void placeMouseAt(float x, float y) {
|
||||||
|
mousePointer.setX(x);
|
||||||
|
mousePointer.setY(y);
|
||||||
|
mouse_x = (x * scaleFactor);
|
||||||
|
mouse_y = (y * scaleFactor);
|
||||||
|
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -25,20 +25,13 @@
|
|||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"/>
|
android:layout_height="fill_parent"/>
|
||||||
|
|
||||||
<LinearLayout
|
<net.kdt.pojavlaunch.Touchpad
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:id="@+id/main_touchpad"
|
android:id="@+id/main_touchpad"
|
||||||
android:visibility="gone">
|
android:visibility="gone"/>
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:layout_height="27dp"
|
|
||||||
android:layout_width="18dp"
|
|
||||||
android:src="@drawable/mouse_pointer"
|
|
||||||
android:id="@+id/main_mouse_pointer"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/console_pointer"
|
android:id="@+id/console_pointer"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user