drag button calibration
This commit is contained in:
@@ -3,13 +3,11 @@ package org.solovyev.android.calculator;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.view.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.android.view.DragButton;
|
||||
import org.solovyev.android.view.DragEvent;
|
||||
import org.solovyev.android.view.OnDragListener;
|
||||
import org.solovyev.android.view.SimpleOnDragListener;
|
||||
import org.solovyev.android.view.*;
|
||||
import org.solovyev.util.StringUtils;
|
||||
import org.solovyev.util.math.MathEntityType;
|
||||
|
||||
@@ -19,14 +17,14 @@ import bsh.Interpreter;
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import org.solovyev.util.math.Point2d;
|
||||
|
||||
public class Calculator extends Activity {
|
||||
public class CalculatorActivity extends Activity {
|
||||
|
||||
@NotNull
|
||||
private EditText editText;
|
||||
|
||||
|
||||
@NotNull
|
||||
private EditText resultEditText;
|
||||
|
||||
@@ -35,18 +33,36 @@ public class Calculator extends Activity {
|
||||
|
||||
@NotNull
|
||||
private HistoryHelper<EditorHistoryState> historyHelper;
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
|
||||
/**
|
||||
* Called when the activity is first created.
|
||||
*/
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
this.editText = (EditText) findViewById(R.id.editText);
|
||||
|
||||
|
||||
this.resultEditText = (EditText) findViewById(R.id.resultEditText);
|
||||
|
||||
final SimpleOnDragListener onDragListener = new SimpleOnDragListener();
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean isDirectionSupported(@NotNull DragButton dragButton, @NotNull DragDirection direction) {
|
||||
return !StringUtils.isEmpty(getActionText(dragButton, direction));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// todo serso: check if there is more convenient method for doing this
|
||||
final R.id ids = new R.id();
|
||||
@@ -59,31 +75,31 @@ public class Calculator extends Activity {
|
||||
((DragButton) view).setOnDragListener(onDragListener);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(Calculator.class.getName(), e.getMessage());
|
||||
Log.e(CalculatorActivity.class.getName(), e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(Calculator.class.getName(), e.getMessage());
|
||||
Log.e(CalculatorActivity.class.getName(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
((DragButton) findViewById(R.id.historyButton)).setOnDragListener(new HistoryOnDragListener());
|
||||
|
||||
((DragButton) findViewById(R.id.historyButton)).setOnDragListener(new SimpleOnDragListener(new HistoryDragProcessor()));
|
||||
|
||||
this.interpreter = new Interpreter();
|
||||
|
||||
try {
|
||||
interpreter.eval(Preprocessor.wrap(JsclOperation.importCommands, "/jscl/editorengine/commands"));
|
||||
} catch (EvalError e) {
|
||||
Log.e(Calculator.class.getName(), e.getMessage());
|
||||
Log.e(CalculatorActivity.class.getName(), e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
this.historyHelper = new SimpleHistoryHelper<EditorHistoryState>();
|
||||
this.historyHelper.addState(getCurrentHistoryState());
|
||||
}
|
||||
|
||||
|
||||
public void elementaryButtonClickHandler(@NotNull View v) {
|
||||
eval(JsclOperation.elementary);
|
||||
}
|
||||
|
||||
|
||||
public void numericButtonClickHandler(@NotNull View v) {
|
||||
eval(JsclOperation.numeric);
|
||||
}
|
||||
@@ -97,25 +113,30 @@ public class Calculator extends Activity {
|
||||
final String preprocessedString = Preprocessor.process(String.valueOf(editText.getText()));
|
||||
resultEditText.setText(String.valueOf(interpreter.eval(Preprocessor.wrap(operation, preprocessedString))));
|
||||
} catch (EvalError e) {
|
||||
Log.e(Calculator.class.getName(), e.getMessage());
|
||||
Log.e(CalculatorActivity.class.getName(), e.getMessage());
|
||||
resultEditText.setText(R.string.syntax_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void digitButtonClickHandler(@NotNull View v) {
|
||||
processButtonAction(v, ((DragButton) v).getTextMiddle());
|
||||
}
|
||||
|
||||
private final class HistoryOnDragListener implements OnDragListener {
|
||||
@Override
|
||||
public void onDrag(@NotNull DragButton dragButton, @NotNull DragEvent event) {
|
||||
Log.d(String.valueOf(dragButton.getId()), "History on drag event start: " + event.getDirection());
|
||||
|
||||
String actionText = getActionText(dragButton, event);
|
||||
private final class HistoryDragProcessor implements SimpleOnDragListener.DragProcessor {
|
||||
|
||||
@Override
|
||||
public boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent) {
|
||||
boolean result = false;
|
||||
|
||||
Log.d(String.valueOf(dragButton.getId()), "History on drag event start: " + dragDirection);
|
||||
|
||||
String actionText = getActionText(dragButton, dragDirection);
|
||||
if (!StringUtils.isEmpty(actionText)) {
|
||||
try {
|
||||
result = true;
|
||||
|
||||
final HistoryAction historyAction = HistoryAction.valueOf(actionText);
|
||||
if ( historyHelper.isActionAvailable(historyAction) ){
|
||||
if (historyHelper.isActionAvailable(historyAction)) {
|
||||
final EditorHistoryState newState = historyHelper.doAction(historyAction, getCurrentHistoryState());
|
||||
if (newState != null) {
|
||||
setCurrentHistoryState(newState);
|
||||
@@ -125,51 +146,53 @@ public class Calculator extends Activity {
|
||||
Log.e(String.valueOf(dragButton.getId()), "Unsupported history action: " + actionText);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getActionText(@NotNull DragButton dragButton, @NotNull DragEvent event) {
|
||||
private static String getActionText(@NotNull DragButton dragButton, @NotNull DragDirection direction) {
|
||||
final String result;
|
||||
|
||||
switch(event.getDirection()) {
|
||||
|
||||
switch (direction) {
|
||||
case up:
|
||||
result = dragButton.getTextUp();
|
||||
break;
|
||||
|
||||
|
||||
case down:
|
||||
result = dragButton.getTextDown();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
result = null;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setCurrentHistoryState(@Nullable EditorHistoryState editorHistoryState) {
|
||||
|
||||
public void setCurrentHistoryState(@NotNull EditorHistoryState editorHistoryState) {
|
||||
this.editText.setText(editorHistoryState.getText());
|
||||
this.editText.setSelection(editorHistoryState.getCursorPosition(), editorHistoryState.getCursorPosition());
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public EditorHistoryState getCurrentHistoryState() {
|
||||
final EditorHistoryState result = new EditorHistoryState();
|
||||
|
||||
|
||||
result.setText(String.valueOf(this.editText.getText()));
|
||||
result.setCursorPosition(this.editText.getSelectionStart());
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void processButtonAction(@NotNull View v, @Nullable String text) {
|
||||
//Toast.makeText(Calculator.this, text, Toast.LENGTH_SHORT).show();
|
||||
//Toast.makeText(CalculatorActivity.this, text, Toast.LENGTH_SHORT).show();
|
||||
|
||||
if (!StringUtils.isEmpty(text)) {
|
||||
final MathEntityType type = MathEntityType.getType(text);
|
||||
|
||||
|
||||
int cursorPositionOffset = 0;
|
||||
|
||||
if (type != null) {
|
||||
@@ -187,10 +210,43 @@ public class Calculator extends Activity {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
this.editText.getText().insert(this.editText.getSelectionStart(), text);
|
||||
this.editText.setSelection(this.editText.getSelectionStart() + cursorPositionOffset, this.editText.getSelectionEnd() + cursorPositionOffset);
|
||||
this.historyHelper.addState(getCurrentHistoryState());
|
||||
this.historyHelper.addState(getCurrentHistoryState());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
final MenuInflater menuInflater = getMenuInflater();
|
||||
menuInflater.inflate(R.menu.main_menu, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
boolean result;
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_item_settings:
|
||||
showSettings();
|
||||
result = true;
|
||||
case R.id.menu_item_help:
|
||||
showHelp();
|
||||
result = true;
|
||||
default:
|
||||
result = super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void showSettings() {
|
||||
startActivity(new Intent(this, CalculatorPreferencesActivity.class));
|
||||
}
|
||||
|
||||
private void showHelp() {
|
||||
Log.d(CalculatorActivity.class + "showHelp()", "Show help!");
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
import org.apache.http.Header;
|
||||
|
||||
import java.security.KeyStore;
|
||||
import java.util.List;
|
||||
import java.util.prefs.PreferencesFactory;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 7/16/11
|
||||
* Time: 6:37 PM
|
||||
*/
|
||||
public class CalculatorPreferencesActivity extends PreferenceActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
|
||||
final Preference dragButtonCalibration = findPreference("dragButtonCalibration");
|
||||
dragButtonCalibration.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
startActivity(new Intent(CalculatorPreferencesActivity.this, DragButtonCalibrationActivity.class));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle state) {
|
||||
super.onRestoreInstanceState(state);
|
||||
}
|
||||
}
|
@@ -0,0 +1,140 @@
|
||||
package org.solovyev.android.calculator;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.solovyev.android.view.*;
|
||||
import org.solovyev.util.math.MathUtils;
|
||||
import org.solovyev.util.math.Point2d;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: serso
|
||||
* Date: 7/16/11
|
||||
* Time: 7:28 PM
|
||||
*/
|
||||
public class DragButtonCalibrationActivity extends Activity {
|
||||
|
||||
|
||||
@NotNull
|
||||
private DragDirection dragDirection = DragDirection.up;
|
||||
|
||||
private final List<DragData> dragHistory = new ArrayList<DragData>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.drag_button_calibration);
|
||||
|
||||
final DragButton calibrationButton = (DragButton) findViewById(R.id.calibrationButton);
|
||||
calibrationButton.setOnDragListener(new CalibrationOnDragListener());
|
||||
|
||||
createDragDirection();
|
||||
}
|
||||
|
||||
private void createDragDirection() {
|
||||
dragDirection = Math.random() > 0.5 ? DragDirection.up : DragDirection.down;
|
||||
|
||||
Toast.makeText(this, dragDirection.name(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
public void restartClickHandler(View v) {
|
||||
createDragDirection();
|
||||
}
|
||||
|
||||
|
||||
private class CalibrationOnDragListener implements OnDragListener {
|
||||
|
||||
@Override
|
||||
public boolean isSuppressOnClickEvent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(@NotNull DragButton dragButton, @NotNull DragEvent event) {
|
||||
final Point2d startPoint = event.getStartPoint();
|
||||
final MotionEvent motionEvent = event.getMotionEvent();
|
||||
|
||||
// init end point
|
||||
final Point2d endPoint = new Point2d(motionEvent.getX(), motionEvent.getY());
|
||||
|
||||
float distance = MathUtils.getDistance(startPoint, endPoint);
|
||||
|
||||
double angle = Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, SimpleOnDragListener.axis), endPoint));
|
||||
|
||||
assert dragDirection == DragDirection.up || dragDirection == DragDirection.down;
|
||||
if (dragDirection == DragDirection.up) {
|
||||
angle = 180 - angle;
|
||||
}
|
||||
|
||||
dragHistory.add(new DragData(distance, angle, dragDirection));
|
||||
|
||||
createDragDirection();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
|
||||
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 class DragData {
|
||||
|
||||
private float distance;
|
||||
|
||||
private double angle;
|
||||
|
||||
@NotNull
|
||||
private DragDirection direction;
|
||||
|
||||
private DragData(float distance, double angle, @NotNull DragDirection direction) {
|
||||
this.distance = distance;
|
||||
this.angle = angle;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public float getDistance() {
|
||||
return distance;
|
||||
}
|
||||
|
||||
public double getAngle() {
|
||||
return angle;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DragDirection getDirection() {
|
||||
return direction;
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@ package org.solovyev.android.view;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.android.calculator.R;
|
||||
import org.solovyev.common.utils.StringsUtils;
|
||||
import org.solovyev.util.StringUtils;
|
||||
import org.solovyev.util.math.MathUtils;
|
||||
import org.solovyev.util.math.Point2d;
|
||||
@@ -93,26 +94,29 @@ public class DragButton extends Button {
|
||||
return onDragListener;
|
||||
}
|
||||
|
||||
public void setTextUp(String textUp) {
|
||||
public void setTextUp(@Nullable String textUp) {
|
||||
this.textUp = textUp;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTextUp() {
|
||||
return textUp;
|
||||
}
|
||||
|
||||
public void setTextDown(String textDown) {
|
||||
public void setTextDown(@Nullable String textDown) {
|
||||
this.textDown = textDown;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTextDown() {
|
||||
return textDown;
|
||||
}
|
||||
|
||||
public void setTextMiddle(String textMiddle) {
|
||||
public void setTextMiddle(@Nullable String textMiddle) {
|
||||
this.textMiddle = textMiddle;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTextMiddle() {
|
||||
return textMiddle;
|
||||
}
|
||||
@@ -129,7 +133,11 @@ public class DragButton extends Button {
|
||||
public boolean onTouch(@NotNull View v, @NotNull MotionEvent event) {
|
||||
// processing on touch event
|
||||
|
||||
if (onDragListener != null) {
|
||||
// in order to avoid possible NPEs
|
||||
final Point2d localStartPoint = startPoint;
|
||||
final OnDragListener localOnDragListener = onDragListener;
|
||||
|
||||
if (localOnDragListener != null) {
|
||||
// only if onDrag() listener specified
|
||||
|
||||
Log.d(String.valueOf(getId()), "onTouch() for: " + getId() + " . Motion event: " + event);
|
||||
@@ -150,8 +158,8 @@ public class DragButton extends Button {
|
||||
case MotionEvent.ACTION_UP:
|
||||
// stop tracking
|
||||
|
||||
if (onDragListener.onDrag(DragButton.this, new DragEvent(startPoint, event))) {
|
||||
if (onDragListener.isSuppressOnClickEvent()) {
|
||||
if (localStartPoint != null && localOnDragListener.onDrag(DragButton.this, new DragEvent(localStartPoint, event))) {
|
||||
if (localOnDragListener.isSuppressOnClickEvent()) {
|
||||
// prevent on click action
|
||||
setPressed(false);
|
||||
}
|
||||
|
@@ -3,5 +3,7 @@ package org.solovyev.android.view;
|
||||
public enum DragDirection {
|
||||
|
||||
up,
|
||||
down;
|
||||
down,
|
||||
left,
|
||||
right;
|
||||
}
|
||||
|
@@ -6,10 +6,10 @@ import org.solovyev.util.math.Point2d;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
public class DragEvent {
|
||||
|
||||
|
||||
@NotNull
|
||||
private final Point2d startPoint;
|
||||
|
||||
|
||||
@NotNull
|
||||
private final MotionEvent motionEvent;
|
||||
|
||||
@@ -18,16 +18,21 @@ public class DragEvent {
|
||||
this.motionEvent = motionEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return motion event started at start point
|
||||
*/
|
||||
@NotNull
|
||||
public MotionEvent getMotionEvent() {
|
||||
return motionEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return start point of dragging
|
||||
*/
|
||||
@NotNull
|
||||
public Point2d getStartPoint() {
|
||||
return startPoint;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,8 +1,6 @@
|
||||
package org.solovyev.android.view;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.solovyev.util.StringUtils;
|
||||
import org.solovyev.util.math.MathUtils;
|
||||
import org.solovyev.util.math.Point2d;
|
||||
|
||||
@@ -12,8 +10,8 @@ import android.view.MotionEvent;
|
||||
public class SimpleOnDragListener implements OnDragListener {
|
||||
|
||||
@NotNull
|
||||
private final Point2d axis = new Point2d(0, 1);
|
||||
|
||||
public static final Point2d axis = new Point2d(0, 1);
|
||||
|
||||
private float minDragDist = 20f;
|
||||
|
||||
private float maxDragDist = 80f;
|
||||
@@ -21,73 +19,79 @@ public class SimpleOnDragListener implements OnDragListener {
|
||||
// max angle (in degrees!) between start and end point vector and axis
|
||||
// vector to register drag event
|
||||
private double maxAngle = 30;
|
||||
|
||||
@NotNull
|
||||
private DragProcessor dragProcessor;
|
||||
|
||||
public SimpleOnDragListener() {
|
||||
}
|
||||
|
||||
public SimpleOnDragListener(@NotNull DragProcessor dragProcessor) {
|
||||
this.dragProcessor = dragProcessor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(@NotNull DragButton dragButton, @NotNull DragEvent event) {
|
||||
boolean result = false;
|
||||
|
||||
logDragEvent(dragButton, event);
|
||||
|
||||
processButtonAction(dragButton, getActionText(dragButton, event));
|
||||
|
||||
final Point2d startPoint = event.getStartPoint();
|
||||
final MotionEvent motionEvent = event.getMotionEvent();
|
||||
|
||||
// init end point
|
||||
final Point2d endPoint = new Point2d(motionEvent.getX(), motionEvent.getY());
|
||||
|
||||
float distance = MathUtils.getDistance(startPoint, endPoint);
|
||||
|
||||
if (minDragDist < distance && distance < maxDragDist) {
|
||||
double angle = Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint));
|
||||
|
||||
final DragDirection direction;
|
||||
if (angle < maxAngle) {
|
||||
direction = DragDirection.down;
|
||||
} else if (180 - angle < maxAngle) {
|
||||
direction = DragDirection.up;
|
||||
} else {
|
||||
direction = null;
|
||||
}
|
||||
|
||||
if (direction != null) {
|
||||
result = dragProcessor.processDragEvent(direction, dragButton, startPoint, motionEvent);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressOnClickEvent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method creates drag event in case if all conditions are satisfied
|
||||
*
|
||||
* @param event
|
||||
* motion event
|
||||
*
|
||||
* @return filled drag event object only if drag event is possible, null
|
||||
* otherwise
|
||||
*/
|
||||
@Nullable
|
||||
protected DragEvent getDragEvent(@NotNull MotionEvent event) {
|
||||
DragEvent result = null;
|
||||
|
||||
if (startPoint != null) {
|
||||
final Point2d endPoint = new Point2d(event.getX(), event.getY());
|
||||
float distance = MathUtils.getDistance(startPoint, endPoint);
|
||||
|
||||
if (minDragDist < distance && distance < maxDragDist) {
|
||||
double angle = Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint));
|
||||
|
||||
final DragDirection direction;
|
||||
if (angle < maxAngle) {
|
||||
direction = DragDirection.down;
|
||||
} else if (180 - angle < maxAngle) {
|
||||
direction = DragDirection.up;
|
||||
} else {
|
||||
direction = null;
|
||||
}
|
||||
|
||||
if (direction != null) {
|
||||
if ( direction == DragDirection.up && StringUtils.isEmpty(textUp) ) {
|
||||
// no action if text is empty
|
||||
} else if (direction == DragDirection.down && StringUtils.isEmpty(textDown)) {
|
||||
// no action if text is empty
|
||||
} else {
|
||||
result = new DragEvent(direction);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void logDragEvent(@NotNull DragButton dragButton, @NotNull DragEvent event) {
|
||||
final Point2d startPoint = event.getStartPoint();
|
||||
final MotionEvent motionEvent = event.getMotionEvent();
|
||||
final Point2d endPoint = new Point2d(motionEvent.getX(), motionEvent.getY());
|
||||
|
||||
Log.d(String.valueOf(dragButton.getId()), "Start point: " + startPoint + ", End point: " + endPoint);
|
||||
Log.d(String.valueOf(dragButton.getId()), "Distance: " + MathUtils.getDistance(startPoint, endPoint));
|
||||
Log.d(String.valueOf(dragButton.getId()), "Angle: " + Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint)));
|
||||
Log.d(String.valueOf(dragButton.getId()), "Axis: " + axis + " Vector: " + MathUtils.subtract(endPoint, startPoint));
|
||||
Log.d(String.valueOf(dragButton.getId()), "Total time: " + (motionEvent.getEventTime() - motionEvent.getDownTime()) + " ms");
|
||||
final Point2d startPoint = event.getStartPoint();
|
||||
final MotionEvent motionEvent = event.getMotionEvent();
|
||||
final Point2d endPoint = new Point2d(motionEvent.getX(), motionEvent.getY());
|
||||
|
||||
Log.d(String.valueOf(dragButton.getId()), "Start point: " + startPoint + ", End point: " + endPoint);
|
||||
Log.d(String.valueOf(dragButton.getId()), "Distance: " + MathUtils.getDistance(startPoint, endPoint));
|
||||
Log.d(String.valueOf(dragButton.getId()), "Angle: " + Math.toDegrees(MathUtils.getAngle(startPoint, MathUtils.sum(startPoint, axis), endPoint)));
|
||||
Log.d(String.valueOf(dragButton.getId()), "Axis: " + axis + " Vector: " + MathUtils.subtract(endPoint, startPoint));
|
||||
Log.d(String.valueOf(dragButton.getId()), "Total time: " + (motionEvent.getEventTime() - motionEvent.getDownTime()) + " ms");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DragProcessor getDragProcessor() {
|
||||
return dragProcessor;
|
||||
}
|
||||
|
||||
public void setDragProcessor(@NotNull DragProcessor dragProcessor) {
|
||||
this.dragProcessor = dragProcessor;
|
||||
}
|
||||
|
||||
public interface DragProcessor {
|
||||
|
||||
boolean processDragEvent(@NotNull DragDirection dragDirection, @NotNull DragButton dragButton, @NotNull Point2d startPoint2d, @NotNull MotionEvent motionEvent);
|
||||
}
|
||||
}
|
@@ -2,17 +2,19 @@ package org.solovyev.util.math;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MathUtils {
|
||||
|
||||
public static float getDistance(@NotNull Point2d startPoint,
|
||||
@NotNull Point2d endPoint) {
|
||||
@NotNull Point2d endPoint) {
|
||||
return getNorm(subtract(endPoint, startPoint));
|
||||
}
|
||||
|
||||
public static Point2d subtract(@NotNull Point2d p1, @NotNull Point2d p2) {
|
||||
return new Point2d(p1.getX() - p2.getX(), p1.getY() - p2.getY());
|
||||
}
|
||||
|
||||
|
||||
public static Point2d sum(@NotNull Point2d p1, @NotNull Point2d p2) {
|
||||
return new Point2d(p1.getX() + p2.getX(), p1.getY() + p2.getY());
|
||||
}
|
||||
@@ -23,7 +25,7 @@ public class MathUtils {
|
||||
}
|
||||
|
||||
public static float getAngle(@NotNull Point2d startPoint,
|
||||
@NotNull Point2d axisEndPoint, @NotNull Point2d endPoint) {
|
||||
@NotNull Point2d axisEndPoint, @NotNull Point2d endPoint) {
|
||||
final Point2d axisVector = subtract(axisEndPoint, startPoint);
|
||||
final Point2d vector = subtract(endPoint, startPoint);
|
||||
|
||||
@@ -36,4 +38,24 @@ public class MathUtils {
|
||||
return (float) Math.acos((-a_2 + b_2 + c_2) / (2 * b * c));
|
||||
}
|
||||
|
||||
public static double countMean(@NotNull List<Double> objects) {
|
||||
|
||||
double sum = 0d;
|
||||
for (Double object : objects) {
|
||||
sum += object;
|
||||
}
|
||||
|
||||
return objects.size() == 0 ? 0d : (sum / objects.size());
|
||||
}
|
||||
|
||||
public static double countStandardDeviation(@NotNull Double mean, @NotNull List<Double> objects) {
|
||||
double sum = 0d;
|
||||
|
||||
for (Double object : objects) {
|
||||
sum += Math.pow(object - mean, 2);
|
||||
}
|
||||
|
||||
return objects.size() == 0 ? 0d : Math.sqrt(sum / objects.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user