removed the ResizeHandle class and created a more universal and consistent SwipeableSoftKey
This commit is contained in:
parent
3f76f40058
commit
aa9bcfd837
5 changed files with 185 additions and 119 deletions
|
|
@ -67,6 +67,10 @@ public class ResizableMainView extends MainView implements View.OnAttachStateCha
|
|||
|
||||
|
||||
public void onAlign(float deltaX) {
|
||||
if (!(main instanceof MainLayoutNumpad)) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean right = deltaX > 0;
|
||||
SettingsStore settings = tt9.getSettings();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,85 +0,0 @@
|
|||
package io.github.sspanak.tt9.ui.main.keys;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.ui.main.ResizableMainView;
|
||||
|
||||
public class ResizeHandle implements View.OnTouchListener {
|
||||
@NonNull private final Runnable onClick;
|
||||
private ResizableMainView mainView;
|
||||
|
||||
private final float ALIGN_THRESHOLD;
|
||||
private final float RESIZE_THRESHOLD;
|
||||
|
||||
private boolean aligning;
|
||||
private boolean resizing;
|
||||
private float startX;
|
||||
private float startY;
|
||||
|
||||
|
||||
ResizeHandle(@NonNull Context context, @NonNull Runnable onClick) {
|
||||
ALIGN_THRESHOLD = context.getResources().getDimensionPixelSize(R.dimen.numpad_key_height) * 0.75f;
|
||||
RESIZE_THRESHOLD = context.getResources().getDimensionPixelSize(R.dimen.numpad_key_height) / 4.0f;
|
||||
this.onClick = onClick;
|
||||
}
|
||||
|
||||
public void setMainView(ResizableMainView mainView) {
|
||||
this.mainView = mainView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
switch(event.getAction() & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
handlePress(event);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
handleDrag(event);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
handleRelease(event);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void handlePress(MotionEvent event) {
|
||||
startX = event.getRawX();
|
||||
startY = event.getRawY();
|
||||
}
|
||||
|
||||
private void handleDrag(MotionEvent event) {
|
||||
if (mainView == null) {
|
||||
aligning = false;
|
||||
resizing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!resizing && Math.abs(event.getRawY() - startY) >= RESIZE_THRESHOLD) {
|
||||
mainView.onResizeStart(event.getRawY());
|
||||
resizing = true;
|
||||
} else if (resizing) {
|
||||
mainView.onResizeThrottled(event.getRawY());
|
||||
} else if (!aligning && Math.abs(event.getRawX() - startX) >= ALIGN_THRESHOLD) {
|
||||
mainView.onAlign(event.getRawX() - startX);
|
||||
aligning = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleRelease(MotionEvent event) {
|
||||
if (mainView != null && resizing) {
|
||||
mainView.onResize(event.getRawY());
|
||||
resizing = false;
|
||||
} else if (mainView != null && aligning) {
|
||||
aligning = false;
|
||||
} else {
|
||||
onClick.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,33 +2,20 @@ package io.github.sspanak.tt9.ui.main.keys;
|
|||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.ui.main.ResizableMainView;
|
||||
|
||||
public class SoftKeyCommandPalette extends SoftKey {
|
||||
private final ResizeHandle resizeHandle = new ResizeHandle(getContext(), this::showCommandPalette);
|
||||
|
||||
public class SoftKeyCommandPalette extends SoftKeySettings {
|
||||
public SoftKeyCommandPalette(Context context) { super(context); }
|
||||
public SoftKeyCommandPalette(Context context, AttributeSet attrs) { super(context, attrs); }
|
||||
public SoftKeyCommandPalette(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
|
||||
|
||||
public void setMainView(ResizableMainView mainView) {
|
||||
resizeHandle.setMainView(mainView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent event) {
|
||||
resizeHandle.onTouch(view, event);
|
||||
return super.onTouch(view, event);
|
||||
}
|
||||
|
||||
protected void showCommandPalette() {
|
||||
if (validateTT9Handler()) {
|
||||
protected boolean handleRelease() {
|
||||
if (notSwiped() && validateTT9Handler()) {
|
||||
tt9.onKeyCommandPalette(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -2,44 +2,58 @@ package io.github.sspanak.tt9.ui.main.keys;
|
|||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.ui.main.ResizableMainView;
|
||||
|
||||
public class SoftKeySettings extends SoftKey {
|
||||
private final ResizeHandle resizeHandle = new ResizeHandle(getContext(), this::showSettings);
|
||||
public class SoftKeySettings extends SwipeableKey {
|
||||
private ResizableMainView mainView;
|
||||
|
||||
public SoftKeySettings(Context context) {
|
||||
super(context);
|
||||
setOnLongClickListener(null);
|
||||
}
|
||||
|
||||
public SoftKeySettings(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setOnLongClickListener(null);
|
||||
}
|
||||
|
||||
public SoftKeySettings(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setOnLongClickListener(null);
|
||||
}
|
||||
|
||||
public void setMainView(ResizableMainView mainView) {
|
||||
resizeHandle.setMainView(mainView);
|
||||
this.mainView = mainView;
|
||||
}
|
||||
|
||||
// this key does not support holding at the moment, so just prevent it
|
||||
@Override protected float getHoldDurationThreshold() { return 1000; }
|
||||
@Override protected float getSwipeXThreshold(Context context) { return context.getResources().getDimensionPixelSize(R.dimen.numpad_key_height) * 0.75f; }
|
||||
@Override protected float getSwipeYThreshold(Context context) { return context.getResources().getDimensionPixelSize(R.dimen.numpad_key_height) / 4.0f; }
|
||||
|
||||
@Override
|
||||
protected boolean handleRelease() {
|
||||
if (notSwiped() && validateTT9Handler()) {
|
||||
tt9.showSettings();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View view, MotionEvent event) {
|
||||
resizeHandle.onTouch(view, event);
|
||||
return super.onTouch(view, event);
|
||||
protected void handleStartSwipeX(float p, float delta) {
|
||||
if (mainView != null) mainView.onAlign(delta);
|
||||
}
|
||||
|
||||
protected void showSettings() {
|
||||
if (validateTT9Handler()) {
|
||||
tt9.showSettings();
|
||||
@Override
|
||||
protected void handleStartSwipeY(float position, float d) {
|
||||
if (mainView != null) mainView.onResizeStart(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleSwipeY(float position, float delta) {
|
||||
if (mainView != null) mainView.onResizeThrottled(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleEndSwipeY(float position, float delta) {
|
||||
if (mainView != null) mainView.onResize(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,146 @@
|
|||
package io.github.sspanak.tt9.ui.main.keys;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
|
||||
|
||||
abstract public class SwipeableKey extends SoftKey {
|
||||
private float HOLD_DURATION_THRESHOLD;
|
||||
protected float SWIPE_X_THRESHOLD;
|
||||
protected float SWIPE_Y_THRESHOLD;
|
||||
|
||||
private boolean isHolding = false;
|
||||
private boolean isSwipingX = false;
|
||||
private boolean isSwipingY = false;
|
||||
private boolean hasSwiped = false;
|
||||
|
||||
private float startX;
|
||||
private float startY;
|
||||
private long startTime;
|
||||
|
||||
|
||||
public SwipeableKey(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
|
||||
public SwipeableKey(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
|
||||
public SwipeableKey(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context);
|
||||
}
|
||||
|
||||
|
||||
private void init(Context context) {
|
||||
if (HOLD_DURATION_THRESHOLD == 0) {
|
||||
HOLD_DURATION_THRESHOLD = getHoldDurationThreshold();
|
||||
}
|
||||
if (SWIPE_X_THRESHOLD == 0) {
|
||||
SWIPE_X_THRESHOLD = getSwipeXThreshold(context);
|
||||
}
|
||||
if (SWIPE_Y_THRESHOLD == 0) {
|
||||
SWIPE_Y_THRESHOLD = getSwipeYThreshold(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected float getHoldDurationThreshold() { return SettingsStore.SOFT_KEY_REPEAT_DELAY * 3; }
|
||||
protected float getSwipeXThreshold(Context context) { return context.getResources().getDimensionPixelSize(R.dimen.numpad_key_height) / 10.0f; }
|
||||
protected float getSwipeYThreshold(Context context) { return context.getResources().getDimensionPixelSize(R.dimen.numpad_key_height) / 10.0f; }
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
switch(event.getAction() & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
onPress(event);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
onMove(v, event);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
onRelease(event);
|
||||
break;
|
||||
}
|
||||
|
||||
return super.onTouch(v, event);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
if (System.currentTimeMillis() - startTime < HOLD_DURATION_THRESHOLD) {
|
||||
return true;
|
||||
}
|
||||
|
||||
isHolding = !isSwipingY && !isSwipingX;
|
||||
return isSwipingY || isSwipingX || super.onLongClick(view);
|
||||
}
|
||||
|
||||
|
||||
private void onPress(MotionEvent event) {
|
||||
startTime = System.currentTimeMillis();
|
||||
startX = event.getRawX();
|
||||
startY = event.getRawY();
|
||||
|
||||
isHolding = false;
|
||||
isSwipingX = false;
|
||||
isSwipingY = false;
|
||||
}
|
||||
|
||||
|
||||
private void onMove(View v, MotionEvent event) {
|
||||
if (isHolding) {
|
||||
return;
|
||||
}
|
||||
|
||||
float deltaY = event.getRawY() - startY;
|
||||
float deltaX = event.getRawX() - startX;
|
||||
|
||||
if (isSwipingY) {
|
||||
handleSwipeY(event.getRawY(), deltaY);
|
||||
} else if (isSwipingX) {
|
||||
handleSwipeX(event.getRawX(), deltaX);
|
||||
} else if (Math.abs(deltaY) >= SWIPE_Y_THRESHOLD) {
|
||||
isSwipingY = true;
|
||||
handleStartSwipeY(event.getRawY(), deltaY);
|
||||
} else if (Math.abs(deltaX) >= SWIPE_X_THRESHOLD) {
|
||||
isSwipingX = true;
|
||||
handleStartSwipeX(event.getRawX(), deltaX);
|
||||
} else if (!isHolding && Math.abs(deltaX) < SWIPE_X_THRESHOLD && Math.abs(deltaY) < SWIPE_Y_THRESHOLD) {
|
||||
onLongClick(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void onRelease(MotionEvent event) {
|
||||
hasSwiped = !isSwipingY && !isSwipingX;
|
||||
|
||||
if (isSwipingY) {
|
||||
isSwipingY = false;
|
||||
handleEndSwipeY(event.getRawY(), event.getRawY() - startY);
|
||||
} else if (isSwipingX) {
|
||||
isSwipingX = false;
|
||||
handleEndSwipeX(event.getRawX(), event.getRawX() - startX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void handleStartSwipeX(float position, float delta) {}
|
||||
protected void handleStartSwipeY(float position, float delta) {}
|
||||
protected void handleSwipeX(float position, float delta) {}
|
||||
protected void handleSwipeY(float position, float delta) {}
|
||||
protected void handleEndSwipeX(float position, float delta) {}
|
||||
protected void handleEndSwipeY(float position, float delta) {}
|
||||
protected boolean notSwiped() { return hasSwiped; }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue