From a4388132336dacf980279bdbe078b6b1c2e720e4 Mon Sep 17 00:00:00 2001 From: toni Date: Tue, 29 Jan 2019 16:35:43 +0100 Subject: [PATCH] refactored mainactivity and moved some files into ui package --- .../tonifetzer/conductorswatch/Croller.java | 823 ------------------ .../tonifetzer/conductorswatch/Estimator.java | 8 - .../conductorswatch/MainActivity.java | 159 ++-- .../OnCrollerChangeListener.java | 9 - .../de/tonifetzer/conductorswatch/TapBpm.java | 69 -- .../conductorswatch/WorkerFragment.java | 21 +- .../app/src/main/res/layout/activity_main.xml | 2 +- 7 files changed, 66 insertions(+), 1025 deletions(-) delete mode 100644 android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Croller.java delete mode 100644 android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/OnCrollerChangeListener.java delete mode 100644 android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/TapBpm.java diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Croller.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Croller.java deleted file mode 100644 index e3b7db3..0000000 --- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Croller.java +++ /dev/null @@ -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(); - } -} diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java index 28e8378..282394d 100644 --- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java +++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/Estimator.java @@ -5,24 +5,16 @@ import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; -import android.os.Handler; -import android.util.Log; -import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Timer; import java.util.TimerTask; -import java.util.Vector; 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.AccelerometerWindowBuffer; import de.tonifetzer.conductorswatch.bpmEstimation.BpmEstimator; -import de.tonifetzer.conductorswatch.network.SensorDataFileSender; import de.tonifetzer.conductorswatch.network.SensorDataFileStreamer; import de.tonifetzer.conductorswatch.utilities.ByteStreamWriter; import de.tonifetzer.conductorswatch.utilities.Utils; diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java index 7675c37..18fe8f1 100644 --- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java +++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/MainActivity.java @@ -8,18 +8,19 @@ import android.os.Bundle; import android.os.Handler; import android.os.Vibrator; import android.support.wearable.activity.WearableActivity; -import android.util.Log; -import android.view.GestureDetector; import android.view.MotionEvent; import android.widget.TextView; +import java.util.Locale; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import de.tonifetzer.conductorswatch.network.SensorDataFileSender; +import de.tonifetzer.conductorswatch.ui.Croller; +import de.tonifetzer.conductorswatch.ui.TapBpm; 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 private TextView mTextView; @@ -34,8 +35,6 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF private volatile boolean mReadyToSend = true; // display center - private int mDisplayWidth; - private int mDisplayHeight; private Point mDisplayCenter; // saved Bpm to reset after recording @@ -47,29 +46,28 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF // tapping private TapBpm mTapBpm; - private boolean mTapRecognized = true; + private boolean mTappingStarted = false; private int mTapBpmEstimation; private Vibrator mVibrator; //parameter for long press to start the worker - //private Point mPreviousMovePoint; - //private int mDistanceJitteringLongPress = 50; // in pixel private int mLongPressDelay = 1200; // in Milliseconds private boolean mLongPressHandlerActivated = false; private final Handler mHandler = new Handler(); + // runnable to switch between record mode and normal mode private Runnable mLongPressed = new Runnable() { public void run() { - Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); - vibrator.vibrate(100); mLongPressHandlerActivated = true; - mModeRecord = !mModeRecord; if (mModeRecord) { WorkerFragment worker = new WorkerFragment(); + //if we tapped, finish tapping + onTapFinished(); + //provide the fragment with the bpm set Bundle args = new Bundle(); args.putInt("bpm", mCroller.getProgress()); @@ -90,6 +88,7 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF transaction.commit(); } else { + //reset colors from red to green mCroller.setProgressPrimaryColor(Color.parseColor("#158b69")); mCroller.setBackCircleColor(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) { 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); } - 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) { mHandler.removeCallbacks(mLongPressed); if (mLongPressHandlerActivated) { @@ -148,7 +132,9 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF return false; } + //animation that fills the circle slowly with color 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()); //only works within the maincircle of the scroller @@ -185,6 +171,7 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF return false; } + //starts a runnable that estimates the bpm (for metronom) by tapping on the center circle public boolean onTapForBpm(MotionEvent ev) { 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 (!mTapRecognized) { - - mTapBpm.addTimestamp(System.currentTimeMillis()); - //mTapRecognized = true; - //} + mTapBpm.addTimestamp(System.currentTimeMillis()); } if (ev.getAction() == MotionEvent.ACTION_UP) { - if (mTapRecognized) { - - mExecutorService.submit(mTapBpm); - - //mTapBpmThread = new Thread(mTapBpm); - //mTapBpmThread.start(); + if (!mTappingStarted) { + mTappingStarted = true; mCroller.setLabel("Tippe weiter"); + mExecutorService.submit(mTapBpm); } - mTapRecognized = false; - } return false; @@ -229,47 +206,20 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF setContentView(R.layout.activity_main); //get display infos - mDisplayWidth = this.getResources().getDisplayMetrics().widthPixels; - mDisplayHeight = this.getResources().getDisplayMetrics().heightPixels; - mDisplayCenter = new Point((mDisplayWidth / 2), (mDisplayHeight / 2)); - - //add tap listener - mTapBpm = new TapBpm(); - mTapBpm.add(this); + int displayWidth = this.getResources().getDisplayMetrics().widthPixels; + int displayHeight = this.getResources().getDisplayMetrics().heightPixels; + mDisplayCenter = new Point((displayWidth / 2), (displayHeight / 2)); + //ui and motion stuff 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); - - // 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); - } - } - }); + mTapBpm.add(this); // Enables Always-on setAmbientEnabled(); @@ -334,14 +284,11 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF mTapBpmEstimation = bpm; synchronized (this) { - runOnUiThread(new Runnable() { - @Override - public void run() { - if (mTapBpmEstimation > 0) { - mCroller.setProgress(mTapBpmEstimation); - mCroller.setLabel("Fertig"); - mVibrator.vibrate(20); - } + runOnUiThread(() -> { + if (mTapBpmEstimation > 0) { + mCroller.setProgress(mTapBpmEstimation); + mCroller.setLabel("Fertig"); + mVibrator.vibrate(20); } }); } @@ -350,23 +297,35 @@ public class MainActivity extends WearableActivity implements WorkerFragment.OnF @Override public void onTapFinished() { - runOnUiThread(new Runnable() { - @Override - public void run() { + synchronized (this) { + runOnUiThread(() -> { mCroller.setLabel(""); - } - }); - mTapBpm.clearTimestamps(); - mTapRecognized = true; - /* - mTapBpmThread.interrupt(); - try { - mTapBpmThread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); + mTapBpm.clearTimestamps(); + mTappingStarted = false; + }); } - */ } + @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); + } + } } diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/OnCrollerChangeListener.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/OnCrollerChangeListener.java deleted file mode 100644 index 7b29b5a..0000000 --- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/OnCrollerChangeListener.java +++ /dev/null @@ -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); -} diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/TapBpm.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/TapBpm.java deleted file mode 100644 index f12821f..0000000 --- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/TapBpm.java +++ /dev/null @@ -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 mReceivedTabs = new Vector(); - 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 listeners = new CopyOnWriteArrayList(); - public void add(TapBpm.OnTapBpmListener listener){listeners.add(listener);} - public void remove(TapBpm.OnTapBpmListener listener){listeners.remove(listener);} -} diff --git a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/WorkerFragment.java b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/WorkerFragment.java index 7d311ee..de28cd6 100644 --- a/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/WorkerFragment.java +++ b/android/ConductorsWatch/app/src/main/java/de/tonifetzer/conductorswatch/WorkerFragment.java @@ -4,7 +4,6 @@ import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.app.Fragment; -import android.os.Vibrator; import android.support.annotation.Nullable; import android.util.Log; import android.view.View; @@ -12,6 +11,8 @@ import android.view.WindowManager; import android.widget.TextView; import java.util.Vector; +import de.tonifetzer.conductorswatch.ui.Croller; + /** * A simple {@link Fragment} subclass. @@ -23,14 +24,12 @@ public class WorkerFragment extends Fragment implements Metronome.OnMetronomeLis private OnFragmentInteractionListener mListener; private Vector mBpmList; - private byte[] mSensorData; private boolean mWorkerRunning = false; private Estimator mEstimator; private Metronome mMetronome; private Thread mMetronomeThread; - private Vibrator mVibrator; private TextView mTextView; private Croller mCroller; @@ -66,8 +65,6 @@ public class WorkerFragment extends Fragment implements Metronome.OnMetronomeLis mMetronome.add(this); mMetronomeThread = new Thread(mMetronome, "metronomThread"); - mVibrator = (Vibrator) this.getActivity().getSystemService(Context.VIBRATOR_SERVICE); - //keep screen always on this.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } @@ -144,7 +141,6 @@ public class WorkerFragment extends Fragment implements Metronome.OnMetronomeLis @Override public void onNewDataAvailable(double bpm) { - //TODO: what if multiple threads access mBpmList? put into synchronized? @frank fragen :D if(mWorkerRunning){ 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 // onNewDataAvailable lives inside the bpm estimation thread. - // TODO: is this really okay? also synchronized? - if(getActivity() != null) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - int tmpBPM = (int) (Math.round(mBpmList.lastElement())); - mTextView.setText(String.valueOf(tmpBPM)); - mCroller.setProgress(tmpBPM); - } + getActivity().runOnUiThread(() -> { + int tmpBPM = (int) (Math.round(mBpmList.lastElement())); + mTextView.setText(String.valueOf(tmpBPM)); + mCroller.setProgress(tmpBPM); }); } } diff --git a/android/ConductorsWatch/app/src/main/res/layout/activity_main.xml b/android/ConductorsWatch/app/src/main/res/layout/activity_main.xml index a679000..645219e 100644 --- a/android/ConductorsWatch/app/src/main/res/layout/activity_main.xml +++ b/android/ConductorsWatch/app/src/main/res/layout/activity_main.xml @@ -16,7 +16,7 @@ android:layout_height="match_parent"> -