diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/GLFWGLSurface.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/GLFWGLSurface.java index 2433356e2a..832110fb6a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/GLFWGLSurface.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/GLFWGLSurface.java @@ -220,30 +220,14 @@ public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) { public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {} }); - this.longPressDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { - - boolean isDragClicking = false; + longPressDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { @Override public void onLongPress(MotionEvent e) { super.onLongPress(e); - if(!isDragClicking) { - isDragClicking = true; - AWTInputBridge.sendKey((char) AWTInputEvent.VK_F5, AWTInputEvent.VK_F5); - } - } - - @Override - public boolean onSingleTapUp(MotionEvent e) { - if(isDragClicking) { - isDragClicking = false; - AWTInputBridge.sendKey((char)AWTInputEvent.VK_F5, AWTInputEvent.VK_F5); - } - return super.onSingleTapUp(e); + CallbackBridge.putMouseEventWithCoords(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, CallbackBridge.mouseX, CallbackBridge.mouseY); } }); - //this.longPressDetector.setIsLongpressEnabled(true); - ((ViewGroup)getParent()).addView(textureView); } } @@ -257,7 +241,7 @@ public boolean onSingleTapUp(MotionEvent e) { @SuppressWarnings("accessibility") public boolean onTouchEvent(MotionEvent e) { scaleGestureDetector.onTouchEvent(e); - //longPressDetector.onTouchEvent(e); + longPressDetector.onTouchEvent(e); // Kinda need to send this back to the layout if(((ControlLayout)getParent()).getModifiable()) return false; @@ -280,7 +264,6 @@ public boolean onTouchEvent(MotionEvent e) { CallbackBridge.mouseY = (e.getY() * mScaleFactor); //One android click = one MC click if(mSingleTapDetector.onTouchEvent(e)){ // - //longPressDetector.onTouchEvent(e);// Touch Mode CallbackBridge.putMouseEventWithCoords(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, CallbackBridge.mouseX, CallbackBridge.mouseY); return true; } @@ -429,6 +412,7 @@ public boolean onTouchEvent(MotionEvent e) { // Actualise the pointer count mLastPointerCount = e.getPointerCount(); + longPressDetector.onTouchEvent(e); return true; } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java index 00408dc406..1c781ff627 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java @@ -3,6 +3,8 @@ import static net.kdt.pojavlaunch.MainActivity.fullyExit; import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics; +import static java.security.AccessController.getContext; + import android.annotation.SuppressLint; import android.content.ClipboardManager; import android.graphics.Color; @@ -48,7 +50,10 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc private LinearLayout mTouchPad; private ImageView mMousePointerImageView; private GestureDetector mGestureDetector; + + private GestureDetector longPressDetector; private boolean cameraMode = false; + float prevX = 0, prevY = 0; private long lastPress = 0; private ScaleGestureDetector scaleGestureDetector; private boolean rcState = false; @@ -91,10 +96,11 @@ protected void onCreate(Bundle savedInstanceState) { ViewGroup.LayoutParams params = mMousePointerImageView.getLayoutParams(); params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE); params.height = (int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE); + if(LauncherPreferences.PREF_VIRTUAL_MOUSE_START) + toggleVirtualMouse(); }); mTouchPad.setOnTouchListener(new View.OnTouchListener() { - float prevX = 0, prevY = 0; @Override public boolean onTouch(View v, MotionEvent event) { // MotionEvent reports input details from the touch screen @@ -120,8 +126,8 @@ public boolean onTouch(View v, MotionEvent event) { } } else { if (action == MotionEvent.ACTION_MOVE) { // 2 - 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)); + mouseX = Math.max(0, Math.min(currentDisplayMetrics.widthPixels, mouseX + (x - prevX) * mouseSpeed)); + mouseY = Math.max(0, Math.min(currentDisplayMetrics.heightPixels, mouseY + (y - prevY) * mouseSpeed)); placeMouseAt(mouseX, mouseY); sendScaledMousePosition(mouseX, mouseY); } @@ -130,8 +136,6 @@ public boolean onTouch(View v, MotionEvent event) { 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!"); - //activateRC(); AWTInputBridge.sendKey((char)AWTInputEvent.VK_F11,AWTInputEvent.VK_F11); AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK); } @@ -146,6 +150,7 @@ public boolean onTouch(View v, MotionEvent event) { mTextureView.setOnTouchListener((v, event) -> { scaleGestureDetector.onTouchEvent(event); + longPressDetector.onTouchEvent(event); float x = event.getX(); float y = event.getY(); if (mGestureDetector.onTouchEvent(event)) { @@ -164,11 +169,34 @@ public boolean onTouch(View v, MotionEvent event) { break; case MotionEvent.ACTION_MOVE: // 2 sendScaledMousePosition(x + mTextureView.getX(), y); + try { + panCamera(prevX-x, prevY-y); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } break; } + + prevY = y; + prevX = x; return true; }); + longPressDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { + @Override + public void onLongPress(MotionEvent e) { + // Send RightClick + AWTInputBridge.sendKey((char)AWTInputEvent.VK_F11,AWTInputEvent.VK_F11); + AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK); + super.onLongPress(e); + } + + @Override + public boolean onSingleTapUp(MotionEvent e) { + return super.onSingleTapUp(e); + } + }); + try { placeMouseAt(CallbackBridge.physicalWidth / 2f, CallbackBridge.physicalHeight / 2f); @@ -203,14 +231,28 @@ public boolean onTouch(View v, MotionEvent event) { } catch (Throwable th) { Tools.showError(this, th, true); } + } + private void panCamera(float dx, float dy) throws InterruptedException { + //Log.i("downthecrop-pan","dx: " +dx + " dy: " + dy); + final float threshold = 8.0f; // adjust this value as needed to control the sensitivity of the panning - getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) { - @Override - public void handleOnBackPressed() { - MainActivity.dialogForceClose(JavaGUILauncherActivity.this); - } - }); + // Check horizontal panning + if(dx > threshold) { + // Finger moved to the right, pan camera to the right + AWTInputBridge.sendKey((char)AWTInputEvent.VK_RIGHT, AWTInputEvent.VK_RIGHT); + } else if(dx < -threshold) { + AWTInputBridge.sendKey((char)AWTInputEvent.VK_LEFT, AWTInputEvent.VK_LEFT); + } + + // Check vertical panning + if(dy > threshold) { + // Finger moved down, pan camera up + AWTInputBridge.sendKey((char)AWTInputEvent.VK_UP, AWTInputEvent.VK_UP); + } else if(dy < -threshold) { + // Finger moved up, pan camera down + AWTInputBridge.sendKey((char)AWTInputEvent.VK_DOWN, AWTInputEvent.VK_DOWN); + } } @Override @@ -261,7 +303,6 @@ public boolean onTouch(View v, MotionEvent e) { // these AWTInputEvent doesn't w break; case R.id.camera: if (!cameraMode) { // Camera Mode On - Log.i("downthecrop", "Hello from the camrea Button"); AWTInputBridge.sendKey((char) AWTInputEvent.VK_F9, AWTInputEvent.VK_F9); // Send F9 cameraMode = true; findViewById(R.id.camera).setBackground(getResources().getDrawable( R.drawable.control_button_pressed )); @@ -272,7 +313,7 @@ public boolean onTouch(View v, MotionEvent e) { // these AWTInputEvent doesn't w } break; case R.id.mouseMode: - toggleVirtualMouse(this.getCurrentFocus()); + toggleVirtualMouse(); } lastPress = time; } @@ -320,7 +361,7 @@ public void openLogOutput(View v) { mLoggerView.setVisibility(View.VISIBLE); } - public void toggleVirtualMouse(View v) { + public void toggleVirtualMouse() { mIsVirtualMouseEnabled = !mIsVirtualMouseEnabled; ImageView view = findViewById(R.id.mouseModeIco); if(!mIsVirtualMouseEnabled){ diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/keyboard/TouchCharInput.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/keyboard/TouchCharInput.java index 8011684c25..f9b14b3008 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/keyboard/TouchCharInput.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/keyboard/TouchCharInput.java @@ -23,6 +23,7 @@ */ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText { public static final String TEXT_FILLER = " "; + public static boolean softKeyboardIsActive = false; public TouchCharInput(@NonNull Context context) { this(context, null); } @@ -49,7 +50,7 @@ protected void onTextChanged(CharSequence text, int start, int lengthBefore, int Log.i("TouchCharInput","New Event (before/after)!: "+ lengthBefore + " : " + lengthAfter); boolean isBackSpace = (lengthBefore > lengthAfter); if(isBackSpace) { - KeyEncoder.sendEncodedChar(KeyEncoder.backspaceUnicode,KeyEncoder.backspaceUnicode); + KeyEncoder.sendUnicodeBackspace(); return; } char c = text.charAt(text.length()-1); @@ -115,6 +116,7 @@ public void clear(){ /** Regain ability to exist, take focus and have some text being input */ public void enable(){ + softKeyboardIsActive = true; setEnabled(true); setFocusable(true); setVisibility(VISIBLE); @@ -123,6 +125,7 @@ public void enable(){ /** Lose ability to exist, take focus and have some text being input */ public void disable(){ + softKeyboardIsActive = false; clear(); setVisibility(GONE); clearFocus(); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/KeyEncoder.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/KeyEncoder.java index 25884bf743..b5c7ca95a2 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/KeyEncoder.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/KeyEncoder.java @@ -1,112 +1,63 @@ package net.kdt.pojavlaunch.utils; import net.kdt.pojavlaunch.AWTInputBridge; +import net.kdt.pojavlaunch.customcontrols.keyboard.TouchCharInput; -/* - About Key Events. Because the Android Spec doesn't require - soft keyboards to dispatch key events not all keyboard implementations - across Android will trigger these actions. +import java.util.HashMap; +import java.util.Map; - Currently we use the following function to translate keycodes for - special character, capital letters, and digits. +public class KeyEncoder { - keycode 123 (F12) is used as a single digit capslock button which - when sent to the miniclient before a char will act accordingly. - */ + private static final Map specialCharMap = createSpecialCharMap(); + private static final char MODIFIER = 123; // F12 key as a modifier for caps lock + private static final char BACKSPACE_ANDROID = 67; + private static final char BACKSPACE_UNICODE = 8; -public class KeyEncoder { + // Initialize the mapping of special characters to their respective keys + private static Map createSpecialCharMap() { + Map map = new HashMap<>(); + map.put('!', '1'); + map.put('@', '2'); + map.put('#', '3'); + map.put('$', '4'); + map.put('%', '5'); + map.put('^', '6'); + map.put('&', '7'); + map.put('*', '8'); + map.put('(', '9'); + map.put(')', '0'); + map.put('_', '-'); + map.put('+', '='); + map.put('{', '['); + map.put('}', ']'); + map.put(':', ';'); + map.put('"', '\''); + map.put('<', ','); + map.put('>', '.'); + map.put('?', '/'); + map.put('|', '\\'); + return map; + } - static String specialChars = "/*!@#$%^&*()\"{}_[+:;=-_]'|\\?/<>,."; - static char modifier = 123; - static char backspaceAndroid = 67; - public static char backspaceUnicode = 8; + public static void sendUnicodeBackspace(){ + AWTInputBridge.sendKey(BACKSPACE_UNICODE, BACKSPACE_UNICODE); + } - public static void sendEncodedChar(int keyCode, char iC){ - System.out.println(keyCode); - if(keyCode == 75) - AWTInputBridge.sendKey((char)222,222); - else if(keyCode == backspaceAndroid){ - AWTInputBridge.sendKey(backspaceUnicode,backspaceUnicode); - } else if(specialChars.contains(""+iC)){ - // Send special character to client - char c = iC; - switch(c){ - case '!': - c = '1'; - break; - case '@': - c = '2'; - break; - case '#': - c = '3'; - break; - case '$': - c = '4'; - break; - case '%': - c = '5'; - break; - case '^': - c = '6'; - break; - case '&': - c = '7'; - break; - case '*': - c = '8'; - break; - case '(': - c = '9'; - break; - case ')': - c = '0'; - break; - case '_': - c = '-'; - break; - case '+': - c = '='; - break; - case '{': - c = '['; - break; - case '}': - c = ']'; - break; - case ':': - c = ';'; - break; - case '"': - c = '\''; - break; - case '<': - c = ','; - break; - case '>': - c = '.'; - break; - case '?': - c = '/'; - break; - case '|': - c = '\\'; - break; - } - if(c != iC){ - AWTInputBridge.sendKey(modifier,modifier); - } - AWTInputBridge.sendKey(c,c); - } else if(Character.isDigit(iC)){ - AWTInputBridge.sendKey(iC,iC); - } else if (iC == Character.toUpperCase(iC)){ - // We send F12 as a modifier to avoid needing to worry about shift. - // Client takes this modifier and does a toUpperCase(). - AWTInputBridge.sendKey(modifier,modifier); - AWTInputBridge.sendKey(Character.toUpperCase(iC),Character.toUpperCase(iC)); - } else if(iC == Character.toLowerCase(iC)){ - AWTInputBridge.sendKey(Character.toUpperCase(iC),Character.toUpperCase(iC)); + public static void sendEncodedChar(int keyCode, char c) { + if (keyCode == BACKSPACE_ANDROID && !TouchCharInput.softKeyboardIsActive) { + sendUnicodeBackspace(); + } else if (specialCharMap.containsKey(c)) { + AWTInputBridge.sendKey(MODIFIER, MODIFIER); + AWTInputBridge.sendKey(specialCharMap.get(c), specialCharMap.get(c)); + } else if (Character.isDigit(c)) { + AWTInputBridge.sendKey(c, c); + } else if (Character.isLowerCase(c)){ + AWTInputBridge.sendKey(Character.toUpperCase(c),Character.toUpperCase(c)); + } else if (Character.isUpperCase(c)) { + AWTInputBridge.sendKey(MODIFIER, MODIFIER); + AWTInputBridge.sendKey(c, c); } else { - AWTInputBridge.sendKey(iC,keyCode); + AWTInputBridge.sendKey(c, keyCode); } } -} \ No newline at end of file +}