A lot of changes

* Custom controls:
- Rename classes
- Add Dynamic position calculator for auto scale. TODO: document position variables
* Source code
- Abstracts MainActivity.java to prepare implement custom control.
This commit is contained in:
khanhduytran0 2020-11-17 14:38:20 +07:00
parent 67a0babb7a
commit 84f97f3ccd
24 changed files with 1682 additions and 1591 deletions

View File

@ -73,5 +73,7 @@ dependencies {
implementation 'org.tukaani:xz:1.8'
implementation 'net.objecthunter:exp4j:0.4.8'
implementation fileTree(dir: 'libs', include: ['*.jar'])
}

View File

@ -11,6 +11,7 @@
* Third party licenses:<br>
• Apache Commons Compress (unknown or Apache License 2.0).<br>
• exp4j: <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.<br>
• gl4es: <a href="https://github.com/ptitSeb/gl4es/blob/master/LICENSE">MIT License</a>.<br>
• LegacyLauncher: (unknown license).<br>
• OpenJDK: <a href="https://openjdk.java.net/legal/gplv2+ce.html">GNU GPLv2 License</a>.<br>

View File

@ -120,7 +120,7 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe
alert.setPositiveButton(android.R.string.ok, null);
alert.setNegativeButton(android.R.string.cancel, null);
final AlertDialog dialog = alert.create();
final ControlButton properties = mHandleView.mView.getProperties();
final ControlData properties = mHandleView.mView.getProperties();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@ -134,7 +134,7 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe
final Spinner spinnerKeycode = dialog.findViewById(R.id.controlsetting_spinner_lwjglkeycode);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(view.getContext(), android.R.layout.simple_spinner_item);
String[] oldSpecialArr = ControlButton.buildSpecialButtonArray();
String[] oldSpecialArr = ControlData.buildSpecialButtonArray();
String[] specialArr = new String[oldSpecialArr.length];
for (int i = 0; i < specialArr.length; i++) {
specialArr[i] = "SPECIAL_" + oldSpecialArr[i];
@ -145,7 +145,7 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe
adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
spinnerKeycode.setAdapter(adapter);
if (properties.keycode < 0) {
spinnerKeycode.setSelection(properties.keycode + 2);
spinnerKeycode.setSelection(properties.keycode + 5);
} else {
spinnerKeycode.setSelection(AndroidLWJGLKeycode.getIndexByLWJGLKey(properties.keycode + 2));
}
@ -194,7 +194,7 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe
@Override
public void onClick(DialogInterface p1, int p2)
{
ControlsLayout layout = ((ControlsLayout) mHandleView.mView.getParent());
ControlLayout layout = ((ControlLayout) mHandleView.mView.getParent());
layout.removeControlButton(mHandleView.mView);
}
});

View File

@ -59,7 +59,7 @@ public abstract class HandleView extends View implements ViewPositionListener, V
private Runnable mActionPopupShower;
// Minimum touch target size for handles
private int mMinSize;
protected ControlView mView;
protected ControlButton mView;
// MOD: Addition. Save old size of parent
private int mDownWidth, mDownHeight;
@ -92,7 +92,7 @@ public abstract class HandleView extends View implements ViewPositionListener, V
return -1;
}
public HandleView(ControlView view) {
public HandleView(ControlButton view) {
super(view.getContext());
mView = view;

View File

@ -27,7 +27,7 @@ import net.kdt.pojavlaunch.customcontrols.*;
public class SelectionEndHandleView extends HandleView
{
public SelectionEndHandleView(ControlView view) {
public SelectionEndHandleView(ControlButton view) {
super(view);
}

View File

@ -86,7 +86,7 @@ public class AWTCanvasView extends TextureView implements TextureView.SurfaceTex
canvas.drawRGB(0, 0, 0);
if (!attached) {
attached = CallbackBridge.nativeAttachThreadToOther(true, false, MainActivity.isInputStackCall);
attached = CallbackBridge.nativeAttachThreadToOther(true, false, BaseMainActivity.isInputStackCall);
} else {
int[] rgbArray = JREUtils.renderAWTScreenFrame(/* canvas, mWidth, mHeight */);
mDrawing = rgbArray != null;

View File

@ -168,7 +168,7 @@ public class AndroidLWJGLKeycode {
return androidKeyNameArray;
}
public static void execKey(MainActivity mainActivity, KeyEvent keyEvent, int i, boolean isDown) {
public static void execKey(BaseMainActivity mainActivity, KeyEvent keyEvent, int i, boolean isDown) {
for (Map.Entry<Integer, Integer> perKey : androidToLwjglMap.entrySet()) {
if (i == 1 && (keyEvent.getSource() == InputDevice.SOURCE_MOUSE)) {
// Right mouse detection
@ -207,7 +207,7 @@ public class AndroidLWJGLKeycode {
}
}
public static void execKeyIndex(MainActivity mainActivity, int index) {
public static void execKeyIndex(BaseMainActivity mainActivity, int index) {
mainActivity.sendKeyPress(getKeyIndex(index));
}

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ public class CustomControlsActivity extends AppCompatActivity
{
private DrawerLayout drawerLayout;
private NavigationView navDrawer;
private ControlsLayout ctrlLayout;
private ControlLayout ctrlLayout;
private CustomControls mCtrl;
private SharedPreferences mPref;
@ -38,7 +38,7 @@ public class CustomControlsActivity extends AppCompatActivity
gson = new GsonBuilder().setPrettyPrinting().create();
ctrlLayout = (ControlsLayout) findViewById(R.id.customctrl_controllayout);
ctrlLayout = (ControlLayout) findViewById(R.id.customctrl_controllayout);
// Menu
drawerLayout = (DrawerLayout) findViewById(R.id.customctrl_drawerlayout);
@ -53,7 +53,7 @@ public class CustomControlsActivity extends AppCompatActivity
actionLoad();
break;
case R.id.menu_ctrl_add:
ctrlLayout.addControlButton(new ControlButton("New", LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN, 100, 100));
ctrlLayout.addControlButton(new ControlData("New", LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN, 100, 100));
break;
case R.id.menu_ctrl_selectdefault:
dialogSelectDefaultCtrl();

View File

@ -70,7 +70,7 @@ public class JavaGUILauncherActivity extends LoggableActivity {
}
public void forceClose(View v) {
MainActivity.dialogForceClose(this);
BaseMainActivity.dialogForceClose(this);
}
public void openLogOutput(View v) {

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,7 @@ public class PojavApplication extends Application
FatalErrorActivity.showError(PojavApplication.this, crashFile.getAbsolutePath(), storagePermAllowed, th);
// android.os.Process.killProcess(android.os.Process.myPid());
MainActivity.fullyExit();
BaseMainActivity.fullyExit();
}
});

View File

@ -52,11 +52,11 @@ public class PojavLoginActivity extends AppCompatActivity
super.onCreate(savedInstanceState); // false);
Tools.updateWindowSize(this);
ControlButton.pixelOf2dp = (int) Tools.dpToPx(this, 2);
ControlButton.pixelOf30dp = (int) Tools.dpToPx(this, 30);
ControlButton.pixelOf50dp = (int) Tools.dpToPx(this, 50);
ControlButton.pixelOf80dp = (int) Tools.dpToPx(this, 80);
ControlButton[] specialButtons = ControlButton.getSpecialButtons();
ControlData.pixelOf2dp = (int) Tools.dpToPx(this, 2);
ControlData.pixelOf30dp = (int) Tools.dpToPx(this, 30);
ControlData.pixelOf50dp = (int) Tools.dpToPx(this, 50);
ControlData.pixelOf80dp = (int) Tools.dpToPx(this, 80);
ControlData[] specialButtons = ControlData.getSpecialButtons();
specialButtons[0].name = getString(R.string.control_keyboard);
specialButtons[1].name = getString(R.string.control_toggle);
specialButtons[2].name = getString(R.string.control_primary);

View File

@ -98,7 +98,7 @@ public final class Tools
@Override
public void onClick(DialogInterface p1, int p2){
MainActivity.fullyExit();
BaseMainActivity.fullyExit();
}
});
dialog.show();
@ -202,7 +202,7 @@ public final class Tools
}
}
String[] argsFromJson = insertVariableArgument(
String[] argsFromJson = JSONUtils.insertJSONValueList(
splitAndFilterEmpty(
versionInfo.minecraftArguments == null ?
fromStringArray(minecraftArgs.toArray(new String[0])):
@ -241,22 +241,6 @@ public final class Tools
return strList.toArray(new String[0]);
}
private static String[] insertVariableArgument(String[] args, Map<String, String> keyValueMap) {
for (int i = 0; i < args.length; i++) {
String arg = args[i];
String argVar = null;
if (arg.startsWith("${") && arg.endsWith("}")) {
argVar = arg.substring(2, arg.length() - 1);
for (Map.Entry<String, String> keyValue : keyValueMap.entrySet()) {
if (argVar.equals(keyValue.getKey())) {
args[i] = keyValue.getValue();
}
}
}
}
return args;
}
public static String artifactToPath(String group, String artifact, String version) {
return group.replaceAll("\\.", "/") + "/" + artifact + "/" + version + "/" + artifact + "-" + version + ".jar";
}
@ -432,8 +416,8 @@ public final class Tools
public void onClick(DialogInterface p1, int p2)
{
if(exitIfOk) {
if (ctx instanceof MainActivity) {
MainActivity.fullyExit();
if (ctx instanceof BaseMainActivity) {
BaseMainActivity.fullyExit();
} else if (ctx instanceof Activity) {
((Activity) ctx).finish();
}
@ -456,8 +440,8 @@ public final class Tools
android.content.ClipboardManager mgr = (android.content.ClipboardManager) ctx.getSystemService(Context.CLIPBOARD_SERVICE);
mgr.setPrimaryClip(ClipData.newPlainText("error", Log.getStackTraceString(e)));
if(exitIfOk) {
if (ctx instanceof MainActivity) {
MainActivity.fullyExit();
if (ctx instanceof BaseMainActivity) {
BaseMainActivity.fullyExit();
} else {
((Activity) ctx).finish();
}

View File

@ -1,99 +1,145 @@
package net.kdt.pojavlaunch.customcontrols;
import java.util.*;
import android.content.*;
import android.view.*;
import android.view.View.*;
import android.widget.*;
import net.kdt.pojavlaunch.*;
import org.lwjgl.glfw.*;
import com.kdt.handleview.*;
import android.view.ViewGroup.*;
public class ControlButton implements Cloneable
public class ControlButton extends Button implements OnLongClickListener, OnTouchListener
{
public static int pixelOf2dp;
public static int pixelOf30dp;
public static int pixelOf50dp;
public static int pixelOf80dp;
public static final int SPECIALBTN_KEYBOARD = -1;
public static final int SPECIALBTN_TOGGLECTRL = -2;
public static final int SPECIALBTN_MOUSEPRI = -3;
public static final int SPECIALBTN_MOUSESEC = -4;
public static final int SPECIALBTN_VIRTUALMOUSE = -5;
private GestureDetector mGestureDetector;
private ControlData mProperties;
private SelectionEndHandleView mHandleView;
private static ControlButton[] SPECIAL_BUTTONS;
private static String[] SPECIAL_BUTTON_NAME_ARRAY;
public static ControlButton[] getSpecialButtons(){
if (SPECIAL_BUTTONS == null) {
SPECIAL_BUTTONS = new ControlButton[]{
new ControlButton("Keyboard", SPECIALBTN_KEYBOARD, pixelOf2dp * 3 + pixelOf80dp * 2, pixelOf2dp, false),
new ControlButton("GUI", SPECIALBTN_TOGGLECTRL, pixelOf2dp, CallbackBridge.windowHeight - pixelOf50dp * 2 + pixelOf2dp * 4),
new ControlButton("PRI", SPECIALBTN_MOUSEPRI, pixelOf2dp, CallbackBridge.windowHeight - pixelOf50dp * 4 + pixelOf2dp * 2),
new ControlButton("SEC", SPECIALBTN_MOUSESEC, pixelOf2dp * 3 + pixelOf50dp * 2, CallbackBridge.windowHeight - pixelOf50dp * 4 + pixelOf2dp * 2),
new ControlButton("Mouse", SPECIALBTN_VIRTUALMOUSE, CallbackBridge.windowWidth - pixelOf80dp, pixelOf2dp, false)
};
}
return SPECIAL_BUTTONS;
private boolean mCanModify = false;
private boolean mCanTriggerLongClick = true;
public ControlButton(Context ctx, ControlData properties) {
super(ctx);
mGestureDetector = new GestureDetector(ctx, new SingleTapConfirm());
setBackgroundResource(R.drawable.control_button);
setOnLongClickListener(this);
setOnTouchListener(this);
setProperties(properties);
mHandleView = new SelectionEndHandleView(this);
}
public HandleView getHandleView() {
return mHandleView;
}
public static String[] buildSpecialButtonArray() {
if (SPECIAL_BUTTON_NAME_ARRAY == null) {
List<String> nameList = new ArrayList<String>();
for (ControlButton btn : getSpecialButtons()) {
nameList.add(btn.name);
public ControlData getProperties() {
return mProperties;
}
public void setProperties(ControlData properties) {
setProperties(properties, true);
}
public void setProperties(ControlData properties, boolean changePos) {
mProperties = properties;
// com.android.internal.R.string.delete
// android.R.string.
setText(properties.name);
if (changePos) {
setTranslationX(moveX = properties.x);
setTranslationY(moveY = properties.y);
}
if (properties.specialButtonListener == null) {
// A non-special button or inside custom controls screen so skip listener
} else if (properties.specialButtonListener instanceof View.OnClickListener) {
setOnClickListener((View.OnClickListener) properties.specialButtonListener);
} else if (properties.specialButtonListener instanceof View.OnTouchListener) {
setOnTouchListener((View.OnTouchListener) properties.specialButtonListener);
} else {
throw new IllegalArgumentException("Field " + ControlData.class.getName() + ".specialButtonListener must be View.OnClickListener or View.OnTouchListener, but is " + properties.specialButtonListener.getClass().getName());
}
setLayoutParams(new FrameLayout.LayoutParams(properties.width, properties.height));
}
@Override
public void setLayoutParams(ViewGroup.LayoutParams params)
{
super.setLayoutParams(params);
mProperties.width = params.width;
mProperties.height = params.height;
}
@Override
public void setTranslationX(float x)
{
super.setTranslationX(x);
mProperties.x = x;
}
@Override
public void setTranslationY(float y) {
super.setTranslationY(y);
mProperties.y = y;
}
public void updateProperties() {
setProperties(mProperties);
}
@Override
public boolean onLongClick(View p1)
{
if (!mCanTriggerLongClick) return false;
if (mHandleView.isShowing()) {
mHandleView.hide();
} else {
if (getParent() != null) {
((ControlLayout) getParent()).hideAllHandleViews();
}
SPECIAL_BUTTON_NAME_ARRAY = nameList.toArray(new String[0]);
mHandleView.show();
}
return SPECIAL_BUTTON_NAME_ARRAY;
return true;
}
public String name;
public float x;
public float y;
public int width = pixelOf50dp;
public int height = pixelOf50dp;
public int keycode;
public int keyindex;
public boolean hidden;
public boolean holdCtrl;
public boolean holdAlt;
public boolean holdShift;
public /* View.OnClickListener */ Object specialButtonListener;
// public boolean hold
public ControlButton() {
this("", LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN, 0, 0);
private float moveX, moveY;
private float downX, downY;
@Override
public boolean onTouch(View view, MotionEvent event) {
if (!mCanModify) {
mCanTriggerLongClick = false;
return false;
}
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mCanTriggerLongClick = true;
downX = event.getX();
downY = event.getY();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_MOVE:
mCanTriggerLongClick = false;
moveX += event.getX() - downX;
moveY += event.getY() - downY;
setTranslationX(moveX);
setTranslationY(moveY);
break;
}
return false;
}
public ControlButton(String name, int keycode) {
this(name, keycode, 0, 0);
}
public ControlButton(String name, int keycode, float x, float y) {
this(name, keycode, x, y, pixelOf50dp, pixelOf50dp);
}
public ControlButton(android.content.Context ctx, int resId, int keycode, float x, float y, boolean isSquare) {
this(ctx.getResources().getString(resId), keycode, x, y, isSquare);
}
public ControlButton(String name, int keycode, float x, float y, boolean isSquare) {
this(name, keycode, x, y, isSquare ? pixelOf50dp : pixelOf80dp, isSquare ? pixelOf50dp : pixelOf30dp);
}
public ControlButton(String name, int keycode, float x, float y, int width, int height) {
this.name = name;
this.keycode = keycode;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public void execute(MainActivity act, boolean isDown) {
act.sendKeyPress(keycode, 0, isDown);
}
public ControlButton clone() {
return new ControlButton(name, keycode, x, y, width, height);
public void setModifiable(boolean z) {
mCanModify = z;
}
}

View File

@ -0,0 +1,98 @@
package net.kdt.pojavlaunch.customcontrols;
import java.util.*;
import net.kdt.pojavlaunch.*;
import org.lwjgl.glfw.*;
public class ControlData implements Cloneable
{
public static int pixelOf2dp;
public static int pixelOf30dp;
public static int pixelOf50dp;
public static int pixelOf80dp;
public static final int SPECIALBTN_KEYBOARD = -1;
public static final int SPECIALBTN_TOGGLECTRL = -2;
public static final int SPECIALBTN_MOUSEPRI = -3;
public static final int SPECIALBTN_MOUSESEC = -4;
public static final int SPECIALBTN_VIRTUALMOUSE = -5;
private static ControlData[] SPECIAL_BUTTONS;
private static String[] SPECIAL_BUTTON_NAME_ARRAY;
public static ControlData[] getSpecialButtons(){
if (SPECIAL_BUTTONS == null) {
SPECIAL_BUTTONS = new ControlData[]{
new DynamicControlData("Keyboard", SPECIALBTN_KEYBOARD, "${margin} * 3 + ${width} * 2", "${margin}", false),
new DynamicControlData("GUI", SPECIALBTN_TOGGLECTRL, "${margin}", "${screen_width} - ${width} * 2 + ${margin}"),
new DynamicControlData("PRI", SPECIALBTN_MOUSEPRI, "${margin}", "${screen_height} - ${height} * 4 + ${margin} * 2"),
new DynamicControlData("SEC", SPECIALBTN_MOUSESEC, "${margin} * 3 + ${width} * 2", "${screen_height} - ${height} * 4 + ${margin} * 2"),
new DynamicControlData("Mouse", SPECIALBTN_VIRTUALMOUSE, "${right}", "${margin}", false)
};
}
return SPECIAL_BUTTONS;
}
public static String[] buildSpecialButtonArray() {
if (SPECIAL_BUTTON_NAME_ARRAY == null) {
List<String> nameList = new ArrayList<String>();
for (ControlData btn : getSpecialButtons()) {
nameList.add(btn.name);
}
SPECIAL_BUTTON_NAME_ARRAY = nameList.toArray(new String[0]);
}
return SPECIAL_BUTTON_NAME_ARRAY;
}
public String name;
public float x;
public float y;
public int width = pixelOf50dp;
public int height = pixelOf50dp;
public int keycode;
public boolean hidden;
public boolean holdCtrl;
public boolean holdAlt;
public boolean holdShift;
public /* View.OnClickListener */ Object specialButtonListener;
// public boolean hold
public ControlData() {
this("", LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN, 0, 0);
}
public ControlData(String name, int keycode) {
this(name, keycode, 0, 0);
}
public ControlData(String name, int keycode, float x, float y) {
this(name, keycode, x, y, pixelOf50dp, pixelOf50dp);
}
public ControlData(android.content.Context ctx, int resId, int keycode, float x, float y, boolean isSquare) {
this(ctx.getResources().getString(resId), keycode, x, y, isSquare);
}
public ControlData(String name, int keycode, float x, float y, boolean isSquare) {
this(name, keycode, x, y, isSquare ? pixelOf50dp : pixelOf80dp, isSquare ? pixelOf50dp : pixelOf30dp);
}
public ControlData(String name, int keycode, float x, float y, int width, int height) {
this.name = name;
this.keycode = keycode;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public void execute(BaseMainActivity act, boolean isDown) {
act.sendKeyPress(keycode, 0, isDown);
}
public ControlData clone() {
return new ControlData(name, keycode, x, y, width, height);
}
}

View File

@ -7,25 +7,25 @@ import com.google.gson.*;
import net.kdt.pojavlaunch.*;
import android.support.v7.app.*;
public class ControlsLayout extends FrameLayout
public class ControlLayout extends FrameLayout
{
private boolean mCanModify;
private CustomControls mLayout;
private CustomControlsActivity mActivity;
private boolean mControlVisible = false;
public ControlsLayout(Context ctx) {
public ControlLayout(Context ctx) {
super(ctx);
}
public ControlsLayout(Context ctx, AttributeSet attrs) {
public ControlLayout(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
}
public void hideAllHandleViews() {
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
if (view instanceof ControlView) {
((ControlView) view).getHandleView().hide();
if (view instanceof ControlButton) {
((ControlButton) view).getHandleView().hide();
}
}
}
@ -41,27 +41,27 @@ public class ControlsLayout extends FrameLayout
public void loadLayout(CustomControls controlLayout) {
mLayout = controlLayout;
removeAllViews();
for (ControlButton button : controlLayout.button) {
for (ControlData button : controlLayout.button) {
addControlView(button);
}
setModified(false);
}
public void addControlButton(ControlButton controlButton) {
public void addControlButton(ControlData controlButton) {
mLayout.button.add(controlButton);
addControlView(controlButton);
}
private void addControlView(ControlButton controlButton) {
final ControlView view = new ControlView(getContext(), controlButton);
private void addControlView(ControlData controlButton) {
final ControlButton view = new ControlButton(getContext(), controlButton);
view.setModifiable(mCanModify);
addView(view);
setModified(true);
}
public void removeControlButton(ControlView controlButton) {
public void removeControlButton(ControlButton controlButton) {
mLayout.button.remove(controlButton.getProperties());
controlButton.setVisibility(View.GONE);
removeView(controlButton);
@ -84,8 +84,8 @@ public class ControlsLayout extends FrameLayout
mControlVisible = !mControlVisible;
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
if (view instanceof ControlView && ((ControlView) view).getProperties().keycode != ControlButton.SPECIALBTN_TOGGLECTRL) {
((ControlView) view).setVisibility(mControlVisible ? (((ControlView) view).getProperties().hidden ? View.INVISIBLE : View.VISIBLE) : View.GONE);
if (view instanceof ControlButton && ((ControlButton) view).getProperties().keycode != ControlData.SPECIALBTN_TOGGLECTRL) {
((ControlButton) view).setVisibility(mControlVisible ? (((ControlButton) view).getProperties().hidden ? View.INVISIBLE : View.VISIBLE) : View.GONE);
}
}
}
@ -94,8 +94,8 @@ public class ControlsLayout extends FrameLayout
mCanModify = z;
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
if (v instanceof ControlView) {
ControlView cv = ((ControlView) v);
if (v instanceof ControlButton) {
ControlButton cv = ((ControlButton) v);
cv.setModifiable(z);
// cv.setVisibility(cv.getProperties().hidden ? View.INVISIBLE : View.VISIBLE);
}

View File

@ -1,145 +0,0 @@
package net.kdt.pojavlaunch.customcontrols;
import android.content.*;
import android.view.*;
import android.view.View.*;
import android.widget.*;
import net.kdt.pojavlaunch.*;
import com.kdt.handleview.*;
import android.view.ViewGroup.*;
public class ControlView extends Button implements OnLongClickListener, OnTouchListener
{
private GestureDetector mGestureDetector;
private ControlButton mProperties;
private SelectionEndHandleView mHandleView;
private boolean mCanModify = false;
private boolean mCanTriggerLongClick = true;
public ControlView(Context ctx, ControlButton properties) {
super(ctx);
mGestureDetector = new GestureDetector(ctx, new SingleTapConfirm());
setBackgroundResource(R.drawable.control_button);
setOnLongClickListener(this);
setOnTouchListener(this);
setProperties(properties);
mHandleView = new SelectionEndHandleView(this);
}
public HandleView getHandleView() {
return mHandleView;
}
public ControlButton getProperties() {
return mProperties;
}
public void setProperties(ControlButton properties) {
setProperties(properties, true);
}
public void setProperties(ControlButton properties, boolean changePos) {
mProperties = properties;
// com.android.internal.R.string.delete
// android.R.string.
setText(properties.name);
if (changePos) {
setTranslationX(moveX = properties.x);
setTranslationY(moveY = properties.y);
}
if (properties.specialButtonListener == null) {
// A non-special button or inside custom controls screen so skip listener
} else if (properties.specialButtonListener instanceof View.OnClickListener) {
setOnClickListener((View.OnClickListener) properties.specialButtonListener);
} else if (properties.specialButtonListener instanceof View.OnTouchListener) {
setOnTouchListener((View.OnTouchListener) properties.specialButtonListener);
} else {
throw new IllegalArgumentException("Field " + ControlButton.class.getName() + ".specialButtonListener must be View.OnClickListener or View.OnTouchListener, but is " + properties.specialButtonListener.getClass().getName());
}
setLayoutParams(new FrameLayout.LayoutParams(properties.width, properties.height));
}
@Override
public void setLayoutParams(ViewGroup.LayoutParams params)
{
super.setLayoutParams(params);
mProperties.width = params.width;
mProperties.height = params.height;
}
@Override
public void setTranslationX(float x)
{
super.setTranslationX(x);
mProperties.x = x;
}
@Override
public void setTranslationY(float y) {
super.setTranslationY(y);
mProperties.y = y;
}
public void updateProperties() {
setProperties(mProperties);
}
@Override
public boolean onLongClick(View p1)
{
if (!mCanTriggerLongClick) return false;
if (mHandleView.isShowing()) {
mHandleView.hide();
} else {
if (getParent() != null) {
((ControlsLayout) getParent()).hideAllHandleViews();
}
mHandleView.show();
}
return true;
}
private float moveX, moveY;
private float downX, downY;
@Override
public boolean onTouch(View view, MotionEvent event) {
if (!mCanModify) {
mCanTriggerLongClick = false;
return false;
}
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mCanTriggerLongClick = true;
downX = event.getX();
downY = event.getY();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_MOVE:
mCanTriggerLongClick = false;
moveX += event.getX() - downX;
moveY += event.getY() - downY;
setTranslationX(moveX);
setTranslationY(moveY);
break;
}
return false;
}
public void setModifiable(boolean z) {
mCanModify = z;
}
}

View File

@ -7,37 +7,37 @@ import org.lwjgl.glfw.*;
public class CustomControls
{
public List<ControlButton> button;
public List<ControlData> button;
public CustomControls() {
this(new ArrayList<ControlButton>());
this(new ArrayList<ControlData>());
}
public CustomControls(List<ControlButton> button) {
public CustomControls(List<ControlData> button) {
this.button = button;
}
// Generate default control
public CustomControls(Context ctx) {
this();
this.button.add(ControlButton.getSpecialButtons()[0].clone()); // Keyboard
this.button.add(ControlButton.getSpecialButtons()[1].clone()); // GUI
this.button.add(ControlButton.getSpecialButtons()[2].clone()); // Primary Mouse button
this.button.add(ControlButton.getSpecialButtons()[3].clone()); // Secondary Mouse button
this.button.add(ControlButton.getSpecialButtons()[4].clone()); // Virtual mouse toggle
this.button.add(ControlData.getSpecialButtons()[0].clone()); // Keyboard
this.button.add(ControlData.getSpecialButtons()[1].clone()); // GUI
this.button.add(ControlData.getSpecialButtons()[2].clone()); // Primary Mouse button
this.button.add(ControlData.getSpecialButtons()[3].clone()); // Secondary Mouse button
this.button.add(ControlData.getSpecialButtons()[4].clone()); // Virtual mouse toggle
this.button.add(new ControlButton(ctx, R.string.control_debug, LWJGLGLFWKeycode.GLFW_KEY_F3, ControlButton.pixelOf2dp, ControlButton.pixelOf2dp, false));
this.button.add(new ControlButton(ctx, R.string.control_chat, LWJGLGLFWKeycode.GLFW_KEY_T, ControlButton.pixelOf2dp * 2 + ControlButton.pixelOf80dp, ControlButton.pixelOf2dp, false));
this.button.add(new ControlButton(ctx, R.string.control_listplayers, LWJGLGLFWKeycode.GLFW_KEY_TAB, ControlButton.pixelOf2dp * 4 + ControlButton.pixelOf80dp * 3, ControlButton.pixelOf2dp, false));
this.button.add(new ControlButton(ctx, R.string.control_thirdperson, LWJGLGLFWKeycode.GLFW_KEY_F5, ControlButton.pixelOf2dp, ControlButton.pixelOf30dp + ControlButton.pixelOf2dp, false));
this.button.add(new DynamicControlData(ctx, R.string.control_debug, LWJGLGLFWKeycode.GLFW_KEY_F3, "${margin}", "${margin}", false));
this.button.add(new DynamicControlData(ctx, R.string.control_chat, LWJGLGLFWKeycode.GLFW_KEY_T, "${margin} * 2 + ${width}", "${margin}", false));
this.button.add(new DynamicControlData(ctx, R.string.control_listplayers, LWJGLGLFWKeycode.GLFW_KEY_TAB, "${margin} * 4 + ${width} * 3", "${margin}", false));
this.button.add(new DynamicControlData(ctx, R.string.control_thirdperson, LWJGLGLFWKeycode.GLFW_KEY_F5, "${margin}", "${height} + ${margin}", false));
this.button.add(new ControlButton(ctx, R.string.control_up, LWJGLGLFWKeycode.GLFW_KEY_W, ControlButton.pixelOf2dp * 2 + ControlButton.pixelOf50dp, CallbackBridge.windowHeight - ControlButton.pixelOf2dp * 3 - ControlButton.pixelOf50dp * 3, true));
this.button.add(new ControlButton(ctx, R.string.control_left, LWJGLGLFWKeycode.GLFW_KEY_A, ControlButton.pixelOf2dp, CallbackBridge.windowHeight - ControlButton.pixelOf2dp * 2 - ControlButton.pixelOf50dp * 2, true));
this.button.add(new ControlButton(ctx, R.string.control_down, LWJGLGLFWKeycode.GLFW_KEY_S, ControlButton.pixelOf2dp * 2 + ControlButton.pixelOf50dp, CallbackBridge.windowHeight - ControlButton.pixelOf2dp - ControlButton.pixelOf50dp, true));
this.button.add(new ControlButton(ctx, R.string.control_right, LWJGLGLFWKeycode.GLFW_KEY_D, ControlButton.pixelOf2dp * 3 + ControlButton.pixelOf50dp * 2, CallbackBridge.windowHeight - ControlButton.pixelOf2dp * 2 - ControlButton.pixelOf50dp * 2, true));
this.button.add(new DynamicControlData(ctx, R.string.control_up, LWJGLGLFWKeycode.GLFW_KEY_W, "${margin} * 2 + ${width}", "${screen_height} - ${margin} * 3 - ${height} * 3", true));
this.button.add(new DynamicControlData(ctx, R.string.control_left, LWJGLGLFWKeycode.GLFW_KEY_A, "${margin}", "${screen_height} - ${margin} * 2 - ${height} * 2", true));
this.button.add(new DynamicControlData(ctx, R.string.control_down, LWJGLGLFWKeycode.GLFW_KEY_S, "${margin} * 2 + ${width}", "${screen_height} - ${margin} - ${width}", true));
this.button.add(new DynamicControlData(ctx, R.string.control_right, LWJGLGLFWKeycode.GLFW_KEY_D, "${margin} * 3 + ${width} * 2", "${screen_height} - ${margin} * 2 - ${width} * 2", true));
this.button.add(new ControlButton(ctx, R.string.control_inventory, LWJGLGLFWKeycode.GLFW_KEY_E, ControlButton.pixelOf2dp * 3 + ControlButton.pixelOf50dp * 2, CallbackBridge.windowHeight - ControlButton.pixelOf2dp - ControlButton.pixelOf50dp, true));
this.button.add(new ControlButton(ctx, R.string.control_shift, LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT, ControlButton.pixelOf2dp * 2 + ControlButton.pixelOf50dp, CallbackBridge.windowHeight - ControlButton.pixelOf2dp * 2 - ControlButton.pixelOf50dp * 2, true));
this.button.add(new ControlButton(ctx, R.string.control_jump, LWJGLGLFWKeycode.GLFW_KEY_SPACE, CallbackBridge.windowWidth - ControlButton.pixelOf2dp * 3 - ControlButton.pixelOf50dp * 2, CallbackBridge.windowHeight - ControlButton.pixelOf2dp * 2 - ControlButton.pixelOf50dp * 2, true));
this.button.add(new DynamicControlData(ctx, R.string.control_inventory, LWJGLGLFWKeycode.GLFW_KEY_E, "${margin} * 3 + ${width} * 2", "${screen_height} - ${margin} - ${width}", true));
this.button.add(new DynamicControlData(ctx, R.string.control_shift, LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT, "${margin} * 2 + ${width}", "${screen_height} - ${margin} * 2 - ${width} * 2", true));
this.button.add(new DynamicControlData(ctx, R.string.control_jump, LWJGLGLFWKeycode.GLFW_KEY_SPACE, "${screen_width} - ${margin} * 3 - ${width} * 2", "${screen_height} - ${margin} * 2 - ${width} * 2", true));
}

View File

@ -1,6 +0,0 @@
package net.kdt.pojavlaunch.customcontrols;
public class DynamicControlButton extends ControlButton
{
// TODO for ${value}
}

View File

@ -0,0 +1,77 @@
package net.kdt.pojavlaunch.customcontrols;
import android.util.*;
import java.util.*;
import net.kdt.pojavlaunch.*;
import net.kdt.pojavlaunch.utils.*;
import net.objecthunter.exp4j.*;
import org.lwjgl.glfw.*;
public class DynamicControlData extends ControlData {
/**
* The DynamicControlData is a ControlData that uses dynamic
* X and Y position, unlike the original one which uses fixed
* position, so it does not provide autoscale when a control
* is made on a small device, then import the control to a
* bigger device or vice versa.
*/
private String dynamicX, dynamicY;
public DynamicControlData() {
this("", LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN);
}
public DynamicControlData(String name, int keycode) {
this(name, keycode, "0", "0");
}
public DynamicControlData(String name, int keycode, String dynamicX, String dynamicY) {
this(name, keycode, dynamicX, dynamicY, pixelOf50dp, pixelOf50dp);
}
public DynamicControlData(android.content.Context ctx, int resId, int keycode, String dynamicX, String dynamicY, boolean isSquare) {
this(ctx.getResources().getString(resId), keycode, dynamicX, dynamicY, isSquare);
}
public DynamicControlData(String name, int keycode, String dynamicX, String dynamicY, boolean isSquare) {
this(name, keycode, dynamicX, dynamicY, isSquare ? pixelOf50dp : pixelOf80dp, isSquare ? pixelOf50dp : pixelOf30dp);
}
public DynamicControlData(String name, int keycode, String dynamicX, String dynamicY, int width, int height) {
super(name, keycode, 0, 0, width, height);
this.dynamicX = dynamicX;
this.dynamicY = dynamicY;
update();
}
public void update() {
// Values in the map below may be always changed
Map<String, String> keyValueMap = new ArrayMap<>();
keyValueMap.put("top", "0");
keyValueMap.put("left", "0");
keyValueMap.put("right", Integer.toString(CallbackBridge.windowWidth - width));
keyValueMap.put("bottom", Integer.toString(CallbackBridge.windowHeight - height));
keyValueMap.put("width", Integer.toString(width));
keyValueMap.put("height", Integer.toString(height));
keyValueMap.put("screen_width", Integer.toString(CallbackBridge.windowWidth));
keyValueMap.put("screen_height", Integer.toString(CallbackBridge.windowHeight));
keyValueMap.put("margin", Integer.toString(pixelOf2dp));
// Insert JSON values to variables
String insertedX = JSONUtils.insertSingleJSONValue(dynamicX, keyValueMap);
String insertedY = JSONUtils.insertSingleJSONValue(dynamicY, keyValueMap);
// Calculate and save, because the dynamic position contains some math equations
x = calculate(insertedX);
y = calculate(insertedY);
}
private static int calculate(String math) {
// try {
return (int) new ExpressionBuilder(math).build().evaluate();
/* } catch (e) {
} */
}
}

View File

@ -229,7 +229,7 @@ public class MinecraftDownloaderTask extends AsyncTask<String, String, Throwable
jvmArgs.add("-Xms128M");
jvmArgs.add("-Xmx1G");
*/
Intent mainIntent = new Intent(mActivity, MainActivity.class);
Intent mainIntent = new Intent(mActivity, BaseMainActivity.class);
// mainIntent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);

View File

@ -0,0 +1,20 @@
package net.kdt.pojavlaunch.utils;
import java.util.*;
public class JSONUtils {
public static String[] insertJSONValueList(String[] args, Map<String, String> keyValueMap) {
for (int i = 0; i < args.length; i++) {
args[i] = insertSingleJSONValue(args[i], keyValueMap);
}
return args;
}
public static String insertSingleJSONValue(String value, Map<String, String> keyValueMap) {
String valueInserted = value;
for (Map.Entry<String, String> keyValue : keyValueMap.entrySet()) {
valueInserted = valueInserted.replace("${" + keyValue.getKey() + "}", keyValue.getValue());
}
return valueInserted;
}
}

View File

@ -32,7 +32,7 @@ public class CallbackBridge {
private static boolean threadAttached;
public static void sendCursorPos(int x, int y) {
if (!threadAttached) {
threadAttached = CallbackBridge.nativeAttachThreadToOther(true, isMinecraft1p12, MainActivity.isInputStackCall);
threadAttached = CallbackBridge.nativeAttachThreadToOther(true, isMinecraft1p12, BaseMainActivity.isInputStackCall);
}
DEBUG_STRING.append("CursorPos=" + x + ", " + y + "\n");
@ -85,12 +85,12 @@ public class CallbackBridge {
public static String accessAndroidClipboard(int type, String copy) {
switch (type) {
case CLIPBOARD_COPY:
MainActivity.GLOBAL_CLIPBOARD.setPrimaryClip(ClipData.newPlainText("Copy", copy));
BaseMainActivity.GLOBAL_CLIPBOARD.setPrimaryClip(ClipData.newPlainText("Copy", copy));
return null;
case CLIPBOARD_PASTE:
if (MainActivity.GLOBAL_CLIPBOARD.hasPrimaryClip() && MainActivity.GLOBAL_CLIPBOARD.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
return MainActivity.GLOBAL_CLIPBOARD.getPrimaryClip().getItemAt(0).getText().toString();
if (BaseMainActivity.GLOBAL_CLIPBOARD.hasPrimaryClip() && BaseMainActivity.GLOBAL_CLIPBOARD.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
return BaseMainActivity.GLOBAL_CLIPBOARD.getPrimaryClip().getItemAt(0).getText().toString();
} else {
return "";
}