From 908eb4ac9912ae4b1cb2cb668ddac13ec2552e30 Mon Sep 17 00:00:00 2001 From: "Alinson S. Xavier" Date: Sat, 18 Mar 2023 05:04:43 -0500 Subject: [PATCH] Convert NumberDialog to AppCompatDialogFragment; remove unused classes --- .../common/dialogs/CheckmarkPopup.kt | 128 ----------------- .../activities/common/dialogs/NumberDialog.kt | 104 ++++++++++++++ .../activities/common/dialogs/NumberPopup.kt | 134 ------------------ .../habits/list/ListHabitsScreen.kt | 19 ++- .../habits/show/ShowHabitActivity.kt | 20 +-- .../screens/habits/show/views/HistoryCard.kt | 4 - 6 files changed, 119 insertions(+), 290 deletions(-) delete mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkPopup.kt create mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberDialog.kt delete mode 100644 uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPopup.kt 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 deleted file mode 100644 index fb7f43d51..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/CheckmarkPopup.kt +++ /dev/null @@ -1,128 +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.app.Dialog -import android.content.Context -import android.view.LayoutInflater -import android.view.View -import android.view.View.GONE -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 -import org.isoron.uhabits.core.models.Entry.Companion.UNKNOWN -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.preferences.Preferences -import org.isoron.uhabits.databinding.CheckmarkPopupBinding -import org.isoron.uhabits.utils.InterfaceUtils.getFontAwesome -import org.isoron.uhabits.utils.dimBehind -import org.isoron.uhabits.utils.dismissCurrentAndShow -import org.isoron.uhabits.utils.dp -import org.isoron.uhabits.utils.sres - -const val POPUP_WIDTH = 4 * 48f + 16f -const val POPUP_HEIGHT = 48f * 2.5f + 8f - -class CheckmarkPopup( - private val context: Context, - private val color: Int, - private var notes: String, - private var value: Int, - private val prefs: Preferences, - 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 - container.clipToOutline = true - } - - init { - view.booleanButtons.visibility = VISIBLE - initColors() - initTypefaces() - hideDisabledButtons() - populate() - } - - private fun initColors() { - arrayOf(view.yesBtn, view.skipBtn).forEach { - it.setTextColor(color) - } - arrayOf(view.noBtn, view.unknownBtn).forEach { - it.setTextColor(view.root.sres.getColor(R.attr.contrast60)) - } - } - - private fun initTypefaces() { - arrayOf(view.yesBtn, view.noBtn, view.skipBtn, view.unknownBtn).forEach { - it.typeface = getFontAwesome(context) - } - } - - private fun hideDisabledButtons() { - if (!prefs.isSkipEnabled) view.skipBtn.visibility = GONE - if (!prefs.areQuestionMarksEnabled) view.unknownBtn.visibility = GONE - } - - private fun populate() { - val selectedBtn = when (value) { - YES_MANUAL -> view.yesBtn - YES_AUTO -> view.noBtn - NO -> view.noBtn - UNKNOWN -> if (prefs.areQuestionMarksEnabled) view.unknownBtn else view.noBtn - SKIP -> if (prefs.isSkipEnabled) view.skipBtn else view.noBtn - else -> null - } - view.notes.setText(notes) - } - - 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 - save() - } - view.yesBtn.setOnClickListener { onClick(YES_MANUAL) } - view.noBtn.setOnClickListener { onClick(NO) } - view.skipBtn.setOnClickListener { onClick(SKIP) } - view.unknownBtn.setOnClickListener { onClick(UNKNOWN) } - dialog.setCanceledOnTouchOutside(true) - dialog.dimBehind() - dialog.dismissCurrentAndShow() - } - - 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/NumberDialog.kt b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberDialog.kt new file mode 100644 index 000000000..7e10baa51 --- /dev/null +++ b/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberDialog.kt @@ -0,0 +1,104 @@ +package org.isoron.uhabits.activities.common.dialogs + +import android.app.Dialog +import android.os.Bundle +import android.text.method.DigitsKeyListener +import android.view.KeyEvent +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import androidx.appcompat.app.AppCompatDialogFragment +import org.isoron.uhabits.HabitsApplication +import org.isoron.uhabits.R +import org.isoron.uhabits.core.models.Entry +import org.isoron.uhabits.databinding.CheckmarkPopupBinding +import org.isoron.uhabits.utils.InterfaceUtils +import org.isoron.uhabits.utils.requestFocusWithKeyboard +import org.isoron.uhabits.utils.sres +import java.text.DecimalFormat +import java.text.DecimalFormatSymbols +import java.text.NumberFormat +import java.text.ParseException + +class NumberDialog : AppCompatDialogFragment() { + + var onToggle: (Double, String) -> Unit = { _, _ -> } + var onDismiss: () -> Unit = {} + + private var originalNotes: String = "" + private var originalValue: Double = 0.0 + private lateinit var view: CheckmarkPopupBinding + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val appComponent = (requireActivity().application as HabitsApplication).component + val prefs = appComponent.preferences + view = CheckmarkPopupBinding.inflate(LayoutInflater.from(context)) + arrayOf(view.yesBtn, view.skipBtn).forEach { + it.setTextColor(requireArguments().getInt("color")) + } + arrayOf(view.noBtn, view.unknownBtn).forEach { + it.setTextColor(view.root.sres.getColor(R.attr.contrast60)) + } + arrayOf(view.yesBtn, view.noBtn, view.skipBtn, view.unknownBtn).forEach { + it.typeface = InterfaceUtils.getFontAwesome(requireContext()) + } + if (!prefs.isSkipEnabled) view.skipBtnNumber.visibility = View.GONE + view.numberButtons.visibility = View.VISIBLE + fixDecimalSeparator(view) + originalNotes = requireArguments().getString("notes")!! + originalValue = requireArguments().getDouble("value") + view.notes.setText(originalNotes) + view.value.setText( + when { + originalValue < 0.01 -> "0" + else -> DecimalFormat("#.##").format(originalValue) + } + ) + view.value.setOnKeyListener { _, keyCode, event -> + if (event.action == MotionEvent.ACTION_DOWN && keyCode == KeyEvent.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.notes.setOnEditorActionListener { v, actionId, event -> + save() + true + } + view.value.requestFocusWithKeyboard() + val dialog = Dialog(requireContext()) + dialog.setContentView(view.root) + dialog.window?.apply { + setBackgroundDrawableResource(android.R.color.transparent) + } + dialog.setOnDismissListener { onDismiss() } + return dialog + } + + private fun fixDecimalSeparator(view: CheckmarkPopupBinding) { + // https://stackoverflow.com/a/34256139 + val separator = DecimalFormatSymbols.getInstance().decimalSeparator + view.value.keyListener = DigitsKeyListener.getInstance("0123456789$separator") + } + + fun save() { + var value = originalValue + try { + val numberFormat = NumberFormat.getInstance() + val valueStr = view.value.text.toString() + value = numberFormat.parse(valueStr)!!.toDouble() + } catch (e: ParseException) { + // NOP + } + val notes = view.notes.text.toString() + onToggle(value, notes) + requireDialog().dismiss() + } +} 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 deleted file mode 100644 index f918fb267..000000000 --- a/uhabits-android/src/main/java/org/isoron/uhabits/activities/common/dialogs/NumberPopup.kt +++ /dev/null @@ -1,134 +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.app.Dialog -import android.content.Context -import android.text.method.DigitsKeyListener -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.dismissCurrentAndShow -import org.isoron.uhabits.utils.dp -import org.isoron.uhabits.utils.requestFocusWithKeyboard -import java.text.DecimalFormat -import java.text.DecimalFormatSymbols -import java.text.NumberFormat -import java.text.ParseException - -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 = { _, _ -> } - var onDismiss: () -> 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 - fixDecimalSeparator() - hideDisabledButtons() - populate() - } - - private fun fixDecimalSeparator() { - // https://stackoverflow.com/a/34256139 - val separator = DecimalFormatSymbols.getInstance().decimalSeparator - view.value.keyListener = DigitsKeyListener.getInstance("0123456789$separator") - } - - 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) - } - dialog.setOnDismissListener { - onDismiss() - } - - 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.dismissCurrentAndShow() - } - - fun save() { - var value = originalValue - try { - val numberFormat = NumberFormat.getInstance() - val valueStr = view.value.text.toString() - value = numberFormat.parse(valueStr)!!.toDouble() - } catch (e: ParseException) { - // NOP - } - 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 8dda56a3d..acbb8c102 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 @@ -30,7 +30,7 @@ import org.isoron.uhabits.R import org.isoron.uhabits.activities.common.dialogs.CheckmarkDialog import org.isoron.uhabits.activities.common.dialogs.ColorPickerDialogFactory import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog -import org.isoron.uhabits.activities.common.dialogs.NumberPopup +import org.isoron.uhabits.activities.common.dialogs.NumberDialog import org.isoron.uhabits.activities.habits.edit.HabitTypeDialog import org.isoron.uhabits.activities.habits.list.views.HabitCardListAdapter import org.isoron.uhabits.core.commands.ArchiveHabitsCommand @@ -234,17 +234,14 @@ class ListHabitsScreen notes: String, callback: ListHabitsBehavior.NumberPickerCallback ) { - val view = rootView.get() - NumberPopup( - context = context, - prefs = preferences, - anchor = view, - notes = notes, - value = value, - ).apply { - onToggle = { value, notes -> callback.onNumberPicked(value, notes) } - show() + val fm = (context as AppCompatActivity).supportFragmentManager + val dialog = NumberDialog() + dialog.arguments = Bundle().apply { + putDouble("value", value) + putString("notes", notes) } + dialog.onToggle = { v, n -> callback.onNumberPicked(v, n) } + dialog.dismissCurrentAndShow(fm, "numberDialog") } override fun showCheckmarkPopup( 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 b92f3a5b1..beb488095 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 @@ -37,7 +37,7 @@ import org.isoron.uhabits.activities.HabitsDirFinder import org.isoron.uhabits.activities.common.dialogs.CheckmarkDialog import org.isoron.uhabits.activities.common.dialogs.ConfirmDeleteDialog import org.isoron.uhabits.activities.common.dialogs.HistoryEditorDialog -import org.isoron.uhabits.activities.common.dialogs.NumberPopup +import org.isoron.uhabits.activities.common.dialogs.NumberDialog import org.isoron.uhabits.core.commands.Command import org.isoron.uhabits.core.commands.CommandRunner import org.isoron.uhabits.core.models.Habit @@ -172,26 +172,20 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener { override fun showNumberPopup( value: Double, notes: String, - preferences: Preferences, callback: ListHabitsBehavior.NumberPickerCallback ) { - 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() + val dialog = NumberDialog() + dialog.arguments = Bundle().apply { + putDouble("value", value) + putString("notes", notes) } + dialog.onToggle = { v, n -> callback.onNumberPicked(v, n) } + dialog.dismissCurrentAndShow(supportFragmentManager, "numberDialog") } override fun showCheckmarkPopup( selectedValue: Int, notes: String, - preferences: Preferences, color: PaletteColor, callback: ListHabitsBehavior.CheckMarkDialogCallback ) { 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 7cde6f0d1..8b6126090 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 @@ -91,7 +91,6 @@ class HistoryCardPresenter( screen.showCheckmarkPopup( entry.value, entry.notes, - preferences, habit.color, ) { newValue, newNotes -> commandRunner.run( @@ -130,7 +129,6 @@ class HistoryCardPresenter( screen.showNumberPopup( value = oldValue / 1000.0, notes = entry.notes, - preferences = preferences, ) { newValue: Double, newNotes: String -> val thousands = (newValue * 1000).roundToInt() commandRunner.run( @@ -203,13 +201,11 @@ class HistoryCardPresenter( fun showNumberPopup( value: Double, notes: String, - preferences: Preferences, callback: ListHabitsBehavior.NumberPickerCallback, ) fun showCheckmarkPopup( selectedValue: Int, notes: String, - preferences: Preferences, color: PaletteColor, callback: ListHabitsBehavior.CheckMarkDialogCallback, )