From 67a3cc5dc02dfa8609d5eb284f063fde786c56aa Mon Sep 17 00:00:00 2001 From: DreamOneX Date: Wed, 2 Aug 2023 14:26:08 +0800 Subject: [PATCH 001/105] feat(control): allow subbuttons of free orientation drawer change size --- .../pojavlaunch/customcontrols/buttons/ControlDrawer.java | 2 +- .../customcontrols/buttons/ControlSubButton.java | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlDrawer.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlDrawer.java index ccacc8323..a43738f24 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlDrawer.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlDrawer.java @@ -88,7 +88,7 @@ public class ControlDrawer extends ControlButton { private void resizeButtons(){ - if (buttons == null) return; + if (buttons == null || drawerData.orientation == ControlDrawerData.Orientation.FREE) return; for(ControlSubButton subButton : buttons){ subButton.mProperties.setWidth(mProperties.getWidth()); subButton.mProperties.setHeight(mProperties.getHeight()); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlSubButton.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlSubButton.java index cd24b8dc9..998b4cdf3 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlSubButton.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlSubButton.java @@ -21,8 +21,10 @@ public class ControlSubButton extends ControlButton { } private void filterProperties(){ - mProperties.setHeight(parentDrawer.getProperties().getHeight()); - mProperties.setWidth(parentDrawer.getProperties().getWidth()); + if (parentDrawer != null && parentDrawer.drawerData.orientation != ControlDrawerData.Orientation.FREE) { + mProperties.setHeight(parentDrawer.getProperties().getHeight()); + mProperties.setWidth(parentDrawer.getProperties().getWidth()); + } mProperties.isDynamicBtn = false; setProperties(mProperties, false); @@ -35,7 +37,7 @@ public class ControlSubButton extends ControlButton { @Override public void setLayoutParams(ViewGroup.LayoutParams params) { - if(parentDrawer != null){ + if(parentDrawer != null && parentDrawer.drawerData.orientation != ControlDrawerData.Orientation.FREE){ params.width = (int)parentDrawer.mProperties.getWidth(); params.height = (int)parentDrawer.mProperties.getHeight(); } From 9f7a580019c8b3d055177042878809b2e8254612 Mon Sep 17 00:00:00 2001 From: DreamOneX Date: Wed, 2 Aug 2023 21:13:49 +0800 Subject: [PATCH 002/105] chore(control): bumb up the version number of control schema --- .../net/kdt/pojavlaunch/customcontrols/CustomControls.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java index 0dc96a006..e089be988 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java @@ -52,13 +52,13 @@ public class CustomControls { this.mControlDataList.add(new ControlData(ctx, R.string.control_jump, new int[]{LwjglGlfwKeycode.GLFW_KEY_SPACE}, "${right} - ${margin} * 2 - ${width}", "${bottom} - ${margin} * 2 - ${height}", true)); //The default controls are conform to the V2 - version = 4; + version = 5; } public void save(String path) throws IOException { - //Current version is the V2.5 so the version as to be marked as 4 ! - version = 4; + //Current version is the V2.6 so the version as to be marked as 5 ! + version = 5; Tools.write(path, Tools.GLOBAL_GSON.toJson(this)); } From 62796497479d6de4cb32fae022b63732c7d6f2af Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Thu, 3 Aug 2023 13:18:24 +0700 Subject: [PATCH 003/105] Fix[glfw]: add missing function for 23w31a --- .../src/main/java/org/lwjgl/glfw/GLFW.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java index ac89bf795..2b101ede9 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java @@ -371,6 +371,15 @@ public class GLFW GLFW_COCOA_CHDIR_RESOURCES = 0x51001, GLFW_COCOA_MENUBAR = 0x51002; + /** Hint value for {@link #GLFW_PLATFORM PLATFORM} that enables automatic platform selection. */ + public static final int + GLFW_ANY_PLATFORM = 0x60000, + GLFW_PLATFORM_WIN32 = 0x60001, + GLFW_PLATFORM_COCOA = 0x60002, + GLFW_PLATFORM_WAYLAND = 0x60003, + GLFW_PLATFORM_X11 = 0x60004, + GLFW_PLATFORM_NULL = 0x60005; + /** Don't care value. */ public static final int GLFW_DONT_CARE = -1; @@ -822,6 +831,10 @@ public class GLFW public static void glfwInitHint(int hint, int value) { } + public static int glfwGetPlatform() { + return GLFW_PLATFORM_X11; + } + @NativeType("GLFWwindow *") public static long glfwGetCurrentContext() { long __functionAddress = Functions.GetCurrentContext; From 8a70c6f4f521adeb6e32b1994169f558b7f24bcb Mon Sep 17 00:00:00 2001 From: DreamOneX Date: Thu, 3 Aug 2023 18:10:29 +0800 Subject: [PATCH 004/105] fix(control): not allowed to open the control file of version 5 --- .../net/kdt/pojavlaunch/customcontrols/LayoutConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java index d8e20a907..f5dd33f9b 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java @@ -28,7 +28,7 @@ public class LayoutConverter { CustomControls layout = LayoutConverter.convertV2Layout(layoutJobj); layout.save(jsonPath); return layout; - }else if (layoutJobj.getInt("version") == 3 || layoutJobj.getInt("version") == 4) { + }else if (layoutJobj.getInt("version") >= 3 && layoutJobj.getInt("version") <= 5) { return Tools.GLOBAL_GSON.fromJson(jsonLayoutData, CustomControls.class); }else{ return null; From aed6c00c40564970f3c2c74d4611c257c218c9fd Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Mon, 15 May 2023 11:31:07 +0200 Subject: [PATCH 005/105] Feat[controls]: Input joystick --- app_pojavlauncher/build.gradle | 1 + .../pojavlaunch/CustomControlsActivity.java | 10 +- .../customcontrols/ControlLayout.java | 18 ++ .../customcontrols/CustomControls.java | 8 +- .../buttons/ControlJoystick.java | 180 ++++++++++++++++++ .../handleview/EditControlPopup.java | 2 +- .../src/main/res/values/headings_array.xml | 9 +- .../src/main/res/values/strings.xml | 1 + 8 files changed, 216 insertions(+), 13 deletions(-) create mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java diff --git a/app_pojavlauncher/build.gradle b/app_pojavlauncher/build.gradle index ab5b93bb8..457511fbd 100644 --- a/app_pojavlauncher/build.gradle +++ b/app_pojavlauncher/build.gradle @@ -187,6 +187,7 @@ dependencies { implementation 'com.github.PojavLauncherTeam:portrait-ssp:6c02fd739b' implementation 'com.github.Mathias-Boulay:ExtendedView:1.0.0' implementation 'com.github.Mathias-Boulay:android_gamepad_remapper:eb92e3a5bb' + implementation 'com.github.Mathias-Boulay:virtual-joystick-android:3832b4f94a' // implementation 'com.intuit.sdp:sdp-android:1.0.5' diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java index b8f3e5a4e..690199e5b 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java @@ -43,11 +43,11 @@ public class CustomControlsActivity extends BaseActivity implements EditorExitab switch(position) { case 0: mControlLayout.addControlButton(new ControlData("New")); break; case 1: mControlLayout.addDrawer(new ControlDrawerData()); break; - //case 2: mControlLayout.addJoystickButton(new ControlData()); break; - case 2: mControlLayout.openLoadDialog(); break; - case 3: mControlLayout.openSaveDialog(this); break; - case 4: mControlLayout.openSetDefaultDialog(); break; - case 5: // Saving the currently shown control + case 2: mControlLayout.addJoystickButton(new ControlData()); break; + case 3: mControlLayout.openLoadDialog(); break; + case 4: mControlLayout.openSaveDialog(this); break; + case 5: mControlLayout.openSetDefaultDialog(); break; + case 6: // Saving the currently shown control try { Uri contentUri = DocumentsContract.buildDocumentUri(getString(R.string.storageProviderAuthorities), mControlLayout.saveToDirectory(mControlLayout.mLayoutFileName)); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java index 9c5000894..3f4dd7f7b 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java @@ -1,6 +1,7 @@ package net.kdt.pojavlaunch.customcontrols; import static android.content.Context.INPUT_METHOD_SERVICE; +import static net.kdt.pojavlaunch.MainActivity.mControlLayout; import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics; import android.annotation.SuppressLint; @@ -27,6 +28,7 @@ import net.kdt.pojavlaunch.Tools; import net.kdt.pojavlaunch.customcontrols.buttons.ControlButton; import net.kdt.pojavlaunch.customcontrols.buttons.ControlDrawer; import net.kdt.pojavlaunch.customcontrols.buttons.ControlInterface; +import net.kdt.pojavlaunch.customcontrols.buttons.ControlJoystick; import net.kdt.pojavlaunch.customcontrols.buttons.ControlSubButton; import net.kdt.pojavlaunch.customcontrols.handleview.ActionRow; import net.kdt.pojavlaunch.customcontrols.handleview.ControlHandleView; @@ -107,6 +109,12 @@ public class ControlLayout extends FrameLayout { if(mModifiable) drawer.areButtonsVisible = true; } + // Joystick(s) + for(ControlData joystick : mLayout.mJoystickDataList){ + addJoystickView(joystick); + } + + mLayout.scaledAt = LauncherPreferences.PREF_BUTTONSIZE; setModified(false); @@ -186,6 +194,16 @@ public class ControlLayout extends FrameLayout { setModified(true); } + // JOYSTICK BUTTON + public void addJoystickButton(ControlData data){ + mLayout.mJoystickDataList.add(data); + addJoystickView(data); + } + + private void addJoystickView(ControlData data){ + addView(new ControlJoystick(this, data)); + } + private void removeAllButtons() { for(ControlInterface button : getButtonChildren()){ diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java index e089be988..a27c6c85a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java @@ -13,16 +13,18 @@ public class CustomControls { public float scaledAt; public List mControlDataList; public List mDrawerDataList; + public List mJoystickDataList; public CustomControls() { - this(new ArrayList<>(), new ArrayList<>()); + this(new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); } - public CustomControls(List mControlDataList, List mDrawerDataList) { + public CustomControls(List mControlDataList, List mDrawerDataList, List mJoystickDataList) { this.mControlDataList = mControlDataList; this.mDrawerDataList = mDrawerDataList; - this.scaledAt = 100f; + this.mJoystickDataList = mJoystickDataList; + this.scaledAt = 100f; } // Generate default control diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java new file mode 100644 index 000000000..825988025 --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java @@ -0,0 +1,180 @@ +package net.kdt.pojavlaunch.customcontrols.buttons; + +import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_EAST; +import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_NONE; +import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_NORTH; +import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_NORTH_EAST; +import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_NORTH_WEST; +import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_SOUTH; +import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_SOUTH_EAST; +import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_SOUTH_WEST; +import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_WEST; + +import android.annotation.SuppressLint; +import android.view.View; + +import net.kdt.pojavlaunch.LwjglGlfwKeycode; +import net.kdt.pojavlaunch.Tools; +import net.kdt.pojavlaunch.customcontrols.ControlData; +import net.kdt.pojavlaunch.customcontrols.ControlLayout; +import net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick; +import net.kdt.pojavlaunch.customcontrols.handleview.EditControlPopup; + +import org.lwjgl.glfw.CallbackBridge; + +import io.github.controlwear.virtual.joystick.android.JoystickView; + +@SuppressLint("ViewConstructor") +public class ControlJoystick extends JoystickView implements ControlInterface{ + public ControlJoystick(ControlLayout parent, ControlData data) { + super(parent.getContext()); + init(data, parent); + } + + + public final static int DIRECTION_FORWARD_LOCK = 8; + + private ControlData mControlData; + private int mLastDirectionInt = GamepadJoystick.DIRECTION_NONE; + private int mCurrentDirectionInt = GamepadJoystick.DIRECTION_NONE; + + // Directions keycode + private final int[] mDirectionForwardLock = new int[]{LwjglGlfwKeycode.GLFW_KEY_W, LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL}; + private final int[] mDirectionForward = new int[]{LwjglGlfwKeycode.GLFW_KEY_W}; + private final int[] mDirectionRight = new int[]{LwjglGlfwKeycode.GLFW_KEY_D}; + private final int[] mDirectionBackward = new int[]{LwjglGlfwKeycode.GLFW_KEY_S}; + private final int[] mDirectionLeft = new int[]{LwjglGlfwKeycode.GLFW_KEY_A}; + + private void init(ControlData data, ControlLayout layout){ + mControlData = data; + setProperties(preProcessProperties(data, layout)); + setDeadzone(40); + setFixedCenter(false); + setAutoReCenterButton(true); + //postDelayed(() -> setForwardLockDistance((int) (data.getHeight()* 0.66f)), 500); + setForwardLockDistance((int) Tools.dpToPx(30)); + layout.setClipChildren(false); + + + injectTouchEventBehavior(); + injectLayoutParamBehavior(); + + setOnMoveListener(new OnMoveListener() { + @Override + public void onMove(int angle, int strength) { + mLastDirectionInt = mCurrentDirectionInt; + mCurrentDirectionInt = getDirectionInt(angle, strength); + + if(mLastDirectionInt != mCurrentDirectionInt){ + sendDirectionalKeycode(mLastDirectionInt, false); + sendDirectionalKeycode(mCurrentDirectionInt, true); + } + } + + @Override + public void onForwardLock(boolean isLocked) { + mLastDirectionInt = mCurrentDirectionInt; + mCurrentDirectionInt = DIRECTION_FORWARD_LOCK; + + if(mLastDirectionInt != mCurrentDirectionInt){ + sendDirectionalKeycode(mLastDirectionInt, false); + sendDirectionalKeycode(mCurrentDirectionInt, true); + } + } + }); + } + + @Override + public View getControlView() {return this;} + + @Override + public ControlData getProperties() { + return mControlData; + } + + @Override + public void setProperties(ControlData properties, boolean changePos) { + mControlData = properties; + ControlInterface.super.setProperties(properties, changePos); + } + + @Override + public void removeButton() { + getControlLayoutParent().getLayout().mJoystickDataList.remove(getProperties()); + getControlLayoutParent().removeView(this); + } + + @Override + public void cloneButton() { + ControlData data = new ControlData(getProperties()); + getControlLayoutParent().addJoystickButton(data); + } + + @Override + public void setVisible(boolean isVisible) { + setVisibility(isVisible ? VISIBLE : GONE); + } + + @Override + public void setBackground() { + setBorderWidth(computeStrokeWidth(getProperties().strokeWidth)); + setBorderColor(getProperties().strokeColor); + setBackgroundColor(getProperties().bgColor); + } + + @Override + public void sendKeyPresses(boolean isDown) {/*STUB since non swipeable*/ } + + @Override + public void loadEditValues(EditControlPopup editControlPopup) { + editControlPopup.loadJoystickValues(mControlData); + } + + private int getDirectionInt(int angle, int intensity){ + if(intensity == 0) return DIRECTION_NONE; + return (int) (((angle+22.5)/45) % 8); + } + + private void sendDirectionalKeycode(int direction, boolean isDown){ + switch (direction){ + case DIRECTION_NORTH: + sendInput(mDirectionForward, isDown); + break; + case DIRECTION_NORTH_EAST: + sendInput(mDirectionForward, isDown); + sendInput(mDirectionRight, isDown); + break; + case DIRECTION_EAST: + sendInput(mDirectionRight, isDown); + break; + case DIRECTION_SOUTH_EAST: + sendInput(mDirectionRight, isDown); + sendInput(mDirectionBackward, isDown); + break; + case DIRECTION_SOUTH: + sendInput(mDirectionBackward, isDown); + break; + case DIRECTION_SOUTH_WEST: + sendInput(mDirectionBackward, isDown); + sendInput(mDirectionLeft, isDown); + break; + case DIRECTION_WEST: + sendInput(mDirectionLeft, isDown); + break; + case DIRECTION_NORTH_WEST: + sendInput(mDirectionForward, isDown); + sendInput(mDirectionLeft, isDown); + break; + case DIRECTION_FORWARD_LOCK: + sendInput(mDirectionForwardLock, isDown); + break; + } + } + + private static void sendInput(int[] keys, boolean isDown){ + for(int key : keys){ + CallbackBridge.sendKeyPress(key, CallbackBridge.getCurrentMods(), isDown); + } + } + +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java index 738e915c8..d2ef00e7a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java @@ -300,7 +300,7 @@ public class EditControlPopup { } /** Load values for the joystick */ - @SuppressWarnings("unused") public void loadJoystickValues(ControlData data){ + public void loadJoystickValues(ControlData data){ loadValues(data); mMappingTextView.setVisibility(GONE); diff --git a/app_pojavlauncher/src/main/res/values/headings_array.xml b/app_pojavlauncher/src/main/res/values/headings_array.xml index fb5d4c695..dd7e914c0 100644 --- a/app_pojavlauncher/src/main/res/values/headings_array.xml +++ b/app_pojavlauncher/src/main/res/values/headings_array.xml @@ -19,10 +19,11 @@ @string/customctrl_addbutton @string/customctrl_addbutton_drawer - @string/global_load - @string/global_save - @string/customctrl_selectdefault - @string/customctrl_export + @string/customctrl_addbutton_joystick + @string/global_load + @string/global_save + @string/customctrl_selectdefault + @string/customctrl_export diff --git a/app_pojavlauncher/src/main/res/values/strings.xml b/app_pojavlauncher/src/main/res/values/strings.xml index 9f571caf3..35b546bd9 100644 --- a/app_pojavlauncher/src/main/res/values/strings.xml +++ b/app_pojavlauncher/src/main/res/values/strings.xml @@ -205,6 +205,7 @@ Shift Add button Add button drawer + Add joystick Add sub-button Sub-button n°%d has been added ! From 58a29ee2caa48e0339a8a85052ff3d405a88601a Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Mon, 15 May 2023 20:38:59 +0200 Subject: [PATCH 006/105] Feat[controls]: Add conditional visibility --- .../customcontrols/ControlData.java | 13 +++++-- .../customcontrols/ControlLayout.java | 6 +++ .../buttons/ControlInterface.java | 37 ++++++++++++++++++- .../handleview/EditControlPopup.java | 17 +++++++++ .../layout/dialog_control_button_setting.xml | 29 +++++++++++++-- 5 files changed, 94 insertions(+), 8 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java index 4d50ba983..e132b8a12 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java @@ -100,6 +100,9 @@ public class ControlData { public float cornerRadius; //0-100% public boolean isSwipeable; + public boolean displayInGame; + public boolean displayInMenu; + public ControlData() { this("button"); } @@ -142,10 +145,10 @@ public class ControlData { } public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle){ - this(name, keycodes, dynamicX, dynamicY, width, height, isToggle, 1,0x4D000000, 0xFFFFFFFF,0,0); + this(name, keycodes, dynamicX, dynamicY, width, height, isToggle, 1,0x4D000000, 0xFFFFFFFF,0,0, true, true); } - public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle, float opacity, int bgColor, int strokeColor, int strokeWidth, float cornerRadius) { + public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle, float opacity, int bgColor, int strokeColor, int strokeWidth, float cornerRadius, boolean displayInGame, boolean displayInMenu) { this.name = name; this.keycodes = inflateKeycodeArray(keycodes); this.dynamicX = dynamicX; @@ -159,6 +162,8 @@ public class ControlData { this.strokeColor = strokeColor; this.strokeWidth = strokeWidth; this.cornerRadius = cornerRadius; + this.displayInGame = displayInGame; + this.displayInMenu = displayInMenu; } //Deep copy constructor @@ -175,7 +180,9 @@ public class ControlData { controlData.bgColor, controlData.strokeColor, controlData.strokeWidth, - controlData.cornerRadius + controlData.cornerRadius, + controlData.displayInGame, + controlData.displayInMenu ); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java index 3f4dd7f7b..98a5d3638 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java @@ -247,6 +247,12 @@ public class ControlLayout extends FrameLayout { removeEditWindow(); } mModifiable = isModifiable; + if(isModifiable){ + // In edit mode, all controls have to be shown + for(ControlInterface button : getButtonChildren()){ + button.setVisible(true); + } + } } public boolean getModifiable(){ diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlInterface.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlInterface.java index 3f3e6fae9..274880f92 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlInterface.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlInterface.java @@ -4,14 +4,17 @@ import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_BUTTONSIZE; import android.annotation.SuppressLint; import android.graphics.drawable.GradientDrawable; +import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import androidx.annotation.CallSuper; +import androidx.annotation.NonNull; import androidx.core.math.MathUtils; +import net.kdt.pojavlaunch.GrabListener; import net.kdt.pojavlaunch.Tools; import net.kdt.pojavlaunch.customcontrols.ControlData; import net.kdt.pojavlaunch.customcontrols.ControlLayout; @@ -24,7 +27,7 @@ import org.lwjgl.glfw.CallbackBridge; * Most of the injected behavior is editing behavior, * sending keys has to be implemented by sub classes. */ -public interface ControlInterface extends View.OnLongClickListener { +public interface ControlInterface extends View.OnLongClickListener, GrabListener { View getControlView(); ControlData getProperties(); @@ -45,8 +48,13 @@ public interface ControlInterface extends View.OnLongClickListener { /** Load the values and hide non useful forms */ void loadEditValues(EditControlPopup editControlPopup); + @Override + default void onGrabState(boolean isGrabbing) { + if(getControlLayoutParent() != null && getControlLayoutParent().getModifiable()) return; // Disable when edited + setVisible((getProperties().displayInGame && isGrabbing) || (getProperties().displayInMenu && !isGrabbing)); + } - default ControlLayout getControlLayoutParent(){ + default ControlLayout getControlLayoutParent() { return (ControlLayout) getControlView().getParent(); } @@ -269,6 +277,31 @@ public interface ControlInterface extends View.OnLongClickListener { injectProperties(); injectTouchEventBehavior(); injectLayoutParamBehavior(); + injectGrabListenerBehavior(); + } + + /** Inject the grab listener, remove it when the view is gone */ + default void injectGrabListenerBehavior(){ + if(getControlView() == null){ + Log.e(ControlInterface.class.toString(), "Failed to inject grab listener behavior !"); + return; + } + + + getControlView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { + @Override + public void onViewAttachedToWindow(@NonNull View v) { + CallbackBridge.addGrabListener(ControlInterface.this); + } + + @Override + public void onViewDetachedFromWindow(@NonNull View v) { + getControlView().removeOnAttachStateChangeListener(this); + CallbackBridge.removeGrabListener(ControlInterface.this); + } + }); + + } default void injectProperties(){ diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java index d2ef00e7a..365023351 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java @@ -19,6 +19,8 @@ import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Interpolator; import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.EditText; import android.widget.SeekBar; import android.widget.Spinner; @@ -84,6 +86,7 @@ public class EditControlPopup { protected TextView mSelectBackgroundColor, mSelectStrokeColor; protected ArrayAdapter mAdapter; protected List mSpecialArray; + protected CheckBox mDisplayInGameCheckbox, mDisplayInMenuCheckbox; // Decorative textviews private TextView mOrientationTextView, mMappingTextView, mNameTextView, mCornerRadiusTextView; @@ -269,6 +272,9 @@ public class EditControlPopup { mPassthroughSwitch.setChecked(data.passThruEnabled); mSwipeableSwitch.setChecked(data.isSwipeable); + mDisplayInGameCheckbox.setChecked(data.displayInGame); + mDisplayInMenuCheckbox.setChecked(data.displayInMenu); + for(int i = 0; i< data.keycodes.length; i++){ if (data.keycodes[i] < 0) { mKeycodeSpinners[i].setSelection(data.keycodes[i] + mSpecialArray.size()); @@ -343,6 +349,8 @@ public class EditControlPopup { mStrokePercentTextView = mScrollView.findViewById(R.id.editStrokeWidth_textView_percent); mAlphaPercentTextView = mScrollView.findViewById(R.id.editButtonOpacity_textView_percent); mCornerRadiusPercentTextView = mScrollView.findViewById(R.id.editCornerRadius_textView_percent); + mDisplayInGameCheckbox = mScrollView.findViewById(R.id.visibility_game_checkbox); + mDisplayInMenuCheckbox = mScrollView.findViewById(R.id.visibility_menu_checkbox); //Decorative stuff mMappingTextView = mScrollView.findViewById(R.id.editMapping_textView); @@ -504,6 +512,15 @@ public class EditControlPopup { public void onNothingSelected(AdapterView parent) {} }); + mDisplayInGameCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> { + if(internalChanges) return; + mCurrentlyEditedButton.getProperties().displayInGame = isChecked; + }); + + mDisplayInMenuCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> { + if(internalChanges) return; + mCurrentlyEditedButton.getProperties().displayInMenu = isChecked; + }); mSelectStrokeColor.setOnClickListener(v -> { mColorSelector.setAlphaEnabled(false); diff --git a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml index 11d0b862a..daf40f55f 100644 --- a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml +++ b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml @@ -220,7 +220,7 @@ @@ -390,6 +388,31 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="@id/editButtonOpacity_textView" /> + + + + + + + From 9829dc436bec60490b95af575f1bda95b50f0d81 Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Mon, 15 May 2023 22:26:23 +0200 Subject: [PATCH 007/105] Workaround[controls]: disable view clipping in game This is only for the joystick, no other view should be affected --- app_pojavlauncher/build.gradle | 4 ++-- .../net/kdt/pojavlaunch/customcontrols/ControlLayout.java | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app_pojavlauncher/build.gradle b/app_pojavlauncher/build.gradle index 457511fbd..87fe87723 100644 --- a/app_pojavlauncher/build.gradle +++ b/app_pojavlauncher/build.gradle @@ -186,8 +186,8 @@ dependencies { implementation 'com.github.PojavLauncherTeam:portrait-sdp:ed33e89cbc' implementation 'com.github.PojavLauncherTeam:portrait-ssp:6c02fd739b' implementation 'com.github.Mathias-Boulay:ExtendedView:1.0.0' - implementation 'com.github.Mathias-Boulay:android_gamepad_remapper:eb92e3a5bb' - implementation 'com.github.Mathias-Boulay:virtual-joystick-android:3832b4f94a' + implementation 'com.github.Mathias-Boulay:android_gamepad_remapper:9c4e285ce8' + implementation 'com.github.Mathias-Boulay:virtual-joystick-android:4fee901b58' // implementation 'com.intuit.sdp:sdp-android:1.0.5' diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java index 98a5d3638..c000bfc7f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java @@ -60,10 +60,12 @@ public class ControlLayout extends FrameLayout { public ControlLayout(Context ctx) { super(ctx); + setClipChildren(false); } public ControlLayout(Context ctx, AttributeSet attrs) { super(ctx, attrs); + setClipChildren(false); } @@ -243,6 +245,9 @@ public class ControlLayout extends FrameLayout { } public void setModifiable(boolean isModifiable) { + // Hack to allow joystick free placement and resize while seeing the forward lock + setClipChildren(isModifiable); + if(!isModifiable && mModifiable){ removeEditWindow(); } From 7b02277186145b0048118b3c143b6dd4f3c72d30 Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Mon, 15 May 2023 22:27:22 +0200 Subject: [PATCH 008/105] Tweak[controls]: Less deadzone, use new injections --- .../customcontrols/buttons/ControlJoystick.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java index 825988025..32458bb97 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java @@ -25,7 +25,7 @@ import org.lwjgl.glfw.CallbackBridge; import io.github.controlwear.virtual.joystick.android.JoystickView; @SuppressLint("ViewConstructor") -public class ControlJoystick extends JoystickView implements ControlInterface{ +public class ControlJoystick extends JoystickView implements ControlInterface { public ControlJoystick(ControlLayout parent, ControlData data) { super(parent.getContext()); init(data, parent); @@ -48,16 +48,12 @@ public class ControlJoystick extends JoystickView implements ControlInterface{ private void init(ControlData data, ControlLayout layout){ mControlData = data; setProperties(preProcessProperties(data, layout)); - setDeadzone(40); + setDeadzone(35); setFixedCenter(false); setAutoReCenterButton(true); - //postDelayed(() -> setForwardLockDistance((int) (data.getHeight()* 0.66f)), 500); - setForwardLockDistance((int) Tools.dpToPx(30)); - layout.setClipChildren(false); + postDelayed(() -> setForwardLockDistance((int) Tools.dpToPx(35)), 10); - - injectTouchEventBehavior(); - injectLayoutParamBehavior(); + injectBehaviors(); setOnMoveListener(new OnMoveListener() { @Override From f0e9f842ad931f895032776d84c9e5dcf19b8d13 Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Mon, 15 May 2023 22:46:30 +0200 Subject: [PATCH 009/105] Fix[controls]: joystick sprint on lock --- .../customcontrols/buttons/ControlJoystick.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java index 32458bb97..4b11df406 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java @@ -39,7 +39,7 @@ public class ControlJoystick extends JoystickView implements ControlInterface { private int mCurrentDirectionInt = GamepadJoystick.DIRECTION_NONE; // Directions keycode - private final int[] mDirectionForwardLock = new int[]{LwjglGlfwKeycode.GLFW_KEY_W, LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL}; + private final int[] mDirectionForwardLock = new int[]{LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL}; private final int[] mDirectionForward = new int[]{LwjglGlfwKeycode.GLFW_KEY_W}; private final int[] mDirectionRight = new int[]{LwjglGlfwKeycode.GLFW_KEY_D}; private final int[] mDirectionBackward = new int[]{LwjglGlfwKeycode.GLFW_KEY_S}; @@ -69,13 +69,7 @@ public class ControlJoystick extends JoystickView implements ControlInterface { @Override public void onForwardLock(boolean isLocked) { - mLastDirectionInt = mCurrentDirectionInt; - mCurrentDirectionInt = DIRECTION_FORWARD_LOCK; - - if(mLastDirectionInt != mCurrentDirectionInt){ - sendDirectionalKeycode(mLastDirectionInt, false); - sendDirectionalKeycode(mCurrentDirectionInt, true); - } + sendInput(mDirectionForwardLock, isLocked); } }); } From 3e9c4b1d59cf0d285d88dd0b6a33bd1cb4f26ab4 Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Mon, 15 May 2023 23:30:31 +0200 Subject: [PATCH 010/105] Fix[control]: Hide size/visibility editor on subButtons --- .../buttons/ControlSubButton.java | 6 +++++ .../handleview/EditControlPopup.java | 22 ++++++++++++++++++- .../layout/dialog_control_button_setting.xml | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlSubButton.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlSubButton.java index 998b4cdf3..b1e9ae040 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlSubButton.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlSubButton.java @@ -8,6 +8,7 @@ import android.view.ViewGroup; import net.kdt.pojavlaunch.customcontrols.ControlData; import net.kdt.pojavlaunch.customcontrols.ControlDrawerData; import net.kdt.pojavlaunch.customcontrols.ControlLayout; +import net.kdt.pojavlaunch.customcontrols.handleview.EditControlPopup; @SuppressLint("ViewConstructor") public class ControlSubButton extends ControlButton { @@ -83,4 +84,9 @@ public class ControlSubButton extends ControlButton { super.snapAndAlign(x, y); // Else the button is forced into place } + + @Override + public void loadEditValues(EditControlPopup editControlPopup) { + editControlPopup.loadSubButtonValues(getProperties()); + } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java index 365023351..b61bf40bb 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java @@ -89,7 +89,8 @@ public class EditControlPopup { protected CheckBox mDisplayInGameCheckbox, mDisplayInMenuCheckbox; // Decorative textviews - private TextView mOrientationTextView, mMappingTextView, mNameTextView, mCornerRadiusTextView; + private TextView mOrientationTextView, mMappingTextView, mNameTextView, + mCornerRadiusTextView, mVisibilityTextView, mSizeTextview, mSizeXTextView; @@ -327,6 +328,22 @@ public class EditControlPopup { mToggleSwitch.setVisibility(View.GONE); } + /** Load values for sub buttons */ + public void loadSubButtonValues(ControlData data){ + loadValues(data); + + // Size linked to the parent drawer + mSizeTextview.setVisibility(GONE); + mSizeXTextView.setVisibility(GONE); + mWidthEditText.setVisibility(GONE); + mHeightEditText.setVisibility(GONE); + + // No conditional, already depends on the parent drawer visibility + mVisibilityTextView.setVisibility(GONE); + mDisplayInMenuCheckbox.setVisibility(GONE); + mDisplayInGameCheckbox.setVisibility(GONE); + } + private void bindLayout(){ mRootView = mScrollView.findViewById(R.id.edit_layout); @@ -357,6 +374,9 @@ public class EditControlPopup { mOrientationTextView = mScrollView.findViewById(R.id.editOrientation_textView); mNameTextView = mScrollView.findViewById(R.id.editName_textView); mCornerRadiusTextView = mScrollView.findViewById(R.id.editCornerRadius_textView); + mVisibilityTextView = mScrollView.findViewById(R.id.visibility_textview); + mSizeTextview = mScrollView.findViewById(R.id.editSize_textView); + mSizeXTextView = mScrollView.findViewById(R.id.editSize_x_textView); } /** diff --git a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml index daf40f55f..6e04d9160 100644 --- a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml +++ b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml @@ -81,6 +81,7 @@ app:layout_constraintTop_toTopOf="@+id/editSize_editTextX" /> Date: Tue, 16 May 2023 00:38:07 +0200 Subject: [PATCH 011/105] Style[controls]: better spacing --- .../drawable/background_control_editor.xml | 11 ++++++ .../layout/dialog_control_button_setting.xml | 35 +++++++++---------- 2 files changed, 27 insertions(+), 19 deletions(-) create mode 100644 app_pojavlauncher/src/main/res/drawable/background_control_editor.xml diff --git a/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml b/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml new file mode 100644 index 000000000..f661cb029 --- /dev/null +++ b/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml index 6e04d9160..1bbb7dabc 100644 --- a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml +++ b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml @@ -1,13 +1,11 @@ - + android:background="@drawable/background_control_editor"> - + app:layout_constraintTop_toBottomOf="@+id/visibility_textview" /> + app:layout_constraintTop_toBottomOf="@+id/visibility_game_checkbox" /> From fd5f46f2439636ad933c65a37e93148cd5c6ebf4 Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Tue, 16 May 2023 12:19:22 +0200 Subject: [PATCH 012/105] Syle[control]: use consistent mapping dropdown --- .../handleview/EditControlPopup.java | 274 ++++++++++-------- .../drawable/background_control_editor.xml | 8 +- .../layout/dialog_control_button_setting.xml | 163 +++++++---- 3 files changed, 274 insertions(+), 171 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java index b61bf40bb..222bdafa5 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java @@ -20,7 +20,6 @@ import android.view.animation.Interpolator; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.CheckBox; -import android.widget.CompoundButton; import android.widget.EditText; import android.widget.SeekBar; import android.widget.Spinner; @@ -45,56 +44,54 @@ import java.util.List; * Class providing a sort of popup on top of a Layout, allowing to edit a given ControlButton */ public class EditControlPopup { + protected final Spinner[] mKeycodeSpinners = new Spinner[4]; private final DefocusableScrollView mScrollView; - private ConstraintLayout mRootView; private final ColorSelector mColorSelector; private final ObjectAnimator mEditPopupAnimator; private final ObjectAnimator mColorEditorAnimator; - private boolean mDisplaying = false; - private boolean mDisplayingColor = false; - public boolean internalChanges = false; // True when we programmatically change stuff. - private ControlInterface mCurrentlyEditedButton; private final int mMargin; + public boolean internalChanges = false; // True when we programmatically change stuff. private final View.OnLayoutChangeListener mLayoutChangedListener = new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { - if(internalChanges) return; + if (internalChanges) return; internalChanges = true; - int width = (int)(safeParseFloat(mWidthEditText.getText().toString())); + int width = (int) (safeParseFloat(mWidthEditText.getText().toString())); - if(width >= 0 && Math.abs(right - width) > 1){ + if (width >= 0 && Math.abs(right - width) > 1) { mWidthEditText.setText(String.valueOf(right - left)); } - int height = (int)(safeParseFloat(mHeightEditText.getText().toString())); - if(height >= 0 && Math.abs(bottom - height) > 1){ + int height = (int) (safeParseFloat(mHeightEditText.getText().toString())); + if (height >= 0 && Math.abs(bottom - height) > 1) { mHeightEditText.setText(String.valueOf(bottom - top)); } internalChanges = false; } }; - protected EditText mNameEditText, mWidthEditText, mHeightEditText; @SuppressLint("UseSwitchCompatOrMaterialCode") protected Switch mToggleSwitch, mPassthroughSwitch, mSwipeableSwitch; protected Spinner mOrientationSpinner; - protected final Spinner[] mKeycodeSpinners = new Spinner[4]; + protected TextView[] mKeycodeTextviews = new TextView[4]; protected SeekBar mStrokeWidthSeekbar, mCornerRadiusSeekbar, mAlphaSeekbar; protected TextView mStrokePercentTextView, mCornerRadiusPercentTextView, mAlphaPercentTextView; protected TextView mSelectBackgroundColor, mSelectStrokeColor; protected ArrayAdapter mAdapter; protected List mSpecialArray; protected CheckBox mDisplayInGameCheckbox, mDisplayInMenuCheckbox; - + private ConstraintLayout mRootView; + private boolean mDisplaying = false; + private boolean mDisplayingColor = false; + private ControlInterface mCurrentlyEditedButton; // Decorative textviews private TextView mOrientationTextView, mMappingTextView, mNameTextView, mCornerRadiusTextView, mVisibilityTextView, mSizeTextview, mSizeXTextView; - - public EditControlPopup(Context context, ViewGroup parent){ + public EditControlPopup(Context context, ViewGroup parent) { mScrollView = (DefocusableScrollView) LayoutInflater.from(context).inflate(R.layout.dialog_control_button_setting, parent, false); parent.addView(mScrollView); @@ -121,18 +118,23 @@ public class EditControlPopup { setupRealTimeListeners(); } + public static void setPercentageText(TextView textView, int progress) { + textView.setText(textView.getContext().getString(R.string.percent_format, progress)); + } - /** Slide the layout into the visible screen area */ - public void appear(boolean fromRight){ + /** + * Slide the layout into the visible screen area + */ + public void appear(boolean fromRight) { disappearColor(); // When someone jumps from a button to another - if(fromRight){ - if(!mDisplaying || !isAtRight()){ + if (fromRight) { + if (!mDisplaying || !isAtRight()) { mEditPopupAnimator.setFloatValues(currentDisplayMetrics.widthPixels, currentDisplayMetrics.widthPixels - mScrollView.getWidth() - mMargin); mEditPopupAnimator.start(); } - }else{ - if (!mDisplaying || isAtRight()){ + } else { + if (!mDisplaying || isAtRight()) { mEditPopupAnimator.setFloatValues(-mScrollView.getWidth(), mMargin); mEditPopupAnimator.start(); } @@ -141,12 +143,14 @@ public class EditControlPopup { mDisplaying = true; } - /** Slide out the layout */ - public void disappear(){ - if(!mDisplaying) return; + /** + * Slide out the layout + */ + public void disappear() { + if (!mDisplaying) return; mDisplaying = false; - if(isAtRight()) + if (isAtRight()) mEditPopupAnimator.setFloatValues(currentDisplayMetrics.widthPixels - mScrollView.getWidth() - mMargin, currentDisplayMetrics.widthPixels); else mEditPopupAnimator.setFloatValues(mMargin, -mScrollView.getWidth()); @@ -154,15 +158,17 @@ public class EditControlPopup { mEditPopupAnimator.start(); } - /** Slide the layout into the visible screen area */ - public void appearColor(boolean fromRight, int color){ - if(fromRight){ - if(!mDisplayingColor || !isAtRight()){ + /** + * Slide the layout into the visible screen area + */ + public void appearColor(boolean fromRight, int color) { + if (fromRight) { + if (!mDisplayingColor || !isAtRight()) { mColorEditorAnimator.setFloatValues(currentDisplayMetrics.widthPixels, currentDisplayMetrics.widthPixels - mScrollView.getWidth() - mMargin); mColorEditorAnimator.start(); } - }else{ - if (!mDisplayingColor || isAtRight()){ + } else { + if (!mDisplayingColor || isAtRight()) { mColorEditorAnimator.setFloatValues(-mScrollView.getWidth(), mMargin); mColorEditorAnimator.start(); } @@ -172,12 +178,14 @@ public class EditControlPopup { mColorSelector.show(color == -1 ? Color.WHITE : color); } - /** Slide out the layout */ - public void disappearColor(){ - if(!mDisplayingColor) return; + /** + * Slide out the layout + */ + public void disappearColor() { + if (!mDisplayingColor) return; mDisplayingColor = false; - if(isAtRight()) + if (isAtRight()) mColorEditorAnimator.setFloatValues(currentDisplayMetrics.widthPixels - mScrollView.getWidth() - mMargin, currentDisplayMetrics.widthPixels); else mColorEditorAnimator.setFloatValues(mMargin, -mScrollView.getWidth()); @@ -185,33 +193,37 @@ public class EditControlPopup { mColorEditorAnimator.start(); } - /** Slide out the first visible layer. - * @return True if the last layer is disappearing */ - public boolean disappearLayer(){ - if(mDisplayingColor){ + /** + * Slide out the first visible layer. + * + * @return True if the last layer is disappearing + */ + public boolean disappearLayer() { + if (mDisplayingColor) { disappearColor(); return false; - }else{ + } else { disappear(); return true; } } - /** Switch the panels position if needed */ - public void adaptPanelPosition(){ - if(mDisplaying){ - boolean isAtRight = mCurrentlyEditedButton.getControlView().getX() + mCurrentlyEditedButton.getControlView().getWidth()/2f < currentDisplayMetrics.widthPixels/2f; + /** + * Switch the panels position if needed + */ + public void adaptPanelPosition() { + if (mDisplaying) { + boolean isAtRight = mCurrentlyEditedButton.getControlView().getX() + mCurrentlyEditedButton.getControlView().getWidth() / 2f < currentDisplayMetrics.widthPixels / 2f; appear(isAtRight); } } - - public void destroy(){ + public void destroy() { ((ViewGroup) mScrollView.getParent()).removeView(mColorSelector.getRootView()); ((ViewGroup) mScrollView.getParent()).removeView(mScrollView); } - private void loadAdapter(){ + private void loadAdapter() { //Initialize adapter for keycodes mAdapter = new ArrayAdapter<>(mRootView.getContext(), R.layout.item_centered_textview); mSpecialArray = ControlData.buildSpecialButtonArray(); @@ -232,27 +244,22 @@ public class EditControlPopup { mOrientationSpinner.setAdapter(adapter); } - - - private void setDefaultVisibilitySetting(){ - for(int i=0; i currentDisplayMetrics.widthPixels/2f; - } - - - public static void setPercentageText(TextView textView, int progress){ - textView.setText(textView.getContext().getString(R.string.percent_format, progress)); + private boolean isAtRight() { + return mScrollView.getX() > currentDisplayMetrics.widthPixels / 2f; } /* LOADING VALUES */ - /** Load values for basic control data */ - public void loadValues(ControlData data){ + /** + * Load values for basic control data + */ + public void loadValues(ControlData data) { setDefaultVisibilitySetting(); mOrientationTextView.setVisibility(GONE); mOrientationSpinner.setVisibility(GONE); @@ -261,11 +268,11 @@ public class EditControlPopup { mWidthEditText.setText(String.valueOf(data.getWidth())); mHeightEditText.setText(String.valueOf(data.getHeight())); - mAlphaSeekbar.setProgress((int) (data.opacity*100)); + mAlphaSeekbar.setProgress((int) (data.opacity * 100)); mStrokeWidthSeekbar.setProgress(data.strokeWidth); mCornerRadiusSeekbar.setProgress((int) data.cornerRadius); - setPercentageText(mAlphaPercentTextView, (int) (data.opacity*100)); + setPercentageText(mAlphaPercentTextView, (int) (data.opacity * 100)); setPercentageText(mStrokePercentTextView, data.strokeWidth); setPercentageText(mCornerRadiusPercentTextView, (int) data.cornerRadius); @@ -276,7 +283,7 @@ public class EditControlPopup { mDisplayInGameCheckbox.setChecked(data.displayInGame); mDisplayInMenuCheckbox.setChecked(data.displayInMenu); - for(int i = 0; i< data.keycodes.length; i++){ + for (int i = 0; i < data.keycodes.length; i++) { if (data.keycodes[i] < 0) { mKeycodeSpinners[i].setSelection(data.keycodes[i] + mSpecialArray.size()); } else { @@ -285,18 +292,20 @@ public class EditControlPopup { } } - /** Load values for extended control data */ - public void loadValues(ControlDrawerData data){ + /** + * Load values for extended control data + */ + public void loadValues(ControlDrawerData data) { loadValues(data.properties); mOrientationSpinner.setSelection( ControlDrawerData.orientationToInt(data.orientation)); mMappingTextView.setVisibility(GONE); - mKeycodeSpinners[0].setVisibility(GONE); - mKeycodeSpinners[1].setVisibility(GONE); - mKeycodeSpinners[2].setVisibility(GONE); - mKeycodeSpinners[3].setVisibility(GONE); + for (int i = 0; i < mKeycodeSpinners.length; i++) { + mKeycodeSpinners[i].setVisibility(GONE); + mKeycodeTextviews[i].setVisibility(GONE); + } mOrientationTextView.setVisibility(VISIBLE); mOrientationSpinner.setVisibility(VISIBLE); @@ -306,15 +315,17 @@ public class EditControlPopup { mToggleSwitch.setVisibility(View.GONE); } - /** Load values for the joystick */ - public void loadJoystickValues(ControlData data){ + /** + * Load values for the joystick + */ + public void loadJoystickValues(ControlData data) { loadValues(data); mMappingTextView.setVisibility(GONE); - mKeycodeSpinners[0].setVisibility(GONE); - mKeycodeSpinners[1].setVisibility(GONE); - mKeycodeSpinners[2].setVisibility(GONE); - mKeycodeSpinners[3].setVisibility(GONE); + for (int i = 0; i < mKeycodeSpinners.length; i++) { + mKeycodeSpinners[i].setVisibility(GONE); + mKeycodeTextviews[i].setVisibility(GONE); + } mNameTextView.setVisibility(GONE); mNameEditText.setVisibility(GONE); @@ -328,8 +339,10 @@ public class EditControlPopup { mToggleSwitch.setVisibility(View.GONE); } - /** Load values for sub buttons */ - public void loadSubButtonValues(ControlData data){ + /** + * Load values for sub buttons + */ + public void loadSubButtonValues(ControlData data) { loadValues(data); // Size linked to the parent drawer @@ -345,7 +358,7 @@ public class EditControlPopup { } - private void bindLayout(){ + private void bindLayout() { mRootView = mScrollView.findViewById(R.id.edit_layout); mNameEditText = mScrollView.findViewById(R.id.editName_editText); mWidthEditText = mScrollView.findViewById(R.id.editSize_editTextX); @@ -357,6 +370,10 @@ public class EditControlPopup { mKeycodeSpinners[1] = mScrollView.findViewById(R.id.editMapping_spinner_2); mKeycodeSpinners[2] = mScrollView.findViewById(R.id.editMapping_spinner_3); mKeycodeSpinners[3] = mScrollView.findViewById(R.id.editMapping_spinner_4); + mKeycodeTextviews[0] = mScrollView.findViewById(R.id.mapping_1_textview); + mKeycodeTextviews[1] = mScrollView.findViewById(R.id.mapping_2_textview); + mKeycodeTextviews[2] = mScrollView.findViewById(R.id.mapping_3_textview); + mKeycodeTextviews[3] = mScrollView.findViewById(R.id.mapping_4_textview); mOrientationSpinner = mScrollView.findViewById(R.id.editOrientation_spinner); mStrokeWidthSeekbar = mScrollView.findViewById(R.id.editStrokeWidth_seekbar); mCornerRadiusSeekbar = mScrollView.findViewById(R.id.editCornerRadius_seekbar); @@ -383,16 +400,19 @@ public class EditControlPopup { * A long function linking all the displayed data on the popup and, * the currently edited mCurrentlyEditedButton */ - public void setupRealTimeListeners(){ + public void setupRealTimeListeners() { mNameEditText.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} + public void onTextChanged(CharSequence s, int start, int before, int count) { + } @Override public void afterTextChanged(Editable s) { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().name = s.toString(); @@ -403,16 +423,19 @@ public class EditControlPopup { mWidthEditText.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} + public void onTextChanged(CharSequence s, int start, int before, int count) { + } @Override public void afterTextChanged(Editable s) { - if(internalChanges) return; + if (internalChanges) return; float width = safeParseFloat(s.toString()); - if(width >= 0){ + if (width >= 0) { mCurrentlyEditedButton.getProperties().setWidth(width); mCurrentlyEditedButton.updateProperties(); } @@ -421,16 +444,19 @@ public class EditControlPopup { mHeightEditText.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} + public void onTextChanged(CharSequence s, int start, int before, int count) { + } @Override public void afterTextChanged(Editable s) { - if(internalChanges) return; + if (internalChanges) return; float height = safeParseFloat(s.toString()); - if(height >= 0){ + if (height >= 0) { mCurrentlyEditedButton.getProperties().setHeight(height); mCurrentlyEditedButton.updateProperties(); } @@ -438,66 +464,77 @@ public class EditControlPopup { }); mSwipeableSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().isSwipeable = isChecked; }); mToggleSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().isToggle = isChecked; }); mPassthroughSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().passThruEnabled = isChecked; }); mAlphaSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if(internalChanges) return; - mCurrentlyEditedButton.getProperties().opacity = mAlphaSeekbar.getProgress()/100f; - mCurrentlyEditedButton.getControlView().setAlpha(mAlphaSeekbar.getProgress()/100f); + if (internalChanges) return; + mCurrentlyEditedButton.getProperties().opacity = mAlphaSeekbar.getProgress() / 100f; + mCurrentlyEditedButton.getControlView().setAlpha(mAlphaSeekbar.getProgress() / 100f); setPercentageText(mAlphaPercentTextView, progress); } @Override - public void onStartTrackingTouch(SeekBar seekBar) {} + public void onStartTrackingTouch(SeekBar seekBar) { + } + @Override - public void onStopTrackingTouch(SeekBar seekBar) {} + public void onStopTrackingTouch(SeekBar seekBar) { + } }); mStrokeWidthSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().strokeWidth = mStrokeWidthSeekbar.getProgress(); mCurrentlyEditedButton.setBackground(); setPercentageText(mStrokePercentTextView, progress); } @Override - public void onStartTrackingTouch(SeekBar seekBar) {} + public void onStartTrackingTouch(SeekBar seekBar) { + } + @Override - public void onStopTrackingTouch(SeekBar seekBar) {} + public void onStopTrackingTouch(SeekBar seekBar) { + } }); mCornerRadiusSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().cornerRadius = mCornerRadiusSeekbar.getProgress(); mCurrentlyEditedButton.setBackground(); setPercentageText(mCornerRadiusPercentTextView, progress); } @Override - public void onStartTrackingTouch(SeekBar seekBar) {} + public void onStartTrackingTouch(SeekBar seekBar) { + } + @Override - public void onStopTrackingTouch(SeekBar seekBar) {} + public void onStopTrackingTouch(SeekBar seekBar) { + } }); - for(int i = 0; i< mKeycodeSpinners.length; ++i){ + for (int i = 0; i < mKeycodeSpinners.length; ++i) { int finalI = i; + mKeycodeTextviews[i].setOnClickListener(v -> mKeycodeSpinners[finalI].performClick()); + mKeycodeSpinners[i].setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { @@ -508,10 +545,12 @@ public class EditControlPopup { } else { mCurrentlyEditedButton.getProperties().keycodes[finalI] = EfficientAndroidLWJGLKeycode.getValueByIndex(mKeycodeSpinners[finalI].getSelectedItemPosition() - mSpecialArray.size()); } + mKeycodeTextviews[finalI].setText((String) mKeycodeSpinners[finalI].getSelectedItem()); } @Override - public void onNothingSelected(AdapterView parent) {} + public void onNothingSelected(AdapterView parent) { + } }); } @@ -522,23 +561,24 @@ public class EditControlPopup { // Side note, spinner listeners are fired later than all the other ones. // Meaning the internalChanges bool is useless here. - if(mCurrentlyEditedButton instanceof ControlDrawer){ - ((ControlDrawer)mCurrentlyEditedButton).drawerData.orientation = ControlDrawerData.intToOrientation(mOrientationSpinner.getSelectedItemPosition()); - ((ControlDrawer)mCurrentlyEditedButton).syncButtons(); + if (mCurrentlyEditedButton instanceof ControlDrawer) { + ((ControlDrawer) mCurrentlyEditedButton).drawerData.orientation = ControlDrawerData.intToOrientation(mOrientationSpinner.getSelectedItemPosition()); + ((ControlDrawer) mCurrentlyEditedButton).syncButtons(); } } @Override - public void onNothingSelected(AdapterView parent) {} + public void onNothingSelected(AdapterView parent) { + } }); mDisplayInGameCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().displayInGame = isChecked; }); mDisplayInMenuCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> { - if(internalChanges) return; + if (internalChanges) return; mCurrentlyEditedButton.getProperties().displayInMenu = isChecked; }); @@ -561,18 +601,18 @@ public class EditControlPopup { }); } - private float safeParseFloat(String string){ + private float safeParseFloat(String string) { float out = -1; // -1 try { out = Float.parseFloat(string); - }catch (NumberFormatException e){ + } catch (NumberFormatException e) { Log.e("EditControlPopup", e.toString()); } return out; } - public void setCurrentlyEditedButton(ControlInterface button){ - if(mCurrentlyEditedButton != null) + public void setCurrentlyEditedButton(ControlInterface button) { + if (mCurrentlyEditedButton != null) mCurrentlyEditedButton.getControlView().removeOnLayoutChangeListener(mLayoutChangedListener); mCurrentlyEditedButton = button; mCurrentlyEditedButton.getControlView().addOnLayoutChangeListener(mLayoutChangedListener); diff --git a/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml b/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml index f661cb029..90c07e23d 100644 --- a/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml +++ b/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml @@ -3,9 +3,9 @@ android:shape="rectangle"> + android:bottom="@dimen/_2sdp" + android:left="@dimen/_2sdp" + android:right="@dimen/_2sdp" + android:top="@dimen/_2sdp" /> diff --git a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml index 1bbb7dabc..bf2dfc9b9 100644 --- a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml +++ b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml @@ -56,7 +56,7 @@ + app:layout_constraintTop_toBottomOf="@+id/editMapping_textView" /> + + + + + + + + + + + - - - + app:layout_constraintBottom_toBottomOf="@+id/mapping_1_textview" + app:layout_constraintEnd_toEndOf="@+id/mapping_1_textview" + app:layout_constraintStart_toEndOf="@id/mapping_1_textview" + app:layout_constraintTop_toTopOf="@+id/mapping_1_textview" /> - - + + + app:layout_constraintTop_toBottomOf="@id/mapping_1_textview" + + tools:text="HELLO" /> + app:layout_constraintBottom_toBottomOf="@+id/mapping_3_textview" + app:layout_constraintEnd_toEndOf="@+id/mapping_3_textview" + app:layout_constraintStart_toEndOf="@id/mapping_3_textview" + app:layout_constraintTop_toBottomOf="@+id/mapping_1_textview" /> - + app:layout_constraintStart_toEndOf="@id/mapping_3_textview" + app:layout_constraintTop_toTopOf="@id/mapping_3_textview" + + tools:text="HELLO" /> From b4a3e18b9ae64b674efb1659ec72aa861dbb4e61 Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Tue, 16 May 2023 15:29:59 +0200 Subject: [PATCH 013/105] Feat[controls]: Decouple stroke width from button size --- .../customcontrols/ControlData.java | 185 +++++++++--------- .../customcontrols/LayoutConverter.java | 108 +++++++--- .../buttons/ControlInterface.java | 163 ++++++++------- .../buttons/ControlJoystick.java | 50 +++-- .../handleview/EditControlPopup.java | 6 +- 5 files changed, 290 insertions(+), 222 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java index e132b8a12..5f39ec0c2 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java @@ -32,21 +32,19 @@ public class ControlData { public static final int SPECIALBTN_SCROLLUP = -7; public static final int SPECIALBTN_SCROLLDOWN = -8; public static final int SPECIALBTN_MENU = -9; - + private static ControlData[] SPECIAL_BUTTONS; private static List SPECIAL_BUTTON_NAME_ARRAY; - - // Internal usage only - public boolean isHideable; - private static WeakReference builder = new WeakReference<>(null); - private static WeakReference> conversionMap = new WeakReference<>(null); + private static WeakReference> conversionMap = new WeakReference<>(null); + static { buildExpressionBuilder(); buildConversionMap(); } - + // Internal usage only + public boolean isHideable; /** * Both fields below are dynamic position data, auto updates * X and Y position, unlike the original one which uses fixed @@ -56,63 +54,29 @@ public class ControlData { */ public String dynamicX, dynamicY; public boolean isDynamicBtn, isToggle, passThruEnabled; - - public static ControlData[] getSpecialButtons(){ - if (SPECIAL_BUTTONS == null) { - SPECIAL_BUTTONS = new ControlData[]{ - new ControlData("Keyboard", new int[]{SPECIALBTN_KEYBOARD}, "${margin} * 3 + ${width} * 2", "${margin}", false), - new ControlData("GUI", new int[]{SPECIALBTN_TOGGLECTRL}, "${margin}", "${bottom} - ${margin}"), - new ControlData("PRI", new int[]{SPECIALBTN_MOUSEPRI}, "${margin}", "${screen_height} - ${margin} * 3 - ${height} * 3"), - new ControlData("SEC", new int[]{SPECIALBTN_MOUSESEC}, "${margin} * 3 + ${width} * 2", "${screen_height} - ${margin} * 3 - ${height} * 3"), - new ControlData("Mouse", new int[]{SPECIALBTN_VIRTUALMOUSE}, "${right}", "${margin}", false), - - new ControlData("MID", new int[]{SPECIALBTN_MOUSEMID}, "${margin}", "${margin}"), - new ControlData("SCROLLUP", new int[]{SPECIALBTN_SCROLLUP}, "${margin}", "${margin}"), - new ControlData("SCROLLDOWN", new int[]{SPECIALBTN_SCROLLDOWN}, "${margin}", "${margin}"), - new ControlData("MENU", new int[]{SPECIALBTN_MENU}, "${margin}", "${margin}") - }; - } - - return SPECIAL_BUTTONS; - } - - public static List buildSpecialButtonArray() { - if (SPECIAL_BUTTON_NAME_ARRAY == null) { - List nameList = new ArrayList<>(); - for (ControlData btn : getSpecialButtons()) { - nameList.add("SPECIAL_" + btn.name); - } - SPECIAL_BUTTON_NAME_ARRAY = nameList; - Collections.reverse(SPECIAL_BUTTON_NAME_ARRAY); - } - - return SPECIAL_BUTTON_NAME_ARRAY; - } - public String name; - private float width; //Dp instead of Px now - private float height; //Dp instead of Px now public int[] keycodes; //Should store up to 4 keys public float opacity; //Alpha value from 0 to 1; public int bgColor; public int strokeColor; - public int strokeWidth; //0-100% + public float strokeWidth; // Dp instead of % now public float cornerRadius; //0-100% public boolean isSwipeable; - public boolean displayInGame; public boolean displayInMenu; + private float width; //Dp instead of Px now + private float height; //Dp instead of Px now public ControlData() { this("button"); } - public ControlData(String name){ - this(name, new int[] {}); + public ControlData(String name) { + this(name, new int[]{}); } public ControlData(String name, int[] keycodes) { - this(name, keycodes, Tools.currentDisplayMetrics.widthPixels/2f, Tools.currentDisplayMetrics.heightPixels/2f); + this(name, keycodes, Tools.currentDisplayMetrics.widthPixels / 2f, Tools.currentDisplayMetrics.heightPixels / 2f); } public ControlData(String name, int[] keycodes, float x, float y) { @@ -144,11 +108,11 @@ public class ControlData { this(name, keycodes, dynamicX, dynamicY, isSquare ? 50 : 80, isSquare ? 50 : 30, false); } - public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle){ - this(name, keycodes, dynamicX, dynamicY, width, height, isToggle, 1,0x4D000000, 0xFFFFFFFF,0,0, true, true); + public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle) { + this(name, keycodes, dynamicX, dynamicY, width, height, isToggle, 1, 0x4D000000, 0xFFFFFFFF, 0, 0, true, true); } - public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle, float opacity, int bgColor, int strokeColor, int strokeWidth, float cornerRadius, boolean displayInGame, boolean displayInMenu) { + public ControlData(String name, int[] keycodes, String dynamicX, String dynamicY, float width, float height, boolean isToggle, float opacity, int bgColor, int strokeColor, float strokeWidth, float cornerRadius, boolean displayInGame, boolean displayInMenu) { this.name = name; this.keycodes = inflateKeycodeArray(keycodes); this.dynamicX = dynamicX; @@ -167,7 +131,7 @@ public class ControlData { } //Deep copy constructor - public ControlData(ControlData controlData){ + public ControlData(ControlData controlData) { this( controlData.name, controlData.keycodes, @@ -186,13 +150,36 @@ public class ControlData { ); } - - public float insertDynamicPos(String dynamicPos) { - // Insert value to ${variable} - String insertedPos = JSONUtils.insertSingleJSONValue(dynamicPos, fillConversionMap()); - - // Calculate, because the dynamic position contains some math equations - return calculate(insertedPos); + public static ControlData[] getSpecialButtons() { + if (SPECIAL_BUTTONS == null) { + SPECIAL_BUTTONS = new ControlData[]{ + new ControlData("Keyboard", new int[]{SPECIALBTN_KEYBOARD}, "${margin} * 3 + ${width} * 2", "${margin}", false), + new ControlData("GUI", new int[]{SPECIALBTN_TOGGLECTRL}, "${margin}", "${bottom} - ${margin}"), + new ControlData("PRI", new int[]{SPECIALBTN_MOUSEPRI}, "${margin}", "${screen_height} - ${margin} * 3 - ${height} * 3"), + new ControlData("SEC", new int[]{SPECIALBTN_MOUSESEC}, "${margin} * 3 + ${width} * 2", "${screen_height} - ${margin} * 3 - ${height} * 3"), + new ControlData("Mouse", new int[]{SPECIALBTN_VIRTUALMOUSE}, "${right}", "${margin}", false), + + new ControlData("MID", new int[]{SPECIALBTN_MOUSEMID}, "${margin}", "${margin}"), + new ControlData("SCROLLUP", new int[]{SPECIALBTN_SCROLLUP}, "${margin}", "${margin}"), + new ControlData("SCROLLDOWN", new int[]{SPECIALBTN_SCROLLDOWN}, "${margin}", "${margin}"), + new ControlData("MENU", new int[]{SPECIALBTN_MENU}, "${margin}", "${margin}") + }; + } + + return SPECIAL_BUTTONS; + } + + public static List buildSpecialButtonArray() { + if (SPECIAL_BUTTON_NAME_ARRAY == null) { + List nameList = new ArrayList<>(); + for (ControlData btn : getSpecialButtons()) { + nameList.add("SPECIAL_" + btn.name); + } + SPECIAL_BUTTON_NAME_ARRAY = nameList; + Collections.reverse(SPECIAL_BUTTON_NAME_ARRAY); + } + + return SPECIAL_BUTTON_NAME_ARRAY; } private static float calculate(String math) { @@ -200,44 +187,16 @@ public class ControlData { return (float) builder.get().build().evaluate(); } - private static int[] inflateKeycodeArray(int[] keycodes){ + private static int[] inflateKeycodeArray(int[] keycodes) { int[] inflatedArray = new int[]{GLFW_KEY_UNKNOWN, GLFW_KEY_UNKNOWN, GLFW_KEY_UNKNOWN, GLFW_KEY_UNKNOWN}; System.arraycopy(keycodes, 0, inflatedArray, 0, keycodes.length); return inflatedArray; } - - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - public boolean containsKeycode(int keycodeToCheck){ - for(int keycode : keycodes) - if(keycodeToCheck == keycode) - return true; - - return false; - } - - //Getters || setters (with conversion for ease of use) - public float getWidth() { - return Tools.dpToPx(width); - } - - public float getHeight(){ - return Tools.dpToPx(height); - } - - - public void setWidth(float widthInPx){ - width = Tools.pxToDp(widthInPx); - } - - public void setHeight(float heightInPx){ - height = Tools.pxToDp(heightInPx); - } - /** * Create a builder, keep a weak reference to it to use it with all views on first inflation */ - private static void buildExpressionBuilder(){ + private static void buildExpressionBuilder() { ExpressionBuilder expressionBuilder = new ExpressionBuilder("1 + 1") .function(new Function("dp", 1) { @Override @@ -256,10 +215,11 @@ public class ControlData { /** * wrapper for the WeakReference to the expressionField. + * * @param stringExpression the expression to set. */ - private static void setExpression(String stringExpression){ - if(builder.get() == null) buildExpressionBuilder(); + private static void setExpression(String stringExpression) { + if (builder.get() == null) buildExpressionBuilder(); builder.get().expression(stringExpression); } @@ -276,7 +236,7 @@ public class ControlData { keyValueMap.put("bottom", "DUMMY_BOTTOM"); keyValueMap.put("width", "DUMMY_WIDTH"); keyValueMap.put("height", "DUMMY_HEIGHT"); - keyValueMap.put("screen_width", "DUMMY_DATA" ); + keyValueMap.put("screen_width", "DUMMY_DATA"); keyValueMap.put("screen_height", "DUMMY_DATA"); keyValueMap.put("margin", Integer.toString((int) Tools.dpToPx(2))); keyValueMap.put("preferred_scale", "DUMMY_DATA"); @@ -284,14 +244,49 @@ public class ControlData { conversionMap = new WeakReference<>(keyValueMap); } + public float insertDynamicPos(String dynamicPos) { + // Insert value to ${variable} + String insertedPos = JSONUtils.insertSingleJSONValue(dynamicPos, fillConversionMap()); + + // Calculate, because the dynamic position contains some math equations + return calculate(insertedPos); + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + public boolean containsKeycode(int keycodeToCheck) { + for (int keycode : keycodes) + if (keycodeToCheck == keycode) + return true; + + return false; + } + + //Getters || setters (with conversion for ease of use) + public float getWidth() { + return Tools.dpToPx(width); + } + + public void setWidth(float widthInPx) { + width = Tools.pxToDp(widthInPx); + } + + public float getHeight() { + return Tools.dpToPx(height); + } + + public void setHeight(float heightInPx) { + height = Tools.pxToDp(heightInPx); + } + /** * Fill the conversionMap with controlData dependent values. * The returned valueMap should NOT be kept in memory. + * * @return the valueMap to use. */ - private Map fillConversionMap(){ + private Map fillConversionMap() { ArrayMap valueMap = conversionMap.get(); - if (valueMap == null){ + if (valueMap == null) { buildConversionMap(); valueMap = conversionMap.get(); } @@ -300,8 +295,8 @@ public class ControlData { valueMap.put("bottom", Float.toString(CallbackBridge.physicalHeight - getHeight())); valueMap.put("width", Float.toString(getWidth())); valueMap.put("height", Float.toString(getHeight())); - valueMap.put("screen_width",Integer.toString(CallbackBridge.physicalWidth)); - valueMap.put("screen_height",Integer.toString(CallbackBridge.physicalHeight)); + valueMap.put("screen_width", Integer.toString(CallbackBridge.physicalWidth)); + valueMap.put("screen_height", Integer.toString(CallbackBridge.physicalHeight)); valueMap.put("preferred_scale", Float.toString(LauncherPreferences.PREF_BUTTONSIZE)); return valueMap; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java index f5dd33f9b..ce4e0e678 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java @@ -20,105 +20,159 @@ public class LayoutConverter { try { JSONObject layoutJobj = new JSONObject(jsonLayoutData); - if(!layoutJobj.has("version")) { //v1 layout + if (!layoutJobj.has("version")) { //v1 layout CustomControls layout = LayoutConverter.convertV1Layout(layoutJobj); layout.save(jsonPath); return layout; - }else if (layoutJobj.getInt("version") == 2) { + } else if (layoutJobj.getInt("version") == 2) { CustomControls layout = LayoutConverter.convertV2Layout(layoutJobj); layout.save(jsonPath); return layout; }else if (layoutJobj.getInt("version") >= 3 && layoutJobj.getInt("version") <= 5) { + return LayoutConverter.convertV3_4Layout(layoutJobj); + } else if (layoutJobj.getInt("version") == 6) { return Tools.GLOBAL_GSON.fromJson(jsonLayoutData, CustomControls.class); - }else{ + } else { return null; } - }catch (JSONException e) { - throw new JsonSyntaxException("Failed to load",e); + } catch (JSONException e) { + throw new JsonSyntaxException("Failed to load", e); } } + + + /** + * Normalize the layout to v5 from v3/4: The stroke width is no longer dependant on the button size + */ + public static CustomControls convertV3_4Layout(JSONObject oldLayoutJson) { + CustomControls layout = Tools.GLOBAL_GSON.fromJson(oldLayoutJson.toString(), CustomControls.class); + convertStrokeWidth(layout); + layout.version = 5; + return layout; + } + + public static CustomControls convertV2Layout(JSONObject oldLayoutJson) throws JSONException { CustomControls layout = Tools.GLOBAL_GSON.fromJson(oldLayoutJson.toString(), CustomControls.class); JSONArray layoutMainArray = oldLayoutJson.getJSONArray("mControlDataList"); layout.mControlDataList = new ArrayList<>(layoutMainArray.length()); - for(int i = 0; i < layoutMainArray.length(); i++) { + for (int i = 0; i < layoutMainArray.length(); i++) { JSONObject button = layoutMainArray.getJSONObject(i); ControlData n_button = Tools.GLOBAL_GSON.fromJson(button.toString(), ControlData.class); - if(!Tools.isValidString(n_button.dynamicX) && button.has("x")) { + if (!Tools.isValidString(n_button.dynamicX) && button.has("x")) { double buttonC = button.getDouble("x"); - double ratio = buttonC/CallbackBridge.physicalWidth; + double ratio = buttonC / CallbackBridge.physicalWidth; n_button.dynamicX = ratio + " * ${screen_width}"; } - if(!Tools.isValidString(n_button.dynamicY) && button.has("y")) { + if (!Tools.isValidString(n_button.dynamicY) && button.has("y")) { double buttonC = button.getDouble("y"); - double ratio = buttonC/CallbackBridge.physicalHeight; + double ratio = buttonC / CallbackBridge.physicalHeight; n_button.dynamicY = ratio + " * ${screen_height}"; } layout.mControlDataList.add(n_button); } JSONArray layoutDrawerArray = oldLayoutJson.getJSONArray("mDrawerDataList"); layout.mDrawerDataList = new ArrayList<>(); - for(int i = 0; i < layoutDrawerArray.length(); i++) { + for (int i = 0; i < layoutDrawerArray.length(); i++) { JSONObject button = layoutDrawerArray.getJSONObject(i); JSONObject buttonProperties = button.getJSONObject("properties"); ControlDrawerData n_button = Tools.GLOBAL_GSON.fromJson(button.toString(), ControlDrawerData.class); - if(!Tools.isValidString(n_button.properties.dynamicX) && buttonProperties.has("x")) { + if (!Tools.isValidString(n_button.properties.dynamicX) && buttonProperties.has("x")) { double buttonC = buttonProperties.getDouble("x"); - double ratio = buttonC/CallbackBridge.physicalWidth; + double ratio = buttonC / CallbackBridge.physicalWidth; n_button.properties.dynamicX = ratio + " * ${screen_width}"; } - if(!Tools.isValidString(n_button.properties.dynamicY) && buttonProperties.has("y")) { + if (!Tools.isValidString(n_button.properties.dynamicY) && buttonProperties.has("y")) { double buttonC = buttonProperties.getDouble("y"); - double ratio = buttonC/CallbackBridge.physicalHeight; + double ratio = buttonC / CallbackBridge.physicalHeight; n_button.properties.dynamicY = ratio + " * ${screen_height}"; } layout.mDrawerDataList.add(n_button); } + convertStrokeWidth(layout); + layout.version = 3; return layout; } + public static CustomControls convertV1Layout(JSONObject oldLayoutJson) throws JSONException { CustomControls empty = new CustomControls(); JSONArray layoutMainArray = oldLayoutJson.getJSONArray("mControlDataList"); - for(int i = 0; i < layoutMainArray.length(); i++) { + for (int i = 0; i < layoutMainArray.length(); i++) { JSONObject button = layoutMainArray.getJSONObject(i); ControlData n_button = new ControlData(); - int[] keycodes = new int[] {LwjglGlfwKeycode.GLFW_KEY_UNKNOWN, + int[] keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_UNKNOWN, LwjglGlfwKeycode.GLFW_KEY_UNKNOWN, LwjglGlfwKeycode.GLFW_KEY_UNKNOWN, LwjglGlfwKeycode.GLFW_KEY_UNKNOWN}; n_button.isDynamicBtn = button.getBoolean("isDynamicBtn"); n_button.dynamicX = button.getString("dynamicX"); n_button.dynamicY = button.getString("dynamicY"); - if(!Tools.isValidString(n_button.dynamicX) && button.has("x")) { + if (!Tools.isValidString(n_button.dynamicX) && button.has("x")) { double buttonC = button.getDouble("x"); - double ratio = buttonC/CallbackBridge.physicalWidth; + double ratio = buttonC / CallbackBridge.physicalWidth; n_button.dynamicX = ratio + " * ${screen_width}"; } - if(!Tools.isValidString(n_button.dynamicY) && button.has("y")) { + if (!Tools.isValidString(n_button.dynamicY) && button.has("y")) { double buttonC = button.getDouble("y"); - double ratio = buttonC/CallbackBridge.physicalHeight; + double ratio = buttonC / CallbackBridge.physicalHeight; n_button.dynamicY = ratio + " * ${screen_height}"; } n_button.name = button.getString("name"); - n_button.opacity = ((float)((button.getInt("transparency")-100)*-1))/100f; + n_button.opacity = ((float) ((button.getInt("transparency") - 100) * -1)) / 100f; n_button.passThruEnabled = button.getBoolean("passThruEnabled"); n_button.isToggle = button.getBoolean("isToggle"); n_button.setHeight(button.getInt("height")); n_button.setWidth(button.getInt("width")); n_button.bgColor = 0x4d000000; n_button.strokeWidth = 0; - if(button.getBoolean("isRound")) { n_button.cornerRadius = 35f; } + if (button.getBoolean("isRound")) { + n_button.cornerRadius = 35f; + } int next_idx = 0; - if(button.getBoolean("holdShift")) { keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT; next_idx++; } - if(button.getBoolean("holdCtrl")) { keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL; next_idx++; } - if(button.getBoolean("holdAlt")) { keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_ALT; next_idx++; } + if (button.getBoolean("holdShift")) { + keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT; + next_idx++; + } + if (button.getBoolean("holdCtrl")) { + keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL; + next_idx++; + } + if (button.getBoolean("holdAlt")) { + keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_ALT; + next_idx++; + } keycodes[next_idx] = button.getInt("keycode"); n_button.keycodes = keycodes; empty.mControlDataList.add(n_button); } - empty.scaledAt = (float)oldLayoutJson.getDouble("scaledAt"); + empty.scaledAt = (float) oldLayoutJson.getDouble("scaledAt"); empty.version = 3; return empty; } + + + /** + * Convert the layout stroke width to the V5 form + */ + private static void convertStrokeWidth(CustomControls layout) { + for (ControlData data : layout.mControlDataList) { + data.strokeWidth = Tools.pxToDp(computeStrokeWidth(data.strokeWidth, data.getWidth(), data.getHeight())); + } + + for (ControlDrawerData data : layout.mDrawerDataList) { + data.properties.strokeWidth = Tools.pxToDp(computeStrokeWidth(data.properties.strokeWidth, data.properties.getWidth(), data.properties.getHeight())); + for (ControlData subButtonData : data.buttonProperties) { + subButtonData.strokeWidth = Tools.pxToDp(computeStrokeWidth(subButtonData.strokeWidth, data.properties.getWidth(), data.properties.getWidth())); + } + } + } + + /** + * Convert a size percentage into a px size, used by older layout versions + */ + static int computeStrokeWidth(float widthInPercent, float width, float height) { + float maxSize = Math.max(width, height); + return (int) ((maxSize / 2) * (widthInPercent / 100)); + } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlInterface.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlInterface.java index 274880f92..08673a77a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlInterface.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlInterface.java @@ -30,27 +30,37 @@ import org.lwjgl.glfw.CallbackBridge; public interface ControlInterface extends View.OnLongClickListener, GrabListener { View getControlView(); + ControlData getProperties(); - /** Remove the button presence from the CustomControl object + default void setProperties(ControlData properties) { + setProperties(properties, true); + } + + /** + * Remove the button presence from the CustomControl object * You need to use {getControlParent()} for this. */ void removeButton(); - /** Duplicate the data of the button and add a view with the duplicated data + /** + * Duplicate the data of the button and add a view with the duplicated data * Relies on the ControlLayout for the implementation. */ void cloneButton(); void setVisible(boolean isVisible); + void sendKeyPresses(boolean isDown); - /** Load the values and hide non useful forms */ + /** + * Load the values and hide non useful forms + */ void loadEditValues(EditControlPopup editControlPopup); @Override default void onGrabState(boolean isGrabbing) { - if(getControlLayoutParent() != null && getControlLayoutParent().getModifiable()) return; // Disable when edited + if (getControlLayoutParent() != null && getControlLayoutParent().getModifiable()) return; // Disable when edited setVisible((getProperties().displayInGame && isGrabbing) || (getProperties().displayInMenu && !isGrabbing)); } @@ -58,8 +68,10 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener return (ControlLayout) getControlView().getParent(); } - /** Apply conversion steps for when the view is created */ - default ControlData preProcessProperties(ControlData properties, ControlLayout layout){ + /** + * Apply conversion steps for when the view is created + */ + default ControlData preProcessProperties(ControlData properties, ControlLayout layout) { //Size properties.setWidth(properties.getWidth() / layout.getLayoutScale() * PREF_BUTTONSIZE); properties.setHeight(properties.getHeight() / layout.getLayoutScale() * PREF_BUTTONSIZE); @@ -74,10 +86,6 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener setProperties(getProperties()); } - default void setProperties(ControlData properties) { - setProperties(properties, true); - } - /* This function should be overridden to store the properties */ @CallSuper default void setProperties(ControlData properties, boolean changePos) { @@ -88,19 +96,22 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener // Recycle layout params ViewGroup.LayoutParams params = getControlView().getLayoutParams(); - if(params == null) params = new FrameLayout.LayoutParams((int) properties.getWidth(), (int) properties.getHeight()); + if (params == null) + params = new FrameLayout.LayoutParams((int) properties.getWidth(), (int) properties.getHeight()); params.width = (int) properties.getWidth(); params.height = (int) properties.getHeight(); getControlView().setLayoutParams(params); } - /** Apply the background according to properties */ - default void setBackground(){ - GradientDrawable gd = getControlView().getBackground() instanceof GradientDrawable + /** + * Apply the background according to properties + */ + default void setBackground() { + GradientDrawable gd = getControlView().getBackground() instanceof GradientDrawable ? (GradientDrawable) getControlView().getBackground() : new GradientDrawable(); gd.setColor(getProperties().bgColor); - gd.setStroke(computeStrokeWidth(getProperties().strokeWidth), getProperties().strokeColor); + gd.setStroke((int) Tools.dpToPx(getProperties().strokeWidth), getProperties().strokeColor); gd.setCornerRadius(computeCornerRadius(getProperties().cornerRadius)); getControlView().setBackground(gd); @@ -108,50 +119,56 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener /** * Apply the dynamic equation on the x axis. + * * @param dynamicX The equation to compute the position from */ - default void setDynamicX(String dynamicX){ + default void setDynamicX(String dynamicX) { getProperties().dynamicX = dynamicX; getControlView().setX(getProperties().insertDynamicPos(dynamicX)); } /** * Apply the dynamic equation on the y axis. + * * @param dynamicY The equation to compute the position from */ - default void setDynamicY(String dynamicY){ + default void setDynamicY(String dynamicY) { getProperties().dynamicY = dynamicY; getControlView().setY(getProperties().insertDynamicPos(dynamicY)); } /** * Generate a dynamic equation from an absolute position, used to scale properly across devices + * * @param x The absolute position on the horizontal axis * @return The equation as a String */ - default String generateDynamicX(float x){ - if(x + (getProperties().getWidth()/2f) > CallbackBridge.physicalWidth/2f){ + default String generateDynamicX(float x) { + if (x + (getProperties().getWidth() / 2f) > CallbackBridge.physicalWidth / 2f) { return (x + getProperties().getWidth()) / CallbackBridge.physicalWidth + " * ${screen_width} - ${width}"; - }else{ + } else { return x / CallbackBridge.physicalWidth + " * ${screen_width}"; } } /** * Generate a dynamic equation from an absolute position, used to scale properly across devices + * * @param y The absolute position on the vertical axis * @return The equation as a String */ - default String generateDynamicY(float y){ - if(y + (getProperties().getHeight()/2f) > CallbackBridge.physicalHeight/2f){ - return (y + getProperties().getHeight()) / CallbackBridge.physicalHeight + " * ${screen_height} - ${height}"; - }else{ + default String generateDynamicY(float y) { + if (y + (getProperties().getHeight() / 2f) > CallbackBridge.physicalHeight / 2f) { + return (y + getProperties().getHeight()) / CallbackBridge.physicalHeight + " * ${screen_height} - ${height}"; + } else { return y / CallbackBridge.physicalHeight + " * ${screen_height}"; } } - /** Regenerate and apply coordinates with supposedly modified properties */ - default void regenerateDynamicCoordinates(){ + /** + * Regenerate and apply coordinates with supposedly modified properties + */ + default void regenerateDynamicCoordinates() { getProperties().dynamicX = generateDynamicX(getControlView().getX()); getProperties().dynamicY = generateDynamicY(getControlView().getY()); updateProperties(); @@ -160,30 +177,28 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener /** * Do a pre-conversion of an equation using values from a button, * so the variables can be used for another button - * + *

* Internal use only. + * * @param equation The dynamic position as a String - * @param button The button to get the values from. + * @param button The button to get the values from. * @return The pre-processed equation as a String. */ - default String applySize(String equation, ControlInterface button){ + default String applySize(String equation, ControlInterface button) { return equation .replace("${right}", "(${screen_width} - ${width})") - .replace("${bottom}","(${screen_height} - ${height})") + .replace("${bottom}", "(${screen_height} - ${height})") .replace("${height}", "(px(" + Tools.pxToDp(button.getProperties().getHeight()) + ") /" + PREF_BUTTONSIZE + " * ${preferred_scale})") .replace("${width}", "(px(" + Tools.pxToDp(button.getProperties().getWidth()) + ") / " + PREF_BUTTONSIZE + " * ${preferred_scale})"); } - /** Convert a size percentage into a px size */ - default int computeStrokeWidth(float widthInPercent){ - float maxSize = Math.max(getProperties().getWidth(), getProperties().getHeight()); - return (int)((maxSize/2) * (widthInPercent/100)); - } - /** Convert a corner radius percentage into a px corner radius */ - default float computeCornerRadius(float radiusInPercent){ + /** + * Convert a corner radius percentage into a px corner radius + */ + default float computeCornerRadius(float radiusInPercent) { float minSize = Math.min(getProperties().getWidth(), getProperties().getHeight()); - return (minSize/2) * (radiusInPercent/100); + return (minSize / 2) * (radiusInPercent / 100); } /** @@ -193,10 +208,10 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener * @return whether or not the button */ @SuppressWarnings("BooleanMethodIsAlwaysInverted") - default boolean canSnap(ControlInterface button){ + default boolean canSnap(ControlInterface button) { float MIN_DISTANCE = Tools.dpToPx(8); - if(button == this) return false; + if (button == this) return false; return !(net.kdt.pojavlaunch.utils.MathUtils.dist( button.getControlView().getX() + button.getControlView().getWidth() / 2f, button.getControlView().getY() + button.getControlView().getHeight() / 2f, @@ -210,13 +225,13 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener * Try to snap, then align to neighboring buttons, given the provided coordinates. * The new position is automatically applied to the View, * regardless of if the View snapped or not. - * + *

* The new position is always dynamic, thus replacing previous dynamic positions * * @param x Coordinate on the x axis * @param y Coordinate on the y axis */ - default void snapAndAlign(float x, float y){ + default void snapAndAlign(float x, float y) { float MIN_DISTANCE = Tools.dpToPx(8); String dynamicX = generateDynamicX(x); String dynamicY = generateDynamicY(y); @@ -224,9 +239,9 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener getControlView().setX(x); getControlView().setY(y); - for(ControlInterface button : ((ControlLayout) getControlView().getParent()).getButtonChildren()){ + for (ControlInterface button : ((ControlLayout) getControlView().getParent()).getButtonChildren()) { //Step 1: Filter unwanted buttons - if(!canSnap(button)) continue; + if (!canSnap(button)) continue; //Step 2: Get Coordinates float button_top = button.getControlView().getY(); @@ -240,28 +255,28 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener float right = getControlView().getX() + getControlView().getWidth(); //Step 3: For each axis, we try to snap to the nearest - if(Math.abs(top - button_bottom) < MIN_DISTANCE){ // Bottom snap - dynamicY = applySize(button.getProperties().dynamicY, button) + applySize(" + ${height}", button) + " + ${margin}" ; - }else if(Math.abs(button_top - bottom) < MIN_DISTANCE){ //Top snap + if (Math.abs(top - button_bottom) < MIN_DISTANCE) { // Bottom snap + dynamicY = applySize(button.getProperties().dynamicY, button) + applySize(" + ${height}", button) + " + ${margin}"; + } else if (Math.abs(button_top - bottom) < MIN_DISTANCE) { //Top snap dynamicY = applySize(button.getProperties().dynamicY, button) + " - ${height} - ${margin}"; } - if(!dynamicY.equals(generateDynamicY(getControlView().getY()))){ //If we snapped - if(Math.abs(button_left - left) < MIN_DISTANCE){ //Left align snap + if (!dynamicY.equals(generateDynamicY(getControlView().getY()))) { //If we snapped + if (Math.abs(button_left - left) < MIN_DISTANCE) { //Left align snap dynamicX = applySize(button.getProperties().dynamicX, button); - }else if(Math.abs(button_right - right) < MIN_DISTANCE){ //Right align snap + } else if (Math.abs(button_right - right) < MIN_DISTANCE) { //Right align snap dynamicX = applySize(button.getProperties().dynamicX, button) + applySize(" + ${width}", button) + " - ${width}"; } } - if(Math.abs(button_left - right) < MIN_DISTANCE){ //Left snap + if (Math.abs(button_left - right) < MIN_DISTANCE) { //Left snap dynamicX = applySize(button.getProperties().dynamicX, button) + " - ${width} - ${margin}"; - }else if(Math.abs(left - button_right) < MIN_DISTANCE){ //Right snap + } else if (Math.abs(left - button_right) < MIN_DISTANCE) { //Right snap dynamicX = applySize(button.getProperties().dynamicX, button) + applySize(" + ${width}", button) + " + ${margin}"; } - if(!dynamicX.equals(generateDynamicX(getControlView().getX()))){ //If we snapped - if(Math.abs(button_top - top) < MIN_DISTANCE){ //Top align snap + if (!dynamicX.equals(generateDynamicX(getControlView().getX()))) { //If we snapped + if (Math.abs(button_top - top) < MIN_DISTANCE) { //Top align snap dynamicY = applySize(button.getProperties().dynamicY, button); - }else if(Math.abs(button_bottom - bottom) < MIN_DISTANCE){ //Bottom align snap + } else if (Math.abs(button_bottom - bottom) < MIN_DISTANCE) { //Bottom align snap dynamicY = applySize(button.getProperties().dynamicY, button) + applySize(" + ${height}", button) + " - ${height}"; } } @@ -272,17 +287,21 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener setDynamicY(dynamicY); } - /** Wrapper for multiple injections at once */ - default void injectBehaviors(){ + /** + * Wrapper for multiple injections at once + */ + default void injectBehaviors() { injectProperties(); injectTouchEventBehavior(); injectLayoutParamBehavior(); injectGrabListenerBehavior(); } - /** Inject the grab listener, remove it when the view is gone */ - default void injectGrabListenerBehavior(){ - if(getControlView() == null){ + /** + * Inject the grab listener, remove it when the view is gone + */ + default void injectGrabListenerBehavior() { + if (getControlView() == null) { Log.e(ControlInterface.class.toString(), "Failed to inject grab listener behavior !"); return; } @@ -304,12 +323,14 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener } - default void injectProperties(){ + default void injectProperties() { getControlView().post(() -> getControlView().setTranslationZ(10)); } - /** Inject a touch listener on the view to make editing controls straight forward */ - default void injectTouchEventBehavior(){ + /** + * Inject a touch listener on the view to make editing controls straight forward + */ + default void injectTouchEventBehavior() { getControlView().setOnTouchListener(new View.OnTouchListener() { private boolean mCanTriggerLongClick = true; private float downX, downY; @@ -318,7 +339,7 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View view, MotionEvent event) { - if(!getControlLayoutParent().getModifiable()){ + if (!getControlLayoutParent().getModifiable()) { // Basically, editing behavior is forced while in game behavior is specific view.onTouchEvent(event); return true; @@ -342,7 +363,7 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener break; case MotionEvent.ACTION_MOVE: - if(Math.abs(event.getRawX() - downRawX) > 8 || Math.abs(event.getRawY() - downRawY) > 8) + if (Math.abs(event.getRawX() - downRawX) > 8 || Math.abs(event.getRawY() - downRawY) > 8) mCanTriggerLongClick = false; getControlLayoutParent().adaptPanelPosition(); @@ -360,17 +381,17 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener }); } - default void injectLayoutParamBehavior(){ + default void injectLayoutParamBehavior() { getControlView().addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { - getProperties().setWidth(right-left); - getProperties().setHeight(bottom-top); + getProperties().setWidth(right - left); + getProperties().setHeight(bottom - top); setBackground(); // Re-calculate position - if(!getProperties().isDynamicBtn){ + if (!getProperties().isDynamicBtn) { getControlView().setX(getControlView().getX()); getControlView().setY(getControlView().getY()); - }else { + } else { getControlView().setX(getProperties().insertDynamicPos(getProperties().dynamicX)); getControlView().setY(getProperties().insertDynamicPos(getProperties().dynamicY)); } @@ -378,7 +399,7 @@ public interface ControlInterface extends View.OnLongClickListener, GrabListener } @Override - default boolean onLongClick(View v){ + default boolean onLongClick(View v) { if (getControlLayoutParent().getModifiable()) { getControlLayoutParent().editControlButton(this); getControlLayoutParent().mActionRow.setFollowedButton(this); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java index 4b11df406..f0a3a1261 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlJoystick.java @@ -26,26 +26,28 @@ import io.github.controlwear.virtual.joystick.android.JoystickView; @SuppressLint("ViewConstructor") public class ControlJoystick extends JoystickView implements ControlInterface { - public ControlJoystick(ControlLayout parent, ControlData data) { - super(parent.getContext()); - init(data, parent); - } - - public final static int DIRECTION_FORWARD_LOCK = 8; - - private ControlData mControlData; - private int mLastDirectionInt = GamepadJoystick.DIRECTION_NONE; - private int mCurrentDirectionInt = GamepadJoystick.DIRECTION_NONE; - // Directions keycode private final int[] mDirectionForwardLock = new int[]{LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL}; private final int[] mDirectionForward = new int[]{LwjglGlfwKeycode.GLFW_KEY_W}; private final int[] mDirectionRight = new int[]{LwjglGlfwKeycode.GLFW_KEY_D}; private final int[] mDirectionBackward = new int[]{LwjglGlfwKeycode.GLFW_KEY_S}; private final int[] mDirectionLeft = new int[]{LwjglGlfwKeycode.GLFW_KEY_A}; + private ControlData mControlData; + private int mLastDirectionInt = GamepadJoystick.DIRECTION_NONE; + private int mCurrentDirectionInt = GamepadJoystick.DIRECTION_NONE; + public ControlJoystick(ControlLayout parent, ControlData data) { + super(parent.getContext()); + init(data, parent); + } - private void init(ControlData data, ControlLayout layout){ + private static void sendInput(int[] keys, boolean isDown) { + for (int key : keys) { + CallbackBridge.sendKeyPress(key, CallbackBridge.getCurrentMods(), isDown); + } + } + + private void init(ControlData data, ControlLayout layout) { mControlData = data; setProperties(preProcessProperties(data, layout)); setDeadzone(35); @@ -61,7 +63,7 @@ public class ControlJoystick extends JoystickView implements ControlInterface { mLastDirectionInt = mCurrentDirectionInt; mCurrentDirectionInt = getDirectionInt(angle, strength); - if(mLastDirectionInt != mCurrentDirectionInt){ + if (mLastDirectionInt != mCurrentDirectionInt) { sendDirectionalKeycode(mLastDirectionInt, false); sendDirectionalKeycode(mCurrentDirectionInt, true); } @@ -75,7 +77,9 @@ public class ControlJoystick extends JoystickView implements ControlInterface { } @Override - public View getControlView() {return this;} + public View getControlView() { + return this; + } @Override public ControlData getProperties() { @@ -107,7 +111,7 @@ public class ControlJoystick extends JoystickView implements ControlInterface { @Override public void setBackground() { - setBorderWidth(computeStrokeWidth(getProperties().strokeWidth)); + setBorderWidth((int) Tools.dpToPx(getProperties().strokeWidth)); setBorderColor(getProperties().strokeColor); setBackgroundColor(getProperties().bgColor); } @@ -120,13 +124,13 @@ public class ControlJoystick extends JoystickView implements ControlInterface { editControlPopup.loadJoystickValues(mControlData); } - private int getDirectionInt(int angle, int intensity){ - if(intensity == 0) return DIRECTION_NONE; - return (int) (((angle+22.5)/45) % 8); + private int getDirectionInt(int angle, int intensity) { + if (intensity == 0) return DIRECTION_NONE; + return (int) (((angle + 22.5) / 45) % 8); } - private void sendDirectionalKeycode(int direction, boolean isDown){ - switch (direction){ + private void sendDirectionalKeycode(int direction, boolean isDown) { + switch (direction) { case DIRECTION_NORTH: sendInput(mDirectionForward, isDown); break; @@ -161,10 +165,4 @@ public class ControlJoystick extends JoystickView implements ControlInterface { } } - private static void sendInput(int[] keys, boolean isDown){ - for(int key : keys){ - CallbackBridge.sendKeyPress(key, CallbackBridge.getCurrentMods(), isDown); - } - } - } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java index 222bdafa5..628d1b7d1 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java @@ -269,11 +269,11 @@ public class EditControlPopup { mHeightEditText.setText(String.valueOf(data.getHeight())); mAlphaSeekbar.setProgress((int) (data.opacity * 100)); - mStrokeWidthSeekbar.setProgress(data.strokeWidth); + mStrokeWidthSeekbar.setProgress((int) data.strokeWidth * 10); mCornerRadiusSeekbar.setProgress((int) data.cornerRadius); setPercentageText(mAlphaPercentTextView, (int) (data.opacity * 100)); - setPercentageText(mStrokePercentTextView, data.strokeWidth); + setPercentageText(mStrokePercentTextView, (int) data.strokeWidth * 10); setPercentageText(mCornerRadiusPercentTextView, (int) data.cornerRadius); mToggleSwitch.setChecked(data.isToggle); @@ -498,7 +498,7 @@ public class EditControlPopup { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (internalChanges) return; - mCurrentlyEditedButton.getProperties().strokeWidth = mStrokeWidthSeekbar.getProgress(); + mCurrentlyEditedButton.getProperties().strokeWidth = mStrokeWidthSeekbar.getProgress() / 10F; mCurrentlyEditedButton.setBackground(); setPercentageText(mStrokePercentTextView, progress); } From 6e194302f5e8a5c253ef4d10df2cd61349c76c47 Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Fri, 19 May 2023 00:39:08 +0200 Subject: [PATCH 014/105] Fix[controls]: incorrect activated overlay on rounded controls --- .../pojavlaunch/customcontrols/buttons/ControlButton.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java index abfd6cb7d..8ee81a853 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java @@ -31,6 +31,9 @@ public class ControlButton extends TextView implements ControlInterface { protected ControlData mProperties; private final ControlLayout mControlLayout; + /* Cache value from the ControlData radius for drawing purposes */ + private float mComputedRadius; + protected boolean mIsToggled = false; protected boolean mIsPointerOutOfBounds = false; @@ -61,6 +64,7 @@ public class ControlButton extends TextView implements ControlInterface { public void setProperties(ControlData properties, boolean changePos) { mProperties = properties; ControlInterface.super.setProperties(properties, changePos); + mComputedRadius = ControlInterface.super.computeCornerRadius(mProperties.cornerRadius); if (mProperties.isToggle) { //For the toggle layer @@ -85,7 +89,7 @@ public class ControlButton extends TextView implements ControlInterface { protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mIsToggled || (!mProperties.isToggle && isActivated())) - canvas.drawRoundRect(0, 0, getWidth(), getHeight(), mProperties.cornerRadius, mProperties.cornerRadius, mRectPaint); + canvas.drawRoundRect(0, 0, getWidth(), getHeight(), mComputedRadius, mComputedRadius, mRectPaint); } From dc7e9856a56775305ef7f0cf7cab37a4642b317e Mon Sep 17 00:00:00 2001 From: Mathias-Boulay Date: Sat, 10 Jun 2023 12:29:55 +0200 Subject: [PATCH 015/105] Fix[physical-controls]: Send mouse position more often --- .../src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java index acd65d4c7..6b8b2afa2 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java @@ -446,9 +446,10 @@ public class MinecraftGLSurface extends View implements GrabListener { CallbackBridge.mouseX += (e.getX()* mScaleFactor); CallbackBridge.mouseY += (e.getY()* mScaleFactor); + CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); + switch (e.getActionMasked()) { case MotionEvent.ACTION_MOVE: - CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); return true; case MotionEvent.ACTION_BUTTON_PRESS: return sendMouseButtonUnconverted(e.getActionButton(), true); From abd7c5b7ee9d30f74e92f42febb6903817e3f1e2 Mon Sep 17 00:00:00 2001 From: Mathias Boulay Date: Sun, 23 Jul 2023 23:38:49 +0200 Subject: [PATCH 016/105] Tweak[control-editor]: Use standarised paddings --- .../drawable/background_control_editor.xml | 8 +++---- .../main/res/layout/dialog_color_selector.xml | 8 +++---- .../layout/dialog_control_button_setting.xml | 21 ++++++++++++------- .../src/main/res/values/dimens.xml | 3 ++- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml b/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml index 90c07e23d..5e350dd5b 100644 --- a/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml +++ b/app_pojavlauncher/src/main/res/drawable/background_control_editor.xml @@ -3,9 +3,9 @@ android:shape="rectangle"> + android:bottom="@dimen/padding_small" + android:left="@dimen/padding_small" + android:right="@dimen/padding_small" + android:top="@dimen/padding_small" /> diff --git a/app_pojavlauncher/src/main/res/layout/dialog_color_selector.xml b/app_pojavlauncher/src/main/res/layout/dialog_color_selector.xml index ffa57362c..a3c69156a 100644 --- a/app_pojavlauncher/src/main/res/layout/dialog_color_selector.xml +++ b/app_pojavlauncher/src/main/res/layout/dialog_color_selector.xml @@ -5,11 +5,11 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="@dimen/_280sdp" android:layout_height="match_parent" - android:background="@color/background_app" - android:paddingHorizontal="@dimen/_5sdp" - android:paddingVertical="@dimen/_5sdp" + android:background="@drawable/background_control_editor" + android:paddingHorizontal="@dimen/padding_moderate" + android:paddingVertical="@dimen/padding_moderate" android:id="@+id/color_picker_layout" - android:layout_marginVertical="@dimen/_14sdp"> + android:layout_marginVertical="@dimen/padding_heavy"> @@ -102,11 +102,16 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/editSize_editTextX" /> + + app:layout_constraintTop_toBottomOf="@+id/mapping_3_textview" /> 16dp 16dp - + @dimen/_1sdp @dimen/_2sdp @dimen/_4sdp + @dimen/_6sdp @dimen/_12sdp @dimen/_16sdp @dimen/_24sdp From e2c45b99f496829e8fe589f3814fcfcb6f100378 Mon Sep 17 00:00:00 2001 From: Mathias Boulay Date: Mon, 24 Jul 2023 22:17:17 +0200 Subject: [PATCH 017/105] Fix[gamepad]: Add right trigger axis --- app_pojavlauncher/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app_pojavlauncher/build.gradle b/app_pojavlauncher/build.gradle index 87fe87723..3f22f732a 100644 --- a/app_pojavlauncher/build.gradle +++ b/app_pojavlauncher/build.gradle @@ -186,7 +186,7 @@ dependencies { implementation 'com.github.PojavLauncherTeam:portrait-sdp:ed33e89cbc' implementation 'com.github.PojavLauncherTeam:portrait-ssp:6c02fd739b' implementation 'com.github.Mathias-Boulay:ExtendedView:1.0.0' - implementation 'com.github.Mathias-Boulay:android_gamepad_remapper:9c4e285ce8' + implementation 'com.github.Mathias-Boulay:android_gamepad_remapper:eb92e3a5bb' implementation 'com.github.Mathias-Boulay:virtual-joystick-android:4fee901b58' From 35208fd413380fa0247bfbeebfa8c913a7cf0519 Mon Sep 17 00:00:00 2001 From: Mathias Boulay Date: Thu, 3 Aug 2023 12:22:42 +0200 Subject: [PATCH 018/105] Refactor: Remove need of the oob canvas --- app_pojavlauncher/build.gradle | 2 +- .../net/kdt/pojavlaunch/customcontrols/ControlLayout.java | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/app_pojavlauncher/build.gradle b/app_pojavlauncher/build.gradle index 3f22f732a..020fbbe4d 100644 --- a/app_pojavlauncher/build.gradle +++ b/app_pojavlauncher/build.gradle @@ -187,7 +187,7 @@ dependencies { implementation 'com.github.PojavLauncherTeam:portrait-ssp:6c02fd739b' implementation 'com.github.Mathias-Boulay:ExtendedView:1.0.0' implementation 'com.github.Mathias-Boulay:android_gamepad_remapper:eb92e3a5bb' - implementation 'com.github.Mathias-Boulay:virtual-joystick-android:4fee901b58' + implementation 'com.github.Mathias-Boulay:virtual-joystick-android:a4ab959955' // implementation 'com.intuit.sdp:sdp-android:1.0.5' diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java index c000bfc7f..98a5d3638 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java @@ -60,12 +60,10 @@ public class ControlLayout extends FrameLayout { public ControlLayout(Context ctx) { super(ctx); - setClipChildren(false); } public ControlLayout(Context ctx, AttributeSet attrs) { super(ctx, attrs); - setClipChildren(false); } @@ -245,9 +243,6 @@ public class ControlLayout extends FrameLayout { } public void setModifiable(boolean isModifiable) { - // Hack to allow joystick free placement and resize while seeing the forward lock - setClipChildren(isModifiable); - if(!isModifiable && mModifiable){ removeEditWindow(); } From 94bfdd74ff2dfeae46aab7e44a5cbbed545cf6c8 Mon Sep 17 00:00:00 2001 From: Mathias Boulay Date: Thu, 3 Aug 2023 13:18:57 +0200 Subject: [PATCH 019/105] Chore[controls]: bump up control version --- .../kdt/pojavlaunch/customcontrols/CustomControls.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java index a27c6c85a..11cf5983a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java @@ -53,14 +53,14 @@ public class CustomControls { this.mControlDataList.add(shiftData); this.mControlDataList.add(new ControlData(ctx, R.string.control_jump, new int[]{LwjglGlfwKeycode.GLFW_KEY_SPACE}, "${right} - ${margin} * 2 - ${width}", "${bottom} - ${margin} * 2 - ${height}", true)); - //The default controls are conform to the V2 - version = 5; + //The default controls are conform to the V3 + version = 6; } public void save(String path) throws IOException { - //Current version is the V2.6 so the version as to be marked as 5 ! - version = 5; + //Current version is the V3.0 so the version as to be marked as 6 ! + version = 6; Tools.write(path, Tools.GLOBAL_GSON.toJson(this)); } From 45e062e67cd2d75e3d67a5e0e5bdf5ba6fd136aa Mon Sep 17 00:00:00 2001 From: Mathias Boulay Date: Thu, 3 Aug 2023 13:22:50 +0200 Subject: [PATCH 020/105] Chore[controls]: bump up layout converter trigger --- .../net/kdt/pojavlaunch/customcontrols/LayoutConverter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java index ce4e0e678..89786b011 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java @@ -42,12 +42,12 @@ public class LayoutConverter { /** - * Normalize the layout to v5 from v3/4: The stroke width is no longer dependant on the button size + * Normalize the layout to v6 from v3/4: The stroke width is no longer dependant on the button size */ public static CustomControls convertV3_4Layout(JSONObject oldLayoutJson) { CustomControls layout = Tools.GLOBAL_GSON.fromJson(oldLayoutJson.toString(), CustomControls.class); convertStrokeWidth(layout); - layout.version = 5; + layout.version = 6; return layout; } From 26328a2fb00b18cc1494cb42344c21b1dd3fdfd9 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Thu, 3 Aug 2023 17:22:15 +0300 Subject: [PATCH 021/105] Change keycode spinner placement --- .../handleview/EditControlPopup.java | 3 ++ .../layout/dialog_control_button_setting.xml | 48 +++++++++---------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java index 628d1b7d1..81bf284fe 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlPopup.java @@ -248,6 +248,9 @@ public class EditControlPopup { for (int i = 0; i < mRootView.getChildCount(); ++i) { mRootView.getChildAt(i).setVisibility(VISIBLE); } + for(Spinner s : mKeycodeSpinners) { + s.setVisibility(View.INVISIBLE); + } } private boolean isAtRight() { diff --git a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml index a5a8b7b2c..06cfeb695 100644 --- a/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml +++ b/app_pojavlauncher/src/main/res/layout/dialog_control_button_setting.xml @@ -109,61 +109,57 @@ --> + app:layout_constraintTop_toBottomOf="@+id/editMapping_textView" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + android:visibility="invisible" + app:layout_constraintTop_toTopOf="@+id/mapping_3_textview" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + app:layout_constraintTop_toTopOf="@+id/mapping_3_textview" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + + + app:layout_constraintTop_toBottomOf="@id/checkboxForwardLock" /> diff --git a/app_pojavlauncher/src/main/res/values/strings.xml b/app_pojavlauncher/src/main/res/values/strings.xml index 35b546bd9..4238f0a4d 100644 --- a/app_pojavlauncher/src/main/res/values/strings.xml +++ b/app_pojavlauncher/src/main/res/values/strings.xml @@ -239,6 +239,7 @@ Changes the speed of the software mouse Mouse pass-thru Swipeable + Forward lock Rounded The current amount of free RAM (%d) is lower than allocated RAM (%d), which may lead to crashes. Change the allocation if the game crashes. Memory allocation From 57ae06a83c07b9bebace8620aa77b764ccdbb601 Mon Sep 17 00:00:00 2001 From: Mathias Boulay Date: Sat, 5 Aug 2023 18:53:06 +0200 Subject: [PATCH 028/105] Fix[profile-editor]: Spinner height aligned with the rest, better selected visibility --- .../fragments/ProfileEditorFragment.java | 2 +- .../pojavlaunch/multirt/RTSpinnerAdapter.java | 2 +- .../res/drawable/background_line_selected.xml | 4 ---- .../drawable/background_line_unselected.xml | 4 ++-- .../res/layout/fragment_profile_editor.xml | 6 ++--- .../main/res/layout/item_simple_list_1.xml | 24 +++++++++++++++++++ .../src/main/res/values/dimens.xml | 4 ++++ 7 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 app_pojavlauncher/src/main/res/layout/item_simple_list_1.xml diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java index 5df28efa7..f01ee9407 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java @@ -75,7 +75,7 @@ public class ProfileEditorFragment extends Fragment { List renderList = new ArrayList<>(5); Collections.addAll(renderList, getResources().getStringArray(R.array.renderer)); renderList.add("Default"); - mDefaultRenderer.setAdapter(new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, renderList)); + mDefaultRenderer.setAdapter(new ArrayAdapter<>(getContext(), R.layout.item_simple_list_1, renderList)); // Set up behaviors mSaveButton.setOnClickListener(v -> { diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTSpinnerAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTSpinnerAdapter.java index e5548fceb..f7de37374 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTSpinnerAdapter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTSpinnerAdapter.java @@ -56,7 +56,7 @@ public class RTSpinnerAdapter implements SpinnerAdapter { public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { View view = convertView != null? convertView: - LayoutInflater.from(mContext).inflate(android.R.layout.simple_list_item_1, parent,false); + LayoutInflater.from(mContext).inflate(R.layout.item_simple_list_1, parent,false); Runtime runtime = mRuntimes.get(position); if(position == mRuntimes.size() - 1 ){ diff --git a/app_pojavlauncher/src/main/res/drawable/background_line_selected.xml b/app_pojavlauncher/src/main/res/drawable/background_line_selected.xml index 56fa839b7..f962a8189 100644 --- a/app_pojavlauncher/src/main/res/drawable/background_line_selected.xml +++ b/app_pojavlauncher/src/main/res/drawable/background_line_selected.xml @@ -7,10 +7,6 @@ - - diff --git a/app_pojavlauncher/src/main/res/drawable/background_line_unselected.xml b/app_pojavlauncher/src/main/res/drawable/background_line_unselected.xml index d1cd8faba..1c95d5431 100644 --- a/app_pojavlauncher/src/main/res/drawable/background_line_unselected.xml +++ b/app_pojavlauncher/src/main/res/drawable/background_line_unselected.xml @@ -8,8 +8,8 @@ + android:bottom="@dimen/padding_input_bottom" + android:top="@dimen/padding_input_top" /> + tools:paddingVertical="@dimen/_12sdp" /> + tools:paddingVertical="@dimen/_12sdp" /> + + + diff --git a/app_pojavlauncher/src/main/res/values/dimens.xml b/app_pojavlauncher/src/main/res/values/dimens.xml index c4dfec7d0..3a04517e8 100644 --- a/app_pojavlauncher/src/main/res/values/dimens.xml +++ b/app_pojavlauncher/src/main/res/values/dimens.xml @@ -16,6 +16,10 @@ @dimen/_24sdp @dimen/_32sdp + + @dimen/padding_heavy + @dimen/_11sdp + 60dp 60dp From f9457442bd73c85c72f26af92762f16ab4cfb4f2 Mon Sep 17 00:00:00 2001 From: Mathias Boulay Date: Sat, 5 Aug 2023 21:08:50 +0200 Subject: [PATCH 029/105] Fix[UI]: proper size on landscape --- app_pojavlauncher/src/main/res/layout/item_simple_list_1.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app_pojavlauncher/src/main/res/layout/item_simple_list_1.xml b/app_pojavlauncher/src/main/res/layout/item_simple_list_1.xml index a29d3a2d3..d2a44c3ea 100644 --- a/app_pojavlauncher/src/main/res/layout/item_simple_list_1.xml +++ b/app_pojavlauncher/src/main/res/layout/item_simple_list_1.xml @@ -19,6 +19,6 @@ android:gravity="center_vertical" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" - android:minHeight="?android:attr/listPreferredItemHeightSmall" + tools:text="PojavLauncher version: Edelweiss" /> From 462baab5aadebda71747836fc9a94e52e78c2d69 Mon Sep 17 00:00:00 2001 From: Mathias Boulay Date: Sat, 5 Aug 2023 23:40:23 +0200 Subject: [PATCH 030/105] Fix[profile]: text accessibility --- .../src/main/res/layout/fragment_profile_editor.xml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app_pojavlauncher/src/main/res/layout/fragment_profile_editor.xml b/app_pojavlauncher/src/main/res/layout/fragment_profile_editor.xml index 9ca3a1ef0..919f871a8 100644 --- a/app_pojavlauncher/src/main/res/layout/fragment_profile_editor.xml +++ b/app_pojavlauncher/src/main/res/layout/fragment_profile_editor.xml @@ -63,8 +63,11 @@