diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt index 7c73776689..ff3d0c778a 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt @@ -56,9 +56,9 @@ class CarbsDialog : DialogFragmentWithDate() { companion object { - private const val FAV1_DEFAULT = 5 - private const val FAV2_DEFAULT = 10 - private const val FAV3_DEFAULT = 20 + const val FAV1_DEFAULT = 5 + const val FAV2_DEFAULT = 10 + const val FAV3_DEFAULT = 20 } private var queryingProtection = false diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt index 9efb110a4f..7c45fe99ee 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt @@ -58,9 +58,9 @@ class InsulinDialog : DialogFragmentWithDate() { companion object { - private const val PLUS1_DEFAULT = 0.5 - private const val PLUS2_DEFAULT = 1.0 - private const val PLUS3_DEFAULT = 2.0 + const val PLUS1_DEFAULT = 0.5 + const val PLUS2_DEFAULT = 1.0 + const val PLUS3_DEFAULT = 2.0 } private var queryingProtection = false diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt index a0ccacf982..25017bfa3b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt @@ -12,6 +12,8 @@ import info.nightscout.androidaps.database.entities.* import info.nightscout.androidaps.database.interfaces.end import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction +import info.nightscout.androidaps.dialogs.CarbsDialog +import info.nightscout.androidaps.dialogs.InsulinDialog import info.nightscout.androidaps.events.EventMobileToWear import info.nightscout.androidaps.extensions.convertedToAbsolute import info.nightscout.androidaps.extensions.toStringShort @@ -694,7 +696,11 @@ class DataHandlerMobile @Inject constructor( unitsMgdl = profileFunction.getUnits() == GlucoseUnit.MGDL, bolusPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100), maxCarbs = sp.getInt(R.string.key_treatmentssafety_maxcarbs, 48), - maxBolus = sp.getDouble(R.string.key_treatmentssafety_maxbolus, 3.0) + maxBolus = sp.getDouble(R.string.key_treatmentssafety_maxbolus, 3.0), + insulin_button_increment_1 = sp.getDouble(R.string.key_insulin_button_increment_1, InsulinDialog.PLUS1_DEFAULT), + insulin_button_increment_2 = sp.getDouble(R.string.key_insulin_button_increment_2, InsulinDialog.PLUS2_DEFAULT), + carbs_button_increment_1 = sp.getInt(R.string.key_carbs_button_increment_1, CarbsDialog.FAV1_DEFAULT), + carbs_button_increment_2 = sp.getInt(R.string.key_carbs_button_increment_2, CarbsDialog.FAV2_DEFAULT) ) ) ) @@ -1185,4 +1191,4 @@ class DataHandlerMobile @Inject constructor( @Synchronized private fun sendError(errorMessage: String) { rxBus.send(EventMobileToWear(EventData.ConfirmAction(rh.gs(R.string.error), errorMessage, returnCommand = EventData.Error(dateUtil.now())))) // ignore return path } -} \ No newline at end of file +} diff --git a/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt b/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt index aca2303c89..bd0d06711b 100644 --- a/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt +++ b/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt @@ -208,7 +208,11 @@ sealed class EventData : Event() { val unitsMgdl: Boolean, val bolusPercentage: Int, val maxCarbs: Int, - val maxBolus: Double + val maxBolus: Double, + val insulin_button_increment_1: Double, + val insulin_button_increment_2: Double, + val carbs_button_increment_1: Int, + val carbs_button_increment_2: Int ) : EventData() @Serializable diff --git a/wear/build.gradle b/wear/build.gradle index ddcfcbfa2f..802c30ddef 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -53,6 +53,10 @@ android { buildConfigField "String", "BUILDVERSION", generateGitBuild() } + buildFeatures { + viewBinding true + } + flavorDimensions "standard" productFlavors { full { @@ -98,6 +102,7 @@ dependencies { implementation "androidx.preference:preference-ktx:$preferencektx_version" implementation 'androidx.wear:wear:1.2.0' implementation "androidx.wear.tiles:tiles:1.0.1" + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' compileOnly "com.google.android.wearable:wearable:$wearable_version" implementation "com.google.android.support:wearable:$wearable_version" diff --git a/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt b/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt index cac52e5439..3a05c06cf0 100644 --- a/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt +++ b/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt @@ -162,6 +162,10 @@ class DataHandlerWear @Inject constructor( sp.putInt(R.string.key_bolus_wizard_percentage, it.bolusPercentage) sp.putInt(R.string.key_treatments_safety_max_carbs, it.maxCarbs) sp.putDouble(R.string.key_treatments_safety_max_bolus, it.maxBolus) + sp.putDouble(R.string.key_insulin_button_increment_1, it.insulin_button_increment_1) + sp.putDouble(R.string.key_insulin_button_increment_2, it.insulin_button_increment_2) + sp.putInt(R.string.key_carbs_button_increment_1, it.carbs_button_increment_1) + sp.putInt(R.string.key_carbs_button_increment_2, it.carbs_button_increment_2) } disposable += rxBus .toObservable(EventData.QuickWizard::class.java) @@ -284,4 +288,4 @@ class DataHandlerWear @Inject constructor( NotificationManagerCompat.from(context).cancel(DataLayerListenerServiceWear.BOLUS_PROGRESS_NOTIF_ID) }.start() } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt index e7e8b56355..766983c581 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt @@ -10,10 +10,12 @@ import android.view.ViewGroup import android.widget.ImageView import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventWearToMobile +import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.shared.SafeParse import info.nightscout.shared.weardata.EventData.ActionBolusPreCheck import java.text.DecimalFormat +import kotlin.math.roundToInt class BolusActivity : ViewSelectorActivity() { @@ -33,13 +35,17 @@ class BolusActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = 2 override fun getRowCount(): Int = 1 + val increment1 = (sp.getDouble(R.string.key_insulin_button_increment_1, 0.5) * 10).roundToInt() / 10.0 + val increment2 = (sp.getDouble(R.string.key_insulin_button_increment_2, 1.0) * 10).roundToInt() / 10.0 + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { val view: View if (col == 0) { - view = getInflatedPlusMinusView(container) + view = EditPlusMinusViewAdapter.getInflatedPlusMinusView(sp, applicationContext, container, true).root val initValue = if (editInsulin != null) SafeParse.stringToDouble(editInsulin?.editText?.text.toString()) else 0.0 val maxBolus = sp.getDouble(getString(R.string.key_treatments_safety_max_bolus), 3.0) - editInsulin = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, initValue, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) + val buttons = listOf(Pair(R.id.plusbutton, 0.1), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) // When taken form phone settings round. + editInsulin = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, initValue, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) setLabelToPlusMinusView(view, getString(R.string.action_insulin)) container.addView(view) view.requestFocus() @@ -62,4 +68,4 @@ class BolusActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt index 4dd487bb79..7de9a45dd3 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt @@ -30,19 +30,23 @@ class CarbActivity : ViewSelectorActivity() { private inner class MyGridViewPagerAdapter : GridPagerAdapter() { + val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() + val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + override fun getColumnCount(arg0: Int): Int = 2 override fun getRowCount(): Int = 1 override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { val view: View if (col == 0) { - view = getInflatedPlusMinusView(container) + view = getInflatedPlusMinusView(container, true) var def = 0.0 if (editCarbs != null) { def = SafeParse.stringToDouble(editCarbs?.editText?.text.toString()) } val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) - editCarbs = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), true) + val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) + editCarbs = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), true) setLabelToPlusMinusView(view, getString(R.string.action_carbs)) container.addView(view) view.requestFocus() @@ -69,4 +73,4 @@ class CarbActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt index 21d7b41f31..50988562a4 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt @@ -36,15 +36,19 @@ class ECarbActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = 4 override fun getRowCount(): Int = 1 + private val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() + private val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { return if (col == 0) { - val view = getInflatedPlusMinusView(container) + val view = getInflatedPlusMinusView(container, true) var def = 0.0 if (editCarbs != null) { def = stringToDouble(editCarbs?.editText?.text.toString()) } val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) - editCarbs = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), true) + val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) + editCarbs = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), true) setLabelToPlusMinusView(view, getString(R.string.action_carbs)) container.addView(view) view.requestFocus() @@ -98,4 +102,4 @@ class ECarbActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt index ed504969b1..630317b89a 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt @@ -15,6 +15,7 @@ import info.nightscout.shared.SafeParse.stringToDouble import info.nightscout.shared.SafeParse.stringToInt import info.nightscout.shared.weardata.EventData.ActionBolusPreCheck import java.text.DecimalFormat +import kotlin.math.roundToInt class TreatmentActivity : ViewSelectorActivity() { @@ -35,23 +36,30 @@ class TreatmentActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = 3 override fun getRowCount(): Int = 1 + val incrementInsulin1 = (sp.getDouble(R.string.key_insulin_button_increment_1, 0.5) * 10).roundToInt() / 10.0 + val incrementInsulin2 = (sp.getDouble(R.string.key_insulin_button_increment_2, 1.0) * 10).roundToInt() / 10.0 + val incrementCarbs1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() + val incrementCarbs2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { return if (col == 0) { - val view = getInflatedPlusMinusView(container) + val view = getInflatedPlusMinusView(container, true) var def = 0.0 if (editInsulin != null) def = stringToDouble(editInsulin?.editText?.text.toString()) val maxBolus = sp.getDouble(getString(R.string.key_treatments_safety_max_bolus), 3.0) - editInsulin = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) + val buttons = listOf(Pair(R.id.plusbutton, 0.1), Pair(R.id.plusbutton2, incrementInsulin1), Pair(R.id.plusbutton3, incrementInsulin2)) + editInsulin = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) setLabelToPlusMinusView(view, getString(R.string.action_insulin)) container.addView(view) view.requestFocus() view } else if (col == 1) { - val view = getInflatedPlusMinusView(container) + val view = getInflatedPlusMinusView(container, true) var def = 0.0 val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) if (editCarbs != null) def = stringToDouble(editCarbs?.editText?.text.toString()) - editCarbs = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) + val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, incrementCarbs1), Pair(R.id.plusbutton3, incrementCarbs2)) + editCarbs = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) setLabelToPlusMinusView(view, getString(R.string.action_carbs)) container.addView(view) view @@ -79,4 +87,4 @@ class TreatmentActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt index 9fd6b9adf1..eb3a9b70d7 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt @@ -73,13 +73,16 @@ open class ViewSelectorActivity : DaggerActivity() { } } - fun getInflatedPlusMinusView(container: ViewGroup?): View = - when (sp.getInt(R.string.key_input_design, 1)) { - 2 -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item_quickrighty, container, false) - 3 -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item_quicklefty, container, false) + fun getInflatedPlusMinusView(container: ViewGroup?, mulitple: Boolean = false): View { + val layoutRight = if (mulitple) R.layout.action_editplusminus_item_quickrighty_plus else R.layout.action_editplusminus_item_quickrighty + val layoutLeft = if (mulitple) R.layout.action_editplusminus_item_quicklefty_plus else R.layout.action_editplusminus_item_quicklefty + return when (sp.getInt(R.string.key_input_design, 1)) { + 2 -> LayoutInflater.from(applicationContext).inflate(layoutRight, container, false) + 3 -> LayoutInflater.from(applicationContext).inflate(layoutLeft, container, false) 4 -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item_viktoria, container, false) else -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item, container, false) } + } fun setLabelToPlusMinusView(view: View, labelText: String?) { val textView = view.findViewById(R.id.label) @@ -89,4 +92,4 @@ open class ViewSelectorActivity : DaggerActivity() { fun showToast(context: Context?, text: Int) { Toast.makeText(context, getString(text), Toast.LENGTH_LONG).show() } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt index f8c6208e52..dfd6e6291b 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt @@ -35,16 +35,19 @@ class WizardActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = if (hasPercentage) 3 else 2 override fun getRowCount(): Int = 1 + private val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() + private val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { return if (col == 0) { - val view = getInflatedPlusMinusView(container) + val view = getInflatedPlusMinusView(container, true) val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) + val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) editCarbs = if (editCarbs == null) { - PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) + PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) } else { val def = SafeParse.stringToDouble(editCarbs?.editText?.text.toString()) - PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) + PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) } setLabelToPlusMinusView(view, getString(R.string.action_carbs)) container.addView(view) @@ -84,4 +87,4 @@ class WizardActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt new file mode 100644 index 0000000000..4b3798940b --- /dev/null +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt @@ -0,0 +1,78 @@ +package info.nightscout.androidaps.interaction.utils + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import info.nightscout.androidaps.R +import info.nightscout.androidaps.databinding.ActionEditplusminusItemBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickleftyPlusBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickleftyBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickrightyBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickrightyPlusBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemViktoriaBinding +import info.nightscout.shared.sharedPreferences.SP + +/** + * NumberPickerViewAdapter binds both NumberPickerLayoutBinding and NumberPickerLayoutVerticalBinding shared attributes to one common view adapter. + * Requires at least one of the ViewBinding as a parameter. Recommended to use the factory object to create the binding. + */ +class EditPlusMinusViewAdapter( + val eS: ActionEditplusminusItemBinding?, + val eQLP: ActionEditplusminusItemQuickleftyPlusBinding?, + val eQL: ActionEditplusminusItemQuickleftyBinding?, + val eQRP: ActionEditplusminusItemQuickleftyPlusBinding?, + val qQR: ActionEditplusminusItemQuickrightyBinding?, + val nQRP: ActionEditplusminusItemQuickrightyPlusBinding?, + val eV: ActionEditplusminusItemViktoriaBinding? +) { + + init { + if (eS == null && eQLP == null && eQL == null && eQRP == null && qQR == null && nQRP == null && eV == null) { + throw IllegalArgumentException("Require at least on Binding parameter") + } + } + + val amountField = + eS?.amountfield ?: eQLP?.amountfield ?: eQL?.amountfield ?: eQRP?.amountfield ?: qQR?.amountfield ?: nQRP?.amountfield ?: eV?.amountfield + ?: throw IllegalArgumentException("Missing require View Binding parameter display") + val minusButton = + eS?.minusbutton ?: eQLP?.minusbutton ?: eQL?.minusbutton ?: eQRP?.minusbutton ?: qQR?.minusbutton ?: nQRP?.minusbutton ?: eV?.minusbutton + ?: throw IllegalArgumentException("Missing require View Binding parameter display") + val plusButton = + eS?.plusbutton ?: eQLP?.plusbutton ?: eQL?.plusbutton ?: eQRP?.plusbutton ?: qQR?.plusbutton ?: nQRP?.plusbutton ?: eV?.plusbutton + ?: throw IllegalArgumentException("Missing require View Binding parameter display") + val label = + eS?.label ?: eQLP?.label ?: eQL?.label ?: eQRP?.label ?: qQR?.label ?: nQRP?.label ?: eV?.label + ?: throw IllegalArgumentException("Missing require View Binding parameter display") + val plusButton2 = eQLP?.plusbutton2 ?: eQRP?.plusbutton2 + val plusButton3 = eQLP?.plusbutton3 ?: eQRP?.plusbutton3 + val root = + eS?.root ?: eQLP?.root ?: eQL?.root ?: eQRP?.root ?: qQR?.root ?: nQRP?.root ?: eV?.root + ?: throw IllegalArgumentException("Missing require View Binding parameter display") + + companion object { + + fun getInflatedPlusMinusView(sp: SP, context: Context, container: ViewGroup?, mulitple: Boolean = false): EditPlusMinusViewAdapter { + val inflater = LayoutInflater.from(context) + val bindLayout = ActionEditplusminusItemBinding.inflate(inflater, container, false) + val binding = EditPlusMinusViewAdapter(bindLayout, null, null, null, null, null, null) + return binding + // val layoutRight = if (mulitple) R.layout.action_editplusminus_item_quickrighty_plus else R.layout.action_editplusminus_item_quickrighty + // val layoutLeft = if (mulitple) R.layout.action_editplusminus_item_quicklefty_plus else R.layout.action_editplusminus_item_quicklefty + // return when (sp.getInt(R.string.key_input_design, 1)) { + // 2 -> LayoutInflater.from(applicationContext).inflate(layoutRight, container, false) + // 3 -> LayoutInflater.from(applicationContext).inflate(layoutLeft, container, false) + // 4 -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item_viktoria, container, false) + // else -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item, container, false) + // } + } + // fun getBinding(bindLayout: NumberPickerLayoutBinding): NumberPickerViewAdapter { + // return NumberPickerViewAdapter(bindLayout, null) + // } + // + // fun getBinding(bindLayout: NumberPickerLayoutVerticalBinding): NumberPickerViewAdapter { + // return NumberPickerViewAdapter(null, bindLayout) + // } + } +} \ No newline at end of file diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt index 1ee994c9d3..f812b7e245 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt @@ -1,67 +1,82 @@ package info.nightscout.androidaps.interaction.utils -import android.os.Handler -import kotlin.jvm.JvmOverloads -import android.view.View.OnTouchListener -import android.view.View.OnGenericMotionListener -import android.widget.TextView -import android.view.MotionEvent -import android.os.Looper -import android.os.Message +import android.annotation.SuppressLint +import android.content.Context +import android.os.* import android.view.KeyEvent +import android.view.MotionEvent import android.view.View -import android.widget.ImageView +import android.view.View.OnGenericMotionListener +import android.view.View.OnTouchListener +import android.widget.TextView +import androidx.appcompat.widget.AppCompatButton import androidx.core.view.InputDeviceCompat import androidx.core.view.MotionEventCompat +import java.text.DecimalFormat import java.text.NumberFormat import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.TimeUnit +import kotlin.Pair /** * Created by mike on 28.06.2016. */ -class PlusMinusEditText @JvmOverloads constructor( +@SuppressLint("SetTextI18n") class PlusMinusEditText @JvmOverloads constructor( view: View, editTextID: Int, - plusID: Int, + private var plusButtons: List>, minusID: Int, initValue: Double, - minValue: Double, - maxValue: Double, - step: Double, - formatter: NumberFormat, - allowZero: Boolean, - roundRobin: Boolean = false + private val minValue: Double, + private val maxValue: Double, + private val stepGeneral: Double, + private val formatter: NumberFormat, + private val allowZero: Boolean, + private val roundRobin: Boolean = false, ) : View.OnKeyListener, OnTouchListener, View.OnClickListener, OnGenericMotionListener { + constructor( + view: View, + editTextID: Int, + plusID: Int, + minusID: Int, + initValue: Double, + minValue: Double, + maxValue: Double, + stepGeneral: Double, + formatter: NumberFormat, + allowZero: Boolean, + roundRobin: Boolean = false + ) : this(view, editTextID, listOf(Pair(plusID, stepGeneral)), minusID, initValue, minValue, maxValue, stepGeneral, formatter, allowZero, roundRobin) + var editText: TextView private set - private var minusImage: ImageView - private var plusImage: ImageView + private var minusImage: View + private var plusImage1: View + private var plusImage2: AppCompatButton? = null + private var plusImage3: AppCompatButton? = null private var value: Double - private var minValue: Double - private var maxValue: Double - private var step: Double - private var formatter: NumberFormat - private var allowZero: Boolean - private var roundRobin: Boolean + private val context: Context private var mChangeCounter = 0 private var mLastChange: Long = 0 private val mHandler: Handler private var mUpdater: ScheduledExecutorService? = null - private inner class UpdateCounterTask(private val mInc: Boolean) : Runnable { + private inner class UpdateCounterTask(private val mInc: Boolean, private val step: Double) : Runnable { private var repeated = 0 private var multiplier = 1 override fun run() { val msg = Message() val doubleLimit = 5 - if (repeated % doubleLimit == 0) multiplier *= 2 - repeated++ - msg.arg1 = multiplier - msg.arg2 = repeated + val multipleButtons = mInc && (plusImage2 != null || plusImage3 != null) + if (!multipleButtons && repeated % doubleLimit == 0) multiplier *= 2 + val bundle = Bundle() + bundle.putDouble("step", step) + bundle.putInt("multiplier", multiplier) + msg.data = bundle + if (mInc) { msg.what = MSG_INC } else { @@ -71,7 +86,7 @@ class PlusMinusEditText @JvmOverloads constructor( } } - private fun inc(multiplier: Int) { + private fun inc(multiplier: Int, step: Double, vibrate: Boolean = true) { value += step * multiplier if (value > maxValue) { if (roundRobin) { @@ -82,9 +97,10 @@ class PlusMinusEditText @JvmOverloads constructor( } } updateEditText() + if (vibrate) vibrateDevice() } - private fun dec(multiplier: Int) { + private fun dec(multiplier: Int, step: Double, vibrate: Boolean = true) { value -= step * multiplier if (value < minValue) { if (roundRobin) { @@ -95,20 +111,39 @@ class PlusMinusEditText @JvmOverloads constructor( } } updateEditText() + if (vibrate) vibrateDevice() + } + + fun vibrateDevice() { + val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + val vibratorManager = + context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager + vibratorManager.defaultVibrator + } else { + @Suppress("DEPRECATION") + context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + vibrator.vibrate(VibrationEffect.createOneShot(10, VibrationEffect.DEFAULT_AMPLITUDE)) + } else { + @Suppress("DEPRECATION") + vibrator.vibrate(10) + } } private fun updateEditText() { if (value == 0.0 && !allowZero) editText.text = "" else editText.text = formatter.format(value) } - private fun startUpdating(inc: Boolean) { + private fun startUpdating(inc: Boolean, step: Double) { if (mUpdater != null) { return } mUpdater = Executors.newSingleThreadScheduledExecutor() mUpdater?.scheduleAtFixedRate( - UpdateCounterTask(inc), 200, 200, + UpdateCounterTask(inc, step), 200, 200, TimeUnit.MILLISECONDS ) } @@ -118,12 +153,30 @@ class PlusMinusEditText @JvmOverloads constructor( mUpdater = null } + private fun getStep(v: View): Double { + return when (v) { + plusImage1 -> plusButtons[0].second + plusImage2 -> plusButtons[1].second + plusImage3 -> plusButtons[2].second + else -> stepGeneral + } + } + + private fun isIncrement(v: View): Boolean { + return when (v) { + plusImage1 -> true + plusImage2 -> true + plusImage3 -> true + else -> false + } + } + override fun onClick(v: View) { if (mUpdater == null) { - if (v === plusImage) { - inc(1) + if (isIncrement(v)) { + inc(1, getStep(v)) } else { - dec(1) + dec(1, getStep(v)) } } } @@ -135,7 +188,7 @@ class PlusMinusEditText @JvmOverloads constructor( if (isKeyOfInterest && isReleased) { stopUpdating() } else if (isKeyOfInterest && isPressed) { - startUpdating(v === plusImage) + startUpdating(isIncrement(v), stepGeneral) } return false } @@ -146,7 +199,7 @@ class PlusMinusEditText @JvmOverloads constructor( if (isReleased) { stopUpdating() } else if (isPressed) { - startUpdating(v === plusImage) + startUpdating(isIncrement(v), getStep(v)) } return false } @@ -158,9 +211,9 @@ class PlusMinusEditText @JvmOverloads constructor( val dynamicMultiplier = if (mChangeCounter < THRESHOLD_COUNTER) 1 else if (mChangeCounter < THRESHOLD_COUNTER_LONG) 2 else 4 val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) if (delta > 0) { - inc(dynamicMultiplier) + inc(dynamicMultiplier, stepGeneral, false) } else { - dec(dynamicMultiplier) + dec(dynamicMultiplier, stepGeneral, false) } mLastChange = System.currentTimeMillis() mChangeCounter++ @@ -179,39 +232,59 @@ class PlusMinusEditText @JvmOverloads constructor( } init { + context = view.context editText = view.findViewById(editTextID) minusImage = view.findViewById(minusID) - plusImage = view.findViewById(plusID) + plusImage1 = view.findViewById(plusButtons.first().first) + val format = DecimalFormat("#.#") + plusButtons.getOrNull(1)?.let { + plusImage2 = view.findViewById(it.first) + plusImage2?.text = "+${format.format(it.second).replaceFirst("^0+(?!$)".toRegex(), "")}" + plusImage2?.visibility = View.VISIBLE + } + plusButtons.getOrNull(2)?.let { + plusImage3 = view.findViewById(it.first) + plusImage3?.text = "+${format.format(it.second).replaceFirst("^0+(?!$)".toRegex(), "")}" + plusImage3?.visibility = View.VISIBLE + } + value = initValue - this.minValue = minValue - this.maxValue = maxValue - this.step = step - this.formatter = formatter - this.allowZero = allowZero - this.roundRobin = roundRobin mHandler = object : Handler(Looper.getMainLooper()) { override fun handleMessage(msg: Message) { + val multiplier = msg.data.getInt("multiplier") + val step = msg.data.getDouble("step") + when (msg.what) { MSG_INC -> { - inc(msg.arg1) + inc(multiplier, step) return } MSG_DEC -> { - dec(msg.arg1) + dec(multiplier, step) return } } super.handleMessage(msg) } } + + editText.showSoftInputOnFocus = false + editText.setTextIsSelectable(false) minusImage.setOnTouchListener(this) minusImage.setOnKeyListener(this) minusImage.setOnClickListener(this) - plusImage.setOnTouchListener(this) - plusImage.setOnKeyListener(this) - plusImage.setOnClickListener(this) + plusImage1.setOnTouchListener(this) + plusImage1.setOnKeyListener(this) + plusImage1.setOnClickListener(this) + plusImage2?.setOnTouchListener(this) + plusImage2?.setOnKeyListener(this) + plusImage2?.setOnClickListener(this) + plusImage3?.setOnTouchListener(this) + plusImage3?.setOnKeyListener(this) + plusImage3?.setOnClickListener(this) editText.setOnGenericMotionListener(this) updateEditText() } + } diff --git a/wear/src/main/res/layout/action_editplusminus_item.xml b/wear/src/main/res/layout/action_editplusminus_item.xml index c3cbe263ba..5c5b8856d5 100644 --- a/wear/src/main/res/layout/action_editplusminus_item.xml +++ b/wear/src/main/res/layout/action_editplusminus_item.xml @@ -7,7 +7,7 @@ android:gravity="center" android:orientation="horizontal"> - - - diff --git a/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml b/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml index bf3418ca2c..d96ae1d26f 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml @@ -7,16 +7,52 @@ android:gravity="center" android:orientation="horizontal"> - + android:layout_marginEnd="-8dp" + android:orientation="vertical"> + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml b/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml index 78c5d7e817..7e3ae3dcb1 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml @@ -41,7 +41,7 @@ tools:ignore="LabelFor" tools:text="label" /> - - + android:layout_marginStart="-8dp" + android:orientation="vertical" + tools:visibility="visible"> + + + + + + + + diff --git a/wear/src/main/res/layout/action_editplusminus_item_quickrighty_plus.xml b/wear/src/main/res/layout/action_editplusminus_item_quickrighty_plus.xml new file mode 100644 index 0000000000..07a9101a0e --- /dev/null +++ b/wear/src/main/res/layout/action_editplusminus_item_quickrighty_plus.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml b/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml index 0b396d8b7f..b734b9db7b 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml @@ -25,7 +25,7 @@ android:layout_gravity="start|center_vertical|center_horizontal" android:orientation="vertical"> - - dark input_design complication_tap_action + insulin_button_increment_1 + insulin_button_increment_2 + carbs_button_increment_1 + carbs_button_increment_2 increment decrement H