drag button calibration

This commit is contained in:
serso
2011-07-18 00:29:54 +04:00
parent 70ff5a109e
commit 0063f193ff
14 changed files with 557 additions and 210 deletions

View File

@@ -2,8 +2,14 @@ package org.solovyev.android.calculator;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.view.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,6 +40,12 @@ public class CalculatorActivity extends Activity {
@NotNull
private HistoryHelper<EditorHistoryState> historyHelper;
@NotNull
private BroadcastReceiver preferencesChangesReceiver;
@NotNull
private List<SimpleOnDragListener> onDragListeners = new ArrayList<SimpleOnDragListener>();
/**
* Called when the activity is first created.
*/
@@ -46,23 +58,19 @@ public class CalculatorActivity extends Activity {
this.resultEditText = (EditText) findViewById(R.id.resultEditText);
final DragButtonCalibrationActivity.Preferences dragPreferences = DragButtonCalibrationActivity.getPreferences(this);
final SimpleOnDragListener onDragListener = new SimpleOnDragListener(new SimpleOnDragListener.DragProcessor() {
@Override
public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
boolean result = isDirectionSupported(dragButton, dragDirection);
if (result) {
processButtonAction(dragButton, getActionText(dragButton, dragDirection));
}
return result;
assert dragButton instanceof DirectionDragButton;
processButtonAction(dragButton, getActionText((DirectionDragButton) dragButton, dragDirection));
return true;
}
public boolean isDirectionSupported(@NotNull DragButton dragButton, @NotNull DragDirection direction) {
return !StringUtils.isEmpty(getActionText(dragButton, direction));
}
}, dragPreferences);
});
onDragListeners.add(onDragListener);
// todo serso: check if there is more convenient method for doing this
final R.id ids = new R.id();
@@ -82,7 +90,9 @@ public class CalculatorActivity extends Activity {
}
}
((DragButton) findViewById(R.id.historyButton)).setOnDragListener(new SimpleOnDragListener(new HistoryDragProcessor()));
final SimpleOnDragListener historyOnDragListener = new SimpleOnDragListener(new HistoryDragProcessor(), dragPreferences);
((DragButton) findViewById(R.id.historyButton)).setOnDragListener(historyOnDragListener);
onDragListeners.add(historyOnDragListener);
this.interpreter = new Interpreter();
@@ -94,6 +104,19 @@ public class CalculatorActivity extends Activity {
this.historyHelper = new SimpleHistoryHelper<EditorHistoryState>();
this.historyHelper.addState(getCurrentHistoryState());
this.preferencesChangesReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DragButtonCalibrationActivity.INTENT_ACTION.equals(intent.getAction())) {
final DragButtonCalibrationActivity.Preferences preferences = DragButtonCalibrationActivity.getPreferences(CalculatorActivity.this);
for (SimpleOnDragListener dragListener : onDragListeners) {
dragListener.setPreferences(preferences);
}
}
}
};
}
public void elementaryButtonClickHandler(@NotNull View v) {
@@ -119,7 +142,7 @@ public class CalculatorActivity extends Activity {
}
public void digitButtonClickHandler(@NotNull View v) {
processButtonAction(v, ((DragButton) v).getTextMiddle());
processButtonAction(v, ((DirectionDragButton) v).getTextMiddle());
}
private final class HistoryDragProcessor implements SimpleOnDragListener.DragProcessor {
@@ -130,7 +153,8 @@ public class CalculatorActivity extends Activity {
Log.d(String.valueOf(dragButton.getId()), "History on drag event start: " + dragDirection);
String actionText = getActionText(dragButton, dragDirection);
assert dragButton instanceof DirectionDragButton;
String actionText = getActionText((DirectionDragButton) dragButton, dragDirection);
if (!StringUtils.isEmpty(actionText)) {
try {
result = true;
@@ -152,7 +176,7 @@ public class CalculatorActivity extends Activity {
}
@Nullable
private static String getActionText(@NotNull DragButton dragButton, @NotNull DragDirection direction) {
private static String getActionText(@NotNull DirectionDragButton dragButton, @NotNull DragDirection direction) {
final String result;
switch (direction) {

View File

@@ -1,19 +1,30 @@
package org.solovyev.android.calculator;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
import android.widget.ImageView;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.view.*;
import org.solovyev.common.collections.ManyValuedHashMap;
import org.solovyev.common.collections.ManyValuedMap;
import org.solovyev.common.utils.Interval;
import org.solovyev.util.math.MathUtils;
import org.solovyev.util.math.Point2d;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.prefs.Preferences;
/**
* User: serso
@@ -22,12 +33,34 @@ import java.util.List;
*/
public class DragButtonCalibrationActivity extends Activity {
@NotNull
private DragDirection dragDirection = DragDirection.up;
@NotNull
private final List<DragData> dragHistory = new ArrayList<DragData>();
@NotNull
private ImageView calibrationArrow;
public static final String PREFERENCES = "dragButtonPreferences";
public static final String PREFERENCES_FIRST_RUN = "firstRun";
public static final String PREFERENCES_MIN = "min";
public static final String PREFERENCES_MAX = "max";
private static final float DEFAULT_VALUE = -999;
private static final int MIN_HISTORY_FOR_CALIBRATION = 10;
public static final String INTENT_ACTION = "org.solovyev.android.calculator.DragButtonPreferencesChanged";
;
public static enum PreferenceType {
angle,
distance,
duration
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -37,17 +70,23 @@ public class DragButtonCalibrationActivity extends Activity {
final DragButton calibrationButton = (DragButton) findViewById(R.id.calibrationButton);
calibrationButton.setOnDragListener(new CalibrationOnDragListener());
createDragDirection();
calibrationArrow = (ImageView) findViewById(R.id.calibrationArrow);
createDragDirection(0);
}
private void createDragDirection() {
dragDirection = Math.random() > 0.5 ? DragDirection.up : DragDirection.down;
private void createDragDirection(long timeout) {
new Handler().postDelayed(new Runnable() {
public void run() {
dragDirection = Math.random() > 0.5 ? DragDirection.up : DragDirection.down;
Toast.makeText(this, dragDirection.name(), Toast.LENGTH_SHORT).show();
calibrationArrow.setImageResource(dragDirection == DragDirection.down ? R.drawable.down : R.drawable.up);
}
}, timeout);
}
public void restartClickHandler(View v) {
createDragDirection();
createDragDirection(0);
}
@@ -71,13 +110,20 @@ public class DragButtonCalibrationActivity extends Activity {
double angle = Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, SimpleOnDragListener.axis), endPoint));
assert dragDirection == DragDirection.up || dragDirection == DragDirection.down;
double deviationAngle = angle;
if (dragDirection == DragDirection.up) {
angle = 180 - angle;
deviationAngle = 180 - deviationAngle;
}
dragHistory.add(new DragData(distance, angle, dragDirection));
if (deviationAngle > 45) {
calibrationArrow.setImageResource(R.drawable.not_ok);
} else {
calibrationArrow.setImageResource(R.drawable.ok);
dragHistory.add(new DragData(dragDirection, distance, angle, (motionEvent.getEventTime() - motionEvent.getDownTime())));
}
createDragDirection();
createDragDirection(500);
return true;
}
@@ -86,28 +132,210 @@ public class DragButtonCalibrationActivity extends Activity {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
final List<Double> angleValues = new ArrayList<Double>();
final List<Double> distanceValues = new ArrayList<Double>();
for (DragData dragData : dragHistory) {
angleValues.add(dragData.getAngle());
distanceValues.add((double) dragData.getDistance());
if (dragHistory.size() > MIN_HISTORY_FOR_CALIBRATION) {
final ManyValuedMap<DragDirection, Double> anglesByDirection = new ManyValuedHashMap<DragDirection, Double>();
final ManyValuedMap<DragDirection, Double> distancesByDirection = new ManyValuedHashMap<DragDirection, Double>();
final ManyValuedMap<DragDirection, Double> timesByDirection = new ManyValuedHashMap<DragDirection, Double>();
for (DragData dragData : dragHistory) {
anglesByDirection.put(dragData.getDirection(), dragData.getAngle());
distancesByDirection.put(dragData.getDirection(), (double) dragData.getDistance());
timesByDirection.put(dragData.getDirection(), dragData.getTime());
}
final Map<DragDirection, MathUtils.StatData> angleStatData = getStatDataByDirection(anglesByDirection);
final Map<DragDirection, MathUtils.StatData> distanceStatData = getStatDataByDirection(distancesByDirection);
final Map<DragDirection, MathUtils.StatData> timeStatData = getStatDataByDirection(timesByDirection);
Log.d(this.getClass().getName(), "Angle statistics: ");
logStatData(angleStatData);
Log.d(this.getClass().getName(), "Distance statistics: ");
logStatData(distanceStatData);
Log.d(this.getClass().getName(), "Time statistics: ");
logStatData(timeStatData);
final SharedPreferences settings = getSharedPreferences(PREFERENCES, 0);
final SharedPreferences.Editor editor = settings.edit();
setPreferences(angleStatData, editor, PreferenceType.angle);
setPreferences(distanceStatData, editor, PreferenceType.distance);
setPreferences(timeStatData, editor, PreferenceType.duration);
editor.commit();
sendOrderedBroadcast(new Intent(INTENT_ACTION), null);
}
double angleMean = MathUtils.countMean(angleValues);
double angleDeviation = MathUtils.countStandardDeviation(angleMean, angleValues);
double distanceMean = MathUtils.countMean(distanceValues);
double distanceDeviation = MathUtils.countStandardDeviation(distanceMean, distanceValues);
Toast.makeText(this, "Angle: m=" + angleMean + ", d=" + angleDeviation, Toast.LENGTH_SHORT).show();
Toast.makeText(this, "Distance: m=" + distanceMean + ", d=" + distanceDeviation, Toast.LENGTH_SHORT).show();
}
return super.onKeyDown(keyCode, event);
}
private void setPreferences(@NotNull Map<DragDirection, MathUtils.StatData> statData, @NotNull SharedPreferences.Editor editor, @NotNull PreferenceType preferenceType) {
for (Map.Entry<DragDirection, MathUtils.StatData> entry : statData.entrySet()) {
final float min = (float) entry.getValue().getMean() - 2 * (float) entry.getValue().getStandardDeviation();
final float max = (float) entry.getValue().getMean() + 2 * (float) entry.getValue().getStandardDeviation();
editor.putFloat(preferenceType.name() + "_" + entry.getKey().name() + "_" + PREFERENCES_MIN, Math.max(0, min));
editor.putFloat(preferenceType.name() + "_" + entry.getKey().name() + "_" + PREFERENCES_MAX, max);
}
}
@NotNull
public static Preferences getPreferences(@NotNull Context context) {
SharedPreferences preferences = context.getSharedPreferences(PREFERENCES, MODE_PRIVATE);
final Preferences result = new Preferences();
for (PreferenceType preferenceType : PreferenceType.values()) {
for (DragDirection dragDirection : DragDirection.values()) {
final float defaultMin;
final float defaultMax;
switch (preferenceType) {
case angle:
switch (dragDirection) {
case up:
defaultMin = 150f;
defaultMax = 180f;
break;
case down:
defaultMin = 0f;
defaultMax = 30f;
break;
default:
defaultMin = DEFAULT_VALUE;
defaultMax = DEFAULT_VALUE;
}
break;
case distance:
defaultMin = 60f;
defaultMax = 140f;
break;
case duration:
defaultMin = 100f;
defaultMax = 300f;
break;
default:
defaultMin = DEFAULT_VALUE;
defaultMax = DEFAULT_VALUE;
}
final float min = preferences.getFloat(preferenceType.name() + "_" + dragDirection.name() + "_" + PREFERENCES_MIN, defaultMin);
final float max = preferences.getFloat(preferenceType.name() + "_" + dragDirection.name() + "_" + PREFERENCES_MAX, defaultMax);
if (min != DEFAULT_VALUE && max != DEFAULT_VALUE) {
final DragPreference directionPreference = new DragPreference(dragDirection, new Interval(min, max));
Preference preference = result.getPreferencesMap().get(preferenceType);
if (preference == null) {
preference = new Preference(preferenceType);
result.getPreferencesMap().put(preferenceType, preference);
}
preference.getDirectionPreferences().put(dragDirection, directionPreference);
} else {
Log.e(DragButtonCalibrationActivity.class.getName(), "New preference type added: default preferences should be defined!");
}
}
}
return result;
}
public static class DragPreference {
@NotNull
private DragDirection direction;
@NotNull
private Interval interval;
public DragPreference(@NotNull DragDirection direction, @NotNull Interval interval) {
this.direction = direction;
this.interval = interval;
}
@NotNull
public DragDirection getDirection() {
return direction;
}
public void setDirection(@NotNull DragDirection direction) {
this.direction = direction;
}
@NotNull
public Interval getInterval() {
return interval;
}
public void setInterval(@NotNull Interval interval) {
this.interval = interval;
}
}
public static class Preference {
@NotNull
private PreferenceType preferenceType;
@NotNull
private Map<DragDirection, DragPreference> directionPreferences = new HashMap<DragDirection, DragPreference>();
public Preference(@NotNull PreferenceType preferenceType) {
this.preferenceType = preferenceType;
}
@NotNull
public PreferenceType getPreferenceType() {
return preferenceType;
}
public void setPreferenceType(@NotNull PreferenceType preferenceType) {
this.preferenceType = preferenceType;
}
@NotNull
public Map<DragDirection, DragPreference> getDirectionPreferences() {
return directionPreferences;
}
public void setDirectionPreferences(@NotNull Map<DragDirection, DragPreference> directionPreferences) {
this.directionPreferences = directionPreferences;
}
}
public static class Preferences {
private final Map<PreferenceType, Preference> preferencesMap = new HashMap<PreferenceType, Preference>();
public Map<PreferenceType, Preference> getPreferencesMap() {
return preferencesMap;
}
}
private void logStatData(@NotNull Map<DragDirection, MathUtils.StatData> statData) {
for (Map.Entry<DragDirection, MathUtils.StatData> entry : statData.entrySet()) {
Log.d(this.getClass().getName(), entry.getKey() + "-> m: " + entry.getValue().getMean() + ", d: " + entry.getValue().getStandardDeviation());
}
}
private Map<DragDirection, MathUtils.StatData> getStatDataByDirection(@NotNull ManyValuedMap<DragDirection, Double> valuesByDirection) {
final Map<DragDirection, MathUtils.StatData> result = new HashMap<DragDirection, MathUtils.StatData>();
for (Map.Entry<DragDirection, List<Double>> entry : valuesByDirection.entrySet()) {
result.put(entry.getKey(), MathUtils.getStatData(entry.getValue()));
}
return result;
}
private class DragData {
@@ -115,13 +343,16 @@ public class DragButtonCalibrationActivity extends Activity {
private double angle;
private double time;
@NotNull
private DragDirection direction;
private DragData(float distance, double angle, @NotNull DragDirection direction) {
private DragData(@NotNull DragDirection direction, float distance, double angle, double time) {
this.distance = distance;
this.angle = angle;
this.direction = direction;
this.time = time;
}
public float getDistance() {
@@ -136,5 +367,9 @@ public class DragButtonCalibrationActivity extends Activity {
public DragDirection getDirection() {
return direction;
}
public double getTime() {
return time;
}
}
}

View File

@@ -0,0 +1,99 @@
package org.solovyev.android.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.Html;
import android.util.AttributeSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.R;
import org.solovyev.util.StringUtils;
/**
* User: serso
* Date: 7/17/11
* Time: 10:25 PM
*/
public class DirectionDragButton extends DragButton {
@Nullable
private String textUp;
@Nullable
private String textDown;
@Nullable
private String textMiddle;
public DirectionDragButton(Context context, @NotNull AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public DirectionDragButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(@NotNull Context context, @NotNull AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DragButton);
final int N = a.getIndexCount();
for (int i = 0; i < N; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.DragButton_textUp:
this.textUp = a.getString(attr);
break;
case R.styleable.DragButton_textDown:
this.textDown = a.getString(attr);
break;
}
}
// backup text
this.textMiddle = String.valueOf(getText());
setText(Html.fromHtml(getStyledUpDownText(this.textUp) + "<br><b>" + StringUtils.getNotEmpty(this.textMiddle, "&nbsp;") + "</b><br>" + getStyledUpDownText(this.textDown)));
// change top padding in order to show all text
setPadding(getPaddingLeft(), -7, getPaddingRight(), getPaddingBottom());
}
private String getStyledUpDownText(@Nullable String text) {
final StringBuilder sb = new StringBuilder();
sb.append("<font color='#585858'><small><small>");
sb.append(StringUtils.getNotEmpty(text, "&nbsp;"));
sb.append("</small></small></font>");
return sb.toString();
}
public void setTextUp(@Nullable String textUp) {
this.textUp = textUp;
}
@Nullable
public String getTextUp() {
return textUp;
}
public void setTextDown(@Nullable String textDown) {
this.textDown = textDown;
}
@Nullable
public String getTextDown() {
return textDown;
}
public void setTextMiddle(@Nullable String textMiddle) {
this.textMiddle = textMiddle;
}
@Nullable
public String getTextMiddle() {
return textMiddle;
}
}

View File

@@ -19,9 +19,6 @@ import android.widget.Button;
public class DragButton extends Button {
// max time in ms to register drag event
private long maxTime = 700;
@Nullable
private Point2d startPoint = null;
@@ -30,61 +27,16 @@ public class DragButton extends Button {
private final OnTouchListener onTouchListener = new OnTouchListenerImpl();
@Nullable
private String textUp;
@Nullable
private String textDown;
@Nullable
private String textMiddle;
public DragButton(Context context, @NotNull AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
setOnTouchListener(this.onTouchListener);
}
public DragButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(@NotNull Context context, @NotNull AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DragButton);
final int N = a.getIndexCount();
for (int i = 0; i < N; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.DragButton_textUp:
this.textUp = a.getString(attr);
break;
case R.styleable.DragButton_textDown:
this.textDown = a.getString(attr);
break;
}
}
// backup text
this.textMiddle = String.valueOf(getText());
setText(Html.fromHtml(getStyledUpDownText(this.textUp) + "<br><b>" + StringUtils.getNotEmpty(this.textMiddle, "&nbsp;") + "</b><br>" + getStyledUpDownText(this.textDown)));
// change top padding in order to show all text
setPadding(getPaddingLeft(), -7, getPaddingRight(), getPaddingBottom());
setOnTouchListener(this.onTouchListener);
}
private String getStyledUpDownText(@Nullable String text) {
final StringBuilder sb = new StringBuilder();
sb.append("<font color='#585858'><small><small>");
sb.append(StringUtils.getNotEmpty(text, "&nbsp;"));
sb.append("</small></small></font>");
return sb.toString();
}
public void setOnDragListener(@Nullable OnDragListener onDragListener) {
this.onDragListener = onDragListener;
}
@@ -94,33 +46,6 @@ public class DragButton extends Button {
return onDragListener;
}
public void setTextUp(@Nullable String textUp) {
this.textUp = textUp;
}
@Nullable
public String getTextUp() {
return textUp;
}
public void setTextDown(@Nullable String textDown) {
this.textDown = textDown;
}
@Nullable
public String getTextDown() {
return textDown;
}
public void setTextMiddle(@Nullable String textMiddle) {
this.textMiddle = textMiddle;
}
@Nullable
public String getTextMiddle() {
return textMiddle;
}
/**
* OnTouchListener implementation that fires onDrag()
*
@@ -148,13 +73,6 @@ public class DragButton extends Button {
startPoint = new Point2d(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
if (event.getEventTime() - event.getDownTime() > maxTime) {
// do not allow very long touch movements
startPoint = null;
}
break;
case MotionEvent.ACTION_UP:
// stop tracking

View File

@@ -1,33 +1,38 @@
package org.solovyev.android.view;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.DragButtonCalibrationActivity;
import org.solovyev.common.utils.Interval;
import org.solovyev.util.math.MathUtils;
import org.solovyev.util.math.Point2d;
import android.util.Log;
import android.view.MotionEvent;
import java.util.Map;
public class SimpleOnDragListener implements OnDragListener {
@NotNull
public static final Point2d axis = new Point2d(0, 1);
private float minDragDist = 20f;
private float maxDragDist = 80f;
// 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() {
@NotNull
private DragButtonCalibrationActivity.Preferences preferences;
public SimpleOnDragListener(@NotNull DragButtonCalibrationActivity.Preferences preferences) {
this.preferences = preferences;
}
public SimpleOnDragListener(@NotNull DragProcessor dragProcessor) {
public SimpleOnDragListener(@NotNull DragProcessor dragProcessor, @NotNull DragButtonCalibrationActivity.Preferences preferences) {
this.dragProcessor = dragProcessor;
this.preferences = preferences;
}
public void setPreferences(@NotNull DragButtonCalibrationActivity.Preferences preferences) {
this.preferences = preferences;
}
@Override
@@ -42,28 +47,48 @@ public class SimpleOnDragListener implements OnDragListener {
// init end point
final Point2d endPoint = new Point2d(motionEvent.getX(), motionEvent.getY());
float distance = MathUtils.getDistance(startPoint, endPoint);
final float distance = MathUtils.getDistance(startPoint, endPoint);
final double angle = Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint));
final double duration = motionEvent.getEventTime() - motionEvent.getDownTime();
if (minDragDist < distance && distance < maxDragDist) {
double angle = Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint));
final DragButtonCalibrationActivity.Preference distancePreferences = preferences.getPreferencesMap().get(DragButtonCalibrationActivity.PreferenceType.distance);
final DragButtonCalibrationActivity.Preference anglePreferences = preferences.getPreferencesMap().get(DragButtonCalibrationActivity.PreferenceType.angle);
final DragDirection direction;
if (angle < maxAngle) {
direction = DragDirection.down;
} else if (180 - angle < maxAngle) {
direction = DragDirection.up;
} else {
direction = null;
DragDirection direction = null;
for (Map.Entry<DragDirection, DragButtonCalibrationActivity.DragPreference> directionEntry : distancePreferences.getDirectionPreferences().entrySet()) {
if (isInInterval(directionEntry.getValue().getInterval(), distance)) {
for (Map.Entry<DragDirection, DragButtonCalibrationActivity.DragPreference> angleEntry : anglePreferences.getDirectionPreferences().entrySet()) {
if (isInInterval(angleEntry.getValue().getInterval(), (float)angle)) {
direction = angleEntry.getKey();
break;
}
}
}
if (direction != null) {
break;
}
}
if (direction != null) {
final DragButtonCalibrationActivity.Preference durationPreferences = preferences.getPreferencesMap().get(DragButtonCalibrationActivity.PreferenceType.duration);
final DragButtonCalibrationActivity.DragPreference durationDragPreferences = durationPreferences.getDirectionPreferences().get(direction);
if (isInInterval(durationDragPreferences.getInterval(), (float)duration)) {
result = dragProcessor.processDragEvent(direction, dragButton, startPoint, motionEvent);
}
}
return result;
}
private boolean isInInterval(@NotNull Interval interval, float value) {
return interval.getStart() - MathUtils.MIN_AMOUNT <= value && value <= interval.getEnd() + MathUtils.MIN_AMOUNT;
}
@Override
public boolean isSuppressOnClickEvent() {
return true;
@@ -91,7 +116,7 @@ public class SimpleOnDragListener implements OnDragListener {
}
public interface DragProcessor {
boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent);
}
}

View File

@@ -6,6 +6,8 @@ import java.util.List;
public class MathUtils {
public static final float MIN_AMOUNT = 0.05f;
public static float getDistance(@NotNull Point2d startPoint,
@NotNull Point2d endPoint) {
return getNorm(subtract(endPoint, startPoint));
@@ -58,4 +60,33 @@ public class MathUtils {
return objects.size() == 0 ? 0d : Math.sqrt(sum / objects.size());
}
public static StatData getStatData(@NotNull List<Double> objects) {
final double mean = countMean(objects);
final double standardDeviation = countStandardDeviation(mean, objects);
return new StatData(mean, standardDeviation);
}
public static class StatData {
private final double mean;
private final double standardDeviation;
public StatData(double mean, double standardDeviation) {
this.mean = mean;
this.standardDeviation = standardDeviation;
}
public double getMean() {
return mean;
}
public double getStandardDeviation() {
return standardDeviation;
}
}
}