refactored mainactivity and moved some files into ui package
This commit is contained in:
@@ -1,823 +0,0 @@
|
|||||||
package de.tonifetzer.conductorswatch;
|
|
||||||
|
|
||||||
import android.animation.ArgbEvaluator;
|
|
||||||
import android.animation.ObjectAnimator;
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import de.tonifetzer.conductorswatch.R;
|
|
||||||
import de.tonifetzer.conductorswatch.utilities.Utils;
|
|
||||||
|
|
||||||
public class Croller extends View {
|
|
||||||
|
|
||||||
private float midx, midy;
|
|
||||||
private Paint textPaint, circlePaint, circlePaint2, linePaint;
|
|
||||||
private float currdeg = 0, deg = 3, downdeg = 0;
|
|
||||||
|
|
||||||
private boolean isContinuous = false;
|
|
||||||
|
|
||||||
private int backCircleColor = Color.parseColor("#222222");
|
|
||||||
private int mainCircleColor = Color.parseColor("#000000");
|
|
||||||
private int indicatorColor = Color.parseColor("#FFA036");
|
|
||||||
private int progressPrimaryColor = Color.parseColor("#FFA036");
|
|
||||||
private int progressSecondaryColor = Color.parseColor("#111111");
|
|
||||||
|
|
||||||
private float progressPrimaryCircleSize = -1;
|
|
||||||
private float progressSecondaryCircleSize = -1;
|
|
||||||
|
|
||||||
private float progressPrimaryStrokeWidth = 25;
|
|
||||||
private float progressSecondaryStrokeWidth = 10;
|
|
||||||
|
|
||||||
private float mainCircleRadius = -1;
|
|
||||||
private float backCircleRadius = -1;
|
|
||||||
private float progressRadius = -1;
|
|
||||||
|
|
||||||
private float touchCircleRadiusMax = -1;
|
|
||||||
private float touchCircleRadiusMin = -1;
|
|
||||||
|
|
||||||
private int max = 25;
|
|
||||||
private int min = 1;
|
|
||||||
|
|
||||||
private float indicatorWidth = 7;
|
|
||||||
|
|
||||||
private String label = "Label";
|
|
||||||
private int labelSize = 20;
|
|
||||||
private int labelColor = Color.WHITE;
|
|
||||||
|
|
||||||
private int startOffset = 30;
|
|
||||||
private int startOffset2 = 0;
|
|
||||||
private int sweepAngle = -1;
|
|
||||||
|
|
||||||
private boolean isAntiClockwise = false;
|
|
||||||
|
|
||||||
private boolean startEventSent = false;
|
|
||||||
|
|
||||||
RectF oval;
|
|
||||||
|
|
||||||
private onProgressChangedListener mProgressChangeListener;
|
|
||||||
private OnCrollerChangeListener mCrollerChangeListener;
|
|
||||||
|
|
||||||
public interface onProgressChangedListener {
|
|
||||||
void onProgressChanged(int progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnProgressChangedListener(onProgressChangedListener mProgressChangeListener) {
|
|
||||||
this.mProgressChangeListener = mProgressChangeListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnCrollerChangeListener(OnCrollerChangeListener mCrollerChangeListener) {
|
|
||||||
this.mCrollerChangeListener = mCrollerChangeListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Croller(Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Croller(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
initXMLAttrs(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Croller(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
initXMLAttrs(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
textPaint = new Paint();
|
|
||||||
textPaint.setAntiAlias(true);
|
|
||||||
textPaint.setColor(labelColor);
|
|
||||||
textPaint.setStyle(Paint.Style.FILL);
|
|
||||||
textPaint.setTextSize(labelSize);
|
|
||||||
textPaint.setFakeBoldText(true);
|
|
||||||
textPaint.setTextAlign(Paint.Align.CENTER);
|
|
||||||
|
|
||||||
circlePaint = new Paint();
|
|
||||||
circlePaint.setAntiAlias(true);
|
|
||||||
circlePaint.setColor(progressSecondaryColor);
|
|
||||||
circlePaint.setStrokeWidth(progressSecondaryStrokeWidth);
|
|
||||||
circlePaint.setStyle(Paint.Style.FILL);
|
|
||||||
|
|
||||||
circlePaint2 = new Paint();
|
|
||||||
circlePaint2.setAntiAlias(true);
|
|
||||||
circlePaint2.setColor(progressPrimaryColor);
|
|
||||||
circlePaint2.setStrokeWidth(progressPrimaryStrokeWidth);
|
|
||||||
circlePaint2.setStyle(Paint.Style.FILL);
|
|
||||||
|
|
||||||
linePaint = new Paint();
|
|
||||||
linePaint.setAntiAlias(true);
|
|
||||||
linePaint.setColor(indicatorColor);
|
|
||||||
linePaint.setStrokeWidth(indicatorWidth);
|
|
||||||
|
|
||||||
oval = new RectF();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initXMLAttrs(Context context, AttributeSet attrs) {
|
|
||||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Croller);
|
|
||||||
final int N = a.getIndexCount();
|
|
||||||
for (int i = 0; i < N; ++i) {
|
|
||||||
int attr = a.getIndex(i);
|
|
||||||
if (attr == R.styleable.Croller_progress) {
|
|
||||||
setProgress(a.getInt(attr, 1));
|
|
||||||
} else if (attr == R.styleable.Croller_label) {
|
|
||||||
setLabel(a.getString(attr));
|
|
||||||
} else if (attr == R.styleable.Croller_back_circle_color) {
|
|
||||||
setBackCircleColor(a.getColor(attr, Color.parseColor("#222222")));
|
|
||||||
} else if (attr == R.styleable.Croller_main_circle_color) {
|
|
||||||
setMainCircleColor(a.getColor(attr, Color.parseColor("#000000")));
|
|
||||||
} else if (attr == R.styleable.Croller_indicator_color) {
|
|
||||||
setIndicatorColor(a.getColor(attr, Color.parseColor("#FFA036")));
|
|
||||||
} else if (attr == R.styleable.Croller_progress_primary_color) {
|
|
||||||
setProgressPrimaryColor(a.getColor(attr, Color.parseColor("#FFA036")));
|
|
||||||
} else if (attr == R.styleable.Croller_progress_secondary_color) {
|
|
||||||
setProgressSecondaryColor(a.getColor(attr, Color.parseColor("#111111")));
|
|
||||||
} else if (attr == R.styleable.Croller_label_size) {
|
|
||||||
setLabelSize(a.getInteger(attr, 40));
|
|
||||||
} else if (attr == R.styleable.Croller_label_color) {
|
|
||||||
setLabelColor(a.getColor(attr, Color.WHITE));
|
|
||||||
} else if (attr == R.styleable.Croller_indicator_width) {
|
|
||||||
setIndicatorWidth(a.getFloat(attr, 7));
|
|
||||||
} else if (attr == R.styleable.Croller_is_continuous) {
|
|
||||||
setIsContinuous(a.getBoolean(attr, false));
|
|
||||||
} else if (attr == R.styleable.Croller_progress_primary_circle_size) {
|
|
||||||
setProgressPrimaryCircleSize(a.getFloat(attr, -1));
|
|
||||||
} else if (attr == R.styleable.Croller_progress_secondary_circle_size) {
|
|
||||||
setProgressSecondaryCircleSize(a.getFloat(attr, -1));
|
|
||||||
} else if (attr == R.styleable.Croller_progress_primary_stroke_width) {
|
|
||||||
setProgressPrimaryStrokeWidth(a.getFloat(attr, 25));
|
|
||||||
} else if (attr == R.styleable.Croller_progress_secondary_stroke_width) {
|
|
||||||
setProgressSecondaryStrokeWidth(a.getFloat(attr, 10));
|
|
||||||
} else if (attr == R.styleable.Croller_sweep_angle) {
|
|
||||||
setSweepAngle(a.getInt(attr, -1));
|
|
||||||
} else if (attr == R.styleable.Croller_start_offset) {
|
|
||||||
setStartOffset(a.getInt(attr, 30));
|
|
||||||
} else if (attr == R.styleable.Croller_max) {
|
|
||||||
setMax(a.getInt(attr, 25));
|
|
||||||
} else if (attr == R.styleable.Croller_min) {
|
|
||||||
setMin(a.getInt(attr, 1));
|
|
||||||
deg = min + 2;
|
|
||||||
} else if (attr == R.styleable.Croller_main_circle_radius) {
|
|
||||||
setMainCircleRadius(a.getFloat(attr, -1));
|
|
||||||
} else if (attr == R.styleable.Croller_back_circle_radius) {
|
|
||||||
setBackCircleRadius(a.getFloat(attr, -1));
|
|
||||||
} else if (attr == R.styleable.Croller_progress_radius) {
|
|
||||||
setProgressRadius(a.getFloat(attr, -1));
|
|
||||||
} else if (attr == R.styleable.Croller_touch_circle_radius_max) {
|
|
||||||
setTouchCircleRadiusMax(a.getFloat(attr, -1));
|
|
||||||
} else if (attr == R.styleable.Croller_touch_circle_radius_min) {
|
|
||||||
setTouchCircleRadiusMin(a.getFloat(attr, -1));
|
|
||||||
}else if (attr == R.styleable.Croller_anticlockwise) {
|
|
||||||
setAntiClockwise(a.getBoolean(attr, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
a.recycle();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
int minWidth = (int) Utils.convertDpToPixel(160, getContext());
|
|
||||||
int minHeight = (int) Utils.convertDpToPixel(160, getContext());
|
|
||||||
|
|
||||||
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
|
||||||
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
|
||||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
|
||||||
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
|
||||||
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
|
|
||||||
if (widthMode == MeasureSpec.EXACTLY) {
|
|
||||||
width = widthSize;
|
|
||||||
} else if (widthMode == MeasureSpec.AT_MOST) {
|
|
||||||
width = Math.min(minWidth, widthSize);
|
|
||||||
} else {
|
|
||||||
// only in case of ScrollViews, otherwise MeasureSpec.UNSPECIFIED is never triggered
|
|
||||||
// If width is wrap_content i.e. MeasureSpec.UNSPECIFIED, then make width equal to height
|
|
||||||
width = heightSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (heightMode == MeasureSpec.EXACTLY) {
|
|
||||||
height = heightSize;
|
|
||||||
} else if (heightMode == MeasureSpec.AT_MOST) {
|
|
||||||
height = Math.min(minHeight, heightSize);
|
|
||||||
} else {
|
|
||||||
// only in case of ScrollViews, otherwise MeasureSpec.UNSPECIFIED is never triggered
|
|
||||||
// If height is wrap_content i.e. MeasureSpec.UNSPECIFIED, then make height equal to width
|
|
||||||
height = widthSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (widthMode == MeasureSpec.UNSPECIFIED && heightMode == MeasureSpec.UNSPECIFIED) {
|
|
||||||
width = minWidth;
|
|
||||||
height = minHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
setMeasuredDimension(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
super.onDraw(canvas);
|
|
||||||
|
|
||||||
//called way to much!
|
|
||||||
if (mProgressChangeListener != null)
|
|
||||||
mProgressChangeListener.onProgressChanged((int) (deg - 2));
|
|
||||||
|
|
||||||
if (mCrollerChangeListener != null)
|
|
||||||
mCrollerChangeListener.onProgressChanged(this, (int) (deg - 2));
|
|
||||||
|
|
||||||
midx = canvas.getWidth() / 2;
|
|
||||||
midy = canvas.getHeight() / 2;
|
|
||||||
|
|
||||||
if (!isContinuous) {
|
|
||||||
|
|
||||||
startOffset2 = startOffset - 15;
|
|
||||||
|
|
||||||
circlePaint.setColor(progressSecondaryColor);
|
|
||||||
circlePaint2.setColor(progressPrimaryColor);
|
|
||||||
linePaint.setStrokeWidth(indicatorWidth);
|
|
||||||
linePaint.setColor(indicatorColor);
|
|
||||||
textPaint.setColor(labelColor);
|
|
||||||
textPaint.setTextSize(labelSize);
|
|
||||||
|
|
||||||
int radius = (int) (Math.min(midx, midy) * ((float) 14.5 / 16));
|
|
||||||
|
|
||||||
if (sweepAngle == -1) {
|
|
||||||
sweepAngle = 360 - (2 * startOffset2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mainCircleRadius == -1) {
|
|
||||||
mainCircleRadius = radius * ((float) 11 / 15);
|
|
||||||
}
|
|
||||||
if (backCircleRadius == -1) {
|
|
||||||
backCircleRadius = radius * ((float) 13 / 15);
|
|
||||||
}
|
|
||||||
if (progressRadius == -1) {
|
|
||||||
progressRadius = radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touchCircleRadiusMax == -1) {
|
|
||||||
touchCircleRadiusMax = Math.max(mainCircleRadius, Math.max(backCircleRadius, progressRadius));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touchCircleRadiusMin == -1) {
|
|
||||||
touchCircleRadiusMin = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float x, y;
|
|
||||||
float deg2 = Math.max(3, deg);
|
|
||||||
float deg3 = Math.min(deg, max + 2);
|
|
||||||
for (int i = (int) (deg2); i < max + 3; i++) {
|
|
||||||
float tmp = ((float) startOffset2 / 360) + ((float) sweepAngle / 360) * (float) i / (max + 5);
|
|
||||||
|
|
||||||
if (isAntiClockwise) {
|
|
||||||
tmp = 1.0f - tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
x = midx + (float) (progressRadius * Math.sin(2 * Math.PI * (1.0 - tmp)));
|
|
||||||
y = midy + (float) (progressRadius * Math.cos(2 * Math.PI * (1.0 - tmp)));
|
|
||||||
circlePaint.setColor(progressSecondaryColor);
|
|
||||||
if (progressSecondaryCircleSize == -1)
|
|
||||||
canvas.drawCircle(x, y, ((float) radius / 30 * ((float) 20 / max) * ((float) sweepAngle / 270)), circlePaint);
|
|
||||||
else
|
|
||||||
canvas.drawCircle(x, y, progressSecondaryCircleSize, circlePaint);
|
|
||||||
}
|
|
||||||
for (int i = 3; i <= deg3; i++) {
|
|
||||||
float tmp = ((float) startOffset2 / 360) + ((float) sweepAngle / 360) * (float) i / (max + 5);
|
|
||||||
|
|
||||||
if (isAntiClockwise) {
|
|
||||||
tmp = 1.0f - tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
x = midx + (float) (progressRadius * Math.sin(2 * Math.PI * (1.0 - tmp)));
|
|
||||||
y = midy + (float) (progressRadius * Math.cos(2 * Math.PI * (1.0 - tmp)));
|
|
||||||
if (progressPrimaryCircleSize == -1)
|
|
||||||
canvas.drawCircle(x, y, (progressRadius / 15 * ((float) 20 / max) * ((float) sweepAngle / 270)), circlePaint2);
|
|
||||||
else
|
|
||||||
canvas.drawCircle(x, y, progressPrimaryCircleSize, circlePaint2);
|
|
||||||
}
|
|
||||||
|
|
||||||
float tmp2 = ((float) startOffset2 / 360) + ((float) sweepAngle / 360) * deg / (max + 5);
|
|
||||||
|
|
||||||
if (isAntiClockwise) {
|
|
||||||
tmp2 = 1.0f - tmp2;
|
|
||||||
}
|
|
||||||
|
|
||||||
float x1 = midx + (float) (radius * ((float) 2 / 5) * Math.sin(2 * Math.PI * (1.0 - tmp2)));
|
|
||||||
float y1 = midy + (float) (radius * ((float) 2 / 5) * Math.cos(2 * Math.PI * (1.0 - tmp2)));
|
|
||||||
float x2 = midx + (float) (radius * ((float) 3 / 5) * Math.sin(2 * Math.PI * (1.0 - tmp2)));
|
|
||||||
float y2 = midy + (float) (radius * ((float) 3 / 5) * Math.cos(2 * Math.PI * (1.0 - tmp2)));
|
|
||||||
|
|
||||||
circlePaint.setColor(backCircleColor);
|
|
||||||
canvas.drawCircle(midx, midy, backCircleRadius, circlePaint);
|
|
||||||
circlePaint.setColor(mainCircleColor);
|
|
||||||
canvas.drawCircle(midx, midy, mainCircleRadius, circlePaint);
|
|
||||||
canvas.drawText(label, midx, midy + (float) (radius * 1.1), textPaint);
|
|
||||||
canvas.drawLine(x1, y1, x2, y2, linePaint);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
int radius = (int) (Math.min(midx, midy) * ((float) 14.5 / 16));
|
|
||||||
|
|
||||||
if (sweepAngle == -1) {
|
|
||||||
sweepAngle = 360 - (2 * startOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mainCircleRadius == -1) {
|
|
||||||
mainCircleRadius = radius * ((float) 11 / 15);
|
|
||||||
}
|
|
||||||
if (backCircleRadius == -1) {
|
|
||||||
backCircleRadius = radius * ((float) 13 / 15);
|
|
||||||
}
|
|
||||||
if (progressRadius == -1) {
|
|
||||||
progressRadius = radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touchCircleRadiusMax == -1) {
|
|
||||||
touchCircleRadiusMax = Math.max(mainCircleRadius, Math.max(backCircleRadius, progressRadius));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touchCircleRadiusMin == -1) {
|
|
||||||
touchCircleRadiusMin = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
circlePaint.setColor(progressSecondaryColor);
|
|
||||||
circlePaint.setStrokeWidth(progressSecondaryStrokeWidth);
|
|
||||||
circlePaint.setStyle(Paint.Style.STROKE);
|
|
||||||
circlePaint2.setColor(progressPrimaryColor);
|
|
||||||
circlePaint2.setStrokeWidth(progressPrimaryStrokeWidth);
|
|
||||||
circlePaint2.setStyle(Paint.Style.STROKE);
|
|
||||||
linePaint.setStrokeWidth(indicatorWidth);
|
|
||||||
linePaint.setColor(indicatorColor);
|
|
||||||
textPaint.setColor(labelColor);
|
|
||||||
textPaint.setTextSize(labelSize);
|
|
||||||
|
|
||||||
float deg3 = Math.min(deg, max + 2);
|
|
||||||
|
|
||||||
oval.set(midx - progressRadius, midy - progressRadius, midx + progressRadius, midy + progressRadius);
|
|
||||||
|
|
||||||
canvas.drawArc(oval, (float) 90 + startOffset, (float) sweepAngle, false, circlePaint);
|
|
||||||
if (isAntiClockwise) {
|
|
||||||
canvas.drawArc(oval, (float) 90 - startOffset, -1 * ((deg3 - 2) * ((float) sweepAngle / max)), false, circlePaint2);
|
|
||||||
} else {
|
|
||||||
canvas.drawArc(oval, (float) 90 + startOffset, ((deg3 - 2) * ((float) sweepAngle / max)), false, circlePaint2);
|
|
||||||
}
|
|
||||||
|
|
||||||
float tmp2 = ((float) startOffset / 360) + (((float) sweepAngle / 360) * ((deg - 2) / (max)));
|
|
||||||
|
|
||||||
if (isAntiClockwise) {
|
|
||||||
tmp2 = 1.0f - tmp2;
|
|
||||||
}
|
|
||||||
|
|
||||||
float x1 = midx + (float) (radius * ((float) 2 / 5) * Math.sin(2 * Math.PI * (1.0 - tmp2)));
|
|
||||||
float y1 = midy + (float) (radius * ((float) 2 / 5) * Math.cos(2 * Math.PI * (1.0 - tmp2)));
|
|
||||||
float x2 = midx + (float) (radius * ((float) 3 / 5) * Math.sin(2 * Math.PI * (1.0 - tmp2)));
|
|
||||||
float y2 = midy + (float) (radius * ((float) 3 / 5) * Math.cos(2 * Math.PI * (1.0 - tmp2)));
|
|
||||||
|
|
||||||
circlePaint.setStyle(Paint.Style.FILL);
|
|
||||||
|
|
||||||
circlePaint.setColor(backCircleColor);
|
|
||||||
canvas.drawCircle(midx, midy, backCircleRadius, circlePaint);
|
|
||||||
circlePaint.setColor(mainCircleColor);
|
|
||||||
canvas.drawCircle(midx, midy, mainCircleRadius, circlePaint);
|
|
||||||
canvas.drawText(label, midx, midy + (float) (radius * 0.9), textPaint);
|
|
||||||
canvas.drawLine(x1, y1, x2, y2, linePaint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent e) {
|
|
||||||
|
|
||||||
double distancePointToMiddle = Utils.getDistance(e.getX(), e.getY(), midx, midy);
|
|
||||||
if ((distancePointToMiddle > touchCircleRadiusMax || distancePointToMiddle < touchCircleRadiusMin)) {
|
|
||||||
if (startEventSent && mCrollerChangeListener != null) {
|
|
||||||
mCrollerChangeListener.onStopTrackingTouch(this);
|
|
||||||
startEventSent = false;
|
|
||||||
}
|
|
||||||
return super.onTouchEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.getAction() == MotionEvent.ACTION_DOWN) {
|
|
||||||
float dx = e.getX() - midx;
|
|
||||||
float dy = e.getY() - midy;
|
|
||||||
downdeg = (float) ((Math.atan2(dy, dx) * 180) / Math.PI);
|
|
||||||
downdeg -= 90;
|
|
||||||
if (downdeg < 0) {
|
|
||||||
downdeg += 360;
|
|
||||||
}
|
|
||||||
downdeg = (float) Math.floor((downdeg / 360) * (max + 5));
|
|
||||||
|
|
||||||
if (mCrollerChangeListener != null) {
|
|
||||||
mCrollerChangeListener.onStartTrackingTouch(this);
|
|
||||||
startEventSent = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (e.getAction() == MotionEvent.ACTION_MOVE) {
|
|
||||||
float dx = e.getX() - midx;
|
|
||||||
float dy = e.getY() - midy;
|
|
||||||
currdeg = (float) ((Math.atan2(dy, dx) * 180) / Math.PI);
|
|
||||||
currdeg -= 90;
|
|
||||||
if (currdeg < 0) {
|
|
||||||
currdeg += 360;
|
|
||||||
}
|
|
||||||
currdeg = (float) Math.floor((currdeg / 360) * (max + 5));
|
|
||||||
|
|
||||||
if ((currdeg / (max + 4)) > 0.75f && ((downdeg - 0) / (max + 4)) < 0.25f) {
|
|
||||||
if (isAntiClockwise) {
|
|
||||||
deg++;
|
|
||||||
if (deg > max + 2) {
|
|
||||||
deg = max + 2;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
deg--;
|
|
||||||
if (deg < (min + 2)) {
|
|
||||||
deg = (min + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((downdeg / (max + 4)) > 0.75f && ((currdeg - 0) / (max + 4)) < 0.25f) {
|
|
||||||
if (isAntiClockwise) {
|
|
||||||
deg--;
|
|
||||||
if (deg < (min + 2)) {
|
|
||||||
deg = (min + 2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
deg++;
|
|
||||||
if (deg > max + 2) {
|
|
||||||
deg = max + 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (isAntiClockwise) {
|
|
||||||
deg -= (currdeg - downdeg);
|
|
||||||
} else {
|
|
||||||
deg += (currdeg - downdeg);
|
|
||||||
}
|
|
||||||
if (deg > max + 2) {
|
|
||||||
deg = max + 2;
|
|
||||||
}
|
|
||||||
if (deg < (min + 2)) {
|
|
||||||
deg = (min + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
downdeg = currdeg;
|
|
||||||
|
|
||||||
invalidate();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
if (e.getAction() == MotionEvent.ACTION_UP) {
|
|
||||||
if (mCrollerChangeListener != null) {
|
|
||||||
mCrollerChangeListener.onStopTrackingTouch(this);
|
|
||||||
startEventSent = false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onTouchEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean dispatchTouchEvent(MotionEvent event) {
|
|
||||||
if (getParent() != null && event.getAction() == MotionEvent.ACTION_DOWN) {
|
|
||||||
getParent().requestDisallowInterceptTouchEvent(true);
|
|
||||||
}
|
|
||||||
return super.dispatchTouchEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProgress() {
|
|
||||||
return (int) (deg - 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgress(int x) {
|
|
||||||
if(deg != x + 2){
|
|
||||||
deg = x + 2;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLabel() {
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLabel(String txt) {
|
|
||||||
if(!label.equals(txt)){
|
|
||||||
label = txt;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBackCircleColor() {
|
|
||||||
return backCircleColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBackCircleColor(int backCircleColor) {
|
|
||||||
if(this.backCircleColor != backCircleColor){
|
|
||||||
this.backCircleColor = backCircleColor;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMainCircleColor() {
|
|
||||||
return mainCircleColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMainCircleColor(int mainCircleColor) {
|
|
||||||
if(this.mainCircleColor != mainCircleColor){
|
|
||||||
this.mainCircleColor = mainCircleColor;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ValueAnimator mainCircleAnimation;
|
|
||||||
public void setMainCircleColorAnimated(int startColor, int endColor, int duration) {
|
|
||||||
|
|
||||||
mainCircleAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), startColor, endColor);
|
|
||||||
mainCircleAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationUpdate(ValueAnimator animator) {
|
|
||||||
setMainCircleColor((Integer) animator.getAnimatedValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
mainCircleAnimation.setDuration(duration);
|
|
||||||
mainCircleAnimation.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopMainCircleColorAnimated(){
|
|
||||||
if(mainCircleAnimation != null){
|
|
||||||
if(mainCircleAnimation.isRunning()){
|
|
||||||
mainCircleAnimation.reverse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void interruptMainCircleColorAnimated(){
|
|
||||||
if(mainCircleAnimation != null){
|
|
||||||
if(mainCircleAnimation.isRunning()){
|
|
||||||
mainCircleAnimation.setDuration(0);
|
|
||||||
mainCircleAnimation.reverse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void interruptBackCircleAnimated(){
|
|
||||||
if(backCircleAnimation != null){
|
|
||||||
if(backCircleAnimation.isRunning()){
|
|
||||||
backCircleAnimation.setDuration(0);
|
|
||||||
backCircleAnimation.reverse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMainCircleAnimationRunning(){
|
|
||||||
if(mainCircleAnimation != null){
|
|
||||||
return mainCircleAnimation.isRunning();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isBackCircleAnimationRunning(){
|
|
||||||
if(backCircleAnimation != null){
|
|
||||||
return backCircleAnimation.isRunning();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ValueAnimator backCircleAnimation;
|
|
||||||
public void setBackCircleColorAnimated(int startColor, int endColor, int duration) {
|
|
||||||
|
|
||||||
backCircleAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), startColor, endColor);
|
|
||||||
backCircleAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationUpdate(ValueAnimator animator) {
|
|
||||||
setBackCircleColor((Integer) animator.getAnimatedValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
backCircleAnimation.setDuration(duration);
|
|
||||||
backCircleAnimation.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopBackCircleColorAnimated(){
|
|
||||||
backCircleAnimation.reverse();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIndicatorColor() {
|
|
||||||
return indicatorColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIndicatorColor(int indicatorColor) {
|
|
||||||
this.indicatorColor = indicatorColor;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProgressPrimaryColor() {
|
|
||||||
return progressPrimaryColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgressPrimaryColor(int progressPrimaryColor) {
|
|
||||||
this.progressPrimaryColor = progressPrimaryColor;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProgressSecondaryColor() {
|
|
||||||
return progressSecondaryColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgressSecondaryColor(int progressSecondaryColor) {
|
|
||||||
this.progressSecondaryColor = progressSecondaryColor;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLabelSize() {
|
|
||||||
return labelSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLabelSize(int labelSize) {
|
|
||||||
this.labelSize = labelSize;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLabelColor() {
|
|
||||||
return labelColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLabelColor(int labelColor) {
|
|
||||||
this.labelColor = labelColor;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getIndicatorWidth() {
|
|
||||||
return indicatorWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIndicatorWidth(float indicatorWidth) {
|
|
||||||
this.indicatorWidth = indicatorWidth;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isContinuous() {
|
|
||||||
return isContinuous;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsContinuous(boolean isContinuous) {
|
|
||||||
this.isContinuous = isContinuous;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getProgressPrimaryCircleSize() {
|
|
||||||
return progressPrimaryCircleSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgressPrimaryCircleSize(float progressPrimaryCircleSize) {
|
|
||||||
this.progressPrimaryCircleSize = progressPrimaryCircleSize;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getProgressSecondaryCircleSize() {
|
|
||||||
return progressSecondaryCircleSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgressSecondaryCircleSize(float progressSecondaryCircleSize) {
|
|
||||||
this.progressSecondaryCircleSize = progressSecondaryCircleSize;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getProgressPrimaryStrokeWidth() {
|
|
||||||
return progressPrimaryStrokeWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgressPrimaryStrokeWidth(float progressPrimaryStrokeWidth) {
|
|
||||||
this.progressPrimaryStrokeWidth = progressPrimaryStrokeWidth;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getProgressSecondaryStrokeWidth() {
|
|
||||||
return progressSecondaryStrokeWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgressSecondaryStrokeWidth(float progressSecondaryStrokeWidth) {
|
|
||||||
this.progressSecondaryStrokeWidth = progressSecondaryStrokeWidth;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSweepAngle() {
|
|
||||||
return sweepAngle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSweepAngle(int sweepAngle) {
|
|
||||||
this.sweepAngle = sweepAngle;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getStartOffset() {
|
|
||||||
return startOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStartOffset(int startOffset) {
|
|
||||||
this.startOffset = startOffset;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMax() {
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMax(int max) {
|
|
||||||
if (max < min) {
|
|
||||||
this.max = min;
|
|
||||||
} else {
|
|
||||||
this.max = max;
|
|
||||||
}
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMin() {
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMin(int min) {
|
|
||||||
if (min < 0) {
|
|
||||||
this.min = 0;
|
|
||||||
} else if (min > max) {
|
|
||||||
this.min = max;
|
|
||||||
} else {
|
|
||||||
this.min = min;
|
|
||||||
}
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getMainCircleRadius() {
|
|
||||||
return mainCircleRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMainCircleRadius(float mainCircleRadius) {
|
|
||||||
this.mainCircleRadius = mainCircleRadius;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getBackCircleRadius() {
|
|
||||||
return backCircleRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBackCircleRadius(float backCircleRadius) {
|
|
||||||
this.backCircleRadius = backCircleRadius;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getProgressRadius() {
|
|
||||||
return progressRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgressRadius(float progressRadius) {
|
|
||||||
this.progressRadius = progressRadius;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getTouchCircleRadiusMax() {
|
|
||||||
return touchCircleRadiusMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTouchCircleRadiusMax(float touchCircleRadiusMax) {
|
|
||||||
this.touchCircleRadiusMax = touchCircleRadiusMax;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public float getTouchCircleRadiusMin() {
|
|
||||||
return touchCircleRadiusMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTouchCircleRadiusMin(float touchCircleRadiusMin) {
|
|
||||||
this.touchCircleRadiusMin = touchCircleRadiusMin;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isAntiClockwise() {
|
|
||||||
return isAntiClockwise;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAntiClockwise(boolean antiClockwise) {
|
|
||||||
isAntiClockwise = antiClockwise;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,24 +5,16 @@ import android.hardware.Sensor;
|
|||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
import android.os.Handler;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import de.tonifetzer.conductorswatch.bpmEstimation.AccelerometerData;
|
import de.tonifetzer.conductorswatch.bpmEstimation.AccelerometerData;
|
||||||
import de.tonifetzer.conductorswatch.bpmEstimation.AccelerometerWindowBuffer;
|
import de.tonifetzer.conductorswatch.bpmEstimation.AccelerometerWindowBuffer;
|
||||||
import de.tonifetzer.conductorswatch.bpmEstimation.BpmEstimator;
|
import de.tonifetzer.conductorswatch.bpmEstimation.BpmEstimator;
|
||||||
import de.tonifetzer.conductorswatch.network.SensorDataFileSender;
|
|
||||||
import de.tonifetzer.conductorswatch.network.SensorDataFileStreamer;
|
import de.tonifetzer.conductorswatch.network.SensorDataFileStreamer;
|
||||||
import de.tonifetzer.conductorswatch.utilities.ByteStreamWriter;
|
import de.tonifetzer.conductorswatch.utilities.ByteStreamWriter;
|
||||||
import de.tonifetzer.conductorswatch.utilities.Utils;
|
import de.tonifetzer.conductorswatch.utilities.Utils;
|
||||||
|
|||||||
@@ -8,18 +8,19 @@ import android.os.Bundle;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
import android.support.wearable.activity.WearableActivity;
|
import android.support.wearable.activity.WearableActivity;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.GestureDetector;
|
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import de.tonifetzer.conductorswatch.network.SensorDataFileSender;
|
import de.tonifetzer.conductorswatch.network.SensorDataFileSender;
|
||||||
|
import de.tonifetzer.conductorswatch.ui.Croller;
|
||||||
|
import de.tonifetzer.conductorswatch.ui.TapBpm;
|
||||||
import de.tonifetzer.conductorswatch.utilities.Utils;
|
import de.tonifetzer.conductorswatch.utilities.Utils;
|
||||||
|
|
||||||
public class MainActivity extends WearableActivity implements WorkerFragment.OnFragmentInteractionListener, TapBpm.OnTapBpmListener {
|
public class MainActivity extends WearableActivity implements WorkerFragment.OnFragmentInteractionListener, TapBpm.OnTapBpmListener, Croller.onProgressChangedListener {
|
||||||
|
|
||||||
// member
|
// member
|
||||||
private TextView mTextView;
|
private TextView mTextView;
|
||||||
@@ -34,8 +35,6 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
private volatile boolean mReadyToSend = true;
|
private volatile boolean mReadyToSend = true;
|
||||||
|
|
||||||
// display center
|
// display center
|
||||||
private int mDisplayWidth;
|
|
||||||
private int mDisplayHeight;
|
|
||||||
private Point mDisplayCenter;
|
private Point mDisplayCenter;
|
||||||
|
|
||||||
// saved Bpm to reset after recording
|
// saved Bpm to reset after recording
|
||||||
@@ -47,29 +46,28 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
|
|
||||||
// tapping
|
// tapping
|
||||||
private TapBpm mTapBpm;
|
private TapBpm mTapBpm;
|
||||||
private boolean mTapRecognized = true;
|
private boolean mTappingStarted = false;
|
||||||
private int mTapBpmEstimation;
|
private int mTapBpmEstimation;
|
||||||
private Vibrator mVibrator;
|
private Vibrator mVibrator;
|
||||||
|
|
||||||
//parameter for long press to start the worker
|
//parameter for long press to start the worker
|
||||||
//private Point mPreviousMovePoint;
|
|
||||||
//private int mDistanceJitteringLongPress = 50; // in pixel
|
|
||||||
private int mLongPressDelay = 1200; // in Milliseconds
|
private int mLongPressDelay = 1200; // in Milliseconds
|
||||||
private boolean mLongPressHandlerActivated = false;
|
private boolean mLongPressHandlerActivated = false;
|
||||||
private final Handler mHandler = new Handler();
|
private final Handler mHandler = new Handler();
|
||||||
|
|
||||||
|
// runnable to switch between record mode and normal mode
|
||||||
private Runnable mLongPressed = new Runnable() {
|
private Runnable mLongPressed = new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
|
||||||
vibrator.vibrate(100);
|
|
||||||
|
|
||||||
mLongPressHandlerActivated = true;
|
mLongPressHandlerActivated = true;
|
||||||
|
|
||||||
mModeRecord = !mModeRecord;
|
mModeRecord = !mModeRecord;
|
||||||
|
|
||||||
if (mModeRecord) {
|
if (mModeRecord) {
|
||||||
WorkerFragment worker = new WorkerFragment();
|
WorkerFragment worker = new WorkerFragment();
|
||||||
|
|
||||||
|
//if we tapped, finish tapping
|
||||||
|
onTapFinished();
|
||||||
|
|
||||||
//provide the fragment with the bpm set
|
//provide the fragment with the bpm set
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putInt("bpm", mCroller.getProgress());
|
args.putInt("bpm", mCroller.getProgress());
|
||||||
@@ -90,6 +88,7 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
transaction.commit();
|
transaction.commit();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
//reset colors from red to green
|
||||||
mCroller.setProgressPrimaryColor(Color.parseColor("#158b69"));
|
mCroller.setProgressPrimaryColor(Color.parseColor("#158b69"));
|
||||||
mCroller.setBackCircleColor(Color.parseColor("#158b69"));
|
mCroller.setBackCircleColor(Color.parseColor("#158b69"));
|
||||||
mTextView.setTextColor(Color.parseColor("#158b69"));
|
mTextView.setTextColor(Color.parseColor("#158b69"));
|
||||||
@@ -104,6 +103,7 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//if we press the center button long enough, start mode switching runnable
|
||||||
private boolean onLongPressCustomized(MotionEvent ev) {
|
private boolean onLongPressCustomized(MotionEvent ev) {
|
||||||
|
|
||||||
Point currentPoint = new Point((int) ev.getX(), (int) ev.getY());
|
Point currentPoint = new Point((int) ev.getX(), (int) ev.getY());
|
||||||
@@ -119,22 +119,6 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
mHandler.postDelayed(mLongPressed, mLongPressDelay);
|
mHandler.postDelayed(mLongPressed, mLongPressDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ev.getAction() == MotionEvent.ACTION_MOVE) || (ev.getAction() == MotionEvent.ACTION_HOVER_MOVE)) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (mPreviousMovePoint == null) {
|
|
||||||
mPreviousMovePoint = currentPoint;
|
|
||||||
} else {
|
|
||||||
int dx = Math.abs(currentPoint.x - mPreviousMovePoint.x);
|
|
||||||
int dy = Math.abs(currentPoint.y - mPreviousMovePoint.y);
|
|
||||||
int distance = (int) Math.sqrt(dx * dx + dy * dy);
|
|
||||||
if (distance > mDistanceJitteringLongPress) {
|
|
||||||
mHandler.removeCallbacks(mLongPressed);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ev.getAction() == MotionEvent.ACTION_UP) {
|
if (ev.getAction() == MotionEvent.ACTION_UP) {
|
||||||
mHandler.removeCallbacks(mLongPressed);
|
mHandler.removeCallbacks(mLongPressed);
|
||||||
if (mLongPressHandlerActivated) {
|
if (mLongPressHandlerActivated) {
|
||||||
@@ -148,7 +132,9 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//animation that fills the circle slowly with color
|
||||||
private boolean onColorChanging(MotionEvent ev, int MainColor) {
|
private boolean onColorChanging(MotionEvent ev, int MainColor) {
|
||||||
|
//TODO: könnte man komplett in den Croller auslagern.
|
||||||
Point currentPoint = new Point((int) ev.getX(), (int) ev.getY());
|
Point currentPoint = new Point((int) ev.getX(), (int) ev.getY());
|
||||||
|
|
||||||
//only works within the maincircle of the scroller
|
//only works within the maincircle of the scroller
|
||||||
@@ -185,6 +171,7 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//starts a runnable that estimates the bpm (for metronom) by tapping on the center circle
|
||||||
public boolean onTapForBpm(MotionEvent ev) {
|
public boolean onTapForBpm(MotionEvent ev) {
|
||||||
|
|
||||||
Point currentPoint = new Point((int) ev.getX(), (int) ev.getY());
|
Point currentPoint = new Point((int) ev.getX(), (int) ev.getY());
|
||||||
@@ -198,26 +185,16 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
|
mTapBpm.addTimestamp(System.currentTimeMillis());
|
||||||
//if (!mTapRecognized) {
|
|
||||||
|
|
||||||
mTapBpm.addTimestamp(System.currentTimeMillis());
|
|
||||||
//mTapRecognized = true;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ev.getAction() == MotionEvent.ACTION_UP) {
|
if (ev.getAction() == MotionEvent.ACTION_UP) {
|
||||||
|
|
||||||
if (mTapRecognized) {
|
if (!mTappingStarted) {
|
||||||
|
mTappingStarted = true;
|
||||||
mExecutorService.submit(mTapBpm);
|
|
||||||
|
|
||||||
//mTapBpmThread = new Thread(mTapBpm);
|
|
||||||
//mTapBpmThread.start();
|
|
||||||
mCroller.setLabel("Tippe weiter");
|
mCroller.setLabel("Tippe weiter");
|
||||||
|
mExecutorService.submit(mTapBpm);
|
||||||
}
|
}
|
||||||
mTapRecognized = false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -229,47 +206,20 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
//get display infos
|
//get display infos
|
||||||
mDisplayWidth = this.getResources().getDisplayMetrics().widthPixels;
|
int displayWidth = this.getResources().getDisplayMetrics().widthPixels;
|
||||||
mDisplayHeight = this.getResources().getDisplayMetrics().heightPixels;
|
int displayHeight = this.getResources().getDisplayMetrics().heightPixels;
|
||||||
mDisplayCenter = new Point((mDisplayWidth / 2), (mDisplayHeight / 2));
|
mDisplayCenter = new Point((displayWidth / 2), (displayHeight / 2));
|
||||||
|
|
||||||
//add tap listener
|
|
||||||
mTapBpm = new TapBpm();
|
|
||||||
mTapBpm.add(this);
|
|
||||||
|
|
||||||
|
//ui and motion stuff
|
||||||
mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
mTextView = (TextView) findViewById(R.id.bpmText);
|
mTapBpm = new TapBpm();
|
||||||
|
mTextView = findViewById(R.id.bpmText);
|
||||||
|
mCroller = findViewById(R.id.croller);
|
||||||
|
|
||||||
|
//listener
|
||||||
|
mCroller.setOnProgressChangedListener(this);
|
||||||
mSender = new SensorDataFileSender(this);
|
mSender = new SensorDataFileSender(this);
|
||||||
|
mTapBpm.add(this);
|
||||||
// circular progress bar
|
|
||||||
mCroller = (Croller) findViewById(R.id.croller);
|
|
||||||
mCroller.setOnProgressChangedListener(new Croller.onProgressChangedListener() {
|
|
||||||
@Override
|
|
||||||
public void onProgressChanged(int currentBPM) {
|
|
||||||
|
|
||||||
if(currentBPM != mLastSendBPM){
|
|
||||||
|
|
||||||
mTextView.setText(Integer.toString(currentBPM));
|
|
||||||
mSender.sendMessage(UPDATE_PATH + ":" + mMetronomBpm + ":" + currentBPM);
|
|
||||||
mLastSendBPM = currentBPM;
|
|
||||||
}
|
|
||||||
|
|
||||||
//künstlicher delay.
|
|
||||||
if(mReadyToSend){
|
|
||||||
mReadyToSend = false;
|
|
||||||
new java.util.Timer().schedule(
|
|
||||||
new java.util.TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// your code here
|
|
||||||
|
|
||||||
mReadyToSend = true;
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Enables Always-on
|
// Enables Always-on
|
||||||
setAmbientEnabled();
|
setAmbientEnabled();
|
||||||
@@ -334,14 +284,11 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
mTapBpmEstimation = bpm;
|
mTapBpmEstimation = bpm;
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(() -> {
|
||||||
@Override
|
if (mTapBpmEstimation > 0) {
|
||||||
public void run() {
|
mCroller.setProgress(mTapBpmEstimation);
|
||||||
if (mTapBpmEstimation > 0) {
|
mCroller.setLabel("Fertig");
|
||||||
mCroller.setProgress(mTapBpmEstimation);
|
mVibrator.vibrate(20);
|
||||||
mCroller.setLabel("Fertig");
|
|
||||||
mVibrator.vibrate(20);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -350,23 +297,35 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF
|
|||||||
@Override
|
@Override
|
||||||
public void onTapFinished() {
|
public void onTapFinished() {
|
||||||
|
|
||||||
runOnUiThread(new Runnable() {
|
synchronized (this) {
|
||||||
@Override
|
runOnUiThread(() -> {
|
||||||
public void run() {
|
|
||||||
mCroller.setLabel("");
|
mCroller.setLabel("");
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mTapBpm.clearTimestamps();
|
mTapBpm.clearTimestamps();
|
||||||
mTapRecognized = true;
|
mTappingStarted = false;
|
||||||
/*
|
});
|
||||||
mTapBpmThread.interrupt();
|
|
||||||
try {
|
|
||||||
mTapBpmThread.join();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(int currentBPM) {
|
||||||
|
|
||||||
|
if(currentBPM != mLastSendBPM){
|
||||||
|
mTextView.setText(String.format(Locale.getDefault(), "%d", currentBPM));
|
||||||
|
mSender.sendMessage(UPDATE_PATH + ":" + mMetronomBpm + ":" + currentBPM);
|
||||||
|
mLastSendBPM = currentBPM;
|
||||||
|
}
|
||||||
|
|
||||||
|
//künstlicher delay, da es sonst so häufig aufgerufen wird und das sendMessage dann in die Hose geht.
|
||||||
|
if(mReadyToSend){
|
||||||
|
mReadyToSend = false;
|
||||||
|
new java.util.Timer().schedule(
|
||||||
|
new java.util.TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mReadyToSend = true;
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package de.tonifetzer.conductorswatch;
|
|
||||||
|
|
||||||
public interface OnCrollerChangeListener {
|
|
||||||
void onProgressChanged(Croller croller, int progress);
|
|
||||||
|
|
||||||
void onStartTrackingTouch(Croller croller);
|
|
||||||
|
|
||||||
void onStopTrackingTouch(Croller croller);
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
package de.tonifetzer.conductorswatch;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Vector;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by toni on 20/11/17.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class TapBpm implements Runnable {
|
|
||||||
|
|
||||||
private Vector<Long> mReceivedTabs = new Vector<Long>();
|
|
||||||
private int mBpmTapped;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
int breakCounter = 2000;
|
|
||||||
mBpmTapped = 0;
|
|
||||||
int calcNewBpmCounter = 3;
|
|
||||||
|
|
||||||
do{
|
|
||||||
if(mBpmTapped > 0){
|
|
||||||
breakCounter = 2 * (60000 / mBpmTapped);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mReceivedTabs.size() > calcNewBpmCounter) {
|
|
||||||
|
|
||||||
long sumDifferenceMs = 0L;
|
|
||||||
for (int i = 0; i < mReceivedTabs.size() -1; ++i) {
|
|
||||||
sumDifferenceMs += mReceivedTabs.get(i + 1)- mReceivedTabs.get(i);
|
|
||||||
}
|
|
||||||
mBpmTapped = (int) (60000 / (sumDifferenceMs / (mReceivedTabs.size() - 1)));
|
|
||||||
|
|
||||||
for (TapBpm.OnTapBpmListener listener:listeners) {
|
|
||||||
listener.onNewTapEstimation(mBpmTapped);
|
|
||||||
}
|
|
||||||
|
|
||||||
//only update everytime a new timestamp arrives
|
|
||||||
++calcNewBpmCounter;
|
|
||||||
}
|
|
||||||
}while(System.currentTimeMillis() - mReceivedTabs.lastElement() < breakCounter);
|
|
||||||
|
|
||||||
|
|
||||||
for (TapBpm.OnTapBpmListener listener:listeners) {
|
|
||||||
listener.onTapFinished();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTimestamp(Long ts){
|
|
||||||
mReceivedTabs.add(ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearTimestamps(){
|
|
||||||
mReceivedTabs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for callback calculated bpm
|
|
||||||
*/
|
|
||||||
public interface OnTapBpmListener {
|
|
||||||
void onTapFinished();
|
|
||||||
void onNewTapEstimation(int bpm);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<TapBpm.OnTapBpmListener> listeners = new CopyOnWriteArrayList<TapBpm.OnTapBpmListener>();
|
|
||||||
public void add(TapBpm.OnTapBpmListener listener){listeners.add(listener);}
|
|
||||||
public void remove(TapBpm.OnTapBpmListener listener){listeners.remove(listener);}
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,6 @@ import android.content.Context;
|
|||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.os.Vibrator;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -12,6 +11,8 @@ import android.view.WindowManager;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import de.tonifetzer.conductorswatch.ui.Croller;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link Fragment} subclass.
|
* A simple {@link Fragment} subclass.
|
||||||
@@ -23,14 +24,12 @@ public class WorkerFragment extends Fragment implements Metronome.OnMetronomeLis
|
|||||||
|
|
||||||
private OnFragmentInteractionListener mListener;
|
private OnFragmentInteractionListener mListener;
|
||||||
private Vector<Double> mBpmList;
|
private Vector<Double> mBpmList;
|
||||||
private byte[] mSensorData;
|
|
||||||
private boolean mWorkerRunning = false;
|
private boolean mWorkerRunning = false;
|
||||||
|
|
||||||
private Estimator mEstimator;
|
private Estimator mEstimator;
|
||||||
private Metronome mMetronome;
|
private Metronome mMetronome;
|
||||||
private Thread mMetronomeThread;
|
private Thread mMetronomeThread;
|
||||||
|
|
||||||
private Vibrator mVibrator;
|
|
||||||
private TextView mTextView;
|
private TextView mTextView;
|
||||||
private Croller mCroller;
|
private Croller mCroller;
|
||||||
|
|
||||||
@@ -66,8 +65,6 @@ public class WorkerFragment extends Fragment implements Metronome.OnMetronomeLis
|
|||||||
mMetronome.add(this);
|
mMetronome.add(this);
|
||||||
mMetronomeThread = new Thread(mMetronome, "metronomThread");
|
mMetronomeThread = new Thread(mMetronome, "metronomThread");
|
||||||
|
|
||||||
mVibrator = (Vibrator) this.getActivity().getSystemService(Context.VIBRATOR_SERVICE);
|
|
||||||
|
|
||||||
//keep screen always on
|
//keep screen always on
|
||||||
this.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
this.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
}
|
}
|
||||||
@@ -144,7 +141,6 @@ public class WorkerFragment extends Fragment implements Metronome.OnMetronomeLis
|
|||||||
@Override
|
@Override
|
||||||
public void onNewDataAvailable(double bpm) {
|
public void onNewDataAvailable(double bpm) {
|
||||||
|
|
||||||
//TODO: what if multiple threads access mBpmList? put into synchronized? @frank fragen :D
|
|
||||||
if(mWorkerRunning){
|
if(mWorkerRunning){
|
||||||
|
|
||||||
mBpmList.add(bpm);
|
mBpmList.add(bpm);
|
||||||
@@ -155,16 +151,11 @@ public class WorkerFragment extends Fragment implements Metronome.OnMetronomeLis
|
|||||||
|
|
||||||
// we need this here, since ui elements can only be changed within activity thread and
|
// we need this here, since ui elements can only be changed within activity thread and
|
||||||
// onNewDataAvailable lives inside the bpm estimation thread.
|
// onNewDataAvailable lives inside the bpm estimation thread.
|
||||||
// TODO: is this really okay? also synchronized?
|
|
||||||
|
|
||||||
if(getActivity() != null) {
|
if(getActivity() != null) {
|
||||||
getActivity().runOnUiThread(new Runnable() {
|
getActivity().runOnUiThread(() -> {
|
||||||
@Override
|
int tmpBPM = (int) (Math.round(mBpmList.lastElement()));
|
||||||
public void run() {
|
mTextView.setText(String.valueOf(tmpBPM));
|
||||||
int tmpBPM = (int) (Math.round(mBpmList.lastElement()));
|
mCroller.setProgress(tmpBPM);
|
||||||
mTextView.setText(String.valueOf(tmpBPM));
|
|
||||||
mCroller.setProgress(tmpBPM);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
|
||||||
<de.tonifetzer.conductorswatch.Croller
|
<de.tonifetzer.conductorswatch.ui.Croller
|
||||||
android:id="@+id/croller"
|
android:id="@+id/croller"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|||||||
Reference in New Issue
Block a user