mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Implement CheckmarkPopup
This commit is contained in:
@@ -29,6 +29,11 @@ enum class Font {
|
||||
FONT_AWESOME
|
||||
}
|
||||
|
||||
data class ScreenLocation(
|
||||
val x: Double,
|
||||
val y: Double,
|
||||
)
|
||||
|
||||
interface Canvas {
|
||||
fun setColor(color: Color)
|
||||
fun drawLine(x1: Double, y1: Double, x2: Double, y2: Double)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.ui.screens.habits.list
|
||||
|
||||
import org.isoron.platform.gui.ScreenLocation
|
||||
import org.isoron.platform.time.LocalDate
|
||||
import org.isoron.uhabits.core.commands.CommandRunner
|
||||
import org.isoron.uhabits.core.commands.CreateRepetitionCommand
|
||||
@@ -50,7 +51,7 @@ open class ListHabitsBehavior @Inject constructor(
|
||||
screen.showHabitScreen(h)
|
||||
}
|
||||
|
||||
fun onEdit(habit: Habit, timestamp: Timestamp?) {
|
||||
fun onEdit(location: ScreenLocation, habit: Habit, timestamp: Timestamp?) {
|
||||
val entry = habit.computedEntries.get(timestamp!!)
|
||||
if (habit.type == HabitType.NUMERICAL) {
|
||||
val oldValue = entry.value.toDouble()
|
||||
@@ -65,12 +66,11 @@ open class ListHabitsBehavior @Inject constructor(
|
||||
commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, value, newNotes))
|
||||
}
|
||||
} else {
|
||||
screen.showCheckmarkDialog(
|
||||
screen.showCheckmarkPopup(
|
||||
entry.value,
|
||||
entry.notes,
|
||||
timestamp.toLocalDate(),
|
||||
timestamp.toDialogDateString(),
|
||||
habit.color,
|
||||
location,
|
||||
) { newValue, newNotes ->
|
||||
commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, newValue, newNotes))
|
||||
}
|
||||
@@ -171,6 +171,13 @@ open class ListHabitsBehavior @Inject constructor(
|
||||
frequency: Frequency,
|
||||
callback: NumberPickerCallback
|
||||
)
|
||||
fun showCheckmarkPopup(
|
||||
selectedValue: Int,
|
||||
notes: String,
|
||||
color: PaletteColor,
|
||||
location: ScreenLocation,
|
||||
callback: CheckMarkDialogCallback
|
||||
)
|
||||
fun showCheckmarkDialog(
|
||||
selectedValue: Int,
|
||||
notes: String,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package org.isoron.uhabits.core.ui.screens.habits.show.views
|
||||
|
||||
import org.isoron.platform.gui.ScreenLocation
|
||||
import org.isoron.platform.time.DayOfWeek
|
||||
import org.isoron.platform.time.LocalDate
|
||||
import org.isoron.uhabits.core.commands.CommandRunner
|
||||
@@ -65,55 +66,65 @@ class HistoryCardPresenter(
|
||||
val screen: Screen,
|
||||
) : OnDateClickedListener {
|
||||
|
||||
override fun onDateLongPress(date: LocalDate) {
|
||||
override fun onDateLongPress(location: ScreenLocation, date: LocalDate) {
|
||||
val timestamp = Timestamp.fromLocalDate(date)
|
||||
screen.showFeedback()
|
||||
if (habit.isNumerical) {
|
||||
showNumberPicker(timestamp)
|
||||
} else {
|
||||
val entry = habit.computedEntries.get(timestamp)
|
||||
val nextValue = Entry.nextToggleValue(
|
||||
value = entry.value,
|
||||
isSkipEnabled = preferences.isSkipEnabled,
|
||||
areQuestionMarksEnabled = preferences.areQuestionMarksEnabled
|
||||
)
|
||||
if (preferences.isShortToggleEnabled) showCheckmarkPopup(location, timestamp)
|
||||
else toggle(timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDateShortPress(location: ScreenLocation, date: LocalDate) {
|
||||
val timestamp = Timestamp.fromLocalDate(date)
|
||||
screen.showFeedback()
|
||||
if (habit.isNumerical) {
|
||||
showNumberPicker(timestamp)
|
||||
} else {
|
||||
if (preferences.isShortToggleEnabled) toggle(timestamp)
|
||||
else showCheckmarkPopup(location, timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showCheckmarkPopup(location: ScreenLocation, timestamp: Timestamp) {
|
||||
val entry = habit.computedEntries.get(timestamp)
|
||||
screen.showCheckmarkPopup(
|
||||
entry.value,
|
||||
entry.notes,
|
||||
preferences,
|
||||
habit.color,
|
||||
location,
|
||||
) { newValue, newNotes ->
|
||||
commandRunner.run(
|
||||
CreateRepetitionCommand(
|
||||
habitList,
|
||||
habit,
|
||||
timestamp,
|
||||
nextValue,
|
||||
entry.notes,
|
||||
newValue,
|
||||
newNotes,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDateShortPress(date: LocalDate) {
|
||||
val timestamp = Timestamp.fromLocalDate(date)
|
||||
screen.showFeedback()
|
||||
if (habit.isNumerical) {
|
||||
showNumberPicker(timestamp)
|
||||
} else {
|
||||
val entry = habit.computedEntries.get(timestamp)
|
||||
screen.showCheckmarkDialog(
|
||||
entry.value,
|
||||
private fun toggle(timestamp: Timestamp) {
|
||||
val entry = habit.computedEntries.get(timestamp)
|
||||
val nextValue = Entry.nextToggleValue(
|
||||
value = entry.value,
|
||||
isSkipEnabled = preferences.isSkipEnabled,
|
||||
areQuestionMarksEnabled = preferences.areQuestionMarksEnabled
|
||||
)
|
||||
commandRunner.run(
|
||||
CreateRepetitionCommand(
|
||||
habitList,
|
||||
habit,
|
||||
timestamp,
|
||||
nextValue,
|
||||
entry.notes,
|
||||
timestamp.toLocalDate(),
|
||||
preferences,
|
||||
habit.color,
|
||||
) { newValue, newNotes ->
|
||||
commandRunner.run(
|
||||
CreateRepetitionCommand(
|
||||
habitList,
|
||||
habit,
|
||||
timestamp,
|
||||
newValue,
|
||||
newNotes,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun showNumberPicker(timestamp: Timestamp) {
|
||||
@@ -211,5 +222,14 @@ class HistoryCardPresenter(
|
||||
color: PaletteColor,
|
||||
callback: ListHabitsBehavior.CheckMarkDialogCallback,
|
||||
)
|
||||
|
||||
fun showCheckmarkPopup(
|
||||
selectedValue: Int,
|
||||
notes: String,
|
||||
preferences: Preferences,
|
||||
color: PaletteColor,
|
||||
location: ScreenLocation,
|
||||
callback: ListHabitsBehavior.CheckMarkDialogCallback,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ package org.isoron.uhabits.core.ui.views
|
||||
import org.isoron.platform.gui.Canvas
|
||||
import org.isoron.platform.gui.Color
|
||||
import org.isoron.platform.gui.DataView
|
||||
import org.isoron.platform.gui.ScreenLocation
|
||||
import org.isoron.platform.gui.TextAlign
|
||||
import org.isoron.platform.time.DayOfWeek
|
||||
import org.isoron.platform.time.LocalDate
|
||||
@@ -33,8 +34,8 @@ import kotlin.math.min
|
||||
import kotlin.math.round
|
||||
|
||||
interface OnDateClickedListener {
|
||||
fun onDateShortPress(date: LocalDate) {}
|
||||
fun onDateLongPress(date: LocalDate) {}
|
||||
fun onDateShortPress(location: ScreenLocation, date: LocalDate) {}
|
||||
fun onDateLongPress(location: ScreenLocation, date: LocalDate) {}
|
||||
}
|
||||
|
||||
class HistoryChart(
|
||||
@@ -90,10 +91,11 @@ class HistoryChart(
|
||||
if (x - padding < 0 || row == 0 || row > 7 || col == nColumns) return
|
||||
val clickedDate = topLeftDate.plus(offset)
|
||||
if (clickedDate.isNewerThan(today)) return
|
||||
val location = ScreenLocation(x, y)
|
||||
if (isLongClick) {
|
||||
onDateClickedListener.onDateLongPress(clickedDate)
|
||||
onDateClickedListener.onDateLongPress(location, clickedDate)
|
||||
} else {
|
||||
onDateClickedListener.onDateShortPress(clickedDate)
|
||||
onDateClickedListener.onDateShortPress(location, clickedDate)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import junit.framework.Assert.assertTrue
|
||||
import org.apache.commons.io.FileUtils
|
||||
import org.hamcrest.MatcherAssert.assertThat
|
||||
import org.hamcrest.core.IsEqual.equalTo
|
||||
import org.isoron.platform.gui.ScreenLocation
|
||||
import org.isoron.uhabits.core.BaseUnitTest
|
||||
import org.isoron.uhabits.core.models.Entry
|
||||
import org.isoron.uhabits.core.models.Frequency
|
||||
@@ -79,7 +80,7 @@ class ListHabitsBehaviorTest : BaseUnitTest() {
|
||||
|
||||
@Test
|
||||
fun testOnEdit() {
|
||||
behavior.onEdit(habit2, getToday())
|
||||
behavior.onEdit(ScreenLocation(0.0, 0.0), habit2, getToday())
|
||||
verify(screen).showNumberPicker(
|
||||
eq(0.1),
|
||||
eq("miles"),
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.nhaarman.mockitokotlin2.reset
|
||||
import com.nhaarman.mockitokotlin2.verify
|
||||
import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.isoron.platform.gui.ScreenLocation
|
||||
import org.isoron.platform.gui.assertRenders
|
||||
import org.isoron.platform.time.DayOfWeek
|
||||
import org.isoron.platform.time.DayOfWeek.SUNDAY
|
||||
@@ -73,8 +74,7 @@ class HistoryChartTest {
|
||||
else -> OFF
|
||||
}
|
||||
},
|
||||
notesIndicators = MutableList(85) {
|
||||
index: Int ->
|
||||
notesIndicators = MutableList(85) { index: Int ->
|
||||
index % 3 == 0
|
||||
}
|
||||
)
|
||||
@@ -90,20 +90,32 @@ class HistoryChartTest {
|
||||
|
||||
// Click top left date
|
||||
view.onClick(20.0, 46.0)
|
||||
verify(dateClickedListener).onDateShortPress(LocalDate(2014, 10, 26))
|
||||
verify(dateClickedListener).onDateShortPress(
|
||||
ScreenLocation(20.0, 46.0),
|
||||
LocalDate(2014, 10, 26)
|
||||
)
|
||||
reset(dateClickedListener)
|
||||
view.onClick(2.0, 28.0)
|
||||
verify(dateClickedListener).onDateShortPress(LocalDate(2014, 10, 26))
|
||||
verify(dateClickedListener).onDateShortPress(
|
||||
ScreenLocation(2.0, 28.0),
|
||||
LocalDate(2014, 10, 26)
|
||||
)
|
||||
reset(dateClickedListener)
|
||||
|
||||
// Click date in the middle
|
||||
view.onClick(163.0, 113.0)
|
||||
verify(dateClickedListener).onDateShortPress(LocalDate(2014, 12, 10))
|
||||
verify(dateClickedListener).onDateShortPress(
|
||||
ScreenLocation(163.0, 113.0),
|
||||
LocalDate(2014, 12, 10)
|
||||
)
|
||||
reset(dateClickedListener)
|
||||
|
||||
// Click today
|
||||
view.onClick(336.0, 37.0)
|
||||
verify(dateClickedListener).onDateShortPress(LocalDate(2015, 1, 25))
|
||||
verify(dateClickedListener).onDateShortPress(
|
||||
ScreenLocation(336.0, 37.0),
|
||||
LocalDate(2015, 1, 25)
|
||||
)
|
||||
reset(dateClickedListener)
|
||||
|
||||
// Click header
|
||||
@@ -121,20 +133,32 @@ class HistoryChartTest {
|
||||
|
||||
// Click top left date
|
||||
view.onLongClick(20.0, 46.0)
|
||||
verify(dateClickedListener).onDateLongPress(LocalDate(2014, 10, 26))
|
||||
verify(dateClickedListener).onDateLongPress(
|
||||
ScreenLocation(20.0, 46.0),
|
||||
LocalDate(2014, 10, 26)
|
||||
)
|
||||
reset(dateClickedListener)
|
||||
view.onLongClick(2.0, 28.0)
|
||||
verify(dateClickedListener).onDateLongPress(LocalDate(2014, 10, 26))
|
||||
verify(dateClickedListener).onDateLongPress(
|
||||
ScreenLocation(2.0, 28.0),
|
||||
LocalDate(2014, 10, 26)
|
||||
)
|
||||
reset(dateClickedListener)
|
||||
|
||||
// Click date in the middle
|
||||
view.onLongClick(163.0, 113.0)
|
||||
verify(dateClickedListener).onDateLongPress(LocalDate(2014, 12, 10))
|
||||
verify(dateClickedListener).onDateLongPress(
|
||||
ScreenLocation(163.0, 113.0),
|
||||
LocalDate(2014, 12, 10)
|
||||
)
|
||||
reset(dateClickedListener)
|
||||
|
||||
// Click today
|
||||
view.onLongClick(336.0, 37.0)
|
||||
verify(dateClickedListener).onDateLongPress(LocalDate(2015, 1, 25))
|
||||
verify(dateClickedListener).onDateLongPress(
|
||||
ScreenLocation(336.0, 37.0),
|
||||
LocalDate(2015, 1, 25)
|
||||
)
|
||||
reset(dateClickedListener)
|
||||
|
||||
// Click header
|
||||
|
||||
Reference in New Issue
Block a user