diff --git a/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java index 314c24f3..f6d34b90 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/activities/DataEntryActivity.java @@ -189,7 +189,8 @@ public class DataEntryActivity extends Activity { switchEditMode.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#D3D3D3"))); } - if (prefs.getBoolean(String.valueOf(expandButton.getId()), false)) { + final boolean doExpand = prefs.getBoolean(String.valueOf(expandButton.getId()), false); + if (doExpand) { expandButton.setBackgroundTintList(ColorStateList.valueOf(ChartUtils.COLOR_ORANGE)); } else { expandButton.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#D3D3D3"))); @@ -211,7 +212,7 @@ public class DataEntryActivity extends Activity { for (MeasurementView measurement : dataEntryMeasurements) { measurement.updateValue(selectedScaleData); measurement.updateDiff(selectedScaleData, prevScaleData); - measurement.setExpand(prefs.getBoolean(String.valueOf(expandButton.getId()), false)); + measurement.setExpand(doExpand); } return; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/BMIMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/BMIMeasurementView.java index 273e35d9..6e761d43 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/BMIMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/BMIMeasurementView.java @@ -55,11 +55,6 @@ public class BMIMeasurementView extends MeasurementView { return evalSheet.evaluateBMI(value); } - @Override - public float getMinValue() { - return 10; - } - @Override public float getMaxValue() { return 50; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/BMRMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/BMRMeasurementView.java index 365ad73d..24b2df54 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/BMRMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/BMRMeasurementView.java @@ -55,11 +55,6 @@ public class BMRMeasurementView extends MeasurementView { return null; } - @Override - public float getMinValue() { - return 0; - } - @Override public float getMaxValue() { return 5000; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/BoneMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/BoneMeasurementView.java index 72f1c468..d995dde6 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/BoneMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/BoneMeasurementView.java @@ -55,11 +55,6 @@ public class BoneMeasurementView extends MeasurementView { return null; } - @Override - public float getMinValue() { - return 0; - } - @Override public float getMaxValue() { return 50; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/CommentMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/CommentMeasurementView.java index 44f70191..95deff1e 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/CommentMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/CommentMeasurementView.java @@ -71,11 +71,6 @@ public class CommentMeasurementView extends MeasurementView { return null; } - @Override - public float getMinValue() { - return 0; - } - @Override public float getMaxValue() { return 0; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/DateMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/DateMeasurementView.java index 2a993e38..289eb695 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/DateMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/DateMeasurementView.java @@ -85,11 +85,6 @@ public class DateMeasurementView extends MeasurementView { return null; } - @Override - public float getMinValue() { - return 0; - } - @Override public float getMaxValue() { return 0; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/FatMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/FatMeasurementView.java index 1b9cb387..f1edde88 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/FatMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/FatMeasurementView.java @@ -70,11 +70,6 @@ public class FatMeasurementView extends MeasurementView { return evalSheet.evaluateBodyFat(value); } - @Override - public float getMinValue() { - return 10; - } - @Override public float getMaxValue() { return 80; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/HipMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/HipMeasurementView.java index b2f0b5d8..0e6b2bc7 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/HipMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/HipMeasurementView.java @@ -55,11 +55,6 @@ public class HipMeasurementView extends MeasurementView { return null; } - @Override - public float getMinValue() { - return 30; - } - @Override public float getMaxValue() { return 200; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/LBWMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/LBWMeasurementView.java index 45026fcd..26762ff8 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/LBWMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/LBWMeasurementView.java @@ -70,11 +70,6 @@ public class LBWMeasurementView extends MeasurementView { return null; } - @Override - public float getMinValue() { - return 10; - } - @Override public float getMaxValue() { return 300; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/LinearGaugeView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/LinearGaugeView.java index 21587b82..bcc4bfcf 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/LinearGaugeView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/LinearGaugeView.java @@ -20,6 +20,8 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; +import android.graphics.Rect; +import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; @@ -34,17 +36,12 @@ public class LinearGaugeView extends View { public static final int COLOR_ORANGE = Color.parseColor("#FFBB33"); public static final int COLOR_RED = Color.parseColor("#FF4444"); - private final float barHeight = 10; - private final float limitLineHeight = 20; - private final float lineThickness = 5.0f; - private final float textOffset = 10.0f; + private static final float barHeight = 10; + private static final float textOffset = 10.0f; + private RectF limitRect = new RectF(0, 0, barHeight / 2, barHeight * 2); - private float firstPercent; - private float firstPos; - private float secondPercent; - private float secondPos; - private float valuePercent; - private float valuePos; + // Pre-created rect to avoid creating object in onDraw + private Rect bounds = new Rect(); private Paint rectPaintLow; private Paint rectPaintNormal; @@ -54,10 +51,8 @@ public class LinearGaugeView extends View { private Paint infoTextPaint; private float value; - private float minValue; - private float maxValue; - private float firstLimit; - private float secondLimit; + private float firstLimit = -1.0f; + private float secondLimit = -1.0f; public LinearGaugeView(Context context) { super(context); @@ -96,9 +91,23 @@ public class LinearGaugeView extends View { infoTextPaint.setColor(Color.GRAY); infoTextPaint.setTextSize(30); infoTextPaint.setTextAlign(Paint.Align.CENTER); + } - firstLimit = -1.0f; - secondLimit = -1.0f; + private float valueToPosition(float value, float minValue, float maxValue) { + final float percent = (value - minValue) / (maxValue - minValue) * 100.0f; + return getWidth() / 100.0f * percent; + } + + private void drawCenteredText(Canvas canvas, String text, float centerX, float y, + Paint paint, Rect textBounds) { + float x = Math.max(0.0f, centerX - textBounds.width() / 2.0f); + x = Math.min(x, getWidth() - textBounds.width()); + canvas.drawText(text, x, y, paint); + } + + private void drawCenteredText(Canvas canvas, String text, float centerX, float y, Paint paint) { + paint.getTextBounds(text, 0, text.length(), bounds); + drawCenteredText(canvas, text, centerX, y, paint, bounds); } @Override @@ -106,57 +115,92 @@ public class LinearGaugeView extends View { super.onDraw(canvas); if (firstLimit < 0 && secondLimit < 0) { - float textY=getHeight() / 2.0f; - float textX=getWidth() / 2.0f; - canvas.drawText(getResources().getString(R.string.info_no_evaluation_available),textX,textY,infoTextPaint); + float textX = getWidth() / 2.0f; + float textY = getHeight() / 2.0f; + canvas.drawText(getResources().getString(R.string.info_no_evaluation_available), textX, textY, infoTextPaint); return; } - firstPercent = (firstLimit / maxValue) * 100.0f; - firstPos = (getWidth() / 100.0f) * firstPercent; + final boolean hasFirstLimit = firstLimit >= 0; - secondPercent = (secondLimit / maxValue) * 100.0f; - secondPos = (getWidth() / 100.0f) * secondPercent; + // Calculate the size of the "normal" span with a fallback if there is no such span + float span = hasFirstLimit ? secondLimit - firstLimit : 0.3f * secondLimit; - valuePercent = (value / maxValue) * 100.0f; - valuePos = (getWidth() / 100.0f) * valuePercent; + // Adjust the span if needed to make the value fit inside of it + if (hasFirstLimit && value < firstLimit - span) { + span = firstLimit - value; + } else if (!hasFirstLimit && value < secondLimit - span) { + span = secondLimit - value; + } else if (value > secondLimit + span) { + span = value - secondLimit; + } + + // Round span to some nice value + if (span <= 1.0f) { + span = (float)Math.ceil(span * 10.0) / 10.0f; + } else if (span <= 10.0f) { + span = (float)Math.ceil(span); + } else { + span = 5.0f * (float)Math.ceil(span / 5.0); + } + + final float minValue = Math.max(0.0f, (hasFirstLimit ? firstLimit : secondLimit) - span); + final float maxValue = secondLimit + span; + + final float firstPos = valueToPosition(firstLimit, minValue, maxValue); + final float secondPos = valueToPosition(secondLimit, minValue, maxValue); + final float valuePos = valueToPosition(value, minValue, maxValue); // Bar + final float barTop = getHeight() / 2.0f - barHeight / 2.0f; + final float barBottom = barTop + barHeight; + if (firstLimit > 0) { - canvas.drawRect(0, (getHeight() / 2.0f) - (barHeight / 2.0f), firstPos, (getHeight() / 2.0f) + (barHeight / 2.0f), rectPaintLow); + canvas.drawRect(0, barTop, firstPos, barBottom, rectPaintLow); + canvas.drawRect(firstPos, barTop, secondPos, barBottom, rectPaintNormal); } else { - canvas.drawRect(0, (getHeight() / 2.0f) - (barHeight / 2.0f), firstPos, (getHeight() / 2.0f) + (barHeight / 2.0f), rectPaintNormal); + canvas.drawRect(0, barTop, secondPos, barBottom, rectPaintNormal); } - canvas.drawRect(firstPos, (getHeight() / 2.0f) - (barHeight / 2.0f), secondPos , (getHeight() / 2.0f) + (barHeight / 2.0f), rectPaintNormal); - canvas.drawRect(secondPos,(getHeight() / 2.0f) - (barHeight / 2.0f), getWidth() , (getHeight() / 2.0f) + (barHeight / 2.0f), rectPaintHigh); + canvas.drawRect(secondPos, barTop, getWidth(), barBottom, rectPaintHigh); // Limit Lines - canvas.drawRect(0, (getHeight() / 2.0f) - (limitLineHeight / 2.0f), 0+lineThickness, (getHeight() / 2.0f) + (limitLineHeight / 2.0f), textPaint); + limitRect.offsetTo(0, getHeight() / 2.0f - limitRect.height() / 2.0f); + canvas.drawRect(limitRect, textPaint); if (firstLimit > 0) { - canvas.drawRect(firstPos, (getHeight() / 2.0f) - (limitLineHeight / 2.0f), firstPos + lineThickness, (getHeight() / 2.0f) + (limitLineHeight / 2.0f), textPaint); + limitRect.offsetTo(firstPos - limitRect.width() / 2.0f, limitRect.top); + canvas.drawRect(limitRect, textPaint); } - canvas.drawRect(secondPos, (getHeight() / 2.0f) - (limitLineHeight / 2.0f), secondPos+lineThickness, (getHeight() / 2.0f) + (limitLineHeight / 2.0f), textPaint); - canvas.drawRect(getWidth()-lineThickness, (getHeight() / 2.0f) - (limitLineHeight / 2.0f), getWidth(), (getHeight() / 2.0f) + (limitLineHeight / 2.0f), textPaint); + limitRect.offsetTo(secondPos - limitRect.width() / 2.0f, limitRect.top); + canvas.drawRect(limitRect, textPaint); + limitRect.offsetTo(getWidth() - limitRect.width(), limitRect.top); + canvas.drawRect(limitRect, textPaint); // Text - canvas.drawText(Float.toString(minValue), 0.0f, (getHeight() / 2.0f) - (barHeight / 2.0f) - textOffset, textPaint); + final float textY = barTop - textOffset; + canvas.drawText(Float.toString(minValue), 0.0f, textY, textPaint); if (firstLimit > 0) { - canvas.drawText(Float.toString(firstLimit), firstPos - 5.0f, (getHeight() / 2.0f) - (barHeight / 2.0f) - textOffset, textPaint); + drawCenteredText(canvas, Float.toString(firstLimit), firstPos, textY, textPaint); } - canvas.drawText(Float.toString(secondLimit), secondPos-5.0f, (getHeight() / 2.0f) - (barHeight / 2.0f) - textOffset, textPaint); - canvas.drawText(Float.toString(maxValue), getWidth()-40.0f, (getHeight() / 2.0f) - (barHeight / 2.0f)- textOffset, textPaint); + drawCenteredText(canvas, Float.toString(secondLimit), secondPos, textY, textPaint); + drawCenteredText(canvas, Float.toString(maxValue), getWidth(), textY, textPaint); // Indicator + final float indicatorBottom = limitRect.bottom + 10.0f; Path path = new Path(); path.setFillType(Path.FillType.EVEN_ODD); - path.moveTo(valuePos, (getHeight() / 2.0f) - 10.0f); - path.lineTo(valuePos + 10.0f, (getHeight() / 2.0f) + 20.0f); - path.lineTo(valuePos - 10.0f, (getHeight() / 2.0f) + 20.0f); - path.lineTo(valuePos, (getHeight() / 2.0f) - 10.0f); + path.moveTo(valuePos, barTop); + path.lineTo(valuePos + 10.0f, indicatorBottom); + path.lineTo(valuePos - 10.0f, indicatorBottom); + path.lineTo(valuePos, barTop); path.close(); canvas.drawPath(path, indicatorPaint); - canvas.drawText(String.format("%.2f", value), valuePos-15.0f, (getHeight() / 2.0f) - (barHeight / 2.0f) - textOffset, indicatorPaint); + + // Value text + String valueStr = String.format("%.2f", value); + indicatorPaint.getTextBounds(valueStr, 0, valueStr.length(), bounds); + drawCenteredText(canvas, valueStr, valuePos, + indicatorBottom + bounds.height() + textOffset, indicatorPaint, bounds); } @Override @@ -201,13 +245,6 @@ public class LinearGaugeView extends View { setMeasuredDimension(width, height); } - public void setMinMaxValue(float min, float max) { - minValue = min; - maxValue = max; - invalidate(); - requestLayout(); - } - public void setLimits(float first, float second) { firstLimit = first; secondLimit = second; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java index 10fafc3f..837896b1 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/MeasurementView.java @@ -205,7 +205,6 @@ public abstract class MeasurementView extends TableLayout { public abstract void updatePreferences(SharedPreferences preferences); public abstract String getUnit(); public abstract EvaluationResult evaluateSheet(EvaluationSheet evalSheet, float value); - public abstract float getMinValue(); public abstract float getMaxValue(); public float getValue() { @@ -220,19 +219,13 @@ public abstract class MeasurementView extends TableLayout { } public void incValue() { - float incValue = getValue() + 0.1f; - - if (incValue <= getMaxValue()) { - setValueOnView(dateTime, incValue); - } + float incValue = Math.min(getMaxValue(), getValue() + 0.1f); + setValueOnView(dateTime, incValue); } public void decValue() { - float decValue = getValue() - 0.1f; - - if (decValue >= 0) { - setValueOnView(dateTime, decValue); - } + float decValue = Math.max(0.0f, getValue() - 0.1f); + setValueOnView(dateTime, decValue); } public String getValueAsString() { @@ -294,7 +287,7 @@ public abstract class MeasurementView extends TableLayout { try{ Float floatValue = Float.parseFloat(value); - if (measurementMode == VIEW) { + if (measurementMode == VIEW || measurementMode == EDIT) { evaluate(floatValue); } valueView.setText(String.format("%.2f ", floatValue) + getUnit()); @@ -382,7 +375,6 @@ public abstract class MeasurementView extends TableLayout { evalResult = new EvaluationResult(); } - evaluatorView.setMinMaxValue(getMinValue(), getMaxValue()); evaluatorView.setLimits(evalResult.lowLimit, evalResult.highLimit); evaluatorView.setValue(value); diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/MuscleMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/MuscleMeasurementView.java index 290284a1..05299f90 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/MuscleMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/MuscleMeasurementView.java @@ -60,11 +60,6 @@ public class MuscleMeasurementView extends MeasurementView { return evalSheet.evaluateBodyMuscle(value); } - @Override - public float getMinValue() { - return 10; - } - @Override public float getMaxValue() { return 80; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/TimeMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/TimeMeasurementView.java index 302201fd..7a11cca3 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/TimeMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/TimeMeasurementView.java @@ -89,11 +89,6 @@ public class TimeMeasurementView extends MeasurementView { return null; } - @Override - public float getMinValue() { - return 0; - } - @Override public float getMaxValue() { return 0; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/WHRMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/WHRMeasurementView.java index ef9d28d3..6684740f 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/WHRMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/WHRMeasurementView.java @@ -60,11 +60,6 @@ public class WHRMeasurementView extends MeasurementView { return evalSheet.evaluateWHR(value); } - @Override - public float getMinValue() { - return 0.5f; - } - @Override public float getMaxValue() { return 1.5f; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/WHtRMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/WHtRMeasurementView.java index 49228621..66793e7e 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/WHtRMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/WHtRMeasurementView.java @@ -60,11 +60,6 @@ public class WHtRMeasurementView extends MeasurementView { return evalSheet.evaluateWHtR(value); } - @Override - public float getMinValue() { - return 0; - } - @Override public float getMaxValue() { return 1; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/WaistMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/WaistMeasurementView.java index 1c322e04..d37ec7c5 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/WaistMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/WaistMeasurementView.java @@ -55,11 +55,6 @@ public class WaistMeasurementView extends MeasurementView { return evalSheet.evaluateWaist(value); } - @Override - public float getMinValue() { - return 30; - } - @Override public float getMaxValue() { return 200; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/WaterMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/WaterMeasurementView.java index 846c0e55..35e955c9 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/WaterMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/WaterMeasurementView.java @@ -70,11 +70,6 @@ public class WaterMeasurementView extends MeasurementView { return evalSheet.evaluateBodyWater(value); } - @Override - public float getMinValue() { - return 30; - } - @Override public float getMaxValue() { return 80; diff --git a/android_app/app/src/main/java/com/health/openscale/gui/views/WeightMeasurementView.java b/android_app/app/src/main/java/com/health/openscale/gui/views/WeightMeasurementView.java index 5f73b560..2ac13135 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/views/WeightMeasurementView.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/views/WeightMeasurementView.java @@ -56,11 +56,6 @@ public class WeightMeasurementView extends MeasurementView { return evalSheet.evaluateWeight(value); } - @Override - public float getMinValue() { - return 30; - } - @Override public float getMaxValue() { return 300;