drag button calibration
This commit is contained in:
parent
70ff5a109e
commit
0063f193ff
@ -13,6 +13,7 @@
|
|||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action a:name="android.intent.action.MAIN" />
|
<action a:name="android.intent.action.MAIN" />
|
||||||
<category a:name="android.intent.category.LAUNCHER" />
|
<category a:name="android.intent.category.LAUNCHER" />
|
||||||
|
<action a:name="org.solovyev.android.calculator.DragButtonPreferencesChanged"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
@ -27,39 +27,44 @@ containing a value of this type.
|
|||||||
public static final int textUp=0x7f010000;
|
public static final int textUp=0x7f010000;
|
||||||
}
|
}
|
||||||
public static final class drawable {
|
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 class id {
|
||||||
public static final int calibrationButton=0x7f080000;
|
public static final int calibrationArrow=0x7f080000;
|
||||||
public static final int calibrationStart=0x7f080001;
|
public static final int calibrationButton=0x7f080001;
|
||||||
public static final int curlyBracketsButton=0x7f080015;
|
public static final int calibrationStart=0x7f080002;
|
||||||
public static final int editText=0x7f080002;
|
public static final int curlyBracketsButton=0x7f080016;
|
||||||
public static final int eigthDigitButton=0x7f080011;
|
public static final int editText=0x7f080003;
|
||||||
public static final int equalsButton=0x7f080013;
|
public static final int eigthDigitButton=0x7f080012;
|
||||||
public static final int fiveDigitButton=0x7f08000b;
|
public static final int equalsButton=0x7f080014;
|
||||||
public static final int fourDigitButton=0x7f08000a;
|
public static final int fiveDigitButton=0x7f08000c;
|
||||||
public static final int historyButton=0x7f08001a;
|
public static final int fourDigitButton=0x7f08000b;
|
||||||
public static final int menu_item_help=0x7f08001d;
|
public static final int historyButton=0x7f08001b;
|
||||||
public static final int menu_item_settings=0x7f08001c;
|
public static final int menu_item_help=0x7f08001e;
|
||||||
public static final int minusButton=0x7f08000e;
|
public static final int menu_item_settings=0x7f08001d;
|
||||||
public static final int muliplicationButton=0x7f080007;
|
public static final int minusButton=0x7f08000f;
|
||||||
public static final int nineDigitButton=0x7f080012;
|
public static final int muliplicationButton=0x7f080008;
|
||||||
public static final int numericButton=0x7f080018;
|
public static final int nineDigitButton=0x7f080013;
|
||||||
public static final int oneDigitButton=0x7f080004;
|
public static final int numericButton=0x7f080019;
|
||||||
public static final int piButton=0x7f08001b;
|
public static final int oneDigitButton=0x7f080005;
|
||||||
public static final int plusButton=0x7f080008;
|
public static final int piButton=0x7f08001c;
|
||||||
public static final int pointDigitButton=0x7f080017;
|
public static final int plusButton=0x7f080009;
|
||||||
public static final int resultEditText=0x7f080003;
|
public static final int pointDigitButton=0x7f080018;
|
||||||
public static final int roundBracketsButton=0x7f080009;
|
public static final int resultEditText=0x7f080004;
|
||||||
public static final int sevenDigitButton=0x7f080010;
|
public static final int roundBracketsButton=0x7f08000a;
|
||||||
public static final int simplifyButton=0x7f080019;
|
public static final int sevenDigitButton=0x7f080011;
|
||||||
public static final int sixDigitButton=0x7f08000c;
|
public static final int simplifyButton=0x7f08001a;
|
||||||
public static final int sqrtButton=0x7f080014;
|
public static final int sixDigitButton=0x7f08000d;
|
||||||
public static final int squareBracketsButton=0x7f08000f;
|
public static final int sqrtButton=0x7f080015;
|
||||||
public static final int subtractionButton=0x7f08000d;
|
public static final int squareBracketsButton=0x7f080010;
|
||||||
public static final int threeDigitButton=0x7f080006;
|
public static final int subtractionButton=0x7f08000e;
|
||||||
public static final int twoDigitButton=0x7f080005;
|
public static final int threeDigitButton=0x7f080007;
|
||||||
public static final int zeroDigitButton=0x7f080016;
|
public static final int twoDigitButton=0x7f080006;
|
||||||
|
public static final int zeroDigitButton=0x7f080017;
|
||||||
}
|
}
|
||||||
public static final class layout {
|
public static final class layout {
|
||||||
public static final int drag_button_calibration=0x7f030000;
|
public static final int drag_button_calibration=0x7f030000;
|
||||||
|
BIN
res/drawable/down.png
Normal file
BIN
res/drawable/down.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
BIN
res/drawable/not_ok.png
Normal file
BIN
res/drawable/not_ok.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.1 KiB |
BIN
res/drawable/ok.png
Normal file
BIN
res/drawable/ok.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.5 KiB |
BIN
res/drawable/up.png
Normal file
BIN
res/drawable/up.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
@ -8,20 +8,29 @@
|
|||||||
a:layout_width="fill_parent"
|
a:layout_width="fill_parent"
|
||||||
a:layout_height="fill_parent">
|
a:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<LinearLayout a:orientation="horizontal"
|
||||||
|
a:layout_width="fill_parent"
|
||||||
|
a:layout_height="wrap_content">
|
||||||
|
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/calibrationButton"
|
<ImageView a:id="@+id/calibrationArrow"
|
||||||
a:text=""
|
a:layout_gravity="left"
|
||||||
calc:textUp="@string/c_up"
|
a:layout_width="80dp"
|
||||||
calc:textDown="@string/c_down"
|
a:layout_height="80dp"/>
|
||||||
style="@style/digitButtonStyle"
|
|
||||||
a:layout_width="50dp"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/calibrationButton"
|
||||||
a:layout_height="50dp"
|
a:text=""
|
||||||
a:gravity="center_vertical" />
|
calc:textUp="@string/c_up"
|
||||||
|
calc:textDown="@string/c_down"
|
||||||
|
style="@style/digitButtonStyle"
|
||||||
|
a:layout_width="80dp"
|
||||||
|
a:layout_height="80dp"
|
||||||
|
a:layout_gravity="center_horizontal"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<Button a:id="@+id/calibrationStart"
|
<Button a:id="@+id/calibrationStart"
|
||||||
a:text="@string/c_restart"
|
a:text="@string/c_restart"
|
||||||
a:layout_width="wrap_content"
|
a:layout_width="wrap_content"
|
||||||
a:layout_height="wrap_content"
|
a:layout_height="wrap_content"
|
||||||
a:onClick="restartClickHandler"
|
a:onClick="restartClickHandler"
|
||||||
a:gravity="bottom"/>
|
a:layout_gravity="bottom"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -30,36 +30,36 @@
|
|||||||
a:layout_width="fill_parent"
|
a:layout_width="fill_parent"
|
||||||
a:layout_height="fill_parent">
|
a:layout_height="fill_parent">
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/oneDigitButton" a:text="1" calc:textUp="sin" calc:textDown="asin" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/oneDigitButton" a:text="1" calc:textUp="sin" calc:textDown="asin" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/twoDigitButton" a:text="2" calc:textUp="cos" calc:textDown="acos" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/twoDigitButton" a:text="2" calc:textUp="cos" calc:textDown="acos" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/threeDigitButton" a:text="3" calc:textUp="tg" calc:textDown="atg" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/threeDigitButton" a:text="3" calc:textUp="tg" calc:textDown="atg" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/muliplicationButton" a:text="*" calc:textUp="^" calc:textDown="^2" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/muliplicationButton" a:text="*" calc:textUp="^" calc:textDown="^2" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/plusButton" a:text="+" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/plusButton" a:text="+" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/roundBracketsButton" a:text="()" calc:textUp="(" calc:textDown=")" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/roundBracketsButton" a:text="()" calc:textUp="(" calc:textDown=")" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/fourDigitButton" a:text="4" calc:textUp="exp" calc:textDown="mod" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/fourDigitButton" a:text="4" calc:textUp="exp" calc:textDown="mod" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/fiveDigitButton" a:text="5" calc:textUp="log" calc:textDown="ln" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/fiveDigitButton" a:text="5" calc:textUp="log" calc:textDown="ln" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/sixDigitButton" a:text="6" calc:textUp="!" calc:textDown="" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sixDigitButton" a:text="6" calc:textUp="!" calc:textDown="" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/subtractionButton" a:text="/" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/subtractionButton" a:text="/" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/minusButton" a:text="-" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/minusButton" a:text="-" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/squareBracketsButton" a:text="[]" calc:textUp="[" calc:textDown="]" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/squareBracketsButton" a:text="[]" calc:textUp="[" calc:textDown="]" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/sevenDigitButton" a:text="7" calc:textUp="" calc:textDown="" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sevenDigitButton" a:text="7" calc:textUp="" calc:textDown="" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/eigthDigitButton" a:text="8" calc:textUp="" calc:textDown="" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/eigthDigitButton" a:text="8" calc:textUp="" calc:textDown="" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/nineDigitButton" a:text="9" calc:textUp="" calc:textDown="" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/nineDigitButton" a:text="9" calc:textUp="" calc:textDown="" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/equalsButton" a:text="=" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/equalsButton" a:text="=" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/sqrtButton" a:text="sqrt" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sqrtButton" a:text="sqrt" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/curlyBracketsButton" a:text="{}" calc:textUp="{" calc:textDown="}" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/curlyBracketsButton" a:text="{}" calc:textUp="{" calc:textDown="}" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/zeroDigitButton" a:text="0" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/zeroDigitButton" a:text="0" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/pointDigitButton" a:text="." calc:textDown="," style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/pointDigitButton" a:text="." calc:textDown="," style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/numericButton" a:text="numeric" style="@style/digitButtonStyle" a:onClick="numericButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/numericButton" a:text="numeric" style="@style/digitButtonStyle" a:onClick="numericButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/simplifyButton" a:text="simplify" style="@style/digitButtonStyle" a:onClick="simplifyButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/simplifyButton" a:text="simplify" style="@style/digitButtonStyle" a:onClick="simplifyButtonClickHandler"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/historyButton" calc:textUp="undo" calc:textDown="redo" style="@style/digitButtonStyle"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/historyButton" calc:textUp="undo" calc:textDown="redo" style="@style/digitButtonStyle"/>
|
||||||
<org.solovyev.android.view.DragButton a:id="@+id/piButton" a:text="pi" calc:textUp="e" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/piButton" a:text="pi" calc:textUp="e" style="@style/digitButtonStyle" a:onClick="digitButtonClickHandler"/>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableLayout>
|
</TableLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -2,8 +2,14 @@ package org.solovyev.android.calculator;
|
|||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
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.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.os.Handler;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -34,6 +40,12 @@ public class CalculatorActivity extends Activity {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private HistoryHelper<EditorHistoryState> historyHelper;
|
private HistoryHelper<EditorHistoryState> historyHelper;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private BroadcastReceiver preferencesChangesReceiver;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private List<SimpleOnDragListener> onDragListeners = new ArrayList<SimpleOnDragListener>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the activity is first created.
|
* Called when the activity is first created.
|
||||||
*/
|
*/
|
||||||
@ -46,23 +58,19 @@ public class CalculatorActivity extends Activity {
|
|||||||
|
|
||||||
this.resultEditText = (EditText) findViewById(R.id.resultEditText);
|
this.resultEditText = (EditText) findViewById(R.id.resultEditText);
|
||||||
|
|
||||||
|
final DragButtonCalibrationActivity.Preferences dragPreferences = DragButtonCalibrationActivity.getPreferences(this);
|
||||||
|
|
||||||
final SimpleOnDragListener onDragListener = new SimpleOnDragListener(new SimpleOnDragListener.DragProcessor() {
|
final SimpleOnDragListener onDragListener = new SimpleOnDragListener(new SimpleOnDragListener.DragProcessor() {
|
||||||
@Override
|
@Override
|
||||||
public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
|
public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
|
||||||
boolean result = isDirectionSupported(dragButton, dragDirection);
|
assert dragButton instanceof DirectionDragButton;
|
||||||
|
processButtonAction(dragButton, getActionText((DirectionDragButton) dragButton, dragDirection));
|
||||||
if (result) {
|
return true;
|
||||||
processButtonAction(dragButton, getActionText(dragButton, dragDirection));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDirectionSupported(@NotNull DragButton dragButton, @NotNull DragDirection direction) {
|
}, dragPreferences);
|
||||||
return !StringUtils.isEmpty(getActionText(dragButton, direction));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
onDragListeners.add(onDragListener);
|
||||||
|
|
||||||
// todo serso: check if there is more convenient method for doing this
|
// todo serso: check if there is more convenient method for doing this
|
||||||
final R.id ids = new R.id();
|
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();
|
this.interpreter = new Interpreter();
|
||||||
|
|
||||||
@ -94,6 +104,19 @@ public class CalculatorActivity extends Activity {
|
|||||||
|
|
||||||
this.historyHelper = new SimpleHistoryHelper<EditorHistoryState>();
|
this.historyHelper = new SimpleHistoryHelper<EditorHistoryState>();
|
||||||
this.historyHelper.addState(getCurrentHistoryState());
|
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) {
|
public void elementaryButtonClickHandler(@NotNull View v) {
|
||||||
@ -119,7 +142,7 @@ public class CalculatorActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void digitButtonClickHandler(@NotNull View v) {
|
public void digitButtonClickHandler(@NotNull View v) {
|
||||||
processButtonAction(v, ((DragButton) v).getTextMiddle());
|
processButtonAction(v, ((DirectionDragButton) v).getTextMiddle());
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class HistoryDragProcessor implements SimpleOnDragListener.DragProcessor {
|
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);
|
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)) {
|
if (!StringUtils.isEmpty(actionText)) {
|
||||||
try {
|
try {
|
||||||
result = true;
|
result = true;
|
||||||
@ -152,7 +176,7 @@ public class CalculatorActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static String getActionText(@NotNull DragButton dragButton, @NotNull DragDirection direction) {
|
private static String getActionText(@NotNull DirectionDragButton dragButton, @NotNull DragDirection direction) {
|
||||||
final String result;
|
final String result;
|
||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
|
@ -1,19 +1,30 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import android.app.Activity;
|
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.os.Bundle;
|
||||||
import android.preference.PreferenceActivity;
|
import android.os.Handler;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.ImageView;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.solovyev.android.view.*;
|
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.MathUtils;
|
||||||
import org.solovyev.util.math.Point2d;
|
import org.solovyev.util.math.Point2d;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
@ -22,12 +33,34 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class DragButtonCalibrationActivity extends Activity {
|
public class DragButtonCalibrationActivity extends Activity {
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private DragDirection dragDirection = DragDirection.up;
|
private DragDirection dragDirection = DragDirection.up;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
private final List<DragData> dragHistory = new ArrayList<DragData>();
|
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
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@ -37,17 +70,23 @@ public class DragButtonCalibrationActivity extends Activity {
|
|||||||
final DragButton calibrationButton = (DragButton) findViewById(R.id.calibrationButton);
|
final DragButton calibrationButton = (DragButton) findViewById(R.id.calibrationButton);
|
||||||
calibrationButton.setOnDragListener(new CalibrationOnDragListener());
|
calibrationButton.setOnDragListener(new CalibrationOnDragListener());
|
||||||
|
|
||||||
createDragDirection();
|
calibrationArrow = (ImageView) findViewById(R.id.calibrationArrow);
|
||||||
|
|
||||||
|
createDragDirection(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createDragDirection() {
|
private void createDragDirection(long timeout) {
|
||||||
dragDirection = Math.random() > 0.5 ? DragDirection.up : DragDirection.down;
|
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) {
|
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));
|
double angle = Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, SimpleOnDragListener.axis), endPoint));
|
||||||
|
|
||||||
assert dragDirection == DragDirection.up || dragDirection == DragDirection.down;
|
assert dragDirection == DragDirection.up || dragDirection == DragDirection.down;
|
||||||
|
|
||||||
|
double deviationAngle = angle;
|
||||||
if (dragDirection == DragDirection.up) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -86,28 +132,210 @@ public class DragButtonCalibrationActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||||
final List<Double> angleValues = new ArrayList<Double>();
|
|
||||||
final List<Double> distanceValues = new ArrayList<Double>();
|
if (dragHistory.size() > MIN_HISTORY_FOR_CALIBRATION) {
|
||||||
for (DragData dragData : dragHistory) {
|
final ManyValuedMap<DragDirection, Double> anglesByDirection = new ManyValuedHashMap<DragDirection, Double>();
|
||||||
angleValues.add(dragData.getAngle());
|
final ManyValuedMap<DragDirection, Double> distancesByDirection = new ManyValuedHashMap<DragDirection, Double>();
|
||||||
distanceValues.add((double) dragData.getDistance());
|
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);
|
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 {
|
private class DragData {
|
||||||
|
|
||||||
@ -115,13 +343,16 @@ public class DragButtonCalibrationActivity extends Activity {
|
|||||||
|
|
||||||
private double angle;
|
private double angle;
|
||||||
|
|
||||||
|
private double time;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private DragDirection direction;
|
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.distance = distance;
|
||||||
this.angle = angle;
|
this.angle = angle;
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDistance() {
|
public float getDistance() {
|
||||||
@ -136,5 +367,9 @@ public class DragButtonCalibrationActivity extends Activity {
|
|||||||
public DragDirection getDirection() {
|
public DragDirection getDirection() {
|
||||||
return direction;
|
return direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
99
src/org/solovyev/android/view/DirectionDragButton.java
Normal file
99
src/org/solovyev/android/view/DirectionDragButton.java
Normal 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, " ") + "</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, " "));
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -19,9 +19,6 @@ import android.widget.Button;
|
|||||||
|
|
||||||
public class DragButton extends Button {
|
public class DragButton extends Button {
|
||||||
|
|
||||||
// max time in ms to register drag event
|
|
||||||
private long maxTime = 700;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Point2d startPoint = null;
|
private Point2d startPoint = null;
|
||||||
|
|
||||||
@ -30,61 +27,16 @@ public class DragButton extends Button {
|
|||||||
|
|
||||||
private final OnTouchListener onTouchListener = new OnTouchListenerImpl();
|
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) {
|
public DragButton(Context context, @NotNull AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
init(context, attrs);
|
setOnTouchListener(this.onTouchListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DragButton(Context context, AttributeSet attrs, int defStyle) {
|
public DragButton(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, 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, " ") + "</b><br>" + getStyledUpDownText(this.textDown)));
|
|
||||||
|
|
||||||
// change top padding in order to show all text
|
|
||||||
setPadding(getPaddingLeft(), -7, getPaddingRight(), getPaddingBottom());
|
|
||||||
|
|
||||||
setOnTouchListener(this.onTouchListener);
|
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, " "));
|
|
||||||
sb.append("</small></small></font>");
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnDragListener(@Nullable OnDragListener onDragListener) {
|
public void setOnDragListener(@Nullable OnDragListener onDragListener) {
|
||||||
this.onDragListener = onDragListener;
|
this.onDragListener = onDragListener;
|
||||||
}
|
}
|
||||||
@ -94,33 +46,6 @@ public class DragButton extends Button {
|
|||||||
return onDragListener;
|
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()
|
* OnTouchListener implementation that fires onDrag()
|
||||||
*
|
*
|
||||||
@ -148,13 +73,6 @@ public class DragButton extends Button {
|
|||||||
startPoint = new Point2d(event.getX(), event.getY());
|
startPoint = new Point2d(event.getX(), event.getY());
|
||||||
break;
|
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:
|
case MotionEvent.ACTION_UP:
|
||||||
// stop tracking
|
// stop tracking
|
||||||
|
|
||||||
|
@ -1,33 +1,38 @@
|
|||||||
package org.solovyev.android.view;
|
package org.solovyev.android.view;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.MathUtils;
|
||||||
import org.solovyev.util.math.Point2d;
|
import org.solovyev.util.math.Point2d;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class SimpleOnDragListener implements OnDragListener {
|
public class SimpleOnDragListener implements OnDragListener {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final Point2d axis = new Point2d(0, 1);
|
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
|
@NotNull
|
||||||
private DragProcessor dragProcessor;
|
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.dragProcessor = dragProcessor;
|
||||||
|
this.preferences = preferences;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreferences(@NotNull DragButtonCalibrationActivity.Preferences preferences) {
|
||||||
|
this.preferences = preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -42,28 +47,48 @@ public class SimpleOnDragListener implements OnDragListener {
|
|||||||
// init end point
|
// init end point
|
||||||
final Point2d endPoint = new Point2d(motionEvent.getX(), motionEvent.getY());
|
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) {
|
final DragButtonCalibrationActivity.Preference distancePreferences = preferences.getPreferencesMap().get(DragButtonCalibrationActivity.PreferenceType.distance);
|
||||||
double angle = Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint));
|
final DragButtonCalibrationActivity.Preference anglePreferences = preferences.getPreferencesMap().get(DragButtonCalibrationActivity.PreferenceType.angle);
|
||||||
|
|
||||||
final DragDirection direction;
|
DragDirection direction = null;
|
||||||
if (angle < maxAngle) {
|
for (Map.Entry<DragDirection, DragButtonCalibrationActivity.DragPreference> directionEntry : distancePreferences.getDirectionPreferences().entrySet()) {
|
||||||
direction = DragDirection.down;
|
|
||||||
} else if (180 - angle < maxAngle) {
|
if (isInInterval(directionEntry.getValue().getInterval(), distance)) {
|
||||||
direction = DragDirection.up;
|
for (Map.Entry<DragDirection, DragButtonCalibrationActivity.DragPreference> angleEntry : anglePreferences.getDirectionPreferences().entrySet()) {
|
||||||
} else {
|
if (isInInterval(angleEntry.getValue().getInterval(), (float)angle)) {
|
||||||
direction = null;
|
direction = angleEntry.getKey();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direction != null) {
|
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);
|
result = dragProcessor.processDragEvent(direction, dragButton, startPoint, motionEvent);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isInInterval(@NotNull Interval interval, float value) {
|
||||||
|
return interval.getStart() - MathUtils.MIN_AMOUNT <= value && value <= interval.getEnd() + MathUtils.MIN_AMOUNT;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSuppressOnClickEvent() {
|
public boolean isSuppressOnClickEvent() {
|
||||||
return true;
|
return true;
|
||||||
@ -91,7 +116,7 @@ public class SimpleOnDragListener implements OnDragListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface DragProcessor {
|
public interface DragProcessor {
|
||||||
|
|
||||||
boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent);
|
boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,6 +6,8 @@ import java.util.List;
|
|||||||
|
|
||||||
public class MathUtils {
|
public class MathUtils {
|
||||||
|
|
||||||
|
public static final float MIN_AMOUNT = 0.05f;
|
||||||
|
|
||||||
public static float getDistance(@NotNull Point2d startPoint,
|
public static float getDistance(@NotNull Point2d startPoint,
|
||||||
@NotNull Point2d endPoint) {
|
@NotNull Point2d endPoint) {
|
||||||
return getNorm(subtract(endPoint, startPoint));
|
return getNorm(subtract(endPoint, startPoint));
|
||||||
@ -58,4 +60,33 @@ public class MathUtils {
|
|||||||
return objects.size() == 0 ? 0d : Math.sqrt(sum / objects.size());
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user