package org.solovyev.android.views.dragbutton;
import android.content.Context;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import static java.lang.Math.toDegrees;
import static org.solovyev.android.views.dragbutton.Drag.*;
public abstract class DirectionDragListener implements DragListener {
@NonNull
private static final PointF axis = new PointF(0, 1);
private final float minDistancePxs;
private final boolean[] right = new boolean[1];
public DirectionDragListener(@NonNull Context context) {
this.minDistancePxs = context.getResources().getDimensionPixelSize(R.dimen.drag_min_distance);
}
@Override
public boolean onDrag(@NonNull View view, @NonNull DragEvent e) {
final long duration = e.motionEvent.getEventTime() - e.motionEvent.getDownTime();
if (duration < 40 || duration > 2500) {
Log.v("DirectionDragListener", "Drag stopped: too fast movement, " + duration + "ms");
return false;
}
final float distance = distance(e.start, e.end);
if (distance < minDistancePxs) {
Log.v("DirectionDragListener", "Drag stopped: too short distance, " + distance + "pxs");
return false;
}
final double angle = toDegrees(getAngle(e.start, sum(e.start, axis), e.end, right));
final DragDirection direction = getDirection((float) angle, right[0]);
if (direction == null) {
Log.v("DirectionDragListener", "Drag stopped: unknown direction");
return false;
}
return onDrag(view, e, direction);
}
protected abstract boolean onDrag(@NonNull View view, @NonNull DragEvent event, @NonNull DragDirection direction);
@Nullable
private static DragDirection getDirection(float angle, boolean right) {
for (DragDirection direction : DragDirection.values()) {
if (direction == DragDirection.left && right) {
continue;
}
if (direction == DragDirection.right && !right) {
continue;
}
if (direction.angleFrom <= angle && angle <= direction.angleTo) {
return direction;
}
}
return null;
}
}