package org.solovyev.android.calculator.view;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import javax.annotation.Nonnull;
import static android.view.HapticFeedbackConstants.*;
public abstract class BaseLongClickEraser implements View.OnTouchListener {
@Nonnull
private final View view;
@Nonnull
private final GestureDetector gestureDetector;
@Nonnull
private final Eraser eraser = new Eraser();
protected boolean vibrateOnKeypress;
protected BaseLongClickEraser(@Nonnull final View view, boolean vibrateOnKeypress) {
this.view = view;
this.vibrateOnKeypress = vibrateOnKeypress;
this.gestureDetector = new GestureDetector(view.getContext(), new GestureDetector.SimpleOnGestureListener() {
public void onLongPress(MotionEvent e) {
if (eraser.isTracking()) {
eraser.start();
}
}
});
this.view.setOnTouchListener(this);
}
public void setVibrateOnKeypress(boolean vibrateOnKeypress) {
this.vibrateOnKeypress = vibrateOnKeypress;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
eraser.stopTracking();
break;
default:
eraser.startTracking();
gestureDetector.onTouchEvent(event);
break;
}
return false;
}
protected abstract void onStopErase();
protected abstract void onStartErase();
protected abstract boolean erase();
private class Eraser implements Runnable {
private static final int DELAY = 300;
private long delay;
private boolean erasing;
private boolean tracking = true;
@Override
public void run() {
if (!erase()) {
stop();
return;
}
delay = Math.max(50, 2 * delay / 3);
view.postDelayed(this, delay);
}
void start() {
if (erasing) {
stop();
}
erasing = true;
delay = DELAY;
view.removeCallbacks(this);
if (vibrateOnKeypress) {
view.performHapticFeedback(KEYBOARD_TAP, FLAG_IGNORE_GLOBAL_SETTING | FLAG_IGNORE_VIEW_SETTING);
}
onStartErase();
run();
}
void stop() {
view.removeCallbacks(this);
if (!erasing) {
return;
}
erasing = false;
onStopErase();
}
public void stopTracking() {
stop();
tracking = false;
}
public boolean isTracking() {
return tracking;
}
public void startTracking() {
tracking = true;
}
}
}