diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java index 46421ab99..9386f0692 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java @@ -12,7 +12,6 @@ import android.graphics.*; import android.os.*; import android.util.*; import android.view.*; -import android.view.View.*; import android.widget.*; import androidx.drawerlayout.widget.*; @@ -36,18 +35,11 @@ public class BaseMainActivity extends LoggableActivity { 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 static boolean rightOverride = false; private DisplayMetrics displayMetrics; public float scaleFactor = 1; public double sensitivityFactor; - private final int fingerScrollThreshold = (int) Tools.dpToPx(6); private boolean mIsResuming = false; @@ -58,7 +50,7 @@ public class BaseMainActivity extends LoggableActivity { private static boolean isVirtualMouseEnabled; - private static LinearLayout touchPad; + private static Touchpad touchpad; private ImageView mousePointer; private MinecraftAccount mProfile; @@ -76,8 +68,6 @@ public class BaseMainActivity extends LoggableActivity { protected volatile JMinecraftVersionList.Version mVersionInfo; - private View.OnTouchListener glTouchListener; - private File logFile; private PrintStream logStream; private PerVersionConfig.VersionConfig config; @@ -134,10 +124,6 @@ public class BaseMainActivity extends LoggableActivity { windowHeight = Tools.getDisplayFriendlyRes(displayMetrics.heightPixels, scaleFactor); System.out.println("WidthHeight: " + windowWidth + ":" + windowHeight); - - - singleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH); - doubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN); // Menu @@ -165,15 +151,7 @@ public class BaseMainActivity extends LoggableActivity { }; navDrawer.setNavigationItemSelectedListener(gameActionListener); - this.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); - }); + touchpad = findViewById(R.id.main_touchpad); this.contentLog = findViewById(R.id.content_log_layout); 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.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()) { 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: - MCOptionUtils.load(); - MCOptionUtils.set("overrideWidth", String.valueOf(windowWidth)); - MCOptionUtils.set("overrideHeight", String.valueOf(windowHeight)); - MCOptionUtils.save(); - 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(); - } - } + minecraftGLView.setSurfaceReadyListener(() -> { + try { + runCraft(); + }catch (Throwable e){ + Tools.showError(getApplicationContext(), e, true); + } + }); - @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) { - return true; - } + minecraftGLView.init(); - @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) { 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) { drawerLayout.openDrawer(Gravity.RIGHT); @@ -706,18 +526,13 @@ public class BaseMainActivity extends LoggableActivity { 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) { if (CallbackBridge.isGrabbing()) return; - isVirtualMouseEnabled = !isVirtualMouseEnabled; - touchPad.setVisibility(isVirtualMouseEnabled ? View.VISIBLE : View.GONE); - Toast.makeText(ctx, - isVirtualMouseEnabled ? R.string.control_mouseon : R.string.control_mouseoff, + Toast.makeText(ctx, touchpad.switchState() + ? R.string.control_mouseon : R.string.control_mouseoff, 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) { sendKeyPress(keyCode, 0, modifiers, status); } @@ -791,36 +600,8 @@ public class BaseMainActivity extends LoggableActivity { 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; - public void adjustMouseSpeedLive() { AlertDialog.Builder b = new AlertDialog.Builder(this); b.setTitle(R.string.mcl_setting_title_mousespeed); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLView.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLView.java index 2df684c4a..75ebe0cc9 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLView.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLView.java @@ -2,32 +2,54 @@ package net.kdt.pojavlaunch; import static net.kdt.pojavlaunch.BaseMainActivity.sendKeyPress; 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.content.*; +import android.graphics.SurfaceTexture; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.*; import android.view.*; +import android.widget.Toast; + +import com.google.android.material.math.MathUtils; import net.kdt.pojavlaunch.prefs.LauncherPreferences; +import net.kdt.pojavlaunch.utils.JREUtils; +import net.kdt.pojavlaunch.utils.MCOptionUtils; import org.lwjgl.glfw.CallbackBridge; +/** + * Class dealing with showing minecraft surface and taking inputs and dispatching them to minecraft + */ public class MinecraftGLView extends TextureView { /* 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 */ - private DisplayMetrics displayMetrics = Tools.getDisplayMetrics((Activity) getContext()); + private final DisplayMetrics displayMetrics = Tools.getDisplayMetrics((Activity) getContext()); /* 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 */ - private final TapDetector singleTapDetector; - private final TapDetector doubleTapDetector; - + private final TapDetector singleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH); + 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 */ private int lastHotbarKey = -1; /* 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 */ private float scrollLastInitialX, scrollLastInitialY; /* 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 */ - 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 */ public static final int MSG_LEFT_MOUSE_BUTTON_CHECK = 1028; public static final int MSG_DROP_ITEM_BUTTON_CHECK = 1029; @@ -58,8 +80,8 @@ public class MinecraftGLView extends TextureView { float x = CallbackBridge.mouseX; float y = CallbackBridge.mouseY; if (CallbackBridge.isGrabbing() && - Math.abs(initialX - x) < fingerStillThreshold && - Math.abs(initialY - y) < fingerStillThreshold) { + Math.abs(initialX - x) < FINGER_STILL_THRESHOLD && + Math.abs(initialY - y) < FINGER_STILL_THRESHOLD) { triggeredLeftMouseButton = true; sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, true); } @@ -88,11 +110,63 @@ public class MinecraftGLView extends TextureView { setOpaque(false); setFocusable(true); - singleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH); - doubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN); + MCOptionUtils.addMCOptionListener(GUIScaleListener); } + 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 @@ -114,26 +188,77 @@ public class MinecraftGLView extends TextureView { //Getting scaled position from the event /* Tells if a double tap happened [MOUSE GRAB ONLY]. Doesn't tell where though. */ - boolean hasDoubleTapped = false; if(!CallbackBridge.isGrabbing()) { mouse_x = (e.getX() * scaleFactor); mouse_y = (e.getY() * scaleFactor); //One android click = one MC click 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; } - }else{ - hasDoubleTapped = doubleTapDetector.onTouchEvent(e); } + // Check double tap state, used for the hotbar + boolean hasDoubleTapped = doubleTapDetector.onTouchEvent(e); + 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 - //shouldBeDown = true; CallbackBridge.sendPrepareGrabInitialPos(); - - int hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY()); + hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY()); boolean isTouchInHotbar = hudKeyHandled != -1; if (isTouchInHotbar) { sendKeyPress(hudKeyHandled); @@ -169,25 +294,30 @@ public class MinecraftGLView extends TextureView { hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY()); isTouchInHotbar = hudKeyHandled != -1; + // We only treat in world events + if (!CallbackBridge.isGrabbing()) break; - if (CallbackBridge.isGrabbing()) { - if (!isTouchInHotbar && !triggeredLeftMouseButton && Math.abs(initialX - mouse_x) < fingerStillThreshold && Math.abs(initialY - mouse_y) < fingerStillThreshold) { - if (!LauncherPreferences.PREF_DISABLE_GESTURES) { - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, true); - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, false); - } - } - 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); - } + // Stop the dropping of items + if (isTouchInHotbar) { + sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_Q, 0, false); + theHandler.removeMessages(MSG_DROP_ITEM_BUTTON_CHECK); + break; } + // 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; case MotionEvent.ACTION_POINTER_DOWN: // 5 @@ -195,7 +325,7 @@ public class MinecraftGLView extends TextureView { scrollLastInitialY = e.getY(); //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)); - if(hudKeyHandled != -1){ + if(hudKeyHandled == -1){ sendKeyPress(hudKeyHandled); if(hasDoubleTapped && hudKeyHandled == lastHotbarKey){ //Prevent double tapping Event on two different slots @@ -206,60 +336,49 @@ public class MinecraftGLView extends TextureView { lastHotbarKey = hudKeyHandled; 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); 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; + } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java new file mode 100644 index 000000000..19e52c46a --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java @@ -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); + } + +} diff --git a/app_pojavlauncher/src/main/res/layout/main_with_customctrl.xml b/app_pojavlauncher/src/main/res/layout/main_with_customctrl.xml index a66d0bd91..87ac7e3ad 100644 --- a/app_pojavlauncher/src/main/res/layout/main_with_customctrl.xml +++ b/app_pojavlauncher/src/main/res/layout/main_with_customctrl.xml @@ -25,20 +25,13 @@ android:layout_width="fill_parent" android:layout_height="fill_parent"/> - + android:visibility="gone"/> - - -