Issue 1316: Skip measurable habit (#1319)

Co-authored-by: Jakub Kalinowski <kalj@netcompany.com>
This commit is contained in:
Jakub Kalinowski
2022-03-24 12:08:31 +01:00
committed by GitHub
parent ca4618579e
commit 3b12ec4bfe
14 changed files with 205 additions and 27 deletions

View File

@@ -22,6 +22,7 @@ package org.isoron.uhabits.activities.common.dialogs
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.content.DialogInterface.BUTTON_NEGATIVE
import android.text.InputFilter
import android.text.Spanned
import android.view.LayoutInflater
@@ -33,7 +34,11 @@ import android.widget.EditText
import android.widget.NumberPicker
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.Frequency
import org.isoron.uhabits.core.models.Frequency.Companion.DAILY
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.InterfaceUtils
@@ -52,6 +57,7 @@ class NumberPickerFactory
unit: String,
notes: String,
dateString: String,
frequency: Frequency,
callback: ListHabitsBehavior.NumberPickerCallback
): AlertDialog {
val inflater = LayoutInflater.from(context)
@@ -92,7 +98,7 @@ class NumberPickerFactory
picker2.value = intValue % 100
etNotes.setText(notes)
val dialog = AlertDialog.Builder(context)
val dialogBuilder = AlertDialog.Builder(context)
.setView(view)
.setTitle(dateString)
.setPositiveButton(R.string.save) { _, _ ->
@@ -108,9 +114,24 @@ class NumberPickerFactory
.setOnDismissListener {
callback.onNumberPickerDismissed()
}
.create()
if (frequency == DAILY) {
dialogBuilder.setNegativeButton(R.string.skip_day) { _, _ ->
picker.clearFocus()
val v = Entry.SKIP.toDouble() / 1000
val note = etNotes.text.toString()
callback.onNumberPicked(v, note)
}
}
val dialog = dialogBuilder.create()
dialog.setOnShowListener {
val preferences =
(context.applicationContext as HabitsApplication).component.preferences
if (!preferences.isSkipEnabled) {
dialog.getButton(BUTTON_NEGATIVE).visibility = View.GONE
}
showSoftInput(dialog, pickerInputText)
}

View File

@@ -173,7 +173,8 @@ class FrequencyChart : ScrollableChart {
rect[0f, 0f, baseSize.toFloat()] = baseSize.toFloat()
rect.offset(prevRect!!.left, prevRect!!.top + baseSize * j)
val i = localeWeekdayList[j] % 7
if (values != null) drawMarker(canvas, rect, values[i])
if (values != null)
drawMarker(canvas, rect, values[i])
rect.offset(0f, rowHeight)
}
drawFooter(canvas, rect, date)
@@ -222,11 +223,14 @@ class FrequencyChart : ScrollableChart {
}
private fun drawMarker(canvas: Canvas, rect: RectF?, value: Int?) {
// value can be negative when the entry is skipped
val valueCopy = value?.let { max(0, it) }
val padding = rect!!.height() * 0.2f
// maximal allowed mark radius
val maxRadius = (rect.height() - 2 * padding) / 2.0f
// the real mark radius is scaled down by a factor depending on the maximal frequency
val scale = 1.0f / maxFreq * value!!
val scale = 1.0f / maxFreq * valueCopy!!
val radius = maxRadius * scale
val colorIndex = min((colors.size - 1), ((colors.size - 1) * scale).roundToInt())
pGraph!!.color = colors[colorIndex]

View File

@@ -40,6 +40,7 @@ import org.isoron.uhabits.core.commands.CreateHabitCommand
import org.isoron.uhabits.core.commands.DeleteHabitsCommand
import org.isoron.uhabits.core.commands.EditHabitCommand
import org.isoron.uhabits.core.commands.UnarchiveHabitsCommand
import org.isoron.uhabits.core.models.Frequency
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.tasks.TaskRunner
@@ -230,9 +231,10 @@ class ListHabitsScreen
unit: String,
notes: String,
dateString: String,
frequency: Frequency,
callback: ListHabitsBehavior.NumberPickerCallback
) {
numberPickerFactory.create(value, unit, notes, dateString, callback).show()
numberPickerFactory.create(value, unit, notes, dateString, frequency, callback).show()
}
override fun showCheckmarkDialog(

View File

@@ -29,6 +29,7 @@ import android.view.View
import android.view.View.OnClickListener
import android.view.View.OnLongClickListener
import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.NumericalHabitType.AT_LEAST
import org.isoron.uhabits.core.models.NumericalHabitType.AT_MOST
import org.isoron.uhabits.core.preferences.Preferences
@@ -143,6 +144,12 @@ class NumberButtonView(
private val lowContrast: Int
private val mediumContrast: Int
private val paint = TextPaint().apply {
typeface = getFontAwesome()
isAntiAlias = true
textAlign = Paint.Align.CENTER
}
private val pUnit: TextPaint = TextPaint().apply {
textSize = getDimension(context, R.dimen.smallerTextSize)
typeface = NORMAL_TYPEFACE
@@ -176,6 +183,11 @@ class NumberButtonView(
val textSize: Float
when {
value == Entry.SKIP.toDouble() / 1000 -> {
label = resources.getString(R.string.fa_skipped)
textSize = dim(R.dimen.smallTextSize)
typeface = getFontAwesome()
}
value >= 0 -> {
label = value.toShortString()
typeface = BOLD_TYPEFACE

View File

@@ -39,6 +39,7 @@ import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog
import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory
import org.isoron.uhabits.core.commands.Command
import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.models.Frequency
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.preferences.Preferences
@@ -169,9 +170,10 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
unit: String,
notes: String,
dateString: String,
callback: ListHabitsBehavior.NumberPickerCallback,
frequency: Frequency,
callback: ListHabitsBehavior.NumberPickerCallback
) {
NumberPickerFactory(this@ShowHabitActivity).create(value, unit, notes, dateString, callback).show()
NumberPickerFactory(this@ShowHabitActivity).create(value, unit, notes, dateString, frequency, callback).show()
}
override fun showCheckmarkDialog(

View File

@@ -81,6 +81,7 @@ class NumericalCheckmarkWidgetActivity : Activity(), ListHabitsBehavior.NumberPi
data.habit.unit,
entry.notes,
today.toDialogDateString(),
data.habit.frequency,
this
).show()
}

View File

@@ -225,6 +225,7 @@
<string name="increment">Increment</string>
<string name="decrement">Decrement</string>
<string name="pref_skip_title">Enable skip days</string>
<string name="skip_day">Skip</string>
<string name="pref_skip_description">Toggle twice to add a skip instead of a checkmark. Skips keep your score unchanged and don\'t break your streak.</string>
<string name="pref_unknown_title">Show question marks for missing data</string>
<string name="pref_unknown_description">Differentiate days without data from actual lapses. To enter a lapse, toggle twice.</string>