- [Custom controls] Trigger modified when move or resize
- Add option to scale buttons
This commit is contained in:
khanhduytran0 2020-11-23 14:04:53 +07:00
parent 4bff91e3f6
commit e91f847134
10 changed files with 354 additions and 538 deletions

View file

@ -13,14 +13,14 @@
* 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>
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>
• LWJGL: <a href="http://legacy.lwjgl.org/license.php.html">LWJGL 2's License</a>.<br><br>
* Notes:<br>
- This app is under development and will not be stable.<br>
- This app is not affiliated with Minecraft, Mojang or Microsoft.
- This app is not affiliated with Minecraft, Mojang or Microsoft.<br><br>
%s
* Translators can be found at https://crowdin.com/project/pojavlauncher

View file

@ -32,40 +32,40 @@ import net.kdt.pojavlaunch.customcontrols.*;
public abstract class HandleView extends View implements ViewPositionListener, View.OnLongClickListener
{
protected Drawable mDrawable;
protected Drawable mDrawableLtr;
protected Drawable mDrawableRtl;
private final PopupWindow mContainer;
// Position with respect to the parent TextView
private int mPositionX, mPositionY;
private boolean mIsDragging;
// Offset from touch position to mPosition
private float mTouchToWindowOffsetX, mTouchToWindowOffsetY;
protected int mHotspotX;
protected int mHorizontalGravity;
// Offsets the hotspot point up, so that cursor is not hidden by the finger when moving up
private float mTouchOffsetY;
// Where the touch position should be on the handle to ensure a maximum cursor visibility
private float mIdealVerticalOffset;
// Parent's (TextView) previous position in window
private int mLastParentX, mLastParentY;
// Transient action popup window for Paste and Replace actions
protected ActionPopupWindow mActionPopupWindow;
// Previous text character offset
private int mPreviousOffset = -1;
// Previous text character offset
private boolean mPositionHasChanged = true;
// Used to delay the appearance of the action popup window
private Runnable mActionPopupShower;
// Minimum touch target size for handles
private int mMinSize;
protected ControlButton mView;
protected Drawable mDrawable;
protected Drawable mDrawableLtr;
protected Drawable mDrawableRtl;
private final PopupWindow mContainer;
// Position with respect to the parent TextView
private int mPositionX, mPositionY;
private boolean mIsDragging;
// Offset from touch position to mPosition
private float mTouchToWindowOffsetX, mTouchToWindowOffsetY;
protected int mHotspotX;
protected int mHorizontalGravity;
// Offsets the hotspot point up, so that cursor is not hidden by the finger when moving up
private float mTouchOffsetY;
// Where the touch position should be on the handle to ensure a maximum cursor visibility
private float mIdealVerticalOffset;
// Parent's (TextView) previous position in window
private int mLastParentX, mLastParentY;
// Transient action popup window for Paste and Replace actions
protected ActionPopupWindow mActionPopupWindow;
// Previous text character offset
private int mPreviousOffset = -1;
// Previous text character offset
private boolean mPositionHasChanged = true;
// Used to delay the appearance of the action popup window
private Runnable mActionPopupShower;
// Minimum touch target size for handles
private int mMinSize;
protected ControlButton mView;
// MOD: Addition. Save old size of parent
private int mDownWidth, mDownHeight;
// int mWindowPosX, mWindowPosY;
// MOD: Addition. Save old size of parent
private int mDownWidth, mDownHeight;
// int mWindowPosX, mWindowPosY;
private PositionListener mPositionListener;
private PositionListener mPositionListener;
public PositionListener getPositionListener() {
if (mPositionListener == null) {
mPositionListener = new PositionListener(mView);
@ -73,260 +73,260 @@ public abstract class HandleView extends View implements ViewPositionListener, V
return mPositionListener;
}
public HandleView(ControlButton view) {
super(view.getContext());
public HandleView(ControlButton view) {
super(view.getContext());
mView = view;
mView = view;
mDownWidth = view.getLayoutParams().width;
mDownHeight = view.getLayoutParams().height;
mDownWidth = view.getLayoutParams().width;
mDownHeight = view.getLayoutParams().height;
mContainer = new PopupWindow(view.getContext(), null, android.R.attr.textSelectHandleWindowStyle);
mContainer.setSplitTouchEnabled(true);
mContainer.setClippingEnabled(false);
mContainer.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
mContainer.setContentView(this);
mContainer = new PopupWindow(view.getContext(), null, android.R.attr.textSelectHandleWindowStyle);
mContainer.setSplitTouchEnabled(true);
mContainer.setClippingEnabled(false);
mContainer.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
mContainer.setContentView(this);
mDrawableLtr = view.getContext().getDrawable(R.drawable.text_select_handle_left_material);
mDrawableRtl = view.getContext().getDrawable(R.drawable.text_select_handle_right_material);
mMinSize = view.getContext().getResources().getDimensionPixelSize(R.dimen.text_handle_min_size);
mDrawableLtr = view.getContext().getDrawable(R.drawable.text_select_handle_left_material);
mDrawableRtl = view.getContext().getDrawable(R.drawable.text_select_handle_right_material);
mMinSize = view.getContext().getResources().getDimensionPixelSize(R.dimen.text_handle_min_size);
setOnLongClickListener(this);
setOnLongClickListener(this);
updateDrawable();
updateDrawable();
final int handleHeight = getPreferredHeight();
mTouchOffsetY = -0.3f * handleHeight;
mIdealVerticalOffset = 0.7f * handleHeight;
}
final int handleHeight = getPreferredHeight();
mTouchOffsetY = -0.3f * handleHeight;
mIdealVerticalOffset = 0.7f * handleHeight;
}
protected void updateDrawable() {
// final int offset = getCurrentCursorOffset();
final boolean isRtlCharAtOffset = true; // mView.getLayout().isRtlCharAt(offset);
mDrawable = isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr;
mHotspotX = getHotspotX(mDrawable, isRtlCharAtOffset);
mHorizontalGravity = getHorizontalGravity(isRtlCharAtOffset);
}
protected void updateDrawable() {
// final int offset = getCurrentCursorOffset();
final boolean isRtlCharAtOffset = true; // mView.getLayout().isRtlCharAt(offset);
mDrawable = isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr;
mHotspotX = getHotspotX(mDrawable, isRtlCharAtOffset);
mHorizontalGravity = getHorizontalGravity(isRtlCharAtOffset);
}
protected abstract int getHotspotX(Drawable drawable, boolean isRtlRun);
protected abstract int getHorizontalGravity(boolean isRtlRun);
protected abstract int getHotspotX(Drawable drawable, boolean isRtlRun);
protected abstract int getHorizontalGravity(boolean isRtlRun);
// Touch-up filter: number of previous positions remembered
private static final int HISTORY_SIZE = 5;
private static final int TOUCH_UP_FILTER_DELAY_AFTER = 150;
private static final int TOUCH_UP_FILTER_DELAY_BEFORE = 350;
private final long[] mPreviousOffsetsTimes = new long[HISTORY_SIZE];
private final int[] mPreviousOffsets = new int[HISTORY_SIZE];
private int mPreviousOffsetIndex = 0;
private int mNumberPreviousOffsets = 0;
// Touch-up filter: number of previous positions remembered
private static final int HISTORY_SIZE = 5;
private static final int TOUCH_UP_FILTER_DELAY_AFTER = 150;
private static final int TOUCH_UP_FILTER_DELAY_BEFORE = 350;
private final long[] mPreviousOffsetsTimes = new long[HISTORY_SIZE];
private final int[] mPreviousOffsets = new int[HISTORY_SIZE];
private int mPreviousOffsetIndex = 0;
private int mNumberPreviousOffsets = 0;
private void startTouchUpFilter(int offset) {
mNumberPreviousOffsets = 0;
addPositionToTouchUpFilter(offset);
}
private void startTouchUpFilter(int offset) {
mNumberPreviousOffsets = 0;
addPositionToTouchUpFilter(offset);
}
private void addPositionToTouchUpFilter(int offset) {
mPreviousOffsetIndex = (mPreviousOffsetIndex + 1) % HISTORY_SIZE;
mPreviousOffsets[mPreviousOffsetIndex] = offset;
mPreviousOffsetsTimes[mPreviousOffsetIndex] = SystemClock.uptimeMillis();
mNumberPreviousOffsets++;
}
private void addPositionToTouchUpFilter(int offset) {
mPreviousOffsetIndex = (mPreviousOffsetIndex + 1) % HISTORY_SIZE;
mPreviousOffsets[mPreviousOffsetIndex] = offset;
mPreviousOffsetsTimes[mPreviousOffsetIndex] = SystemClock.uptimeMillis();
mNumberPreviousOffsets++;
}
private void filterOnTouchUp() {
final long now = SystemClock.uptimeMillis();
int i = 0;
int index = mPreviousOffsetIndex;
final int iMax = Math.min(mNumberPreviousOffsets, HISTORY_SIZE);
while (i < iMax && (now - mPreviousOffsetsTimes[index]) < TOUCH_UP_FILTER_DELAY_AFTER) {
i++;
index = (mPreviousOffsetIndex - i + HISTORY_SIZE) % HISTORY_SIZE;
}
private void filterOnTouchUp() {
final long now = SystemClock.uptimeMillis();
int i = 0;
int index = mPreviousOffsetIndex;
final int iMax = Math.min(mNumberPreviousOffsets, HISTORY_SIZE);
while (i < iMax && (now - mPreviousOffsetsTimes[index]) < TOUCH_UP_FILTER_DELAY_AFTER) {
i++;
index = (mPreviousOffsetIndex - i + HISTORY_SIZE) % HISTORY_SIZE;
}
if (i > 0 && i < iMax &&
(now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
positionAtCursorOffset(mPreviousOffsets[index], false);
}
}
if (i > 0 && i < iMax &&
(now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
positionAtCursorOffset(mPreviousOffsets[index], false);
}
}
public boolean offsetHasBeenChanged() {
return mNumberPreviousOffsets > 1;
}
public boolean offsetHasBeenChanged() {
return mNumberPreviousOffsets > 1;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getPreferredWidth(), getPreferredHeight());
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getPreferredWidth(), getPreferredHeight());
}
private int getPreferredWidth() {
return Math.max(mDrawable.getIntrinsicWidth(), mMinSize);
}
private int getPreferredWidth() {
return Math.max(mDrawable.getIntrinsicWidth(), mMinSize);
}
private int getPreferredHeight() {
return Math.max(mDrawable.getIntrinsicHeight(), mMinSize);
}
private int getPreferredHeight() {
return Math.max(mDrawable.getIntrinsicHeight(), mMinSize);
}
public void show() {
if (isShowing()) return;
public void show() {
if (isShowing()) return;
getPositionListener().addSubscriber(this, true /* local position may change */);
getPositionListener().addSubscriber(this, true /* local position may change */);
// Make sure the offset is always considered new, even when focusing at same position
mPreviousOffset = -1;
positionAtCursorOffset(getCurrentCursorOffset(), false);
// Make sure the offset is always considered new, even when focusing at same position
mPreviousOffset = -1;
positionAtCursorOffset(getCurrentCursorOffset(), false);
hideActionPopupWindow();
}
hideActionPopupWindow();
}
protected void dismiss() {
mIsDragging = false;
mContainer.dismiss();
onDetached();
}
protected void dismiss() {
mIsDragging = false;
mContainer.dismiss();
onDetached();
}
public void hide() {
dismiss();
public void hide() {
dismiss();
getPositionListener().removeSubscriber(this);
}
getPositionListener().removeSubscriber(this);
}
void showActionPopupWindow(int delay) {
if (mActionPopupWindow == null) {
mActionPopupWindow = new ActionPopupWindow(this);
}
if (mActionPopupShower == null) {
mActionPopupShower = new Runnable() {
public void run() {
mActionPopupWindow.show();
}
};
} else {
mView.removeCallbacks(mActionPopupShower);
}
mView.postDelayed(mActionPopupShower, delay);
}
void showActionPopupWindow(int delay) {
if (mActionPopupWindow == null) {
mActionPopupWindow = new ActionPopupWindow(this);
}
if (mActionPopupShower == null) {
mActionPopupShower = new Runnable() {
public void run() {
mActionPopupWindow.show();
}
};
} else {
mView.removeCallbacks(mActionPopupShower);
}
mView.postDelayed(mActionPopupShower, delay);
}
protected void hideActionPopupWindow() {
if (mActionPopupShower != null) {
mView.removeCallbacks(mActionPopupShower);
}
if (mActionPopupWindow != null) {
mActionPopupWindow.hide();
}
}
protected void hideActionPopupWindow() {
if (mActionPopupShower != null) {
mView.removeCallbacks(mActionPopupShower);
}
if (mActionPopupWindow != null) {
mActionPopupWindow.hide();
}
}
public boolean isShowing() {
return mContainer.isShowing();
}
public boolean isShowing() {
return mContainer.isShowing();
}
private boolean isVisible() {
// Always show a dragging handle.
if (mIsDragging) {
return true;
}
private boolean isVisible() {
// Always show a dragging handle.
if (mIsDragging) {
return true;
}
return mView.getVisibility() == View.VISIBLE;
}
return mView.getVisibility() == View.VISIBLE;
}
public abstract int getCurrentCursorOffset();
public abstract int getCurrentCursorOffset();
protected abstract void updateSelection(int offset);
protected abstract void updateSelection(int offset);
public abstract void updatePosition(float x, float y);
public abstract void updatePosition(float x, float y);
protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
mPositionX = (int) (mView.getWidth() / 1.1);
mPositionY = mView.getHeight();
protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
mPositionX = (int) (mView.getWidth() / 1.1);
mPositionY = mView.getHeight();
mPositionHasChanged = true;
}
mPositionHasChanged = true;
}
public void updatePosition(int parentPositionX, int parentPositionY,
boolean parentPositionChanged, boolean parentScrolled) {
positionAtCursorOffset(getCurrentCursorOffset(), parentScrolled);
if (parentPositionChanged || mPositionHasChanged) {
if (mIsDragging) {
// Update touchToWindow offset in case of parent scrolling while dragging
if (parentPositionX != mLastParentX || parentPositionY != mLastParentY) {
mTouchToWindowOffsetX += parentPositionX - mLastParentX;
mTouchToWindowOffsetY += parentPositionY - mLastParentY;
mLastParentX = parentPositionX;
mLastParentY = parentPositionY;
}
public void updatePosition(int parentPositionX, int parentPositionY,
boolean parentPositionChanged, boolean parentScrolled) {
positionAtCursorOffset(getCurrentCursorOffset(), parentScrolled);
if (parentPositionChanged || mPositionHasChanged) {
if (mIsDragging) {
// Update touchToWindow offset in case of parent scrolling while dragging
if (parentPositionX != mLastParentX || parentPositionY != mLastParentY) {
mTouchToWindowOffsetX += parentPositionX - mLastParentX;
mTouchToWindowOffsetY += parentPositionY - mLastParentY;
mLastParentX = parentPositionX;
mLastParentY = parentPositionY;
}
onHandleMoved();
}
onHandleMoved();
}
if (isVisible()) {
final int positionX = parentPositionX + mPositionX;
final int positionY = parentPositionY + mPositionY;
/*
mWindowPosX = positionX;
mWindowPosY = positionY;
*/
if (isShowing()) {
mContainer.update(positionX, positionY, -1, -1);
} else {
mContainer.showAtLocation(mView, Gravity.NO_GRAVITY,
positionX, positionY);
}
} else {
if (isShowing()) {
dismiss();
}
}
if (isVisible()) {
final int positionX = parentPositionX + mPositionX;
final int positionY = parentPositionY + mPositionY;
/*
mWindowPosX = positionX;
mWindowPosY = positionY;
*/
if (isShowing()) {
mContainer.update(positionX, positionY, -1, -1);
} else {
mContainer.showAtLocation(mView, Gravity.NO_GRAVITY,
positionX, positionY);
}
} else {
if (isShowing()) {
dismiss();
}
}
mPositionHasChanged = false;
}
}
mPositionHasChanged = false;
}
}
@Override
protected void onDraw(Canvas c) {
final int drawWidth = mDrawable.getIntrinsicWidth();
final int left = getHorizontalOffset();
@Override
protected void onDraw(Canvas c) {
final int drawWidth = mDrawable.getIntrinsicWidth();
final int left = getHorizontalOffset();
mDrawable.setBounds(left, 0, left + drawWidth, mDrawable.getIntrinsicHeight());
mDrawable.draw(c);
}
mDrawable.setBounds(left, 0, left + drawWidth, mDrawable.getIntrinsicHeight());
mDrawable.draw(c);
}
private int getHorizontalOffset() {
final int width = getPreferredWidth();
final int drawWidth = mDrawable.getIntrinsicWidth();
final int left;
switch (mHorizontalGravity) {
case Gravity.LEFT:
left = 0;
break;
default:
case Gravity.CENTER:
left = (width - drawWidth) / 2;
break;
case Gravity.RIGHT:
left = width - drawWidth;
break;
}
return left;
}
private int getHorizontalOffset() {
final int width = getPreferredWidth();
final int drawWidth = mDrawable.getIntrinsicWidth();
final int left;
switch (mHorizontalGravity) {
case Gravity.LEFT:
left = 0;
break;
default:
case Gravity.CENTER:
left = (width - drawWidth) / 2;
break;
case Gravity.RIGHT:
left = width - drawWidth;
break;
}
return left;
}
protected int getCursorOffset() {
return 0;
}
protected int getCursorOffset() {
return 0;
}
// Addition
@Override
public boolean onLongClick(View view) {
showActionPopupWindow(0);
return true;
}
// Addition
@Override
public boolean onLongClick(View view) {
showActionPopupWindow(0);
return true;
}
// Addition
private float mDownX, mDownY;
// Addition
private float mDownX, mDownY;
@Override
public boolean onTouchEvent(MotionEvent ev) {
ViewGroup.LayoutParams params = mView.getLayoutParams();
@Override
public boolean onTouchEvent(MotionEvent ev) {
ViewGroup.LayoutParams params = mView.getLayoutParams();
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
startTouchUpFilter(getCurrentCursorOffset());
mTouchToWindowOffsetX = ev.getRawX() - mPositionX;
mTouchToWindowOffsetY = ev.getRawY() - mPositionY;
@ -336,16 +336,16 @@ public abstract class HandleView extends View implements ViewPositionListener, V
mLastParentY = positionListener.getPositionY();
mIsDragging = true;
// MOD: Addition
mDownX = ev.getRawX();
mDownY = ev.getRawY();
mDownWidth = params.width;
mDownHeight = params.height;
// MOD: Addition
mDownX = ev.getRawX();
mDownY = ev.getRawY();
mDownWidth = params.width;
mDownHeight = params.height;
break;
}
case MotionEvent.ACTION_MOVE: {
case MotionEvent.ACTION_MOVE: {
final float rawX = ev.getRawX();
final float rawY = ev.getRawY();
@ -365,41 +365,41 @@ public abstract class HandleView extends View implements ViewPositionListener, V
final float newPosX = rawX - mTouchToWindowOffsetX + mHotspotX;
final float newPosY = rawY - mTouchToWindowOffsetY + mTouchOffsetY;
int newWidth = (int) (mDownWidth + (rawX - mDownX));
int newHeight = (int) (mDownHeight + (rawY - mDownY));
int newWidth = (int) (mDownWidth + (rawX - mDownX));
int newHeight = (int) (mDownHeight + (rawY - mDownY));
if (newWidth > 49) params.width = newWidth;
if (newHeight > 49) params.height = newHeight;
params.width = Math.max(50, newWidth);
params.height = Math.max(50, newHeight);
mView.setLayoutParams(params);
mView.setLayoutParams(params);
updatePosition(newPosX, newPosY);
// break;
return true;
return true;
}
case MotionEvent.ACTION_UP:
filterOnTouchUp();
mIsDragging = false;
break;
case MotionEvent.ACTION_UP:
filterOnTouchUp();
mIsDragging = false;
break;
case MotionEvent.ACTION_CANCEL:
mIsDragging = false;
break;
}
return false; // super.onTouchEvent(ev);
}
case MotionEvent.ACTION_CANCEL:
mIsDragging = false;
break;
}
return false; // super.onTouchEvent(ev);
}
public boolean isDragging() {
return mIsDragging;
}
public boolean isDragging() {
return mIsDragging;
}
void onHandleMoved() {
hideActionPopupWindow();
}
void onHandleMoved() {
hideActionPopupWindow();
}
public void onDetached() {
hideActionPopupWindow();
}
public void onDetached() {
hideActionPopupWindow();
}
}

View file

@ -27,51 +27,51 @@ import net.kdt.pojavlaunch.customcontrols.*;
public class SelectionEndHandleView extends HandleView
{
public SelectionEndHandleView(ControlButton view) {
super(view);
}
public SelectionEndHandleView(ControlButton view) {
super(view);
}
@Override
protected int getHotspotX(Drawable drawable, boolean isRtlRun) {
if (isRtlRun) {
return (drawable.getIntrinsicWidth() * 3) / 4;
} else {
return drawable.getIntrinsicWidth() / 4;
}
}
@Override
protected int getHotspotX(Drawable drawable, boolean isRtlRun) {
if (isRtlRun) {
return (drawable.getIntrinsicWidth() * 3) / 4;
} else {
return drawable.getIntrinsicWidth() / 4;
}
}
@Override
protected int getHorizontalGravity(boolean isRtlRun) {
return isRtlRun ? Gravity.LEFT : Gravity.RIGHT;
}
@Override
protected int getHorizontalGravity(boolean isRtlRun) {
return isRtlRun ? Gravity.LEFT : Gravity.RIGHT;
}
@Override
public int getCurrentCursorOffset() {
return 0; // mView.getSelectionEnd();
}
@Override
public int getCurrentCursorOffset() {
return 0; // mView.getSelectionEnd();
}
@Override
public void show() {
super.show();
@Override
public void show() {
super.show();
showActionPopupWindow(0);
}
showActionPopupWindow(0);
}
@Override
public void updateSelection(int offset) {
// Selection.setSelection((Spannable) mView.getText(), mView.getSelectionStart(), offset);
updateDrawable();
}
@Override
public void updateSelection(int offset) {
// Selection.setSelection((Spannable) mView.getText(), mView.getSelectionStart(), offset);
updateDrawable();
}
@Override
public void updatePosition(float x, float y) {
// updatePosition((int) x, (int) y, false, false);
positionAtCursorOffset(0, false);
}
/*
public void setActionPopupWindow(ActionPopupWindow actionPopupWindow) {
mActionPopupWindow = actionPopupWindow;
}
*/
@Override
public void updatePosition(float x, float y) {
// updatePosition((int) x, (int) y, false, false);
positionAtCursorOffset(0, false);
}
/*
public void setActionPopupWindow(ActionPopupWindow actionPopupWindow) {
mActionPopupWindow = actionPopupWindow;
}
*/
}

View file

@ -86,7 +86,7 @@ public abstract class BaseLauncherActivity extends BaseActivity {
aboutB.setMessage(Html.fromHtml(String.format(Tools.read(getAssets().open("about_en.txt")),
Tools.APP_NAME,
Tools.usingVerName,
"3.2.3", getString(R.string.mcl_about_translated_by))
"3.2.3")
));
} catch (Exception e) {
throw new RuntimeException(e);

View file

@ -129,8 +129,6 @@ public class MainActivity extends BaseMainActivity implements OnClickListener, O
private Button findButton(int id) {
Button button = (Button) findViewById(id);
button.setWidth((int) (button.getWidth() * Tools.currentDisplayMetrics.scaledDensity));
button.setHeight((int) (button.getHeight() * LauncherPreferences.PREF_BUTTONSIZE));
button.setOnTouchListener(this);
button.setFocusable(false);
button.setFocusableInTouchMode(false);

View file

@ -25,11 +25,11 @@ public class ControlButton extends Button implements OnLongClickListener, OnTouc
mGestureDetector = new GestureDetector(ctx, new SingleTapConfirm());
setBackgroundResource(R.drawable.control_button);
setOnLongClickListener(this);
setOnTouchListener(this);
setProperties(properties);
setModified(false);
mHandleView = new SelectionEndHandleView(this);
}
@ -80,24 +80,29 @@ public class ControlButton extends Button implements OnLongClickListener, OnTouc
}
@Override
public void setLayoutParams(ViewGroup.LayoutParams params)
{
public void setLayoutParams(ViewGroup.LayoutParams params) {
super.setLayoutParams(params);
mProperties.width = params.width;
mProperties.height = params.height;
setModified(true);
}
@Override
public void setTranslationX(float x) {
super.setTranslationX(x);
mProperties.x = x;
setModified(true);
}
@Override
public void setTranslationY(float y) {
super.setTranslationY(y);
mProperties.y = y;
setModified(true);
}
public void updateProperties() {
@ -180,4 +185,10 @@ public class ControlButton extends Button implements OnLongClickListener, OnTouc
public void setModifiable(boolean z) {
mModifiable = z;
}
private void setModified(boolean modified) {
if (getParent() != null) {
((ControlLayout) getParent()).setModified(modified);
}
}
}

View file

@ -108,7 +108,7 @@ public class ControlLayout extends FrameLayout
}
}
private void setModified(boolean z) {
protected void setModified(boolean z) {
if (mActivity != null) mActivity.isModified = z;
}
}

View file

@ -99,6 +99,8 @@
<string name="mcl_setting_subtitle_freeform">Launch Minecraft in floating window. Requires Android 7.0+</string>
<string name="mcl_setting_title_longpresstrigger">How long will trigger after long press</string>
<string name="mcl_setting_subtitle_longpresstrigger">Change trigger time for long press in destroy block and drop item.</string>
<string name="mcl_setting_title_buttonscale">Control buttons scaling</string>
<string name="mcl_setting_subtitle_buttonscale">Upscale them if buttons are too small.</string>
<string name="mcl_setting_title_controlsize">Set control buttons size</string>
<string name="mcl_setting_title_javaargs">JVM Launch arguments</string>
<string name="mcl_setting_subtitle_javaargs">Be careful, this may make game crash if modified without knowledge.</string>
@ -109,9 +111,6 @@
<string name="mcl_setting_veroption_oldalpha">Old-alpha</string>
<string name="mcl_setting_veroption_oldbeta">Old-beta</string>
<!-- Credit translators in this language, append your name there -->
<string name="mcl_about_translated_by">"Translated by: "</string>
<string name="mcl_version_clone">Clone</string>
<!-- Global strings -->
@ -148,6 +147,7 @@
" - This app is not affiliated with Minecraft, Mojang or Microsoft.\n")
</string>
-->
<!-- MainActivity: strings -->
<string name="mcn_exit_title">Application/Game exited with code %d</string>
<string name="mcn_exit_call">Exit</string>

View file

@ -15,6 +15,11 @@
android:title="@string/mcl_setting_title_longpresstrigger"
android:summary="@string/mcl_setting_subtitle_longpresstrigger" />
<android.support.v7.preference.SeekBarPreference
android:key="buttonscale"
android:title="@string/mcl_setting_title_buttonscale"
android:summary="@string/mcl_setting_subtitle_buttonscale" />
<android.support.v7.preference.SwitchPreferenceCompat
android:defaultValue="false"
android:key="freeform"

View file

@ -1,198 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- App name part -->
<string name="app_name">PojavLauncher (Minecraft: Java Edition for Android)</string>
<string name="app_short_name">PojavLauncher</string>
<string name="app_motd">Chạy Minecraft: Java Edition trên thiết bị của bạn!</string>
<!-- Action bar part -->
<string name="actionbar_help">GIÚP ĐỠ</string>
<!-- Languages list part -->
<string name="language_name">TIẾNG VIỆT - VN</string>
<!-- Logging output -->
<string name="log_title">Log output</string>
<!-- Login strings -->
<string name="login_online_username_hint">Email hoặc tên người dùng</string>
<string name="login_online_username_question">(Which do I use?)</string>
<string name="login_online_password_hint">Mật khẩu</string>
<string name="login_online_password_question">Quên mật khẩu?</string>
<string name="login_online_remember">Nhớ tài khoản?</string>
<string name="login_online_login_label">Đăng nhập</string>
<string name="login_online_create_account">(Tạo tài khoản mới?)</string>
<string name="login_offline_switch">Tài khoản Offline?</string>
<string name="login_offline_warning_1">Bạn đang đăng nhập bằng tài khoản Offline, nhưng nếu không lưu, dữ liệu của bạn có thể bị mất trong thế giới/multiplayer/server.</string>
<string name="login_error_short_username">Tên người dùng phải có ít nhất 3 kí tự</string>
<string name="login_error_exist_username">Tên người dùng này đã tồn tại</string>
<string name="login_select_account">Chọn tài khoản</string>
<!-- OpenJDK -->
<string name="openjdk_install_download_main">Đang tải OpenJDK v3</string>
<string name="openjdk_install_unpack_main">Đang giải nén OpenJDK v3</string>
<string name="openjdk_install_download_patch">Một bản vá hiện có. Đang tải bản vá OpenJDK v3.</string>
<string name="openjdk_install_unpack_patch">Một bản vá hiện có. Đang giải nén bản vá OpenJDK v3.</string>
<!-- Hint -->
<string name="hint_select_account">Nhấn vào tài khoản muốn chọn. Nhấn giữ vào tài khoản muốn xóa.</string>
<string name="hint_control_mapping">Vuốt từ phải qua trái để mở menu\n◀</string>
<!-- Warning -->
<string name="warning_title">Cảnh báo</string>
<string name="warning_msg">Bản v3 này đang trong giai đoạn thử nghiệm và có thể không hoạt động. Nếu không thực sự muốn test thì hãy xuống v2!</string>
<string name="warning_noshowagain">Không hiện nữa</string>
<string name="warning_action_tryanyway">Vẫn thử</string>
<string name="warning_action_exit">Thoát</string>
<string name="warning_remove_account">Tài khoản này sẽ bị xóa!</string>
<!-- AlertDialog title -->
<string name="alerttitle_selectkeymap">Chọn một điều khiển json</string>
<string name="alerttitle_installmod">Chọn một trình cài đặt mod</string>
<!-- Error messages -->
<string name="error_checklog">Lỗi! Please check the log below: %s</string>
<string name="error_no_version">Không có phiên bản!</string>
<string name="error_load_version">Không thể tải phiên bản %s</string>
<string name="error_convert_lib">Không thể chuyển đổi thư viện %s</string>
<string name="error_convert_client">Không thể chuyển đổi Minecraft %s</string>
<string name="error_show_more">Nhiều hơn</string>
<string name="error_show_less">Ít hơn</string>
<!-- Toast messages -->
<string name="toast_permission_denied">Quyền truy cập đọc/viết vào bộ nhớ là cần thiết!</string>
<string name="toast_login_error">Something went wrong after login. Please feedback to the developer.\nError: %s</string>
<string name="toast_optifine_success">Install successful</string>
<!--
<string name="toast_3">Exit</string>
-->
<!-- MCLauncherActivity: Tabs -->
<string name="mcl_tab_news">Tin tức Launcher</string>
<string name="mcl_tab_console">Development console</string>
<string name="mcl_tab_crash">Nhật kí lỗi</string>
<!-- MCLauncherActivity: Strings -->
<string name="mcl_version_msg">Ready to play Minecraft %s</string>
<string name="mcl_launch_cleancache">Cleaning cache files</string>
<string name="mcl_launch_downloading">Downloading %s</string>
<string name="mcl_launch_download_lib">Downloading library %s</string>
<string name="mcl_launch_download_client">Downloading Minecraft %s</string>
<string name="mcl_launch_convert_lib">Converting library %s</string>
<string name="mcl_launch_convert_client">Converting Minecraft %s</string>
<string name="mcl_launch_patch_client">Patching Minecraft %s</string>
<string name="mcl_launch_download_assets">Preparing to download resources</string>
<string name="mcl_options">Options</string>
<string name="mcl_option_modmgr">Mod manager (no function)</string>
<string name="mcl_option_installmod">Install mod (Forge, OptiFine, LabyMod,...)</string>
<string name="mcl_option_checkupdate">Check for update</string>
<string name="mcl_option_customcontrol">Custom controls</string>
<string name="mcl_option_settings">Settings</string>
<string name="mcl_option_about">About</string>
<string name="mcl_setting_title_setmaxdxref">Set max DX references</string>
<string name="mcl_setting_subtitle_setmaxdxref">Increase If an error happend while converting: Too many ... references. You may try multi-dex option. Recommended: 4096 or 8192.</string>
<string name="mcl_setting_title_freeform">Launch Minecraft in Freeform mode</string>
<string name="mcl_setting_subtitle_freeform">Launch Minecraft in floating window. Requires Android 7.0+</string>
<string name="mcl_setting_title_longpresstrigger">How long will trigger after long press</string>
<string name="mcl_setting_subtitle_longpresstrigger">Change trigger time for long press in destroy block and drop item.</string>
<string name="mcl_setting_title_controlsize">Set control buttons size</string>
<string name="mcl_setting_title_runasroot">Run Minecraft as root</string>
<string name="mcl_setting_subtitle_runasroot">Useful for fixing Bad system call or Permission Denied in some devices and VMOS.</string>
<string name="mcl_setting_category_general">General settings</string>
<string name="mcl_setting_category_veroption">Version type will be in version list</string>
<string name="mcl_setting_veroption_release">Release</string>
<string name="mcl_setting_veroption_snapshot">Snapshot</string>
<string name="mcl_setting_veroption_oldalpha">Old-alpha</string>
<string name="mcl_setting_veroption_oldbeta">Old-beta</string>
<string name="mcl_version_clone">Clone</string>
<!-- Global strings -->
<string name="global_add">Add</string>
<string name="global_edit">Edit</string>
<string name="global_error">Error</string>
<string name="global_load">Load</string>
<string name="global_name">Name</string>
<string name="global_remove">Remove</string>
<string name="global_save">Save</string>
<string name="global_error_field_empty">This field can\'t be empty</string>
<string name="global_play">Play</string>
<string name="global_skip">Skip</string>
<!--
<string name="mcl_about">
%1$s BETA (Minecraft Java launcher for Android), version " + PathTools.usingVerName + "\n" +
" - by Khanh Duy Tran (based from \"Boardwalk\" app)\n" +
//"© 2019 Khanh Duy Tran\n" +
"Using libraries:\n" +
" • LWJGL " + org.lwjgl.Sys.getVersion() + "\n" +
//" • Boardwalk memory manager (not used now).\n" +
" • gl4es: OpenGL for OpenGL ES devices by lunixbochs and ptitSeb.\n" +
" • dx: tool to convert.\n" +
" • Java AWT Implementation includes:\n" +
" - Boardwalk's makeshift.\n" +
" - Apache Harmony AWT Framework.\n" +
" - OpenJDK 7 codes implementation.\n" +
" - Developer code implement (copy text, open browser,...)\n" +
"\n" +
"* Notes:\n" +
" - This app is currently BETA, it will not be stable.\n" +
//"* This app will unstable on Android 7.0 or higher devices.\n" +
" - This app only use LWJGL2 and don't have a JRE8 desugar, so doesn't support 1.13 or higher versions.\n" +
" - This app is not affiliated with Minecraft, Mojang or Microsoft.\n")
</string>
-->
<!-- MainActivity: strings -->
<string name="mcn_exit_title">Java Application exited</string>
<string name="mcn_exit_call">Exit</string>
<string name="mcn_exit_crash">Java Application exited with error code %d! This may caused by a corrupted OpenJDK install, an invalid Java App, a Minecraft crash,... See Log output for more details.</string>
<string name="mcn_exit_errcrash">Unable to locate crash!</string>
<string name="mcn_exit_confirm">Are you sure want to force close?</string>
<!-- MainActivity: Control buttons -->
<string name="controls">Controls</string>
<string name="control_toggle">GUI</string>
<string name="control_keyboard">Keyboard</string>
<string name="control_chat">Chat</string>
<string name="control_debug">Debug</string>
<string name="control_zoom">Zoom (C)</string>
<string name="control_primary">Pri</string>
<string name="control_secondary">Sec</string>
<string name="control_shift"></string>
<string name="control_inventory">Inv</string>
<string name="control_up"></string>
<string name="control_left"></string>
<string name="control_right"></string>
<string name="control_down"></string>
<string name="control_jump"></string>
<string name="control_thirdperson">3rd</string>
<string name="control_listplayers">Tab</string>
<string name="control_mouseoff">Mouse: off</string>
<string name="control_mouseon">Mouse: on </string>
<!-- MainActivity: Menu advanced controls -->
<string name="control_forceclose">Force close</string>
<string name="control_viewout">Log output</string>
<string name="control_adebug">PointerCapture Debug</string>
<string name="control_customkey">Send custom keycode</string>
<string name="control_more3"></string>
<string name="control_more4"></string>
<string name="customctrl_error">Unable to load control file %s</string>
<string name="customctrl_keyname">Keycode</string>
<string name="customctrl_specialkey">Special Key</string>
<string name="customctrl_hidden">Hidden</string>
<string name="customctrl_addbutton">Add button</string>
<string name="customctrl_title_selectctrl">Select default Control json</string>
<string name="customctrl_selectdefault">Select default Control json</string>
<!-- Update part (unused now) -->
<string name="update_console">Update console</string>
</resources>