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) {
|
public void onAlign(float deltaX) {
|
||||||
|
if (!(main instanceof MainLayoutNumpad)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boolean right = deltaX > 0;
|
boolean right = deltaX > 0;
|
||||||
SettingsStore settings = tt9.getSettings();
|
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.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.R;
|
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) { super(context); }
|
||||||
public SoftKeyCommandPalette(Context context, AttributeSet attrs) { super(context, attrs); }
|
public SoftKeyCommandPalette(Context context, AttributeSet attrs) { super(context, attrs); }
|
||||||
public SoftKeyCommandPalette(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
|
public SoftKeyCommandPalette(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
|
||||||
|
|
||||||
public void setMainView(ResizableMainView mainView) {
|
|
||||||
resizeHandle.setMainView(mainView);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View view, MotionEvent event) {
|
protected boolean handleRelease() {
|
||||||
resizeHandle.onTouch(view, event);
|
if (notSwiped() && validateTT9Handler()) {
|
||||||
return super.onTouch(view, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void showCommandPalette() {
|
|
||||||
if (validateTT9Handler()) {
|
|
||||||
tt9.onKeyCommandPalette(false);
|
tt9.onKeyCommandPalette(false);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -2,44 +2,58 @@ package io.github.sspanak.tt9.ui.main.keys;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.R;
|
import io.github.sspanak.tt9.R;
|
||||||
import io.github.sspanak.tt9.ui.main.ResizableMainView;
|
import io.github.sspanak.tt9.ui.main.ResizableMainView;
|
||||||
|
|
||||||
public class SoftKeySettings extends SoftKey {
|
public class SoftKeySettings extends SwipeableKey {
|
||||||
private final ResizeHandle resizeHandle = new ResizeHandle(getContext(), this::showSettings);
|
private ResizableMainView mainView;
|
||||||
|
|
||||||
public SoftKeySettings(Context context) {
|
public SoftKeySettings(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
setOnLongClickListener(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SoftKeySettings(Context context, AttributeSet attrs) {
|
public SoftKeySettings(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
setOnLongClickListener(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SoftKeySettings(Context context, AttributeSet attrs, int defStyleAttr) {
|
public SoftKeySettings(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
setOnLongClickListener(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMainView(ResizableMainView mainView) {
|
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
|
@Override
|
||||||
public boolean onTouch(View view, MotionEvent event) {
|
protected void handleStartSwipeX(float p, float delta) {
|
||||||
resizeHandle.onTouch(view, event);
|
if (mainView != null) mainView.onAlign(delta);
|
||||||
return super.onTouch(view, event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void showSettings() {
|
@Override
|
||||||
if (validateTT9Handler()) {
|
protected void handleStartSwipeY(float position, float d) {
|
||||||
tt9.showSettings();
|
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
|
@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