diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0fa5d311..c18c9208 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -13,6 +13,7 @@
+
diff --git a/gen/org/solovyev/android/calculator/R.java b/gen/org/solovyev/android/calculator/R.java
index 33366b49..be166f9d 100644
--- a/gen/org/solovyev/android/calculator/R.java
+++ b/gen/org/solovyev/android/calculator/R.java
@@ -27,39 +27,44 @@ containing a value of this type.
public static final int textUp=0x7f010000;
}
public static final class drawable {
- public static final int icon=0x7f020000;
+ public static final int down=0x7f020000;
+ public static final int icon=0x7f020001;
+ public static final int not_ok=0x7f020002;
+ public static final int ok=0x7f020003;
+ public static final int up=0x7f020004;
}
public static final class id {
- public static final int calibrationButton=0x7f080000;
- public static final int calibrationStart=0x7f080001;
- public static final int curlyBracketsButton=0x7f080015;
- public static final int editText=0x7f080002;
- public static final int eigthDigitButton=0x7f080011;
- public static final int equalsButton=0x7f080013;
- public static final int fiveDigitButton=0x7f08000b;
- public static final int fourDigitButton=0x7f08000a;
- public static final int historyButton=0x7f08001a;
- public static final int menu_item_help=0x7f08001d;
- public static final int menu_item_settings=0x7f08001c;
- public static final int minusButton=0x7f08000e;
- public static final int muliplicationButton=0x7f080007;
- public static final int nineDigitButton=0x7f080012;
- public static final int numericButton=0x7f080018;
- public static final int oneDigitButton=0x7f080004;
- public static final int piButton=0x7f08001b;
- public static final int plusButton=0x7f080008;
- public static final int pointDigitButton=0x7f080017;
- public static final int resultEditText=0x7f080003;
- public static final int roundBracketsButton=0x7f080009;
- public static final int sevenDigitButton=0x7f080010;
- public static final int simplifyButton=0x7f080019;
- public static final int sixDigitButton=0x7f08000c;
- public static final int sqrtButton=0x7f080014;
- public static final int squareBracketsButton=0x7f08000f;
- public static final int subtractionButton=0x7f08000d;
- public static final int threeDigitButton=0x7f080006;
- public static final int twoDigitButton=0x7f080005;
- public static final int zeroDigitButton=0x7f080016;
+ public static final int calibrationArrow=0x7f080000;
+ public static final int calibrationButton=0x7f080001;
+ public static final int calibrationStart=0x7f080002;
+ public static final int curlyBracketsButton=0x7f080016;
+ public static final int editText=0x7f080003;
+ public static final int eigthDigitButton=0x7f080012;
+ public static final int equalsButton=0x7f080014;
+ public static final int fiveDigitButton=0x7f08000c;
+ public static final int fourDigitButton=0x7f08000b;
+ public static final int historyButton=0x7f08001b;
+ public static final int menu_item_help=0x7f08001e;
+ public static final int menu_item_settings=0x7f08001d;
+ public static final int minusButton=0x7f08000f;
+ public static final int muliplicationButton=0x7f080008;
+ public static final int nineDigitButton=0x7f080013;
+ public static final int numericButton=0x7f080019;
+ public static final int oneDigitButton=0x7f080005;
+ public static final int piButton=0x7f08001c;
+ public static final int plusButton=0x7f080009;
+ public static final int pointDigitButton=0x7f080018;
+ public static final int resultEditText=0x7f080004;
+ public static final int roundBracketsButton=0x7f08000a;
+ public static final int sevenDigitButton=0x7f080011;
+ public static final int simplifyButton=0x7f08001a;
+ public static final int sixDigitButton=0x7f08000d;
+ public static final int sqrtButton=0x7f080015;
+ public static final int squareBracketsButton=0x7f080010;
+ public static final int subtractionButton=0x7f08000e;
+ public static final int threeDigitButton=0x7f080007;
+ public static final int twoDigitButton=0x7f080006;
+ public static final int zeroDigitButton=0x7f080017;
}
public static final class layout {
public static final int drag_button_calibration=0x7f030000;
diff --git a/res/drawable/down.png b/res/drawable/down.png
new file mode 100644
index 00000000..8550c498
Binary files /dev/null and b/res/drawable/down.png differ
diff --git a/res/drawable/not_ok.png b/res/drawable/not_ok.png
new file mode 100644
index 00000000..292b7d21
Binary files /dev/null and b/res/drawable/not_ok.png differ
diff --git a/res/drawable/ok.png b/res/drawable/ok.png
new file mode 100644
index 00000000..c7c11172
Binary files /dev/null and b/res/drawable/ok.png differ
diff --git a/res/drawable/up.png b/res/drawable/up.png
new file mode 100644
index 00000000..9d65c209
Binary files /dev/null and b/res/drawable/up.png differ
diff --git a/res/layout/drag_button_calibration.xml b/res/layout/drag_button_calibration.xml
index c77f4f2e..93fbaef5 100644
--- a/res/layout/drag_button_calibration.xml
+++ b/res/layout/drag_button_calibration.xml
@@ -8,20 +8,29 @@
a:layout_width="fill_parent"
a:layout_height="fill_parent">
+
-
+
+
+
+
+ a:layout_gravity="bottom"/>
diff --git a/res/layout/main.xml b/res/layout/main.xml
index 03b8493a..5047a00c 100644
--- a/res/layout/main.xml
+++ b/res/layout/main.xml
@@ -30,36 +30,36 @@
a:layout_width="fill_parent"
a:layout_height="fill_parent">
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/org/solovyev/android/calculator/CalculatorActivity.java b/src/org/solovyev/android/calculator/CalculatorActivity.java
index 9f2e16f6..0d1263d0 100644
--- a/src/org/solovyev/android/calculator/CalculatorActivity.java
+++ b/src/org/solovyev/android/calculator/CalculatorActivity.java
@@ -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 historyHelper;
+ @NotNull
+ private BroadcastReceiver preferencesChangesReceiver;
+
+ @NotNull
+ private List onDragListeners = new ArrayList();
+
/**
* 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();
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) {
diff --git a/src/org/solovyev/android/calculator/DragButtonCalibrationActivity.java b/src/org/solovyev/android/calculator/DragButtonCalibrationActivity.java
index 35cd2972..cd934173 100644
--- a/src/org/solovyev/android/calculator/DragButtonCalibrationActivity.java
+++ b/src/org/solovyev/android/calculator/DragButtonCalibrationActivity.java
@@ -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 dragHistory = new ArrayList();
+ @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 angleValues = new ArrayList();
- final List distanceValues = new ArrayList();
- for (DragData dragData : dragHistory) {
- angleValues.add(dragData.getAngle());
- distanceValues.add((double) dragData.getDistance());
+
+ if (dragHistory.size() > MIN_HISTORY_FOR_CALIBRATION) {
+ final ManyValuedMap anglesByDirection = new ManyValuedHashMap();
+ final ManyValuedMap distancesByDirection = new ManyValuedHashMap();
+ final ManyValuedMap timesByDirection = new ManyValuedHashMap();
+ 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 angleStatData = getStatDataByDirection(anglesByDirection);
+ final Map distanceStatData = getStatDataByDirection(distancesByDirection);
+ final Map 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 statData, @NotNull SharedPreferences.Editor editor, @NotNull PreferenceType preferenceType) {
+ for (Map.Entry 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 directionPreferences = new HashMap();
+
+
+ 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 getDirectionPreferences() {
+ return directionPreferences;
+ }
+
+ public void setDirectionPreferences(@NotNull Map directionPreferences) {
+ this.directionPreferences = directionPreferences;
+ }
+ }
+
+
+ public static class Preferences {
+
+ private final Map preferencesMap = new HashMap();
+
+ public Map getPreferencesMap() {
+ return preferencesMap;
+ }
+ }
+
+ private void logStatData(@NotNull Map statData) {
+ for (Map.Entry entry : statData.entrySet()) {
+ Log.d(this.getClass().getName(), entry.getKey() + "-> m: " + entry.getValue().getMean() + ", d: " + entry.getValue().getStandardDeviation());
+ }
+ }
+
+ private Map getStatDataByDirection(@NotNull ManyValuedMap valuesByDirection) {
+ final Map result = new HashMap();
+
+ for (Map.Entry> 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;
+ }
}
}
diff --git a/src/org/solovyev/android/view/DirectionDragButton.java b/src/org/solovyev/android/view/DirectionDragButton.java
new file mode 100644
index 00000000..761e212a
--- /dev/null
+++ b/src/org/solovyev/android/view/DirectionDragButton.java
@@ -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) + "
" + StringUtils.getNotEmpty(this.textMiddle, " ") + "
" + 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("");
+ sb.append(StringUtils.getNotEmpty(text, " "));
+ sb.append("");
+ 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;
+ }
+}
diff --git a/src/org/solovyev/android/view/DragButton.java b/src/org/solovyev/android/view/DragButton.java
index 991e3849..6c5e99a2 100644
--- a/src/org/solovyev/android/view/DragButton.java
+++ b/src/org/solovyev/android/view/DragButton.java
@@ -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) + "
" + StringUtils.getNotEmpty(this.textMiddle, " ") + "
" + 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("");
- sb.append(StringUtils.getNotEmpty(text, " "));
- sb.append("");
- 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
diff --git a/src/org/solovyev/android/view/SimpleOnDragListener.java b/src/org/solovyev/android/view/SimpleOnDragListener.java
index 4cf0264e..bf186d1b 100644
--- a/src/org/solovyev/android/view/SimpleOnDragListener.java
+++ b/src/org/solovyev/android/view/SimpleOnDragListener.java
@@ -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 directionEntry : distancePreferences.getDirectionPreferences().entrySet()) {
+
+ if (isInInterval(directionEntry.getValue().getInterval(), distance)) {
+ for (Map.Entry 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);
}
}
\ No newline at end of file
diff --git a/src/org/solovyev/util/math/MathUtils.java b/src/org/solovyev/util/math/MathUtils.java
index 6beda9b8..6d649ee2 100644
--- a/src/org/solovyev/util/math/MathUtils.java
+++ b/src/org/solovyev/util/math/MathUtils.java
@@ -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 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;
+ }
+
+ }
+
}