1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-19 00:19:25 +01:00

Add combined goals widget

This commit is contained in:
Arjan Schrijver 2024-01-13 21:52:44 +01:00
parent cb77ca0495
commit c5ed03962c
10 changed files with 296 additions and 116 deletions

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 Arjan Schrijver
/* Copyright (C) 2023-2024 Arjan Schrijver
This file is part of Gadgetbridge.
@ -43,6 +43,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.AbstractDashboardWidget;
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardActiveTimeWidget;
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardDistanceWidget;
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardGoalsWidget;
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardSleepWidget;
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardStepsWidget;
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardTodayWidget;
@ -57,6 +58,7 @@ public class DashboardFragment extends Fragment {
private TextView arrowRight;
private GridLayout gridLayout;
private DashboardTodayWidget todayWidget;
private DashboardGoalsWidget goalsWidget;
private DashboardStepsWidget stepsWidget;
private DashboardDistanceWidget distanceWidget;
private DashboardActiveTimeWidget activeTimeWidget;
@ -85,6 +87,7 @@ public class DashboardFragment extends Fragment {
});
todayWidget = null;
goalsWidget = null;
stepsWidget = null;
distanceWidget = null;
activeTimeWidget = null;
@ -116,6 +119,7 @@ public class DashboardFragment extends Fragment {
super.onActivityResult(requestCode, resultCode, data);
gridLayout.removeAllViews();
todayWidget = null;
goalsWidget = null;
stepsWidget = null;
distanceWidget = null;
activeTimeWidget = null;
@ -150,6 +154,14 @@ public class DashboardFragment extends Fragment {
todayWidget.setTimespan(timeFrom, timeTo);
}
}
if (prefs.getBoolean("dashboard_widget_goals_enabled", true)) {
if (goalsWidget == null) {
goalsWidget = DashboardGoalsWidget.newInstance(timeFrom, timeTo);
createWidget(goalsWidget, cardsEnabled, 2);
} else {
goalsWidget.setTimespan(timeFrom, timeTo);
}
}
if (prefs.getBoolean("dashboard_widget_steps_enabled", true)) {
if (stepsWidget == null) {
stepsWidget = DashboardStepsWidget.newInstance(timeFrom, timeTo);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 Arjan Schrijver
/* Copyright (C) 2023-2024 Arjan Schrijver
This file is part of Gadgetbridge.
@ -32,6 +32,7 @@ import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.activities.charts.StepAnalysis;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
@ -40,6 +41,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySession;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.DailyTotals;
public abstract class AbstractDashboardWidget extends Fragment {
@ -51,6 +53,14 @@ public abstract class AbstractDashboardWidget extends Fragment {
protected int timeFrom;
protected int timeTo;
protected @ColorInt int color_not_worn = Color.argb(128, 0, 0, 0);
protected @ColorInt int color_worn = Color.argb(128, 128, 128, 128);
protected @ColorInt int color_activity = Color.GREEN;
protected @ColorInt int color_deep_sleep = Color.BLUE;
protected @ColorInt int color_light_sleep = Color.rgb(150, 150, 255);
protected @ColorInt int color_distance = Color.BLUE;
protected @ColorInt int color_active_time = Color.rgb(170, 0, 255);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -136,4 +146,102 @@ public abstract class AbstractDashboardWidget extends Fragment {
return bitmap;
}
protected int getStepsTotal() {
List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
int totalSteps = 0;
try (DBHandler dbHandler = GBApplication.acquireDB()) {
for (GBDevice dev : devices) {
if (dev.getDeviceCoordinator().supportsActivityTracking()) {
totalSteps += getSteps(dev, dbHandler);
}
}
} catch (Exception e) {
LOG.warn("Could not calculate total amount of steps: ", e);
}
return totalSteps;
}
protected float getStepsGoalFactor() {
ActivityUser activityUser = new ActivityUser();
float stepsGoal = activityUser.getStepsGoal();
float goalFactor = getStepsTotal() / stepsGoal;
if (goalFactor > 1) goalFactor = 1;
return goalFactor;
}
protected float getDistanceTotal() {
List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
long totalSteps = 0;
try (DBHandler dbHandler = GBApplication.acquireDB()) {
for (GBDevice dev : devices) {
if (dev.getDeviceCoordinator().supportsActivityTracking()) {
totalSteps += getSteps(dev, dbHandler);
}
}
} catch (Exception e) {
LOG.warn("Could not calculate total distance: ", e);
}
ActivityUser activityUser = new ActivityUser();
int stepLength = activityUser.getStepLengthCm();
return totalSteps * stepLength * 0.01f;
}
protected float getDistanceGoalFactor() {
ActivityUser activityUser = new ActivityUser();
int distanceGoal = activityUser.getDistanceGoalMeters();
float goalFactor = getDistanceTotal() / distanceGoal;
if (goalFactor > 1) goalFactor = 1;
return goalFactor;
}
protected long getActiveMinutesTotal() {
List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
long totalActiveMinutes = 0;
try (DBHandler dbHandler = GBApplication.acquireDB()) {
for (GBDevice dev : devices) {
if (dev.getDeviceCoordinator().supportsActivityTracking()) {
totalActiveMinutes += getActiveMinutes(dev, dbHandler, timeFrom, timeTo);
}
}
} catch (Exception e) {
LOG.warn("Could not calculate total amount of activity: ", e);
}
return totalActiveMinutes;
}
protected float getActiveMinutesGoalFactor() {
ActivityUser activityUser = new ActivityUser();
int activeTimeGoal = activityUser.getActiveTimeGoalMinutes();
float goalFactor = (float) getActiveMinutesTotal() / activeTimeGoal;
if (goalFactor > 1) goalFactor = 1;
return goalFactor;
}
protected long getSleepMinutesTotal() {
List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
long totalSleepMinutes = 0;
try (DBHandler dbHandler = GBApplication.acquireDB()) {
for (GBDevice dev : devices) {
if (dev.getDeviceCoordinator().supportsActivityTracking()) {
totalSleepMinutes += getSleep(dev, dbHandler);
}
}
} catch (Exception e) {
LOG.warn("Could not calculate total amount of sleep: ", e);
}
return totalSleepMinutes;
}
protected float getSleepMinutesGoalFactor() {
ActivityUser activityUser = new ActivityUser();
int sleepMinutesGoal = activityUser.getSleepDurationGoal() * 60;
float goalFactor = (float) getSleepMinutesTotal() / sleepMinutesGoal;
if (goalFactor > 1) goalFactor = 1;
return goalFactor;
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 Arjan Schrijver
/* Copyright (C) 2023-2024 Arjan Schrijver
This file is part of Gadgetbridge.
@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.dashboard;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -27,13 +26,7 @@ import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
/**
* A simple {@link AbstractDashboardWidget} subclass.
@ -86,26 +79,12 @@ public class DashboardActiveTimeWidget extends AbstractDashboardWidget {
@Override
protected void fillData() {
// Update text representation
List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
long totalActiveMinutes = 0;
try (DBHandler dbHandler = GBApplication.acquireDB()) {
for (GBDevice dev : devices) {
if (dev.getDeviceCoordinator().supportsActivityTracking()) {
totalActiveMinutes += getActiveMinutes(dev, dbHandler, timeFrom, timeTo);
}
}
} catch (Exception e) {
LOG.warn("Could not calculate total amount of activity: ", e);
}
long totalActiveMinutes = getActiveMinutesTotal();
String activeHours = String.format("%d", (int) Math.floor(totalActiveMinutes / 60f));
String activeMinutes = String.format("%02d", (int) (totalActiveMinutes % 60f));
activeTime.setText(activeHours + ":" + activeMinutes);
// Draw gauge
ActivityUser activityUser = new ActivityUser();
int activeTimeGoal = activityUser.getActiveTimeGoalMinutes();
float goalFactor = (float) totalActiveMinutes / activeTimeGoal;
if (goalFactor > 1) goalFactor = 1;
activeTimeGauge.setImageBitmap(drawGauge(200, 15, Color.rgb(170, 0, 255), goalFactor));
activeTimeGauge.setImageBitmap(drawGauge(200, 15, color_active_time, getActiveMinutesGoalFactor()));
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 Arjan Schrijver
/* Copyright (C) 2023-2024 Arjan Schrijver
This file is part of Gadgetbridge.
@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.dashboard;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -27,13 +26,7 @@ import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.util.FormatUtils;
/**
@ -87,27 +80,10 @@ public class DashboardDistanceWidget extends AbstractDashboardWidget {
@Override
protected void fillData() {
// Update text representation
List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
long totalSteps = 0;
try (DBHandler dbHandler = GBApplication.acquireDB()) {
for (GBDevice dev : devices) {
if (dev.getDeviceCoordinator().supportsActivityTracking()) {
totalSteps += getSteps(dev, dbHandler);
}
}
} catch (Exception e) {
LOG.warn("Could not calculate total distance: ", e);
}
ActivityUser activityUser = new ActivityUser();
int stepLength = activityUser.getStepLengthCm();
float distanceMeters = totalSteps * stepLength * 0.01f;
String distanceFormatted = FormatUtils.getFormattedDistanceLabel(distanceMeters);
String distanceFormatted = FormatUtils.getFormattedDistanceLabel(getDistanceTotal());
distanceText.setText(distanceFormatted);
// Draw gauge
int distanceGoal = activityUser.getDistanceGoalMeters();
float goalFactor = distanceMeters / distanceGoal;
if (goalFactor > 1) goalFactor = 1;
distanceGauge.setImageBitmap(drawGauge(200, 15, Color.GREEN, goalFactor));
distanceGauge.setImageBitmap(drawGauge(200, 15, color_distance, getDistanceGoalFactor()));
}
}

View File

@ -0,0 +1,128 @@
/* Copyright (C) 2023-2024 Arjan Schrijver
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.dashboard;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.R;
/**
* A simple {@link AbstractDashboardWidget} subclass.
* Use the {@link DashboardGoalsWidget#newInstance} factory method to
* create an instance of this fragment.
*/
public class DashboardGoalsWidget extends AbstractDashboardWidget {
private static final Logger LOG = LoggerFactory.getLogger(DashboardGoalsWidget.class);
private ImageView goalsChart;
public DashboardGoalsWidget() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param timeFrom Start time in seconds since Unix epoch.
* @param timeTo End time in seconds since Unix epoch.
* @return A new instance of fragment DashboardGoalsWidget.
*/
public static DashboardGoalsWidget newInstance(int timeFrom, int timeTo) {
DashboardGoalsWidget fragment = new DashboardGoalsWidget();
Bundle args = new Bundle();
args.putInt(ARG_TIME_FROM, timeFrom);
args.putInt(ARG_TIME_TO, timeTo);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View todayView = inflater.inflate(R.layout.dashboard_widget_goals, container, false);
goalsChart = todayView.findViewById(R.id.dashboard_goals_chart);
// Initialize legend
TextView legend = todayView.findViewById(R.id.dashboard_goals_legend);
SpannableString l_steps = new SpannableString("" + getString(R.string.steps));
l_steps.setSpan(new ForegroundColorSpan(color_activity), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableString l_distance = new SpannableString("" + getString(R.string.distance));
l_distance.setSpan(new ForegroundColorSpan(color_distance), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableString l_active_time = new SpannableString("" + getString(R.string.activity_list_summary_active_time));
l_active_time.setSpan(new ForegroundColorSpan(color_active_time), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableString l_sleep = new SpannableString("" + getString(R.string.menuitem_sleep));
l_sleep.setSpan(new ForegroundColorSpan(color_light_sleep), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableStringBuilder legendBuilder = new SpannableStringBuilder();
legend.setText(legendBuilder.append(l_steps).append(" ").append(l_distance).append("\n").append(l_sleep).append(" ").append(l_active_time));
fillData();
return todayView;
}
@Override
public void onResume() {
super.onResume();
if (goalsChart != null) fillData();
}
protected void fillData() {
int width = 230;
int height = 230;
int barWidth = 10;
int barMargin = (int) Math.ceil(barWidth / 2f);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(barWidth);
paint.setColor(color_activity);
canvas.drawArc(barMargin, barMargin, width - barMargin, height - barMargin, 270, 360 * getStepsGoalFactor(), false, paint);
barMargin += barWidth * 1.5;
paint.setColor(color_distance);
canvas.drawArc(barMargin, barMargin, width - barMargin, height - barMargin, 270, 360 * getDistanceGoalFactor(), false, paint);
barMargin += barWidth * 1.5;
paint.setColor(color_active_time);
canvas.drawArc(barMargin, barMargin, width - barMargin, height - barMargin, 270, 360 * getActiveMinutesGoalFactor(), false, paint);
barMargin += barWidth * 1.5;
paint.setColor(color_deep_sleep);
canvas.drawArc(barMargin, barMargin, width - barMargin, height - barMargin, 270, 360 * getSleepMinutesGoalFactor(), false, paint);
goalsChart.setImageBitmap(bitmap);
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 Arjan Schrijver
/* Copyright (C) 2023-2024 Arjan Schrijver
This file is part of Gadgetbridge.
@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.dashboard;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -27,13 +26,7 @@ import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
/**
* A simple {@link AbstractDashboardWidget} subclass.
@ -86,26 +79,12 @@ public class DashboardSleepWidget extends AbstractDashboardWidget {
@Override
protected void fillData() {
// Update text representation
List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
long totalSleepMinutes = 0;
try (DBHandler dbHandler = GBApplication.acquireDB()) {
for (GBDevice dev : devices) {
if (dev.getDeviceCoordinator().supportsActivityTracking()) {
totalSleepMinutes += getSleep(dev, dbHandler);
}
}
} catch (Exception e) {
LOG.warn("Could not calculate total amount of sleep: ", e);
}
long totalSleepMinutes = getSleepMinutesTotal();
String sleepHours = String.format("%d", (int) Math.floor(totalSleepMinutes / 60f));
String sleepMinutes = String.format("%02d", (int) (totalSleepMinutes % 60f));
sleepAmount.setText(sleepHours + ":" + sleepMinutes);
// Draw gauge
ActivityUser activityUser = new ActivityUser();
int sleepMinutesGoal = activityUser.getSleepDurationGoal() * 60;
float goalFactor = (float) totalSleepMinutes / sleepMinutesGoal;
if (goalFactor > 1) goalFactor = 1;
sleepGauge.setImageBitmap(drawGauge(200, 15, Color.rgb(170, 0, 255), goalFactor));
sleepGauge.setImageBitmap(drawGauge(200, 15, color_light_sleep, getSleepMinutesGoalFactor()));
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 Arjan Schrijver
/* Copyright (C) 2023-2024 Arjan Schrijver
This file is part of Gadgetbridge.
@ -16,7 +16,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities.dashboard;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -27,13 +26,7 @@ import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
/**
* A simple {@link AbstractDashboardWidget} subclass.
@ -83,24 +76,9 @@ public class DashboardStepsWidget extends AbstractDashboardWidget {
protected void fillData() {
// Update text representation
List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
int totalSteps = 0;
try (DBHandler dbHandler = GBApplication.acquireDB()) {
for (GBDevice dev : devices) {
if (dev.getDeviceCoordinator().supportsActivityTracking()) {
totalSteps += getSteps(dev, dbHandler);
}
}
} catch (Exception e) {
LOG.warn("Could not calculate total amount of steps: ", e);
}
stepsCount.setText(String.valueOf(totalSteps));
stepsCount.setText(String.valueOf(getStepsTotal()));
// Draw gauge
ActivityUser activityUser = new ActivityUser();
float stepsGoal = activityUser.getStepsGoal();
float goalFactor = totalSteps / stepsGoal;
if (goalFactor > 1) goalFactor = 1;
stepsGauge.setImageBitmap(drawGauge(200, 15, Color.BLUE, goalFactor));
stepsGauge.setImageBitmap(drawGauge(200, 15, color_activity, getStepsGoalFactor()));
}
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 Arjan Schrijver
/* Copyright (C) 2023-2024 Arjan Schrijver
This file is part of Gadgetbridge.
@ -114,13 +114,13 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
// Initialize legend
TextView legend = todayView.findViewById(R.id.dashboard_piechart_legend);
SpannableString l_not_worn = new SpannableString("" + getString(R.string.abstract_chart_fragment_kind_not_worn));
l_not_worn.setSpan(new ForegroundColorSpan(Color.rgb(0, 0, 0)), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
l_not_worn.setSpan(new ForegroundColorSpan(color_not_worn), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableString l_activity = new SpannableString("" + getString(R.string.activity_type_activity));
l_activity.setSpan(new ForegroundColorSpan(Color.rgb(0, 255, 0)), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
l_activity.setSpan(new ForegroundColorSpan(color_activity), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableString l_deep_sleep = new SpannableString("" + getString(R.string.activity_type_deep_sleep));
l_deep_sleep.setSpan(new ForegroundColorSpan(Color.rgb(0, 0, 255)), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
l_deep_sleep.setSpan(new ForegroundColorSpan(color_deep_sleep), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableString l_light_sleep = new SpannableString("" + getString(R.string.activity_type_light_sleep));
l_light_sleep.setSpan(new ForegroundColorSpan(Color.rgb(150, 150, 255)), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
l_light_sleep.setSpan(new ForegroundColorSpan(color_light_sleep), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableStringBuilder legendBuilder = new SpannableStringBuilder();
legend.setText(legendBuilder.append(l_not_worn).append(" ").append(l_activity).append("\n").append(l_light_sleep).append(" ").append(l_deep_sleep));
@ -143,7 +143,7 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
PieDataSet scaleDataSet = new PieDataSet(scaleEntries, "Time scale");
scaleDataSet.setSliceSpace(0f);
scaleDataSet.setDrawValues(false);
scaleDataSet.setColor(Color.argb(0,0,0,0));
scaleDataSet.setColor(Color.TRANSPARENT);
PieData scaleData = new PieData(scaleDataSet);
scale.setData(scaleData);
@ -265,24 +265,24 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
// Draw inactive slice
if (activity.timeFrom > secondIndex) {
entries.add(new PieEntry(activity.timeFrom - secondIndex, "Inactive"));
colors.add(Color.rgb(128, 128, 128));
colors.add(color_worn);
}
// Draw activity slices
if (activity.activityKind == ActivityKind.TYPE_NOT_WORN) {
entries.add(new PieEntry(activity.timeTo - activity.timeFrom, "Not worn"));
colors.add(Color.rgb(0, 0, 0));
colors.add(color_not_worn);
secondIndex = activity.timeTo;
} else if (activity.activityKind == ActivityKind.TYPE_LIGHT_SLEEP || activity.activityKind == ActivityKind.TYPE_SLEEP) {
entries.add(new PieEntry(activity.timeTo - activity.timeFrom, "Light sleep"));
colors.add(Color.rgb(150, 150, 255));
colors.add(color_light_sleep);
secondIndex = activity.timeTo;
} else if (activity.activityKind == ActivityKind.TYPE_DEEP_SLEEP) {
entries.add(new PieEntry(activity.timeTo - activity.timeFrom, "Deep sleep"));
colors.add(Color.rgb(0, 0, 255));
colors.add(color_deep_sleep);
secondIndex = activity.timeTo;
} else {
entries.add(new PieEntry(activity.timeTo - activity.timeFrom, "Active"));
colors.add(Color.rgb(0, 255, 0));
colors.add(color_activity);
secondIndex = activity.timeTo;
}
}
@ -291,7 +291,7 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
if (currentTime > timeFrom && currentTime < midDaySecond) {
// Fill with unknown slice up until current time
entries_0_12.add(new PieEntry(currentTime - secondIndex, "Unknown"));
colors_0_12.add(Color.argb(128, 128, 128, 128));
colors_0_12.add(color_worn);
// Draw transparent slice for remaining time until midday
entries_0_12.add(new PieEntry(midDaySecond - currentTime, "Empty"));
colors_0_12.add(Color.TRANSPARENT);
@ -299,7 +299,7 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
if (currentTime >= midDaySecond && currentTime < timeTo) {
// Fill with unknown slice up until current time
entries_12_24.add(new PieEntry(currentTime - secondIndex, "Unknown"));
colors_12_24.add(Color.rgb(128, 128, 128));
colors_12_24.add(color_worn);
// Draw transparent slice for remaining time until midnight
entries_12_24.add(new PieEntry(timeTo - currentTime, "Empty"));
colors_12_24.add(Color.TRANSPARENT);

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activities.dashboard.DashboardGoalsWidget">
<ImageView
android:id="@+id/dashboard_goals_chart"
android:layout_width="match_parent"
android:layout_height="230dp"
android:scaleType="fitCenter" />
<TextView
android:id="@+id/dashboard_goals_legend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:textAlignment="center" />
</LinearLayout>

View File

@ -98,7 +98,6 @@
android:key="dashboard_widget_goals_enabled"
android:layout="@layout/preference_checkbox"
android:title="Goals chart"
android:enabled="false"
app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
android:defaultValue="true"