diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryButtonViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryButtonViewTest.kt index 9b807c764..f37cc1838 100644 --- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryButtonViewTest.kt +++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/EntryButtonViewTest.kt @@ -45,7 +45,7 @@ class EntryButtonViewTest : BaseViewTest() { value = Entry.NO color = PaletteUtils.getAndroidTestColor(5) onToggle = { _, _, _ -> toggled = true } - onEdit = { _ -> edited = true } + onEdit = { edited = true } } measureView(view, dpToPixels(48), dpToPixels(48)) } diff --git a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/NumberPanelViewTest.kt b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/NumberPanelViewTest.kt index fb816f4d4..6d9ce4e8e 100644 --- a/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/NumberPanelViewTest.kt +++ b/uhabits-android/src/androidTest/java/org/isoron/uhabits/activities/habits/list/views/NumberPanelViewTest.kt @@ -76,7 +76,7 @@ class NumberPanelViewTest : BaseViewTest() { @Test fun testEdit() { val timestamps = mutableListOf() - view.onEdit = { _, t -> timestamps.plusAssign(t) } + view.onEdit = { t -> timestamps.plusAssign(t) } view.buttons[0].performLongClick() view.buttons[2].performLongClick() view.buttons[3].performLongClick() @@ -87,7 +87,7 @@ class NumberPanelViewTest : BaseViewTest() { fun testEdit_withOffset() { val timestamps = mutableListOf() view.dataOffset = 3 - view.onEdit = { _, t -> timestamps += t } + view.onEdit = { t -> timestamps += t } view.buttons[0].performLongClick() view.buttons[2].performLongClick() view.buttons[3].performLongClick() diff --git a/uhabits-android/src/main/AndroidManifest.xml b/uhabits-android/src/main/AndroidManifest.xml index 3b0851207..721a10ae5 100644 --- a/uhabits-android/src/main/AndroidManifest.xml +++ b/uhabits-android/src/main/AndroidManifest.xml @@ -125,7 +125,7 @@ android:exported="true" android:label="NumericalCheckmarkWidget" android:noHistory="true" - android:theme="@style/Theme.AppCompat.Light.Dialog"> + android:theme="@style/Theme.Transparent"> diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkPopup.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkPopup.kt index 85d7fdfc1..9a862076f 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkPopup.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkPopup.kt @@ -19,14 +19,12 @@ package org.isoron.uhabits.activities.common.dialogs +import android.app.Dialog import android.content.Context -import android.graphics.drawable.ColorDrawable -import android.view.Gravity import android.view.LayoutInflater import android.view.View import android.view.View.GONE -import android.widget.PopupWindow -import org.isoron.platform.gui.ScreenLocation +import android.view.View.VISIBLE import org.isoron.uhabits.R import org.isoron.uhabits.core.models.Entry.Companion.NO import org.isoron.uhabits.core.models.Entry.Companion.SKIP @@ -52,6 +50,7 @@ class CheckmarkPopup( private val anchor: View, ) { var onToggle: (Int, String) -> Unit = { _, _ -> } + private lateinit var dialog: Dialog private val view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context)).apply { // Required for round corners @@ -59,6 +58,7 @@ class CheckmarkPopup( } init { + view.booleanButtons.visibility = VISIBLE initColors() initTypefaces() hideDisabledButtons() @@ -94,34 +94,34 @@ class CheckmarkPopup( SKIP -> if (prefs.isSkipEnabled) view.skipBtn else view.noBtn else -> null } - selectedBtn?.background = ColorDrawable(view.root.sres.getColor(R.attr.contrast40)) view.notes.setText(notes) } - fun show(location: ScreenLocation) { - val popup = PopupWindow() - popup.contentView = view.root - popup.width = view.root.dp(POPUP_WIDTH).toInt() - popup.height = view.root.dp(POPUP_HEIGHT).toInt() - popup.isFocusable = true - popup.elevation = view.root.dp(24f) + fun show() { + dialog = Dialog(context, android.R.style.Theme_NoTitleBar) + dialog.setContentView(view.root) + dialog.window?.apply { + setLayout( + view.root.dp(POPUP_WIDTH).toInt(), + view.root.dp(POPUP_HEIGHT).toInt() + ) + setBackgroundDrawableResource(android.R.color.transparent) + } fun onClick(v: Int) { this.value = v - popup.dismiss() + save() } view.yesBtn.setOnClickListener { onClick(YES_MANUAL) } view.noBtn.setOnClickListener { onClick(NO) } view.skipBtn.setOnClickListener { onClick(SKIP) } view.unknownBtn.setOnClickListener { onClick(UNKNOWN) } - popup.setOnDismissListener { - onToggle(value, view.notes.text.toString()) - } - popup.showAtLocation( - anchor, - Gravity.NO_GRAVITY, - view.root.dp(location.x.toFloat()).toInt(), - view.root.dp(location.y.toFloat()).toInt(), - ) - popup.dimBehind() + dialog.setCanceledOnTouchOutside(true) + dialog.dimBehind() + dialog.show() + } + + fun save() { + onToggle(value, view.notes.text.toString().trim()) + dialog.dismiss() } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPickerFactory.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPickerFactory.kt deleted file mode 100644 index 0ee4dad34..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPickerFactory.kt +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2016-2021 Á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.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 -import android.view.View -import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE -import android.view.inputmethod.EditorInfo -import android.view.inputmethod.InputMethodManager -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 -import java.text.DecimalFormatSymbols -import javax.inject.Inject -import kotlin.math.roundToLong - -class NumberPickerFactory -@Inject constructor( - @ActivityContext private val context: Context -) { - @SuppressLint("SetTextI18n") - fun create( - value: Double, - unit: String, - notes: String, - dateString: String, - frequency: Frequency, - callback: ListHabitsBehavior.NumberPickerCallback - ): AlertDialog { - clearCurrentDialog() - - val inflater = LayoutInflater.from(context) - val view = inflater.inflate(R.layout.number_picker_dialog, null) - - val picker = view.findViewById(R.id.picker) - val picker2 = view.findViewById(R.id.picker2) - val etNotes = view.findViewById(R.id.etNotes) - - // Install filter to intercept decimal separator before it is parsed - val watcherFilter: InputFilter = SeparatorWatcherInputFilter(picker2) - val pickerInputText = getNumberPickerInputText(picker) - pickerInputText.filters = arrayOf(watcherFilter).plus(pickerInputText.filters) - - // Install custom focus listener to replace "5" by "50" instead of "05" - val picker2InputText = getNumberPickerInputText(picker2) - val prevFocusChangeListener = picker2InputText.onFocusChangeListener - picker2InputText.onFocusChangeListener = View.OnFocusChangeListener { v, hasFocus -> - val str = picker2InputText.text.toString() - if (str.length == 1) picker2InputText.setText("${str}0") - prevFocusChangeListener.onFocusChange(v, hasFocus) - } - - view.findViewById(R.id.tvUnit).text = unit - view.findViewById(R.id.tvSeparator).text = - DecimalFormatSymbols.getInstance().decimalSeparator.toString() - - val intValue = (value * 100).roundToLong().toInt() - - picker.minValue = 0 - picker.maxValue = Integer.MAX_VALUE / 100 - picker.value = intValue / 100 - picker.wrapSelectorWheel = false - - picker2.minValue = 0 - picker2.maxValue = 99 - picker2.setFormatter { v -> String.format("%02d", v) } - picker2.value = intValue % 100 - - etNotes.setText(notes) - val dialogBuilder = AlertDialog.Builder(context) - .setView(view) - .setTitle(dateString) - .setPositiveButton(R.string.save) { _, _ -> - picker.clearFocus() - picker2.clearFocus() - val v = picker.value + 0.01 * picker2.value - val note = etNotes.text.toString().trim() - callback.onNumberPicked(v, note) - } - .setNegativeButton(android.R.string.cancel) { _, _ -> - callback.onNumberPickerDismissed() - } - .setOnDismissListener { - callback.onNumberPickerDismissed() - currentDialog = null - } - - 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) - } - - InterfaceUtils.setupEditorAction( - picker - ) { _, actionId, _ -> - if (actionId == EditorInfo.IME_ACTION_DONE) { - dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick() - } - false - } - - InterfaceUtils.setupEditorAction( - picker2 - ) { _, actionId, _ -> - if (actionId == EditorInfo.IME_ACTION_DONE) { - dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick() - } - false - } - - currentDialog = dialog - return dialog - } - - @SuppressLint("DiscouragedPrivateApi") - private fun getNumberPickerInputText(picker: NumberPicker): EditText { - val f = NumberPicker::class.java.getDeclaredField("mInputText") - f.isAccessible = true - return f.get(picker) as EditText - } - - private fun showSoftInput(dialog: AlertDialog, v: View) { - dialog.window?.setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE) - v.requestFocus() - val inputMethodManager = context.getSystemService(InputMethodManager::class.java) - inputMethodManager?.showSoftInput(v, 0) - } - - companion object { - private var currentDialog: AlertDialog? = null - fun clearCurrentDialog() { - currentDialog?.dismiss() - currentDialog = null - } - } -} - -class SeparatorWatcherInputFilter(private val nextPicker: NumberPicker) : InputFilter { - override fun filter( - source: CharSequence?, - start: Int, - end: Int, - dest: Spanned?, - dstart: Int, - dend: Int - ): CharSequence { - if (source == null || source.isEmpty()) { - return "" - } - for (c in source) { - if (c == DecimalFormatSymbols.getInstance().decimalSeparator || c == '.' || c == ',') { - nextPicker.performLongClick() - break - } - } - return source - } -} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPopup.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPopup.kt new file mode 100644 index 000000000..11f63215f --- /dev/null +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPopup.kt @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2016-2021 Á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.activities.common.dialogs + +import android.app.Dialog +import android.content.Context +import android.view.KeyEvent.KEYCODE_ENTER +import android.view.LayoutInflater +import android.view.MotionEvent.ACTION_DOWN +import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE +import org.isoron.uhabits.core.models.Entry +import org.isoron.uhabits.core.preferences.Preferences +import org.isoron.uhabits.databinding.CheckmarkPopupBinding +import org.isoron.uhabits.utils.dimBehind +import org.isoron.uhabits.utils.dp +import org.isoron.uhabits.utils.requestFocusWithKeyboard +import java.text.DecimalFormat + +class NumberPopup( + private val context: Context, + private var notes: String, + private var value: Double, + private val prefs: Preferences, + private val anchor: View, +) { + var onToggle: (Double, String) -> Unit = { _, _ -> } + private val originalValue = value + private lateinit var dialog: Dialog + + private val view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context)).apply { + // Required for round corners + container.clipToOutline = true + } + + init { + view.numberButtons.visibility = VISIBLE + hideDisabledButtons() + populate() + } + + private fun hideDisabledButtons() { + if (!prefs.isSkipEnabled) view.skipBtnNumber.visibility = GONE + } + + private fun populate() { + view.notes.setText(notes) + view.value.setText( + when { + value < 0.01 -> "0" + else -> DecimalFormat("#.##").format(value) + } + ) + } + + fun show() { + dialog = Dialog(context, android.R.style.Theme_NoTitleBar) + dialog.setContentView(view.root) + dialog.window?.apply { + setLayout( + view.root.dp(POPUP_WIDTH).toInt(), + view.root.dp(POPUP_HEIGHT).toInt() + ) + setBackgroundDrawableResource(android.R.color.transparent) + } + + view.value.setOnKeyListener { _, keyCode, event -> + if (event.action == ACTION_DOWN && keyCode == KEYCODE_ENTER) { + save() + return@setOnKeyListener true + } + return@setOnKeyListener false + } + view.saveBtn.setOnClickListener { + save() + } + view.skipBtnNumber.setOnClickListener { + view.value.setText((Entry.SKIP.toDouble() / 1000).toString()) + save() + } + view.value.requestFocusWithKeyboard() + dialog.setCanceledOnTouchOutside(true) + dialog.dimBehind() + dialog.show() + } + + fun save() { + val value = view.value.text.toString().toDoubleOrNull() ?: originalValue + val notes = view.notes.text.toString() + onToggle(value, notes) + dialog.dismiss() + } +} diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreen.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreen.kt index d5794a388..343b50644 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreen.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/ListHabitsScreen.kt @@ -24,14 +24,12 @@ import android.content.Context import android.content.Intent import androidx.appcompat.app.AppCompatActivity import dagger.Lazy -import org.isoron.platform.gui.ScreenLocation import org.isoron.platform.gui.toInt import org.isoron.uhabits.R import org.isoron.uhabits.activities.common.dialogs.CheckmarkPopup import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialogFactory import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog -import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory -import org.isoron.uhabits.activities.common.dialogs.POPUP_WIDTH +import org.isoron.uhabits.activities.common.dialogs.NumberPopup import org.isoron.uhabits.activities.habits.edit.HabitTypeDialog import org.isoron.uhabits.activities.habits.list.views.HabitCardListAdapter import org.isoron.uhabits.core.commands.ArchiveHabitsCommand @@ -42,7 +40,6 @@ 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.preferences.Preferences @@ -95,7 +92,6 @@ class ListHabitsScreen private val exportDBFactory: ExportDBTaskFactory, private val importTaskFactory: ImportDataTaskFactory, private val colorPickerFactory: ColorPickerDialogFactory, - private val numberPickerFactory: NumberPickerFactory, private val behavior: Lazy, private val preferences: Preferences, private val rootView: Lazy, @@ -231,22 +227,28 @@ class ListHabitsScreen picker.show(activity.supportFragmentManager, "picker") } - override fun showNumberPicker( + override fun showNumberPopup( value: Double, - unit: String, notes: String, - dateString: String, - frequency: Frequency, callback: ListHabitsBehavior.NumberPickerCallback ) { - numberPickerFactory.create(value, unit, notes, dateString, frequency, callback).show() + val view = rootView.get() + NumberPopup( + context = context, + prefs = preferences, + anchor = view, + notes = notes, + value = value, + ).apply { + onToggle = { value, notes -> callback.onNumberPicked(value, notes) } + show() + } } override fun showCheckmarkPopup( selectedValue: Int, notes: String, color: PaletteColor, - location: ScreenLocation, callback: ListHabitsBehavior.CheckMarkDialogCallback ) { val view = rootView.get() @@ -259,12 +261,7 @@ class ListHabitsScreen value = selectedValue, ).apply { onToggle = { value, notes -> callback.onNotesSaved(value, notes) } - show( - ScreenLocation( - x = location.x - POPUP_WIDTH / 2, - y = location.y - ) - ) + show() } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt index a408f92ee..176cec62a 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkButtonView.kt @@ -28,7 +28,6 @@ import android.text.TextPaint import android.view.HapticFeedbackConstants import android.view.View import android.view.View.MeasureSpec.EXACTLY -import org.isoron.platform.gui.ScreenLocation import org.isoron.uhabits.R import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry.Companion.NO @@ -39,7 +38,6 @@ import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.inject.ActivityContext import org.isoron.uhabits.utils.drawNotesIndicator -import org.isoron.uhabits.utils.getCenter import org.isoron.uhabits.utils.getFontAwesome import org.isoron.uhabits.utils.sp import org.isoron.uhabits.utils.sres @@ -83,7 +81,7 @@ class CheckmarkButtonView( var onToggle: (Int, String, Long) -> Unit = { _, _, _ -> } - var onEdit: (ScreenLocation) -> Unit = { _ -> } + var onEdit: () -> Unit = { } private var drawer = Drawer() @@ -105,11 +103,11 @@ class CheckmarkButtonView( override fun onClick(v: View) { if (preferences.isShortToggleEnabled) performToggle(TOGGLE_DELAY_MILLIS) - else onEdit(getCenter()) + else onEdit() } override fun onLongClick(v: View): Boolean { - if (preferences.isShortToggleEnabled) onEdit(getCenter()) + if (preferences.isShortToggleEnabled) onEdit() else performToggle(TOGGLE_DELAY_MILLIS) return true } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt index 62fb3e436..35f639691 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/CheckmarkPanelView.kt @@ -20,7 +20,6 @@ package org.isoron.uhabits.activities.habits.list.views import android.content.Context -import org.isoron.platform.gui.ScreenLocation import org.isoron.uhabits.core.models.Entry.Companion.UNKNOWN import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.preferences.Preferences @@ -67,7 +66,7 @@ class CheckmarkPanelView( setupButtons() } - var onEdit: (ScreenLocation, Timestamp) -> Unit = { _, _ -> } + var onEdit: (Timestamp) -> Unit = { _ -> } set(value) { field = value setupButtons() @@ -91,7 +90,7 @@ class CheckmarkPanelView( } button.color = color button.onToggle = { value, notes, delay -> onToggle(timestamp, value, notes, delay) } - button.onEdit = { location -> onEdit(location, timestamp) } + button.onEdit = { onEdit(timestamp) } } } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt index 7296575e7..424aae50b 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/HabitCardView.kt @@ -167,17 +167,17 @@ class HabitCardView( { runPendingToggles(taskId) }.delay(delay) } } - onEdit = { location, timestamp -> + onEdit = { timestamp -> triggerRipple(timestamp) - habit?.let { behavior.onEdit(location, it, timestamp) } + habit?.let { behavior.onEdit(it, timestamp) } } } numberPanel = numberPanelFactory.create().apply { visibility = GONE - onEdit = { location, timestamp -> + onEdit = { timestamp -> triggerRipple(timestamp) - habit?.let { behavior.onEdit(location, it, timestamp) } + habit?.let { behavior.onEdit(it, timestamp) } } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/NumberButtonView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/NumberButtonView.kt index 4d8bdda05..03fe66e53 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/NumberButtonView.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/NumberButtonView.kt @@ -108,7 +108,8 @@ class NumberButtonView( invalidate() } - var onEdit: () -> Unit = {} + var onEdit: () -> Unit = { } + private var drawer: Drawer = Drawer(context) init { diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/NumberPanelView.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/NumberPanelView.kt index dc49b557b..0c7d142bb 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/NumberPanelView.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/list/views/NumberPanelView.kt @@ -20,13 +20,11 @@ package org.isoron.uhabits.activities.habits.list.views import android.content.Context -import org.isoron.platform.gui.ScreenLocation import org.isoron.uhabits.core.models.NumericalHabitType import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.inject.ActivityContext -import org.isoron.uhabits.utils.getCenter import javax.inject.Inject class NumberPanelViewFactory @@ -80,7 +78,7 @@ class NumberPanelView( setupButtons() } - var onEdit: (ScreenLocation, Timestamp) -> Unit = { _, _ -> } + var onEdit: (Timestamp) -> Unit = { _ -> } set(value) { field = value setupButtons() @@ -106,7 +104,7 @@ class NumberPanelView( button.targetType = targetType button.threshold = threshold button.units = units - button.onEdit = { onEdit(getCenter(), timestamp) } + button.onEdit = { onEdit(timestamp) } } } } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt index 6eadb1b59..1e90e1ae9 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/habits/show/ShowHabitActivity.kt @@ -23,11 +23,11 @@ import android.os.Bundle import android.view.HapticFeedbackConstants import android.view.Menu import android.view.MenuItem +import android.view.View import androidx.appcompat.app.AppCompatActivity import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import org.isoron.platform.gui.ScreenLocation import org.isoron.platform.gui.toInt import org.isoron.uhabits.AndroidDirFinder import org.isoron.uhabits.HabitsApplication @@ -37,11 +37,9 @@ import org.isoron.uhabits.activities.HabitsDirFinder import org.isoron.uhabits.activities.common.dialogs.CheckmarkPopup import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog -import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory -import org.isoron.uhabits.activities.common.dialogs.POPUP_WIDTH +import org.isoron.uhabits.activities.common.dialogs.NumberPopup 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 @@ -52,7 +50,6 @@ import org.isoron.uhabits.core.ui.screens.habits.show.ShowHabitPresenter import org.isoron.uhabits.core.ui.views.OnDateClickedListener import org.isoron.uhabits.intents.IntentFactory import org.isoron.uhabits.utils.currentTheme -import org.isoron.uhabits.utils.getTopLeftCorner import org.isoron.uhabits.utils.showMessage import org.isoron.uhabits.utils.showSendFileScreen import org.isoron.uhabits.widgets.WidgetUpdater @@ -169,22 +166,23 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener { window.decorView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY) } - override fun showNumberPicker( + override fun showNumberPopup( value: Double, - unit: String, notes: String, - dateString: String, - frequency: Frequency, + preferences: Preferences, callback: ListHabitsBehavior.NumberPickerCallback ) { - NumberPickerFactory(this@ShowHabitActivity).create( - value, - unit, - notes, - dateString, - frequency, - callback - ).show() + val anchor = getPopupAnchor() ?: return + NumberPopup( + context = this@ShowHabitActivity, + prefs = preferences, + notes = notes, + anchor = anchor, + value = value, + ).apply { + onToggle = { v, n -> callback.onNumberPicked(v, n) } + show() + } } override fun showCheckmarkPopup( @@ -192,32 +190,27 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener { notes: String, preferences: Preferences, color: PaletteColor, - location: ScreenLocation, callback: ListHabitsBehavior.CheckMarkDialogCallback ) { - val dialog = - supportFragmentManager.findFragmentByTag("historyEditor") as HistoryEditorDialog? - ?: return - val view = dialog.dataView - val corner = view.getTopLeftCorner() + val anchor = getPopupAnchor() ?: return CheckmarkPopup( context = this@ShowHabitActivity, prefs = preferences, notes = notes, color = view.currentTheme().color(color).toInt(), - anchor = view, + anchor = anchor, value = selectedValue, ).apply { onToggle = { v, n -> callback.onNotesSaved(v, n) } - show( - ScreenLocation( - x = corner.x + location.x - POPUP_WIDTH / 2, - y = corner.y + location.y, - ) - ) + show() } } + private fun getPopupAnchor(): View? { + val dialog = supportFragmentManager.findFragmentByTag("historyEditor") as HistoryEditorDialog? + return dialog?.dataView + } + override fun showEditHabitScreen(habit: Habit) { startActivity(IntentFactory().startEditActivity(this@ShowHabitActivity, habit)) } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/utils/ViewExtensions.kt b/uhabits-android/src/main/java/org/isoron/uhabits/utils/ViewExtensions.kt index df140aa79..35a8cecbd 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/utils/ViewExtensions.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/utils/ViewExtensions.kt @@ -20,21 +20,22 @@ package org.isoron.uhabits.utils import android.app.Activity +import android.app.Dialog import android.content.ActivityNotFoundException -import android.content.Context import android.content.Intent import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.drawable.ColorDrawable import android.os.Handler +import android.os.SystemClock import android.view.LayoutInflater +import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import android.view.WindowManager -import android.widget.PopupWindow import android.widget.RelativeLayout import android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM import android.widget.RelativeLayout.ALIGN_PARENT_TOP @@ -45,7 +46,6 @@ import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.core.content.FileProvider import com.google.android.material.snackbar.Snackbar -import org.isoron.platform.gui.ScreenLocation import org.isoron.platform.gui.toInt import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.R @@ -218,41 +218,20 @@ fun View.drawNotesIndicator(canvas: Canvas, color: Int, size: Float, notes: Stri val View.sres: StyledResources get() = StyledResources(context) -fun PopupWindow.dimBehind() { - // https://stackoverflow.com/questions/35874001/dim-the-background-using-popupwindow-in-android - val container = contentView.rootView - val context = contentView.context - val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager - val p = container.layoutParams as WindowManager.LayoutParams - p.flags = p.flags or WindowManager.LayoutParams.FLAG_DIM_BEHIND - p.dimAmount = 0.5f - wm.updateViewLayout(container, p) -} - -/** - * Returns the absolute screen coordinates for the center of this view (in density-independent - * pixels). - */ -fun View.getCenter(): ScreenLocation { - val density = resources.displayMetrics.density - val loc = IntArray(2) - this.getLocationInWindow(loc) - return ScreenLocation( - x = ((loc[0] + width / 2) / density).toDouble(), - y = ((loc[1] + height / 2) / density).toDouble(), - ) -} - -/** - * Returns the absolute screen coordinates for the top left corner of this view (in - * density-independent pixels). - */ -fun View.getTopLeftCorner(): ScreenLocation { - val density = resources.displayMetrics.density - val loc = IntArray(2) - this.getLocationInWindow(loc) - return ScreenLocation( - x = (loc[0] / density).toDouble(), - y = (loc[1] / density).toDouble(), - ) +fun Dialog.dimBehind() { + window?.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) + window?.setDimAmount(0.5f) +} + +fun View.requestFocusWithKeyboard() { + // For some reason, Android does not open the soft keyboard by default when view.requestFocus + // is called. Several online solutions suggest using InputMethodManager, but these solutions + // are not reliable; sometimes the keyboard does not show, and sometimes it does not go away + // after focus is lost. Here, we simulate a click on the view, which triggers the keyboard. + // Based on: https://stackoverflow.com/a/7699556 + postDelayed({ + val time = SystemClock.uptimeMillis() + dispatchTouchEvent(MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0f, 0f, 0)) + dispatchTouchEvent(MotionEvent.obtain(time, time, MotionEvent.ACTION_UP, 0f, 0f, 0)) + }, 250) } diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/activities/NumericalCheckmarkWidgetActivity.kt b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/activities/NumericalCheckmarkWidgetActivity.kt index b7bc7f229..a7305521e 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/widgets/activities/NumericalCheckmarkWidgetActivity.kt +++ b/uhabits-android/src/main/java/org/isoron/uhabits/widgets/activities/NumericalCheckmarkWidgetActivity.kt @@ -22,11 +22,12 @@ package org.isoron.uhabits.widgets.activities import android.app.Activity import android.content.Context import android.os.Bundle -import android.view.Window +import android.view.View +import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.widget.FrameLayout import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.activities.AndroidThemeSwitcher -import org.isoron.uhabits.activities.common.dialogs.NumberPickerFactory +import org.isoron.uhabits.activities.common.dialogs.NumberPopup import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior import org.isoron.uhabits.core.ui.widgets.WidgetBehavior import org.isoron.uhabits.core.utils.DateUtils @@ -39,11 +40,13 @@ class NumericalCheckmarkWidgetActivity : Activity(), ListHabitsBehavior.NumberPi private lateinit var behavior: WidgetBehavior private lateinit var data: IntentParser.CheckmarkIntentData private lateinit var widgetUpdater: WidgetUpdater + private lateinit var rootView: View override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - requestWindowFeature(Window.FEATURE_NO_TITLE) - setContentView(FrameLayout(this)) + rootView = FrameLayout(this) + rootView.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) + setContentView(rootView) val app = this.applicationContext as HabitsApplication val component = app.component val parser = app.component.intentParser @@ -55,8 +58,9 @@ class NumericalCheckmarkWidgetActivity : Activity(), ListHabitsBehavior.NumberPi component.preferences ) widgetUpdater = component.widgetUpdater - showNumberSelector(this) - + rootView.post { + showNumberSelector(this) + } SystemUtils.unlockScreen(this) } @@ -73,17 +77,22 @@ class NumericalCheckmarkWidgetActivity : Activity(), ListHabitsBehavior.NumberPi private fun showNumberSelector(context: Context) { val app = this.applicationContext as HabitsApplication AndroidThemeSwitcher(this, app.component.preferences).apply() - val numberPickerFactory = NumberPickerFactory(context) val today = DateUtils.getTodayWithOffset() val entry = data.habit.computedEntries.get(today) - numberPickerFactory.create( - entry.value / 1000.0, - data.habit.unit, - entry.notes, - today.toDialogDateString(), - data.habit.frequency, - this - ).show() + NumberPopup( + context = context, + prefs = app.component.preferences, + anchor = rootView, + notes = entry.notes, + value = entry.value / 1000.0, + ).apply { + onToggle = { value, notes -> + onNumberPicked(value, notes) + finish() + overridePendingTransition(0, 0) + } + show() + } } companion object { diff --git a/uhabits-android/src/main/res/layout/checkmark_popup.xml b/uhabits-android/src/main/res/layout/checkmark_popup.xml index f1aa569a6..72dc79786 100644 --- a/uhabits-android/src/main/res/layout/checkmark_popup.xml +++ b/uhabits-android/src/main/res/layout/checkmark_popup.xml @@ -42,6 +42,8 @@ android:text="" /> - + + + + + + + + + \ No newline at end of file diff --git a/uhabits-android/src/main/res/values/styles.xml b/uhabits-android/src/main/res/values/styles.xml index f25602748..a3b2be8ba 100644 --- a/uhabits-android/src/main/res/values/styles.xml +++ b/uhabits-android/src/main/res/values/styles.xml @@ -398,4 +398,28 @@ @dimen/smallerTextSize + + + + diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt index b14ecc591..5041ab066 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.kt @@ -18,10 +18,8 @@ */ package org.isoron.uhabits.core.ui.screens.habits.list -import org.isoron.platform.gui.ScreenLocation import org.isoron.uhabits.core.commands.CommandRunner import org.isoron.uhabits.core.commands.CreateRepetitionCommand -import org.isoron.uhabits.core.models.Frequency import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.HabitList import org.isoron.uhabits.core.models.HabitType @@ -50,17 +48,11 @@ open class ListHabitsBehavior @Inject constructor( screen.showHabitScreen(h) } - fun onEdit(location: ScreenLocation, habit: Habit, timestamp: Timestamp?) { + fun onEdit(habit: Habit, timestamp: Timestamp?) { val entry = habit.computedEntries.get(timestamp!!) if (habit.type == HabitType.NUMERICAL) { - val oldValue = entry.value.toDouble() - screen.showNumberPicker( - oldValue / 1000, - habit.unit, - entry.notes, - timestamp.toDialogDateString(), - habit.frequency - ) { newValue: Double, newNotes: String, -> + val oldValue = entry.value.toDouble() / 1000 + screen.showNumberPopup(oldValue, entry.notes) { newValue: Double, newNotes: String -> val value = (newValue * 1000).roundToInt() commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, value, newNotes)) } @@ -69,7 +61,6 @@ open class ListHabitsBehavior @Inject constructor( entry.value, entry.notes, habit.color, - location, ) { newValue, newNotes -> commandRunner.run(CreateRepetitionCommand(habitList, habit, timestamp, newValue, newNotes)) } @@ -162,19 +153,15 @@ open class ListHabitsBehavior @Inject constructor( fun showHabitScreen(h: Habit) fun showIntroScreen() fun showMessage(m: Message) - fun showNumberPicker( + fun showNumberPopup( value: Double, - unit: String, notes: String, - dateString: String, - frequency: Frequency, callback: NumberPickerCallback ) fun showCheckmarkPopup( selectedValue: Int, notes: String, color: PaletteColor, - location: ScreenLocation, callback: CheckMarkDialogCallback ) fun showSendBugReportToDeveloperScreen(log: String) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt index a6f9fd98b..7cde6f0d1 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/screens/habits/show/views/HistoryCard.kt @@ -19,7 +19,6 @@ 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 @@ -28,7 +27,6 @@ import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry.Companion.SKIP import org.isoron.uhabits.core.models.Entry.Companion.YES_AUTO import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL -import org.isoron.uhabits.core.models.Frequency import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.HabitList import org.isoron.uhabits.core.models.NumericalHabitType.AT_LEAST @@ -66,36 +64,35 @@ class HistoryCardPresenter( val screen: Screen, ) : OnDateClickedListener { - override fun onDateLongPress(location: ScreenLocation, date: LocalDate) { + override fun onDateLongPress(date: LocalDate) { val timestamp = Timestamp.fromLocalDate(date) screen.showFeedback() if (habit.isNumerical) { - showNumberPicker(timestamp) + showNumberPopup(timestamp) } else { - if (preferences.isShortToggleEnabled) showCheckmarkPopup(location, timestamp) + if (preferences.isShortToggleEnabled) showCheckmarkPopup(timestamp) else toggle(timestamp) } } - override fun onDateShortPress(location: ScreenLocation, date: LocalDate) { + override fun onDateShortPress(date: LocalDate) { val timestamp = Timestamp.fromLocalDate(date) screen.showFeedback() if (habit.isNumerical) { - showNumberPicker(timestamp) + showNumberPopup(timestamp) } else { if (preferences.isShortToggleEnabled) toggle(timestamp) - else showCheckmarkPopup(location, timestamp) + else showCheckmarkPopup(timestamp) } } - private fun showCheckmarkPopup(location: ScreenLocation, timestamp: Timestamp) { + private fun showCheckmarkPopup(timestamp: Timestamp) { val entry = habit.computedEntries.get(timestamp) screen.showCheckmarkPopup( entry.value, entry.notes, preferences, habit.color, - location, ) { newValue, newNotes -> commandRunner.run( CreateRepetitionCommand( @@ -127,15 +124,13 @@ class HistoryCardPresenter( ) } - private fun showNumberPicker(timestamp: Timestamp) { + private fun showNumberPopup(timestamp: Timestamp) { val entry = habit.computedEntries.get(timestamp) val oldValue = entry.value - screen.showNumberPicker( - oldValue / 1000.0, - habit.unit, - entry.notes, - timestamp.toDialogDateString(), - frequency = habit.frequency + screen.showNumberPopup( + value = oldValue / 1000.0, + notes = entry.notes, + preferences = preferences, ) { newValue: Double, newNotes: String -> val thousands = (newValue * 1000).roundToInt() commandRunner.run( @@ -205,21 +200,17 @@ class HistoryCardPresenter( interface Screen { fun showHistoryEditorDialog(listener: OnDateClickedListener) fun showFeedback() - fun showNumberPicker( + fun showNumberPopup( value: Double, - unit: String, notes: String, - dateString: String, - frequency: Frequency, - callback: ListHabitsBehavior.NumberPickerCallback + preferences: Preferences, + callback: ListHabitsBehavior.NumberPickerCallback, ) - fun showCheckmarkPopup( selectedValue: Int, notes: String, preferences: Preferences, color: PaletteColor, - location: ScreenLocation, callback: ListHabitsBehavior.CheckMarkDialogCallback, ) } diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt index 8d7435540..a752e271c 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt @@ -22,7 +22,6 @@ 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 @@ -34,8 +33,8 @@ import kotlin.math.min import kotlin.math.round interface OnDateClickedListener { - fun onDateShortPress(location: ScreenLocation, date: LocalDate) {} - fun onDateLongPress(location: ScreenLocation, date: LocalDate) {} + fun onDateShortPress(date: LocalDate) {} + fun onDateLongPress(date: LocalDate) {} } class HistoryChart( @@ -91,11 +90,10 @@ 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(location, clickedDate) + onDateClickedListener.onDateLongPress(clickedDate) } else { - onDateClickedListener.onDateShortPress(location, clickedDate) + onDateClickedListener.onDateShortPress(clickedDate) } } diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehaviorTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehaviorTest.kt index c147fa524..c5e5f7b44 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehaviorTest.kt +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehaviorTest.kt @@ -31,10 +31,8 @@ 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 import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday @@ -80,13 +78,10 @@ class ListHabitsBehaviorTest : BaseUnitTest() { @Test fun testOnEdit() { - behavior.onEdit(ScreenLocation(0.0, 0.0), habit2, getToday()) - verify(screen).showNumberPicker( + behavior.onEdit(habit2, getToday()) + verify(screen).showNumberPopup( eq(0.1), - eq("miles"), eq(""), - eq("Jan 25, 2015"), - eq(Frequency.DAILY), picker.capture() ) picker.lastValue.onNumberPicked(100.0, "") diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt index 8373805b7..d25483fb1 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt @@ -24,7 +24,6 @@ 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 @@ -90,32 +89,20 @@ class HistoryChartTest { // Click top left date view.onClick(20.0, 46.0) - verify(dateClickedListener).onDateShortPress( - ScreenLocation(20.0, 46.0), - LocalDate(2014, 10, 26) - ) + verify(dateClickedListener).onDateShortPress(LocalDate(2014, 10, 26)) reset(dateClickedListener) view.onClick(2.0, 28.0) - verify(dateClickedListener).onDateShortPress( - ScreenLocation(2.0, 28.0), - LocalDate(2014, 10, 26) - ) + verify(dateClickedListener).onDateShortPress(LocalDate(2014, 10, 26)) reset(dateClickedListener) // Click date in the middle view.onClick(163.0, 113.0) - verify(dateClickedListener).onDateShortPress( - ScreenLocation(163.0, 113.0), - LocalDate(2014, 12, 10) - ) + verify(dateClickedListener).onDateShortPress(LocalDate(2014, 12, 10)) reset(dateClickedListener) // Click today view.onClick(336.0, 37.0) - verify(dateClickedListener).onDateShortPress( - ScreenLocation(336.0, 37.0), - LocalDate(2015, 1, 25) - ) + verify(dateClickedListener).onDateShortPress(LocalDate(2015, 1, 25)) reset(dateClickedListener) // Click header @@ -133,32 +120,20 @@ class HistoryChartTest { // Click top left date view.onLongClick(20.0, 46.0) - verify(dateClickedListener).onDateLongPress( - ScreenLocation(20.0, 46.0), - LocalDate(2014, 10, 26) - ) + verify(dateClickedListener).onDateLongPress(LocalDate(2014, 10, 26)) reset(dateClickedListener) view.onLongClick(2.0, 28.0) - verify(dateClickedListener).onDateLongPress( - ScreenLocation(2.0, 28.0), - LocalDate(2014, 10, 26) - ) + verify(dateClickedListener).onDateLongPress(LocalDate(2014, 10, 26)) reset(dateClickedListener) // Click date in the middle view.onLongClick(163.0, 113.0) - verify(dateClickedListener).onDateLongPress( - ScreenLocation(163.0, 113.0), - LocalDate(2014, 12, 10) - ) + verify(dateClickedListener).onDateLongPress(LocalDate(2014, 12, 10)) reset(dateClickedListener) // Click today view.onLongClick(336.0, 37.0) - verify(dateClickedListener).onDateLongPress( - ScreenLocation(336.0, 37.0), - LocalDate(2015, 1, 25) - ) + verify(dateClickedListener).onDateLongPress(LocalDate(2015, 1, 25)) reset(dateClickedListener) // Click header