mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Create target widget
This commit is contained in:
@@ -17,8 +17,8 @@
|
||||
android:theme="@style/AppBaseTheme">
|
||||
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".activities.habits.edit.EditHabitActivity">
|
||||
android:name=".activities.habits.edit.EditHabitActivity"
|
||||
android:exported="true">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".activities.habits.list.ListHabitsActivity" />
|
||||
@@ -53,6 +53,7 @@
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".activities.habits.list.ListHabitsActivity" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".activities.settings.SettingsActivity"
|
||||
android:label="@string/settings">
|
||||
@@ -60,10 +61,12 @@
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".activities.habits.list.ListHabitsActivity" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".activities.intro.IntroActivity"
|
||||
android:label=""
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
|
||||
|
||||
<activity
|
||||
android:name=".widgets.HabitPickerDialog"
|
||||
android:theme="@style/Theme.AppCompat.Light.Dialog">
|
||||
@@ -71,6 +74,7 @@
|
||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".activities.about.AboutActivity"
|
||||
android:label="@string/about">
|
||||
@@ -78,11 +82,12 @@
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".activities.habits.list.ListHabitsActivity" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".notifications.SnoozeDelayPickerActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||
|
||||
<receiver
|
||||
android:name=".widgets.CheckmarkWidgetProvider"
|
||||
@@ -112,6 +117,7 @@
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_history_info" />
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name=".widgets.ScoreWidgetProvider"
|
||||
android:label="@string/habit_strength">
|
||||
@@ -123,6 +129,7 @@
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_score_info" />
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name=".widgets.StreakWidgetProvider"
|
||||
android:label="@string/streaks">
|
||||
@@ -134,6 +141,7 @@
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_streak_info" />
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name=".widgets.FrequencyWidgetProvider"
|
||||
android:label="@string/frequency">
|
||||
@@ -145,11 +153,25 @@
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_frequency_info" />
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name=".widgets.TargetWidgetProvider"
|
||||
android:label="@string/target">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/widget_frequency_info" />
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".receivers.ReminderReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".receivers.WidgetReceiver">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
@@ -178,7 +200,9 @@
|
||||
android:host="org.isoron.uhabits"
|
||||
android:scheme="content" />
|
||||
</intent-filter>
|
||||
</receiver> <!-- Locale/Tasker -->
|
||||
</receiver>
|
||||
|
||||
<!-- Locale/Tasker -->
|
||||
<activity
|
||||
android:name=".automation.EditSettingActivity"
|
||||
android:exported="true"
|
||||
@@ -187,7 +211,9 @@
|
||||
<intent-filter>
|
||||
<action android:name="com.twofortyfouram.locale.intent.action.EDIT_SETTING" />
|
||||
</intent-filter>
|
||||
</activity> <!-- Locale/Tasker -->
|
||||
</activity>
|
||||
|
||||
<!-- Locale/Tasker -->
|
||||
<receiver
|
||||
android:name=".automation.FireSettingReceiver"
|
||||
android:exported="true">
|
||||
@@ -209,7 +235,8 @@
|
||||
<service
|
||||
android:name=".sync.SyncService"
|
||||
android:enabled="true"
|
||||
android:exported="false"></service>
|
||||
android:exported="false" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -93,7 +93,8 @@ public class TargetChart extends View
|
||||
maxLabelSize = Math.max(maxLabelSize, len);
|
||||
}
|
||||
|
||||
rect.set(0, 0, getWidth(), baseSize);
|
||||
float marginTop = (getHeight() - baseSize * labels.size()) / 2.0f;
|
||||
rect.set(0, marginTop, getWidth(), marginTop + baseSize);
|
||||
for (int i = 0; i < labels.size(); i++) {
|
||||
drawRow(canvas, i, rect);
|
||||
rect.offset(0, baseSize);
|
||||
@@ -103,8 +104,17 @@ public class TargetChart extends View
|
||||
@Override
|
||||
protected void onMeasure(int widthSpec, int heightSpec)
|
||||
{
|
||||
baseSize = getResources().getDimensionPixelSize(R.dimen.baseSize);
|
||||
|
||||
int width = getSize(widthSpec);
|
||||
int height = labels.size() * baseSize;
|
||||
|
||||
ViewGroup.LayoutParams params = getLayoutParams();
|
||||
if (params != null && params.height == ViewGroup.LayoutParams.MATCH_PARENT) {
|
||||
height = getSize(heightSpec);
|
||||
if (labels.size() > 0) baseSize = height / labels.size();
|
||||
}
|
||||
|
||||
heightSpec = makeMeasureSpec(height, EXACTLY);
|
||||
widthSpec = makeMeasureSpec(width, EXACTLY);
|
||||
setMeasuredDimension(widthSpec, heightSpec);
|
||||
@@ -194,7 +204,6 @@ public class TargetChart extends View
|
||||
mediumContrastTextColor = res.getColor(R.attr.mediumContrastTextColor);
|
||||
highContrastReverseTextColor = res.getColor(R.attr.highContrastReverseTextColor);
|
||||
tinyTextSize = getDimension(getContext(), R.dimen.tinyTextSize);
|
||||
baseSize = getResources().getDimensionPixelSize(R.dimen.baseSize);
|
||||
}
|
||||
|
||||
public void setValues(List<Double> values)
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.content.res.*;
|
||||
import android.util.*;
|
||||
import android.widget.*;
|
||||
|
||||
import androidx.annotation.*;
|
||||
|
||||
import org.isoron.uhabits.R;
|
||||
import org.isoron.uhabits.*;
|
||||
import org.isoron.uhabits.activities.common.views.*;
|
||||
@@ -86,10 +88,10 @@ public class TargetCard extends HabitCard
|
||||
@Override
|
||||
protected Task createRefreshTask()
|
||||
{
|
||||
return new RefreshTask();
|
||||
return new RefreshTask(getContext(), getHabit(), firstWeekday, targetChart, title);
|
||||
}
|
||||
|
||||
private class RefreshTask extends CancelableTask
|
||||
public static class RefreshTask extends CancelableTask
|
||||
{
|
||||
double todayValue;
|
||||
double thisWeekValue;
|
||||
@@ -97,11 +99,30 @@ public class TargetCard extends HabitCard
|
||||
double thisQuarterValue;
|
||||
double thisYearValue;
|
||||
|
||||
private Context context;
|
||||
private Habit habit;
|
||||
private int firstWeekday;
|
||||
private TargetChart chart;
|
||||
private TextView title;
|
||||
|
||||
public RefreshTask(@NonNull Context context,
|
||||
@NonNull Habit habit,
|
||||
int firstWeekday,
|
||||
@NonNull TargetChart chart,
|
||||
@Nullable TextView title)
|
||||
{
|
||||
this.context = context;
|
||||
this.habit = habit;
|
||||
this.firstWeekday = firstWeekday;
|
||||
this.chart = chart;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doInBackground()
|
||||
{
|
||||
if (isCanceled()) return;
|
||||
CheckmarkList checkmarks = getHabit().getCheckmarks();
|
||||
CheckmarkList checkmarks = habit.getCheckmarks();
|
||||
todayValue = checkmarks.getTodayValue() / 1e3;
|
||||
thisWeekValue = checkmarks.getThisWeekValue(firstWeekday) / 1e3;
|
||||
thisMonthValue = checkmarks.getThisMonthValue() / 1e3;
|
||||
@@ -113,15 +134,14 @@ public class TargetCard extends HabitCard
|
||||
public void onPostExecute()
|
||||
{
|
||||
if (isCanceled()) return;
|
||||
|
||||
Calendar cal = DateUtils.getStartOfTodayCalendar();
|
||||
int daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
|
||||
int daysInQuarter = 91;
|
||||
int daysInYear = cal.getActualMaximum(Calendar.DAY_OF_YEAR);
|
||||
|
||||
int den = getHabit().getFrequency().getDenominator();
|
||||
double dailyTarget = getHabit().getTargetValue() / den;
|
||||
Resources res = getResources();
|
||||
int den = habit.getFrequency().getDenominator();
|
||||
double dailyTarget = habit.getTargetValue() / den;
|
||||
Resources res = context.getResources();
|
||||
|
||||
ArrayList<Double> values = new ArrayList<>();
|
||||
if (den <= 1) values.add(todayValue);
|
||||
@@ -129,7 +149,7 @@ public class TargetCard extends HabitCard
|
||||
values.add(thisMonthValue);
|
||||
values.add(thisQuarterValue);
|
||||
values.add(thisYearValue);
|
||||
targetChart.setValues(values);
|
||||
chart.setValues(values);
|
||||
|
||||
ArrayList<Double> targets = new ArrayList<>();
|
||||
if (den <= 1) targets.add(dailyTarget);
|
||||
@@ -137,7 +157,7 @@ public class TargetCard extends HabitCard
|
||||
targets.add(dailyTarget * daysInMonth);
|
||||
targets.add(dailyTarget * daysInQuarter);
|
||||
targets.add(dailyTarget * daysInYear);
|
||||
targetChart.setTargets(targets);
|
||||
chart.setTargets(targets);
|
||||
|
||||
ArrayList<String> labels = new ArrayList<>();
|
||||
if (den <= 1) labels.add(res.getString(R.string.today));
|
||||
@@ -145,15 +165,15 @@ public class TargetCard extends HabitCard
|
||||
labels.add(res.getString(R.string.month));
|
||||
labels.add(res.getString(R.string.quarter));
|
||||
labels.add(res.getString(R.string.year));
|
||||
targetChart.setLabels(labels);
|
||||
chart.setLabels(labels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreExecute()
|
||||
{
|
||||
int color = PaletteUtils.getColor(getContext(), getHabit().getColor());
|
||||
title.setTextColor(color);
|
||||
targetChart.setColor(color);
|
||||
int color = PaletteUtils.getColor(context, habit.getColor());
|
||||
if(title != null) title.setTextColor(color);
|
||||
chart.setColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ public enum StackWidgetType {
|
||||
FREQUENCY(1),
|
||||
SCORE(2), // habit strength widget
|
||||
HISTORY(3),
|
||||
STREAKS(4);
|
||||
STREAKS(4),
|
||||
TARGET(5);
|
||||
|
||||
private int value;
|
||||
StackWidgetType(int value) {
|
||||
@@ -34,6 +35,8 @@ public enum StackWidgetType {
|
||||
return HISTORY;
|
||||
} else if (STREAKS.getValue() == value) {
|
||||
return STREAKS;
|
||||
} else if (TARGET.getValue() == value) {
|
||||
return TARGET;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -50,6 +53,8 @@ public enum StackWidgetType {
|
||||
return R.layout.history_stackview_widget;
|
||||
case STREAKS:
|
||||
return R.layout.streak_stackview_widget;
|
||||
case TARGET:
|
||||
return R.layout.target_stackview_widget;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -66,6 +71,8 @@ public enum StackWidgetType {
|
||||
return R.id.historyStackWidgetView;
|
||||
case STREAKS:
|
||||
return R.id.streakStackWidgetView;
|
||||
case TARGET:
|
||||
return R.id.targetStackWidgetView;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -82,6 +89,8 @@ public enum StackWidgetType {
|
||||
return R.id.historyStackWidgetEmptyView;
|
||||
case STREAKS:
|
||||
return R.id.streakStackWidgetEmptyView;
|
||||
case TARGET:
|
||||
return R.id.targetStackWidgetEmptyView;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker 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 General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.isoron.uhabits.widgets
|
||||
|
||||
import android.content.*
|
||||
import android.view.*
|
||||
import android.view.ViewGroup.*
|
||||
import android.view.ViewGroup.LayoutParams.*
|
||||
import org.isoron.uhabits.activities.common.views.*
|
||||
import org.isoron.uhabits.activities.habits.show.views.*
|
||||
import org.isoron.uhabits.core.models.*
|
||||
import org.isoron.uhabits.widgets.views.*
|
||||
|
||||
class TargetWidget(
|
||||
context: Context,
|
||||
id: Int,
|
||||
private val habit: Habit
|
||||
) : BaseWidget(context, id) {
|
||||
|
||||
override fun getOnClickPendingIntent(context: Context) =
|
||||
pendingIntentFactory.showHabit(habit)
|
||||
|
||||
override fun refreshData(view: View) {
|
||||
val widgetView = view as GraphWidgetView
|
||||
widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
|
||||
val chart = (widgetView.dataView as TargetChart)
|
||||
with(TargetCard.RefreshTask(context, habit, prefs.firstWeekday, chart, null)) {
|
||||
onPreExecute()
|
||||
doInBackground()
|
||||
onPostExecute()
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildView(): View {
|
||||
return GraphWidgetView(context, TargetChart(context)).apply {
|
||||
setTitle(habit.name)
|
||||
layoutParams = LayoutParams(MATCH_PARENT, MATCH_PARENT)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDefaultHeight() = 200
|
||||
override fun getDefaultWidth() = 200
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker 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 General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.isoron.uhabits.widgets
|
||||
|
||||
import android.content.*
|
||||
|
||||
class TargetWidgetProvider : BaseWidgetProvider() {
|
||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||
val habits = getHabitsFromWidgetId(id)
|
||||
if (habits.size == 1) return TargetWidget(context, id, habits[0])
|
||||
else return StackWidget(context, id, StackWidgetType.TARGET, habits)
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@ class WidgetUpdater
|
||||
updateWidgets(modifiedHabitId, ScoreWidgetProvider::class.java)
|
||||
updateWidgets(modifiedHabitId, StreakWidgetProvider::class.java)
|
||||
updateWidgets(modifiedHabitId, FrequencyWidgetProvider::class.java)
|
||||
updateWidgets(modifiedHabitId, TargetWidgetProvider::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<StackView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/targetStackWidgetView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:loopViews="true" />
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/targetStackWidgetEmptyView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/streaks_stack_widget"
|
||||
android:gravity="center"
|
||||
android:textColor="#ffffff"
|
||||
android:textStyle="bold"
|
||||
android:textSize="16sp" />
|
||||
</FrameLayout>
|
||||
Reference in New Issue
Block a user