Feat[touchpad]: draw properly instead of using an inner View

This commit is contained in:
artdeell 2024-04-07 21:24:42 -04:00 committed by Maksim Belov
parent 251e90c4b3
commit 916dfbfc7b
2 changed files with 47 additions and 35 deletions

View File

@ -1,18 +1,17 @@
package net.kdt.pojavlaunch; package net.kdt.pojavlaunch;
import static net.kdt.pojavlaunch.customcontrols.mouse.InGUIEventProcessor.FINGER_SCROLL_THRESHOLD;
import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics; import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics;
import static net.kdt.pojavlaunch.customcontrols.mouse.InGUIEventProcessor.FINGER_SCROLL_THRESHOLD;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.DEFAULT_PREF; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.DEFAULT_PREF;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.GestureDetector; import android.view.GestureDetector;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -25,11 +24,12 @@ import org.lwjgl.glfw.CallbackBridge;
/** /**
* Class dealing with the virtual mouse * Class dealing with the virtual mouse
*/ */
public class Touchpad extends FrameLayout implements GrabListener{ public class Touchpad extends View implements GrabListener {
/* Whether the Touchpad should be displayed */ /* Whether the Touchpad should be displayed */
private boolean mDisplayState; private boolean mDisplayState;
/* Mouse pointer icon used by the touchpad */ /* Mouse pointer icon used by the touchpad */
private final ImageView mMousePointerImageView = new ImageView(getContext()); private Drawable mMousePointerDrawable;
private float mMouseX, mMouseY;
/* Detect a classic android Tap */ /* Detect a classic android Tap */
private final GestureDetector mSingleTapDetector = new GestureDetector(getContext(), new SingleTapConfirm()); private final GestureDetector mSingleTapDetector = new GestureDetector(getContext(), new SingleTapConfirm());
/* Resolution scaler option, allow downsizing a window */ /* Resolution scaler option, allow downsizing a window */
@ -51,7 +51,7 @@ public class Touchpad extends FrameLayout implements GrabListener{
init(); init();
} }
@SuppressWarnings("accessibility") @SuppressWarnings("ClickableViewAccessibility")
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
// MotionEvent reports input details from the touch screen // MotionEvent reports input details from the touch screen
@ -66,15 +66,10 @@ public class Touchpad extends FrameLayout implements GrabListener{
float x = event.getX(); float x = event.getX();
float y = event.getY(); float y = event.getY();
float mouseX = mMousePointerImageView.getX();
float mouseY = mMousePointerImageView.getY();
if (mSingleTapDetector.onTouchEvent(event)) { if (mSingleTapDetector.onTouchEvent(event)) {
CallbackBridge.mouseX = (mouseX * mScaleFactor); sendMousePosition();
CallbackBridge.mouseY = (mouseY * mScaleFactor);
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
CallbackBridge.sendMouseKeycode(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT); CallbackBridge.sendMouseKeycode(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT);
return true; return true;
} }
@ -93,24 +88,22 @@ public class Touchpad extends FrameLayout implements GrabListener{
case MotionEvent.ACTION_MOVE: // 2 case MotionEvent.ACTION_MOVE: // 2
//Scrolling feature //Scrolling feature
if (!LauncherPreferences.PREF_DISABLE_GESTURES && !CallbackBridge.isGrabbing() && event.getPointerCount() >= 2) { if (!LauncherPreferences.PREF_DISABLE_GESTURES && !CallbackBridge.isGrabbing() && event.getPointerCount() >= 2) {
int hScroll = (int) ((event.getX() - mScrollLastInitialX) / FINGER_SCROLL_THRESHOLD); int hScroll = (int) ((x - mScrollLastInitialX) / FINGER_SCROLL_THRESHOLD);
int vScroll = (int) ((event.getY() - mScrollLastInitialY) / FINGER_SCROLL_THRESHOLD); int vScroll = (int) ((y - mScrollLastInitialY) / FINGER_SCROLL_THRESHOLD);
if(vScroll != 0 || hScroll != 0){ if(vScroll != 0 || hScroll != 0){
CallbackBridge.sendScroll(hScroll, vScroll); CallbackBridge.sendScroll(hScroll, vScroll);
mScrollLastInitialX = event.getX(); mScrollLastInitialX = x;
mScrollLastInitialY = event.getY(); mScrollLastInitialY = y;
} }
break; break;
} }
// Mouse movement // Mouse movement
if(mCurrentPointerID == event.getPointerId(0)) { if(mCurrentPointerID == event.getPointerId(0)) {
mouseX = Math.max(0, Math.min(currentDisplayMetrics.widthPixels, mouseX + (x - mPrevX) * LauncherPreferences.PREF_MOUSESPEED)); mMouseX = Math.max(0, Math.min(currentDisplayMetrics.widthPixels, mMouseX + (x - mPrevX) * LauncherPreferences.PREF_MOUSESPEED));
mouseY = Math.max(0, Math.min(currentDisplayMetrics.heightPixels, mouseY + (y - mPrevY) * LauncherPreferences.PREF_MOUSESPEED)); mMouseY = Math.max(0, Math.min(currentDisplayMetrics.heightPixels, mMouseY + (y - mPrevY) * LauncherPreferences.PREF_MOUSESPEED));
updateMousePosition();
placeMouseAt(mouseX, mouseY);
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
}else mCurrentPointerID = event.getPointerId(0); }else mCurrentPointerID = event.getPointerId(0);
mPrevX = x; mPrevX = x;
@ -149,22 +142,42 @@ public class Touchpad extends FrameLayout implements GrabListener{
} }
public void placeMouseAt(float x, float y) { public void placeMouseAt(float x, float y) {
mMousePointerImageView.setX(x); mMouseX = x;
mMousePointerImageView.setY(y); mMouseY = y;
CallbackBridge.mouseX = (x * mScaleFactor); updateMousePosition();
CallbackBridge.mouseY = (y * mScaleFactor); }
private void sendMousePosition() {
CallbackBridge.mouseX = (mMouseX * mScaleFactor);
CallbackBridge.mouseY = (mMouseY * mScaleFactor);
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
} }
private void updateMousePosition() {
sendMousePosition();
// I wanted to implement a dirty rect for this, but it is ignored since API level 21
// (which is our min API)
// Let's hope the "internally calculated area" is good enough.
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.translate(mMouseX, mMouseY);
mMousePointerDrawable.draw(canvas);
}
private void init(){ private void init(){
// Setup mouse pointer // Setup mouse pointer
mMousePointerImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_mouse_pointer, getContext().getTheme())); mMousePointerDrawable = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_mouse_pointer, getContext().getTheme());
mMousePointerImageView.post(() -> { // For some reason it's annotated as Nullable even though it doesn't seem to actually
ViewGroup.LayoutParams params = mMousePointerImageView.getLayoutParams(); // ever return null
params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE); assert mMousePointerDrawable != null;
params.height = (int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE); mMousePointerDrawable.setBounds(
}); 0, 0,
addView(mMousePointerImageView); (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE),
(int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE)
);
setFocusable(false); setFocusable(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setDefaultFocusHighlightEnabled(false); setDefaultFocusHighlightEnabled(false);

View File

@ -13,7 +13,6 @@ import androidx.annotation.Nullable;
import net.kdt.pojavlaunch.LwjglGlfwKeycode; import net.kdt.pojavlaunch.LwjglGlfwKeycode;
import net.kdt.pojavlaunch.TapDetector; import net.kdt.pojavlaunch.TapDetector;
import net.kdt.pojavlaunch.Tools;
import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import net.kdt.pojavlaunch.utils.MCOptionUtils; import net.kdt.pojavlaunch.utils.MCOptionUtils;
import net.kdt.pojavlaunch.utils.MathUtils; import net.kdt.pojavlaunch.utils.MathUtils;
@ -123,7 +122,7 @@ public class HotbarView extends View implements MCOptionUtils.MCOptionListener,
@Override @Override
public void onOptionChanged() { public void onOptionChanged() {
Tools.runOnUiThread(this); post(this);
} }
@Override @Override