1
0
Fork 0

fixed Backspace swiping for the 3rd time with stricter checks for pressing

This commit is contained in:
sspanak 2024-10-24 11:47:01 +03:00 committed by Dimo Karaivanov
parent 45285828e0
commit b08d4e6cdf
3 changed files with 53 additions and 16 deletions

View file

@ -89,6 +89,7 @@ public class SoftKey extends androidx.appcompat.widget.AppCompatButton implement
} else if (action == MotionEvent.ACTION_UP) { } else if (action == MotionEvent.ACTION_UP) {
if (!repeat || hold) { if (!repeat || hold) {
hold = false; hold = false;
repeat = false;
boolean result = handleRelease(); boolean result = handleRelease();
lastPressedKey = ignoreLastPressedKey ? -1 : getId(); lastPressedKey = ignoreLastPressedKey ? -1 : getId();
return result; return result;

View file

@ -12,8 +12,11 @@ import io.github.sspanak.tt9.ui.Vibration;
public class SoftKeyBackspace extends SwipeableKey { public class SoftKeyBackspace extends SwipeableKey {
private int repeat = 0; private int repeat = 0;
private boolean isActionPerformed = false;
private final Handler waitForSwipe = new Handler(); private final Handler waitForSwipe = new Handler();
public SoftKeyBackspace(Context context) { public SoftKeyBackspace(Context context) {
super(context); super(context);
} }
@ -63,20 +66,36 @@ public class SoftKeyBackspace extends SwipeableKey {
@Override @Override
final protected boolean handlePress() { final protected boolean handlePress() {
super.handlePress(); super.handlePress();
waitForSwipe.postDelayed(this::handlePressDebounced, 15); isActionPerformed = false;
waitForSwipe.postDelayed(this::handlePressDebounced, 1 + getAverageSwipeProcessingTime());
return true; return true;
} }
/**
* Avoids deleting text twice when swiping - first, when the user touches the screen, and then,
* when they finish the swipe gesture.
*/
private void handlePressDebounced() { private void handlePressDebounced() {
if (notSwiped()) { if (!isActionPerformed) {
isActionPerformed = true;
deleteText(); deleteText();
} }
} }
@Override
protected void handleStartSwipeX(float position, float delta) {
if (!isActionPerformed && validateTT9Handler()) {
isActionPerformed = true;
tt9.onBackspace(SettingsStore.BACKSPACE_ACCELERATION_REPEAT_DEBOUNCE);
}
}
@Override @Override
final protected void handleHold() { final protected void handleHold() {
isActionPerformed = true;
repeat++; repeat++;
deleteText(); deleteText();
} }
@ -86,24 +105,11 @@ public class SoftKeyBackspace extends SwipeableKey {
final protected boolean handleRelease() { final protected boolean handleRelease() {
vibrate(repeat > 0 ? Vibration.getReleaseVibration() : Vibration.getNoVibration()); vibrate(repeat > 0 ? Vibration.getReleaseVibration() : Vibration.getNoVibration());
repeat = 0; repeat = 0;
return true; return true;
} }
@Override
protected void handleStartSwipeX(float position, float delta) {
waitForSwipe.removeCallbacksAndMessages(null);
}
@Override
protected void handleEndSwipeX(float position, float delta) {
if (validateTT9Handler()) {
tt9.onBackspace(SettingsStore.BACKSPACE_ACCELERATION_REPEAT_DEBOUNCE);
}
}
private void deleteText() { private void deleteText() {
if (validateTT9Handler() && !tt9.onBackspace(repeat)) { if (validateTT9Handler() && !tt9.onBackspace(repeat)) {
// Limited or special numeric field (e.g. formatted money or dates) cannot always return // Limited or special numeric field (e.g. formatted money or dates) cannot always return

View file

@ -7,8 +7,11 @@ import android.view.View;
import io.github.sspanak.tt9.R; import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.settings.SettingsStore; import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.util.Timer;
abstract public class SwipeableKey extends SoftKey { abstract public class SwipeableKey extends SoftKey {
private static final String LOG_TAG = SwipeableKey.class.getSimpleName();
private float HOLD_DURATION_THRESHOLD; private float HOLD_DURATION_THRESHOLD;
protected float SWIPE_X_THRESHOLD; protected float SWIPE_X_THRESHOLD;
protected float SWIPE_Y_THRESHOLD; protected float SWIPE_Y_THRESHOLD;
@ -22,6 +25,10 @@ abstract public class SwipeableKey extends SoftKey {
private float startY; private float startY;
private long startTime; private long startTime;
private int swipeCount = 0;
private long swipeProcessingTime = 0;
private long swipeProcessingTimeAverage = 40;
public SwipeableKey(Context context) { public SwipeableKey(Context context) {
super(context); super(context);
@ -53,10 +60,31 @@ abstract public class SwipeableKey extends SoftKey {
protected float getSwipeYThreshold(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; }
private void updateSwipeTimingStats() {
long time = Timer.get(LOG_TAG);
long deltaT = time - swipeProcessingTimeAverage;
if (deltaT < -swipeProcessingTimeAverage || deltaT > 5) {
swipeCount = 0;
swipeProcessingTime = 0;
}
swipeCount++;
swipeProcessingTime += time;
swipeProcessingTimeAverage = swipeProcessingTime / swipeCount;
}
protected long getAverageSwipeProcessingTime() {
return swipeProcessingTimeAverage;
}
@Override @Override
public boolean onTouch(View v, MotionEvent event) { public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction() & MotionEvent.ACTION_MASK) { switch(event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
Timer.start(LOG_TAG);
onPress(event); onPress(event);
break; break;
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
@ -107,9 +135,11 @@ abstract public class SwipeableKey extends SoftKey {
handleSwipeX(event.getRawX(), deltaX); handleSwipeX(event.getRawX(), deltaX);
} else if (Math.abs(deltaY) >= SWIPE_Y_THRESHOLD) { } else if (Math.abs(deltaY) >= SWIPE_Y_THRESHOLD) {
isSwipingY = true; isSwipingY = true;
updateSwipeTimingStats();
handleStartSwipeY(event.getRawY(), deltaY); handleStartSwipeY(event.getRawY(), deltaY);
} else if (Math.abs(deltaX) >= SWIPE_X_THRESHOLD) { } else if (Math.abs(deltaX) >= SWIPE_X_THRESHOLD) {
isSwipingX = true; isSwipingX = true;
updateSwipeTimingStats();
handleStartSwipeX(event.getRawX(), deltaX); handleStartSwipeX(event.getRawX(), deltaX);
} else if (!isHolding && Math.abs(deltaX) < SWIPE_X_THRESHOLD && Math.abs(deltaY) < SWIPE_Y_THRESHOLD) { } else if (!isHolding && Math.abs(deltaX) < SWIPE_X_THRESHOLD && Math.abs(deltaY) < SWIPE_Y_THRESHOLD) {
onLongClick(v); onLongClick(v);