diff --git a/android/uhabits-android/src/main/AndroidManifest.xml b/android/uhabits-android/src/main/AndroidManifest.xml
index b5138b3d3..9a3e7961f 100644
--- a/android/uhabits-android/src/main/AndroidManifest.xml
+++ b/android/uhabits-android/src/main/AndroidManifest.xml
@@ -1,6 +1,6 @@
+ package="org.isoron.uhabits">
@@ -8,37 +8,37 @@
+ android:name=".HabitsApplication"
+ android:allowBackup="true"
+ android:backupAgent=".HabitsBackupAgent"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/main_activity_title"
+ android:supportsRtl="true"
+ android:theme="@style/AppBaseTheme">
+ android:name=".activities.habits.edit.EditHabitActivity"
+ android:exported="true">
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activities.habits.list.ListHabitsActivity" />
+ android:name="com.google.android.backup.api_key"
+ android:value="AEdPqrEAAAAI6aeWncbnMNo8E5GWeZ44dlc5cQ7tCROwFhOtiw" />
+ android:name=".activities.habits.list.ListHabitsActivity"
+ android:exported="true"
+ android:label="@string/main_activity_title"
+ android:launchMode="singleTop" />
+ android:name=".MainActivity"
+ android:label="@string/main_activity_title"
+ android:launchMode="singleTop"
+ android:targetActivity=".activities.habits.list.ListHabitsActivity">
@@ -47,109 +47,131 @@
+ android:name=".activities.habits.show.ShowHabitActivity"
+ android:label="@string/title_activity_show_habit">
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activities.habits.list.ListHabitsActivity" />
+
+ android:name=".activities.settings.SettingsActivity"
+ android:label="@string/settings">
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activities.habits.list.ListHabitsActivity" />
+
+ android:name=".activities.intro.IntroActivity"
+ android:label=""
+ android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
+
+ android:name=".widgets.HabitPickerDialog"
+ android:theme="@style/Theme.AppCompat.Light.Dialog">
+
+ android:name=".activities.about.AboutActivity"
+ android:label="@string/about">
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activities.habits.list.ListHabitsActivity" />
+
+ android:name=".notifications.SnoozeDelayPickerActivity"
+ android:excludeFromRecents="true"
+ android:launchMode="singleInstance"
+ android:theme="@android:style/Theme.Translucent.NoTitleBar" />
+ android:name=".widgets.CheckmarkWidgetProvider"
+ android:label="@string/checkmark">
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_checkmark_info" />
+ android:name=".widgets.StackWidgetService"
+ android:exported="false"
+ android:permission="android.permission.BIND_REMOTEVIEWS" />
+
+
+
+
+
+
+
+
+ android:name=".widgets.ScoreWidgetProvider"
+ android:label="@string/habit_strength">
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_score_info" />
+
+ android:name=".widgets.StreakWidgetProvider"
+ android:label="@string/streaks">
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_streak_info" />
+
+ android:name=".widgets.FrequencyWidgetProvider"
+ android:label="@string/frequency">
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_frequency_info" />
+
+ android:name=".widgets.TargetWidgetProvider"
+ android:label="@string/target">
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_frequency_info" />
+
+
@@ -157,8 +179,8 @@
+ android:host="org.isoron.uhabits"
+ android:scheme="content" />
@@ -166,8 +188,8 @@
+ android:host="org.isoron.uhabits"
+ android:scheme="content" />
@@ -175,41 +197,46 @@
+ android:host="org.isoron.uhabits"
+ android:scheme="content" />
-
+
+
+
+ android:name=".automation.EditSettingActivity"
+ android:exported="true"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/app_name">
-
+
+
+
+ android:name=".automation.FireSettingReceiver"
+ android:exported="true">
+ android:name="androidx.core.content.FileProvider"
+ android:authorities="org.isoron.uhabits"
+ android:exported="false"
+ android:grantUriPermissions="true">
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/file_paths" />
+ android:name=".sync.SyncService"
+ android:enabled="true"
+ android:exported="false" />
+
\ No newline at end of file
diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/TargetChart.java b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/TargetChart.java
index cc1051f8d..30ec17bd9 100644
--- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/TargetChart.java
+++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/views/TargetChart.java
@@ -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 values)
diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/TargetCard.java b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/TargetCard.java
index aaa7a30d2..464ca1955 100644
--- a/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/TargetCard.java
+++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/views/TargetCard.java
@@ -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 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 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 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);
}
}
}
diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.java b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.java
index a5aeebb82..7a014f394 100644
--- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.java
+++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/StackWidgetType.java
@@ -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;
}
diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt
new file mode 100644
index 000000000..e38e25f9e
--- /dev/null
+++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidget.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 Álinson Santos Xavier
+ *
+ * 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 .
+ */
+
+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
+}
diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidgetProvider.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidgetProvider.kt
new file mode 100644
index 000000000..90524c890
--- /dev/null
+++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/TargetWidgetProvider.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2016 Álinson Santos Xavier
+ *
+ * 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 .
+ */
+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)
+ }
+}
diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt
index b8293582a..17d6d5d77 100644
--- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt
+++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/WidgetUpdater.kt
@@ -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)
}
}
diff --git a/android/uhabits-android/src/main/res/layout/target_stackview_widget.xml b/android/uhabits-android/src/main/res/layout/target_stackview_widget.xml
new file mode 100644
index 000000000..99ab7eefa
--- /dev/null
+++ b/android/uhabits-android/src/main/res/layout/target_stackview_widget.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file