Skip to content

Commit 88286a5

Browse files
authored
Merge pull request AngelAuraMC#279 from TouchController/v3_openjdk
Adds configurable panning animation when keyboard opens
2 parents ed3bb0d + 8e3583f commit 88286a5

11 files changed

Lines changed: 229 additions & 69 deletions

File tree

app_pojavlauncher/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
android:configChanges="keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|keyboard|navigation|uiMode"
111111
android:launchMode="singleTop"
112112
android:process=":game"
113+
android:windowSoftInputMode="adjustResize"
113114
android:screenOrientation="sensorLandscape" />
114115

115116
<provider

app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import android.content.ServiceConnection;
2323
import android.content.res.Configuration;
2424
import android.graphics.Color;
25+
import android.graphics.RectF;
2526
import android.graphics.drawable.ColorDrawable;
2627
import android.net.Uri;
2728
import android.os.Build;
@@ -32,15 +33,22 @@
3233
import android.view.KeyEvent;
3334
import android.view.MotionEvent;
3435
import android.view.View;
36+
import android.view.WindowManager;
3537
import android.widget.AdapterView;
3638
import android.widget.ArrayAdapter;
39+
import android.widget.FrameLayout;
3740
import android.widget.ListView;
3841
import android.widget.Toast;
3942

4043
import androidx.annotation.Keep;
4144
import androidx.annotation.NonNull;
45+
import androidx.annotation.Nullable;
4246
import androidx.annotation.RequiresApi;
4347
import androidx.core.content.ContextCompat;
48+
import androidx.core.view.ViewCompat;
49+
import androidx.core.view.WindowCompat;
50+
import androidx.core.view.WindowInsetsAnimationCompat;
51+
import androidx.core.view.WindowInsetsCompat;
4452
import androidx.drawerlayout.widget.DrawerLayout;
4553

4654
import com.kdt.LoggerView;
@@ -75,9 +83,10 @@
7583

7684
import java.io.File;
7785
import java.io.IOException;
86+
import java.util.List;
7887
import java.util.Objects;
7988

80-
public class MainActivity extends BaseActivity implements ControlButtonMenuListener, EditorExitable, ServiceConnection {
89+
public class MainActivity extends BaseActivity implements ControlButtonMenuListener, EditorExitable, ServiceConnection, TouchControllerInputView.InputAreaRectListener {
8190
public static volatile ClipboardManager GLOBAL_CLIPBOARD;
8291
public static final String TAG = "MainActivity";
8392
public static final String INTENT_MINECRAFT_VERSION = "intent_version";
@@ -96,6 +105,12 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
96105
private GyroControl mGyroControl = null;
97106
private ControlLayout mControlLayout;
98107
private HotbarView mHotbarView;
108+
private FrameLayout contentFrame;
109+
110+
@Nullable
111+
private RectF inputAreaRect;
112+
private int imeHeight;
113+
private boolean hasOngoingImeAnimation;
99114

100115
MinecraftProfile minecraftProfile;
101116

@@ -110,6 +125,8 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
110125
@Override
111126
public void onCreate(Bundle savedInstanceState) {
112127
super.onCreate(savedInstanceState);
128+
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
129+
113130
if (LauncherPreferences.PREF_GAMEPAD_SDL_PASSTHRU) {
114131
// TODO: Use lower level HID capture that needs a dialogue box from the user for the
115132
// app to fully take focus of the input devices. Might cause issues with older android
@@ -185,6 +202,39 @@ public void onCreate(Bundle savedInstanceState) {
185202
MCOptionUtils.addMCOptionListener(optionListener);
186203
mControlLayout.setModifiable(false);
187204

205+
// Listen to IME insets animation
206+
ViewCompat.setWindowInsetsAnimationCallback(contentFrame, new WindowInsetsAnimationCompat.Callback(WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP) {
207+
@Override
208+
public void onPrepare(@NonNull WindowInsetsAnimationCompat animation) {
209+
if ((animation.getTypeMask() & WindowInsetsCompat.Type.ime()) != 0) {
210+
hasOngoingImeAnimation = true;
211+
}
212+
}
213+
214+
@NonNull
215+
@Override
216+
public WindowInsetsCompat onProgress(@NonNull WindowInsetsCompat insets, @NonNull List<WindowInsetsAnimationCompat> runningAnimations) {
217+
imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
218+
refreshImeTranslation();
219+
return insets;
220+
}
221+
222+
@Override
223+
public void onEnd(@NonNull WindowInsetsAnimationCompat animation) {
224+
if ((animation.getTypeMask() & WindowInsetsCompat.Type.ime()) != 0) {
225+
hasOngoingImeAnimation = false;
226+
}
227+
}
228+
});
229+
ViewCompat.setOnApplyWindowInsetsListener(contentFrame, (v, insets) -> {
230+
// Only refresh translation if IME change insets itself, not the animation
231+
if (!hasOngoingImeAnimation) {
232+
imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
233+
refreshImeTranslation();
234+
}
235+
return insets;
236+
});
237+
188238
// Set the activity for the executor. Must do this here, or else Tools.showErrorRemote() may not
189239
// execute the correct method
190240
ContextExecutor.setActivity(this);
@@ -209,7 +259,7 @@ protected void initLayout(int resId) {
209259
GLOBAL_CLIPBOARD = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
210260
touchCharInput.setCharacterSender(new LwjglCharSender());
211261

212-
touchControllerInputView.setSize(minecraftGLView.getWidth(), minecraftGLView.getHeight());
262+
touchControllerInputView.setInputAreaRectListener(this);
213263

214264
if(minecraftProfile.pojavRendererName != null) {
215265
Log.i("RdrDebug","__P_renderer="+minecraftProfile.pojavRendererName);
@@ -260,6 +310,9 @@ protected void initLayout(int resId) {
260310
touchpad.post(() -> touchpad.switchState());
261311
}
262312

313+
// At this time, correct size is known
314+
touchControllerInputView.setSize(minecraftGLView.getWidth(), minecraftGLView.getHeight());
315+
263316
runCraft(finalVersion, mVersionInfo);
264317
}catch (Throwable e){
265318
Tools.showErrorRemote(e);
@@ -314,6 +367,7 @@ private void bindValues(){
314367
touchControllerInputView = findViewById(R.id.touch_controller_input);
315368
mDrawerPullButton = findViewById(R.id.drawer_button);
316369
mHotbarView = findViewById(R.id.hotbar_view);
370+
contentFrame = findViewById(R.id.content_frame);
317371
}
318372

319373
@Override
@@ -701,4 +755,33 @@ public void onTrimMemory(int level) {
701755
public void onBackPressed() {
702756
super.onBackPressed();
703757
}
758+
759+
@Override
760+
public void updateInputAreaRect(@Nullable RectF rect) {
761+
inputAreaRect = rect;
762+
refreshImeTranslation();
763+
}
764+
765+
private void refreshImeTranslation() {
766+
if (imeHeight == 0) {
767+
// Early exit
768+
contentFrame.setTranslationY(0);
769+
return;
770+
}
771+
772+
int inputAreaBottom;
773+
if (inputAreaRect != null) {
774+
inputAreaBottom = (int) inputAreaRect.bottom;
775+
} else if (LauncherPreferences.PREF_KEYBOARD_PANNING) {
776+
inputAreaBottom = contentFrame.getHeight();
777+
} else {
778+
contentFrame.setTranslationY(0);
779+
return;
780+
}
781+
782+
int bottomDistance = contentFrame.getHeight() - inputAreaBottom;
783+
int bottomPadding = Math.max(imeHeight - bottomDistance, 0);
784+
785+
contentFrame.setTranslationY(-bottomPadding);
786+
}
704787
}

app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/Touchpad.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,11 @@ public boolean getDisplayState() {
123123

124124
@Override
125125
public void applyMotionVector(float x, float y) {
126-
mMouseX = Math.max(0, Math.min(currentDisplayMetrics.widthPixels, mMouseX + x * LauncherPreferences.PREF_MOUSESPEED));
127-
mMouseY = Math.max(0, Math.min(currentDisplayMetrics.heightPixels, mMouseY + y * LauncherPreferences.PREF_MOUSESPEED));
128-
updateMousePosition();
126+
if (mDisplayState) { // Make sure no motion leaks through when disabling a moving cursor
127+
mMouseX = Math.max(0, Math.min(currentDisplayMetrics.widthPixels, mMouseX + x * LauncherPreferences.PREF_MOUSESPEED));
128+
mMouseY = Math.max(0, Math.min(currentDisplayMetrics.heightPixels, mMouseY + y * LauncherPreferences.PREF_MOUSESPEED));
129+
updateMousePosition();
130+
}
129131
}
130132

131133
@Override

app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public class LauncherPreferences {
7575
public static int PREF_TOUCHCONTROLLER_VIBRATE_LENGTH = 100;
7676

7777
public static boolean PREF_MOUSE_GRAB_FORCE = false;
78+
public static boolean PREF_KEYBOARD_PANNING = true;
7879

7980

8081
public static void loadPreferences(Context ctx) {
@@ -121,6 +122,7 @@ public static void loadPreferences(Context ctx) {
121122
PREF_FORCE_ENABLE_TOUCHCONTROLLER = DEFAULT_PREF.getBoolean("forceEnableTouchController", false);
122123
PREF_TOUCHCONTROLLER_VIBRATE_LENGTH = DEFAULT_PREF.getInt("touchControllerVibrateLength", 100);
123124
PREF_MOUSE_GRAB_FORCE = DEFAULT_PREF.getBoolean("always_grab_mouse", false);
125+
PREF_KEYBOARD_PANNING = DEFAULT_PREF.getBoolean("keyboardPanning", true);
124126

125127
String argLwjglLibname = "-Dorg.lwjgl.opengl.libname=";
126128
for (String arg : JREUtils.parseJavaArguments(PREF_CUSTOM_JAVA_ARGS)) {

app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/QuickSettingSideDialog.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GYRO_INVERT_X;
66
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GYRO_INVERT_Y;
77
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GYRO_SENSITIVITY;
8+
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_KEYBOARD_PANNING;
89
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_LONGPRESS_TRIGGER;
910
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_MOUSESPEED;
1011
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_MOUSE_GRAB_FORCE;
@@ -32,11 +33,11 @@ public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView {
3233

3334
private SharedPreferences.Editor mEditor;
3435
@SuppressLint("UseSwitchCompatOrMaterialCode")
35-
private Switch mGyroSwitch, mGyroXSwitch, mGyroYSwitch, mGestureSwitch, mMouseGrabSwitch;
36+
private Switch mGyroSwitch, mGyroXSwitch, mGyroYSwitch, mGestureSwitch, mMouseGrabSwitch, mKeyboardPanningSwitch;
3637
private CustomSeekbar mGyroSensitivityBar, mMouseSpeedBar, mGestureDelayBar, mResolutionBar;
3738
private TextView mGyroSensitivityText, mGyroSensitivityDisplayText, mMouseSpeedText, mGestureDelayText, mGestureDelayDisplayText, mResolutionText;
3839

39-
private boolean mOriginalGyroEnabled, mOriginalGyroXEnabled, mOriginalGyroYEnabled, mOriginalGestureDisabled, mOriginalMouseGrab;
40+
private boolean mOriginalGyroEnabled, mOriginalGyroXEnabled, mOriginalGyroYEnabled, mOriginalGestureDisabled, mOriginalMouseGrab, mOriginalKeyboardPanning;
4041
private float mOriginalGyroSensitivity, mOriginalMouseSpeed, mOriginalResolution;
4142
private int mOriginalGestureDelay;
4243

@@ -67,6 +68,7 @@ private void bindLayout() {
6768
mGyroYSwitch = mDialogContent.findViewById(R.id.checkboxGyroY);
6869
mGestureSwitch = mDialogContent.findViewById(R.id.checkboxGesture);
6970
mMouseGrabSwitch = mDialogContent.findViewById(R.id.always_grab_mouse_side_dialog);
71+
mKeyboardPanningSwitch = mDialogContent.findViewById(R.id.checkboxKeyboardPanning);
7072

7173
mGyroSensitivityBar = mDialogContent.findViewById(R.id.editGyro_seekbar);
7274
mMouseSpeedBar = mDialogContent.findViewById(R.id.editMouseSpeed_seekbar);
@@ -89,6 +91,7 @@ private void setupListeners() {
8991
mOriginalGyroYEnabled = PREF_GYRO_INVERT_Y;
9092
mOriginalGestureDisabled = PREF_DISABLE_GESTURES;
9193
mOriginalMouseGrab = PREF_MOUSE_GRAB_FORCE;
94+
mOriginalKeyboardPanning = PREF_KEYBOARD_PANNING;
9295

9396
mOriginalGyroSensitivity = PREF_GYRO_SENSITIVITY;
9497
mOriginalMouseSpeed = PREF_MOUSESPEED;
@@ -100,6 +103,7 @@ private void setupListeners() {
100103
mGyroYSwitch.setChecked(mOriginalGyroYEnabled);
101104
mGestureSwitch.setChecked(mOriginalGestureDisabled);
102105
mMouseGrabSwitch.setChecked(mOriginalMouseGrab);
106+
mKeyboardPanningSwitch.setChecked(mOriginalKeyboardPanning);
103107

104108
mGyroSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
105109
PREF_ENABLE_GYRO = isChecked;
@@ -131,6 +135,11 @@ private void setupListeners() {
131135
mEditor.putBoolean("always_grab_mouse", isChecked);
132136
});
133137

138+
mKeyboardPanningSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
139+
PREF_KEYBOARD_PANNING = isChecked;
140+
mEditor.putBoolean("keyboardPanning", isChecked);
141+
});
142+
134143
mGyroSensitivityBar.setOnSeekBarChangeListener((SimpleSeekBarListener) (seekBar, progress, fromUser) -> {
135144
PREF_GYRO_SENSITIVITY = progress / 100f;
136145
mEditor.putInt("gyroSensitivity", progress);
@@ -217,6 +226,7 @@ private void removeListeners() {
217226
mGyroYSwitch.setOnCheckedChangeListener(null);
218227
mGestureSwitch.setOnCheckedChangeListener(null);
219228
mMouseGrabSwitch.setOnCheckedChangeListener(null);
229+
mKeyboardPanningSwitch.setOnCheckedChangeListener(null);
220230

221231
mGyroSensitivityBar.setOnSeekBarChangeListener(null);
222232
mMouseSpeedBar.setOnSeekBarChangeListener(null);
@@ -241,6 +251,7 @@ public void cancel() {
241251
PREF_GYRO_INVERT_Y = mOriginalGyroYEnabled;
242252
PREF_DISABLE_GESTURES = mOriginalGestureDisabled;
243253
PREF_MOUSE_GRAB_FORCE = mOriginalMouseGrab;
254+
PREF_KEYBOARD_PANNING = mOriginalKeyboardPanning;
244255

245256
PREF_GYRO_SENSITIVITY = mOriginalGyroSensitivity;
246257
PREF_MOUSESPEED = mOriginalMouseSpeed;

0 commit comments

Comments
 (0)