drag button calibration

This commit is contained in:
serso
2011-07-16 23:25:12 +04:00
parent f3341e04b7
commit 6b94159ef9
15 changed files with 532 additions and 161 deletions

View File

@@ -3,6 +3,7 @@ package org.solovyev.android.view;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.R;
import org.solovyev.common.utils.StringsUtils;
import org.solovyev.util.StringUtils;
import org.solovyev.util.math.MathUtils;
import org.solovyev.util.math.Point2d;
@@ -93,26 +94,29 @@ public class DragButton extends Button {
return onDragListener;
}
public void setTextUp(String textUp) {
public void setTextUp(@Nullable String textUp) {
this.textUp = textUp;
}
@Nullable
public String getTextUp() {
return textUp;
}
public void setTextDown(String textDown) {
public void setTextDown(@Nullable String textDown) {
this.textDown = textDown;
}
@Nullable
public String getTextDown() {
return textDown;
}
public void setTextMiddle(String textMiddle) {
public void setTextMiddle(@Nullable String textMiddle) {
this.textMiddle = textMiddle;
}
@Nullable
public String getTextMiddle() {
return textMiddle;
}
@@ -129,7 +133,11 @@ public class DragButton extends Button {
public boolean onTouch(@NotNull View v, @NotNull MotionEvent event) {
// processing on touch event
if (onDragListener != null) {
// in order to avoid possible NPEs
final Point2d localStartPoint = startPoint;
final OnDragListener localOnDragListener = onDragListener;
if (localOnDragListener != null) {
// only if onDrag() listener specified
Log.d(String.valueOf(getId()), "onTouch() for: " + getId() + " . Motion event: " + event);
@@ -150,8 +158,8 @@ public class DragButton extends Button {
case MotionEvent.ACTION_UP:
// stop tracking
if (onDragListener.onDrag(DragButton.this, new DragEvent(startPoint, event))) {
if (onDragListener.isSuppressOnClickEvent()) {
if (localStartPoint != null && localOnDragListener.onDrag(DragButton.this, new DragEvent(localStartPoint, event))) {
if (localOnDragListener.isSuppressOnClickEvent()) {
// prevent on click action
setPressed(false);
}

View File

@@ -3,5 +3,7 @@ package org.solovyev.android.view;
public enum DragDirection {
up,
down;
down,
left,
right;
}

View File

@@ -6,10 +6,10 @@ import org.solovyev.util.math.Point2d;
import android.view.MotionEvent;
public class DragEvent {
@NotNull
private final Point2d startPoint;
@NotNull
private final MotionEvent motionEvent;
@@ -18,16 +18,21 @@ public class DragEvent {
this.motionEvent = motionEvent;
}
/**
* @return motion event started at start point
*/
@NotNull
public MotionEvent getMotionEvent() {
return motionEvent;
}
/**
* @return start point of dragging
*/
@NotNull
public Point2d getStartPoint() {
return startPoint;
}
}

View File

@@ -1,8 +1,6 @@
package org.solovyev.android.view;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.util.StringUtils;
import org.solovyev.util.math.MathUtils;
import org.solovyev.util.math.Point2d;
@@ -12,8 +10,8 @@ import android.view.MotionEvent;
public class SimpleOnDragListener implements OnDragListener {
@NotNull
private final Point2d axis = new Point2d(0, 1);
public static final Point2d axis = new Point2d(0, 1);
private float minDragDist = 20f;
private float maxDragDist = 80f;
@@ -21,73 +19,79 @@ public class SimpleOnDragListener implements OnDragListener {
// max angle (in degrees!) between start and end point vector and axis
// vector to register drag event
private double maxAngle = 30;
@NotNull
private DragProcessor dragProcessor;
public SimpleOnDragListener() {
}
public SimpleOnDragListener(@NotNull DragProcessor dragProcessor) {
this.dragProcessor = dragProcessor;
}
@Override
public boolean onDrag(@NotNull DragButton dragButton, @NotNull DragEvent event) {
boolean result = false;
logDragEvent(dragButton, event);
processButtonAction(dragButton, getActionText(dragButton, event));
final Point2d startPoint = event.getStartPoint();
final MotionEvent motionEvent = event.getMotionEvent();
// init end point
final Point2d endPoint = new Point2d(motionEvent.getX(), motionEvent.getY());
float distance = MathUtils.getDistance(startPoint, endPoint);
if (minDragDist < distance && distance < maxDragDist) {
double angle = Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint));
final DragDirection direction;
if (angle < maxAngle) {
direction = DragDirection.down;
} else if (180 - angle < maxAngle) {
direction = DragDirection.up;
} else {
direction = null;
}
if (direction != null) {
result = dragProcessor.processDragEvent(direction, dragButton, startPoint, motionEvent);
}
}
return result;
}
@Override
public boolean isSuppressOnClickEvent() {
return true;
}
/**
* Method creates drag event in case if all conditions are satisfied
*
* @param event
* motion event
*
* @return filled drag event object only if drag event is possible, null
* otherwise
*/
@Nullable
protected DragEvent getDragEvent(@NotNull MotionEvent event) {
DragEvent result = null;
if (startPoint != null) {
final Point2d endPoint = new Point2d(event.getX(), event.getY());
float distance = MathUtils.getDistance(startPoint, endPoint);
if (minDragDist < distance && distance < maxDragDist) {
double angle = Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint));
final DragDirection direction;
if (angle < maxAngle) {
direction = DragDirection.down;
} else if (180 - angle < maxAngle) {
direction = DragDirection.up;
} else {
direction = null;
}
if (direction != null) {
if ( direction == DragDirection.up && StringUtils.isEmpty(textUp) ) {
// no action if text is empty
} else if (direction == DragDirection.down && StringUtils.isEmpty(textDown)) {
// no action if text is empty
} else {
result = new DragEvent(direction);
}
}
}
}
return result;
}
private void logDragEvent(@NotNull DragButton dragButton, @NotNull DragEvent event) {
final Point2d startPoint = event.getStartPoint();
final MotionEvent motionEvent = event.getMotionEvent();
final Point2d endPoint = new Point2d(motionEvent.getX(), motionEvent.getY());
Log.d(String.valueOf(dragButton.getId()), "Start point: " + startPoint + ", End point: " + endPoint);
Log.d(String.valueOf(dragButton.getId()), "Distance: " + MathUtils.getDistance(startPoint, endPoint));
Log.d(String.valueOf(dragButton.getId()), "Angle: " + Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint)));
Log.d(String.valueOf(dragButton.getId()), "Axis: " + axis + " Vector: " + MathUtils.subtract(endPoint, startPoint));
Log.d(String.valueOf(dragButton.getId()), "Total time: " + (motionEvent.getEventTime() - motionEvent.getDownTime()) + " ms");
final Point2d startPoint = event.getStartPoint();
final MotionEvent motionEvent = event.getMotionEvent();
final Point2d endPoint = new Point2d(motionEvent.getX(), motionEvent.getY());
Log.d(String.valueOf(dragButton.getId()), "Start point: " + startPoint + ", End point: " + endPoint);
Log.d(String.valueOf(dragButton.getId()), "Distance: " + MathUtils.getDistance(startPoint, endPoint));
Log.d(String.valueOf(dragButton.getId()), "Angle: " + Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint)));
Log.d(String.valueOf(dragButton.getId()), "Axis: " + axis + " Vector: " + MathUtils.subtract(endPoint, startPoint));
Log.d(String.valueOf(dragButton.getId()), "Total time: " + (motionEvent.getEventTime() - motionEvent.getDownTime()) + " ms");
}
@NotNull
public DragProcessor getDragProcessor() {
return dragProcessor;
}
public void setDragProcessor(@NotNull DragProcessor dragProcessor) {
this.dragProcessor = dragProcessor;
}
public interface DragProcessor {
boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent);
}
}