Merge pull request #1861 from Andries-Smit/wear/muliple-plus-buttons-2

Wear multiple plus buttons
This commit is contained in:
Milos Kozak 2022-06-30 20:52:39 +02:00 committed by GitHub
commit 5d749e121f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 840 additions and 232 deletions

View file

@ -56,9 +56,9 @@ class CarbsDialog : DialogFragmentWithDate() {
companion object { companion object {
private const val FAV1_DEFAULT = 5 const val FAV1_DEFAULT = 5
private const val FAV2_DEFAULT = 10 const val FAV2_DEFAULT = 10
private const val FAV3_DEFAULT = 20 const val FAV3_DEFAULT = 20
} }
private var queryingProtection = false private var queryingProtection = false

View file

@ -58,9 +58,9 @@ class InsulinDialog : DialogFragmentWithDate() {
companion object { companion object {
private const val PLUS1_DEFAULT = 0.5 const val PLUS1_DEFAULT = 0.5
private const val PLUS2_DEFAULT = 1.0 const val PLUS2_DEFAULT = 1.0
private const val PLUS3_DEFAULT = 2.0 const val PLUS3_DEFAULT = 2.0
} }
private var queryingProtection = false private var queryingProtection = false

View file

@ -12,6 +12,8 @@ import info.nightscout.androidaps.database.entities.*
import info.nightscout.androidaps.database.interfaces.end import info.nightscout.androidaps.database.interfaces.end
import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction 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.events.EventMobileToWear
import info.nightscout.androidaps.extensions.convertedToAbsolute import info.nightscout.androidaps.extensions.convertedToAbsolute
import info.nightscout.androidaps.extensions.toStringShort import info.nightscout.androidaps.extensions.toStringShort
@ -694,7 +696,11 @@ class DataHandlerMobile @Inject constructor(
unitsMgdl = profileFunction.getUnits() == GlucoseUnit.MGDL, unitsMgdl = profileFunction.getUnits() == GlucoseUnit.MGDL,
bolusPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100), bolusPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100),
maxCarbs = sp.getInt(R.string.key_treatmentssafety_maxcarbs, 48), 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),
insulinButtonIncrement1 = sp.getDouble(R.string.key_insulin_button_increment_1, InsulinDialog.PLUS1_DEFAULT),
insulinButtonIncrement2 = sp.getDouble(R.string.key_insulin_button_increment_2, InsulinDialog.PLUS2_DEFAULT),
carbsButtonIncrement1 = sp.getInt(R.string.key_carbs_button_increment_1, CarbsDialog.FAV1_DEFAULT),
carbsButtonIncrement2 = sp.getInt(R.string.key_carbs_button_increment_2, CarbsDialog.FAV2_DEFAULT)
) )
) )
) )

View file

@ -208,7 +208,11 @@ sealed class EventData : Event() {
val unitsMgdl: Boolean, val unitsMgdl: Boolean,
val bolusPercentage: Int, val bolusPercentage: Int,
val maxCarbs: Int, val maxCarbs: Int,
val maxBolus: Double val maxBolus: Double,
val insulinButtonIncrement1: Double,
val insulinButtonIncrement2: Double,
val carbsButtonIncrement1: Int,
val carbsButtonIncrement2: Int
) : EventData() ) : EventData()
@Serializable @Serializable

View file

@ -53,6 +53,10 @@ android {
buildConfigField "String", "BUILDVERSION", generateGitBuild() buildConfigField "String", "BUILDVERSION", generateGitBuild()
} }
buildFeatures {
viewBinding true
}
flavorDimensions "standard" flavorDimensions "standard"
productFlavors { productFlavors {
full { full {
@ -98,6 +102,7 @@ dependencies {
implementation "androidx.preference:preference-ktx:$preferencektx_version" implementation "androidx.preference:preference-ktx:$preferencektx_version"
implementation 'androidx.wear:wear:1.2.0' implementation 'androidx.wear:wear:1.2.0'
implementation "androidx.wear.tiles:tiles:1.0.1" implementation "androidx.wear.tiles:tiles:1.0.1"
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
compileOnly "com.google.android.wearable:wearable:$wearable_version" compileOnly "com.google.android.wearable:wearable:$wearable_version"
implementation "com.google.android.support:wearable:$wearable_version" implementation "com.google.android.support:wearable:$wearable_version"

View file

@ -162,6 +162,10 @@ class DataHandlerWear @Inject constructor(
sp.putInt(R.string.key_bolus_wizard_percentage, it.bolusPercentage) sp.putInt(R.string.key_bolus_wizard_percentage, it.bolusPercentage)
sp.putInt(R.string.key_treatments_safety_max_carbs, it.maxCarbs) 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_treatments_safety_max_bolus, it.maxBolus)
sp.putDouble(R.string.key_insulin_button_increment_1, it.insulinButtonIncrement1)
sp.putDouble(R.string.key_insulin_button_increment_2, it.insulinButtonIncrement2)
sp.putInt(R.string.key_carbs_button_increment_1, it.carbsButtonIncrement1)
sp.putInt(R.string.key_carbs_button_increment_2, it.carbsButtonIncrement2)
} }
disposable += rxBus disposable += rxBus
.toObservable(EventData.QuickWizard::class.java) .toObservable(EventData.QuickWizard::class.java)

View file

@ -56,10 +56,9 @@ class AcceptActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = 2 override fun getColumnCount(arg0: Int): Int = 2
override fun getRowCount(): Int = 1 override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) {
val view: View 0 -> {
if (col == 0) { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_text, container, false)
view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_text, container, false)
val textView = view.findViewById<TextView>(R.id.message) val textView = view.findViewById<TextView>(R.id.message)
val scrollView = view.findViewById<View>(R.id.message_scroll) val scrollView = view.findViewById<View>(R.id.message_scroll)
textView.text = message textView.text = message
@ -79,8 +78,11 @@ class AcceptActivity : ViewSelectorActivity() {
false false
} }
scrollView.requestFocus() scrollView.requestFocus()
} else { view
view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) }
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton) val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
confirmButton.setOnClickListener { confirmButton.setOnClickListener {
if (actionKey.isNotEmpty()) startService(IntentWearToMobile(this@AcceptActivity, actionKey)) if (actionKey.isNotEmpty()) startService(IntentWearToMobile(this@AcceptActivity, actionKey))
@ -88,8 +90,8 @@ class AcceptActivity : ViewSelectorActivity() {
finishAffinity() finishAffinity()
} }
container.addView(view) container.addView(view)
view
} }
return view
} }
override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) { override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) {

View file

@ -10,10 +10,12 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventWearToMobile import info.nightscout.androidaps.events.EventWearToMobile
import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter
import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.androidaps.interaction.utils.PlusMinusEditText
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.weardata.EventData.ActionBolusPreCheck import info.nightscout.shared.weardata.EventData.ActionBolusPreCheck
import java.text.DecimalFormat import java.text.DecimalFormat
import kotlin.math.roundToInt
class BolusActivity : ViewSelectorActivity() { class BolusActivity : ViewSelectorActivity() {
@ -33,18 +35,25 @@ class BolusActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = 2 override fun getColumnCount(arg0: Int): Int = 2
override fun getRowCount(): Int = 1 override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { val increment1 = (sp.getDouble(R.string.key_insulin_button_increment_1, 0.5) * 10).roundToInt() / 10.0
val view: View val increment2 = (sp.getDouble(R.string.key_insulin_button_increment_2, 1.0) * 10).roundToInt() / 10.0
if (col == 0) { val stepValues = listOf(0.1, increment1, increment2)
view = getInflatedPlusMinusView(container)
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) {
0 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true)
val initValue = if (editInsulin != null) SafeParse.stringToDouble(editInsulin?.editText?.text.toString()) else 0.0 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) 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 title = getString(R.string.action_insulin)
setLabelToPlusMinusView(view, getString(R.string.action_insulin)) editInsulin = PlusMinusEditText(viewAdapter, initValue, 0.0, maxBolus, stepValues, DecimalFormat("#0.0"), false, title)
val view = viewAdapter.root
container.addView(view) container.addView(view)
view.requestFocus() view.requestFocus()
} else { view
view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) }
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton) val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
confirmButton.setOnClickListener { confirmButton.setOnClickListener {
rxBus.send(EventWearToMobile(ActionBolusPreCheck(SafeParse.stringToDouble(editInsulin?.editText?.text.toString()), 0))) rxBus.send(EventWearToMobile(ActionBolusPreCheck(SafeParse.stringToDouble(editInsulin?.editText?.text.toString()), 0)))
@ -52,8 +61,8 @@ class BolusActivity : ViewSelectorActivity() {
finishAffinity() finishAffinity()
} }
container.addView(view) container.addView(view)
view
} }
return view
} }
override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) { override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) {

View file

@ -10,6 +10,7 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventWearToMobile import info.nightscout.androidaps.events.EventWearToMobile
import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter
import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.androidaps.interaction.utils.PlusMinusEditText
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.weardata.EventData.ActionECarbsPreCheck import info.nightscout.shared.weardata.EventData.ActionECarbsPreCheck
@ -30,24 +31,30 @@ class CarbActivity : ViewSelectorActivity() {
private inner class MyGridViewPagerAdapter : GridPagerAdapter() { 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()
val stepValues = listOf(1.0, increment1, increment2)
override fun getColumnCount(arg0: Int): Int = 2 override fun getColumnCount(arg0: Int): Int = 2
override fun getRowCount(): Int = 1 override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) {
val view: View 0 -> {
if (col == 0) { val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true)
view = getInflatedPlusMinusView(container) val view = viewAdapter.root
var def = 0.0 var def = 0.0
if (editCarbs != null) { if (editCarbs != null) {
def = SafeParse.stringToDouble(editCarbs?.editText?.text.toString()) def = SafeParse.stringToDouble(editCarbs?.editText?.text.toString())
} }
val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) 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) editCarbs = PlusMinusEditText(viewAdapter, def, 0.0, maxCarbs.toDouble(), stepValues, DecimalFormat("0"), true, getString(R.string.action_carbs))
setLabelToPlusMinusView(view, getString(R.string.action_carbs))
container.addView(view) container.addView(view)
view.requestFocus() view.requestFocus()
} else { view
view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) }
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton) val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
confirmButton.setOnClickListener { confirmButton.setOnClickListener {
// With start time 0 and duration 0 // With start time 0 and duration 0
@ -57,8 +64,8 @@ class CarbActivity : ViewSelectorActivity() {
finishAffinity() finishAffinity()
} }
container.addView(view) container.addView(view)
view
} }
return view
} }
override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) { override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) {

View file

@ -10,6 +10,7 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventWearToMobile import info.nightscout.androidaps.events.EventWearToMobile
import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter
import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.androidaps.interaction.utils.PlusMinusEditText
import info.nightscout.shared.SafeParse.stringToDouble import info.nightscout.shared.SafeParse.stringToDouble
import info.nightscout.shared.SafeParse.stringToInt import info.nightscout.shared.SafeParse.stringToInt
@ -36,44 +37,53 @@ class ECarbActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = 4 override fun getColumnCount(arg0: Int): Int = 4
override fun getRowCount(): Int = 1 override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble()
return if (col == 0) { val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble()
val view = getInflatedPlusMinusView(container) val stepValues = listOf(1.0, increment1, increment2)
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) {
0 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true)
val view = viewAdapter.root
var def = 0.0 var def = 0.0
if (editCarbs != null) { if (editCarbs != null) {
def = stringToDouble(editCarbs?.editText?.text.toString()) def = stringToDouble(editCarbs?.editText?.text.toString())
} }
val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) 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) editCarbs = PlusMinusEditText(viewAdapter, def, 0.0, maxCarbs.toDouble(), stepValues, DecimalFormat("0"), true, getString(R.string.action_carbs))
setLabelToPlusMinusView(view, getString(R.string.action_carbs))
container.addView(view) container.addView(view)
view.requestFocus() view.requestFocus()
view view
} else if (col == 1) { }
val view = getInflatedPlusMinusView(container)
1 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
var def = 0.0 var def = 0.0
if (editStartTime != null) { if (editStartTime != null) {
def = stringToDouble(editStartTime?.editText?.text.toString()) def = stringToDouble(editStartTime?.editText?.text.toString())
} }
editStartTime = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, -60.0, 300.0, 15.0, DecimalFormat("0"), false) editStartTime = PlusMinusEditText(viewAdapter, 15.0, def, -60.0, 300.0, DecimalFormat("0"), false, getString(R.string.action_start_min))
setLabelToPlusMinusView(view, getString(R.string.action_start_min))
container.addView(view) container.addView(view)
view view
} else if (col == 2) { }
val view = getInflatedPlusMinusView(container)
2 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
var def = 0.0 var def = 0.0
if (editDuration != null) { if (editDuration != null) {
def = stringToDouble(editDuration?.editText?.text.toString()) def = stringToDouble(editDuration?.editText?.text.toString())
} }
editDuration = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, 8.0, 1.0, DecimalFormat("0"), false) editDuration = PlusMinusEditText(viewAdapter, 1.0, def, 0.0, 8.0, DecimalFormat("0"), false, getString(R.string.action_duration_h))
setLabelToPlusMinusView(view, getString(R.string.action_duration_h))
container.addView(view) container.addView(view)
view view
} else { }
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton) val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
confirmButton.setOnClickListener { confirmButton.setOnClickListener {
// check if it can happen that the fragment is never created that hold data? // check if it can happen that the fragment is never created that hold data?
// (you have to swipe past them anyways - but still) // (you have to swipe past them anyways - but still)
val bolus = ActionECarbsPreCheck( val bolus = ActionECarbsPreCheck(

View file

@ -10,6 +10,7 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventWearToMobile import info.nightscout.androidaps.events.EventWearToMobile
import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter
import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.androidaps.interaction.utils.PlusMinusEditText
import info.nightscout.shared.SafeParse.stringToDouble import info.nightscout.shared.SafeParse.stringToDouble
import info.nightscout.shared.weardata.EventData.ActionFillPreCheck import info.nightscout.shared.weardata.EventData.ActionFillPreCheck
@ -33,19 +34,21 @@ class FillActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = 2 override fun getColumnCount(arg0: Int): Int = 2
override fun getRowCount(): Int = 1 override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) {
return if (col == 0) { 0 -> {
val view = getInflatedPlusMinusView(container) val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
var def = 0.0 var def = 0.0
if (editInsulin != null) { if (editInsulin != null) {
def = stringToDouble(editInsulin?.editText?.text.toString()) def = stringToDouble(editInsulin?.editText?.text.toString())
} }
editInsulin = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, 30.0, 0.1, DecimalFormat("#0.0"), false) editInsulin = PlusMinusEditText(viewAdapter, def, 0.0, 30.0, 0.1, DecimalFormat("#0.0"), false, getString(R.string.action_insulin))
setLabelToPlusMinusView(view, getString(R.string.action_insulin))
container.addView(view) container.addView(view)
view.requestFocus() view.requestFocus()
view view
} else { }
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton) val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
confirmButton.setOnClickListener { confirmButton.setOnClickListener {

View file

@ -10,6 +10,7 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventWearToMobile import info.nightscout.androidaps.events.EventWearToMobile
import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter
import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.androidaps.interaction.utils.PlusMinusEditText
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.weardata.EventData.ActionProfileSwitchPreCheck import info.nightscout.shared.weardata.EventData.ActionProfileSwitchPreCheck
@ -43,29 +44,34 @@ class ProfileSwitchActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = 3 override fun getColumnCount(arg0: Int): Int = 3
override fun getRowCount(): Int = 1 override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) {
return if (col == 0) { 0 -> {
val view = getInflatedPlusMinusView(container) val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
var def = timeshift.toDouble() var def = timeshift.toDouble()
if (editTimeshift != null) { if (editTimeshift != null) {
def = SafeParse.stringToDouble(editTimeshift?.editText?.text.toString()) def = SafeParse.stringToDouble(editTimeshift?.editText?.text.toString())
} }
editTimeshift = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, 23.0, 1.0, DecimalFormat("0"), true, true) editTimeshift = PlusMinusEditText(viewAdapter, def, 0.0, 23.0, 1.0, DecimalFormat("0"), true, getString(R.string.action_timeshift), true)
setLabelToPlusMinusView(view, getString(R.string.action_timeshift))
container.addView(view) container.addView(view)
view.requestFocus() view.requestFocus()
view view
} else if (col == 1) { }
val view = getInflatedPlusMinusView(container)
1 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
var def = percentage.toDouble() var def = percentage.toDouble()
if (editPercentage != null) { if (editPercentage != null) {
def = SafeParse.stringToDouble(editPercentage?.editText?.text.toString()) def = SafeParse.stringToDouble(editPercentage?.editText?.text.toString())
} }
editPercentage = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 30.0, 250.0, 1.0, DecimalFormat("0"), false) editPercentage = PlusMinusEditText(viewAdapter, def, 30.0, 250.0, 1.0, DecimalFormat("0"), false, getString(R.string.action_percentage))
setLabelToPlusMinusView(view, getString(R.string.action_percentage))
container.addView(view) container.addView(view)
view view
} else { }
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton) val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
confirmButton.setOnClickListener { confirmButton.setOnClickListener {

View file

@ -10,6 +10,7 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventWearToMobile import info.nightscout.androidaps.events.EventWearToMobile
import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter
import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.androidaps.interaction.utils.PlusMinusEditText
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.weardata.EventData.ActionTempTargetPreCheck import info.nightscout.shared.weardata.EventData.ActionTempTargetPreCheck
@ -45,49 +46,55 @@ class TempTargetActivity : ViewSelectorActivity() {
return 1 return 1
} }
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when {
return if (col == 0) { col == 0 -> {
val view = getInflatedPlusMinusView(container) val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
time = if (time == null) { time = if (time == null) {
PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, 60.0, 0.0, 24 * 60.0, 5.0, DecimalFormat("0"), false) PlusMinusEditText(viewAdapter, 60.0, 0.0, 24 * 60.0, 5.0, DecimalFormat("0"), false, getString(R.string.action_duration))
} else { } else {
val def = SafeParse.stringToDouble(time?.editText?.text.toString()) val def = SafeParse.stringToDouble(time?.editText?.text.toString())
PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, 24 * 60.0, 5.0, DecimalFormat("0"), false) PlusMinusEditText(viewAdapter, def, 0.0, 24 * 60.0, 5.0, DecimalFormat("0"), false, getString(R.string.action_duration))
} }
setLabelToPlusMinusView(view, getString(R.string.action_duration))
container.addView(view) container.addView(view)
view.requestFocus() view.requestFocus()
view view
} else if (col == 1) { }
val view = getInflatedPlusMinusView(container)
col == 1 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
val title = if (isSingleTarget) getString(R.string.action_target) else getString(R.string.action_low)
if (isMGDL) { if (isMGDL) {
var def = 100.0 var def = 100.0
if (lowRange != null) def = SafeParse.stringToDouble(lowRange?.editText?.text.toString()) if (lowRange != null) def = SafeParse.stringToDouble(lowRange?.editText?.text.toString())
lowRange = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 72.0, 180.0, 1.0, DecimalFormat("0"), false) lowRange = PlusMinusEditText(viewAdapter, def, 72.0, 180.0, 1.0, DecimalFormat("0"), false, title)
} else { } else {
var def = 5.5 var def = 5.5
if (lowRange != null) def = SafeParse.stringToDouble(lowRange?.editText?.text.toString()) if (lowRange != null) def = SafeParse.stringToDouble(lowRange?.editText?.text.toString())
lowRange = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 4.0, 10.0, 0.1, DecimalFormat("#0.0"), false) lowRange = PlusMinusEditText(viewAdapter, def, 4.0, 10.0, 0.1, DecimalFormat("#0.0"), false, title)
} }
if (isSingleTarget) setLabelToPlusMinusView(view, getString(R.string.action_target))
else setLabelToPlusMinusView(view, getString(R.string.action_low))
container.addView(view) container.addView(view)
view view
} else if (col == 2 && !isSingleTarget) { }
val view = getInflatedPlusMinusView(container)
col == 2 && !isSingleTarget -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
if (isMGDL) { if (isMGDL) {
var def = 100.0 var def = 100.0
if (highRange != null) def = SafeParse.stringToDouble(highRange?.editText?.text.toString()) if (highRange != null) def = SafeParse.stringToDouble(highRange?.editText?.text.toString())
highRange = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 72.0, 180.0, 1.0, DecimalFormat("0"), false) highRange = PlusMinusEditText(viewAdapter, def, 72.0, 180.0, 1.0, DecimalFormat("0"), false, getString(R.string.action_high))
} else { } else {
var def = 5.5 var def = 5.5
if (highRange != null) def = SafeParse.stringToDouble(highRange?.editText?.text.toString()) if (highRange != null) def = SafeParse.stringToDouble(highRange?.editText?.text.toString())
highRange = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 4.0, 10.0, 0.1, DecimalFormat("#0.0"), false) highRange = PlusMinusEditText(viewAdapter, def, 4.0, 10.0, 0.1, DecimalFormat("#0.0"), false, getString(R.string.action_high))
} }
setLabelToPlusMinusView(view, getString(R.string.action_high))
container.addView(view) container.addView(view)
view view
} else { }
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton) val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
confirmButton.setOnClickListener { confirmButton.setOnClickListener {

View file

@ -10,11 +10,13 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventWearToMobile import info.nightscout.androidaps.events.EventWearToMobile
import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter
import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.androidaps.interaction.utils.PlusMinusEditText
import info.nightscout.shared.SafeParse.stringToDouble import info.nightscout.shared.SafeParse.stringToDouble
import info.nightscout.shared.SafeParse.stringToInt import info.nightscout.shared.SafeParse.stringToInt
import info.nightscout.shared.weardata.EventData.ActionBolusPreCheck import info.nightscout.shared.weardata.EventData.ActionBolusPreCheck
import java.text.DecimalFormat import java.text.DecimalFormat
import kotlin.math.roundToInt
class TreatmentActivity : ViewSelectorActivity() { class TreatmentActivity : ViewSelectorActivity() {
@ -35,27 +37,39 @@ class TreatmentActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = 3 override fun getColumnCount(arg0: Int): Int = 3
override fun getRowCount(): Int = 1 override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { val incrementInsulin1 = (sp.getDouble(R.string.key_insulin_button_increment_1, 0.5) * 10).roundToInt() / 10.0
return if (col == 0) { val incrementInsulin2 = (sp.getDouble(R.string.key_insulin_button_increment_2, 1.0) * 10).roundToInt() / 10.0
val view = getInflatedPlusMinusView(container) val stepValuesInsulin = listOf(0.1, incrementInsulin1, incrementInsulin2)
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()
val stepValuesCarbs = listOf(1.0, incrementCarbs1, incrementCarbs2)
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) {
0 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true)
val view = viewAdapter.root
var def = 0.0 var def = 0.0
if (editInsulin != null) def = stringToDouble(editInsulin?.editText?.text.toString()) if (editInsulin != null) def = stringToDouble(editInsulin?.editText?.text.toString())
val maxBolus = sp.getDouble(getString(R.string.key_treatments_safety_max_bolus), 3.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, def, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) editInsulin = PlusMinusEditText(viewAdapter, def, 0.0, maxBolus, stepValuesInsulin, DecimalFormat("#0.0"), false, getString(R.string.action_insulin))
setLabelToPlusMinusView(view, getString(R.string.action_insulin))
container.addView(view) container.addView(view)
view.requestFocus() view.requestFocus()
view view
} else if (col == 1) { }
val view = getInflatedPlusMinusView(container)
1 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true)
val view = viewAdapter.root
var def = 0.0 var def = 0.0
val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48)
if (editCarbs != null) def = stringToDouble(editCarbs?.editText?.text.toString()) 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)
setLabelToPlusMinusView(view, getString(R.string.action_carbs)) editCarbs = PlusMinusEditText(viewAdapter, def, 0.0, maxCarbs.toDouble(), stepValuesCarbs, DecimalFormat("0"), false, getString(R.string.action_carbs))
container.addView(view) container.addView(view)
view view
} else { }
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton) val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
confirmButton.setOnClickListener { confirmButton.setOnClickListener {

View file

@ -73,19 +73,6 @@ 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)
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<TextView>(R.id.label)
textView.text = labelText
}
fun showToast(context: Context?, text: Int) { fun showToast(context: Context?, text: Int) {
Toast.makeText(context, getString(text), Toast.LENGTH_LONG).show() Toast.makeText(context, getString(text), Toast.LENGTH_LONG).show()
} }

View file

@ -10,6 +10,7 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventWearToMobile import info.nightscout.androidaps.events.EventWearToMobile
import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter
import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.androidaps.interaction.utils.PlusMinusEditText
import info.nightscout.shared.SafeParse import info.nightscout.shared.SafeParse
import info.nightscout.shared.weardata.EventData.ActionWizardPreCheck import info.nightscout.shared.weardata.EventData.ActionWizardPreCheck
@ -35,34 +36,41 @@ class WizardActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = if (hasPercentage) 3 else 2 override fun getColumnCount(arg0: Int): Int = if (hasPercentage) 3 else 2
override fun getRowCount(): Int = 1 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()
val stepValues = listOf(1.0, increment1, increment2)
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when {
return if (col == 0) { col == 0 -> {
val view = getInflatedPlusMinusView(container) val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true)
val view = viewAdapter.root
val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48)
editCarbs = if (editCarbs == null) { 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(viewAdapter, 0.0, 0.0, maxCarbs.toDouble(), stepValues, DecimalFormat("0"), false, getString(R.string.action_carbs))
} else { } else {
val def = SafeParse.stringToDouble(editCarbs?.editText?.text.toString()) 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(viewAdapter, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, getString(R.string.action_carbs))
} }
setLabelToPlusMinusView(view, getString(R.string.action_carbs))
container.addView(view) container.addView(view)
view.requestFocus() view.requestFocus()
view view
} else if (col == 1 && hasPercentage) { }
val view = getInflatedPlusMinusView(container)
col == 1 && hasPercentage -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
val percentage = sp.getInt(getString(R.string.key_bolus_wizard_percentage), 100) val percentage = sp.getInt(getString(R.string.key_bolus_wizard_percentage), 100)
editPercentage = if (editPercentage == null) { editPercentage = if (editPercentage == null) {
PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, percentage.toDouble(), 50.0, 150.0, 1.0, DecimalFormat("0"), false) PlusMinusEditText(viewAdapter, percentage.toDouble(), 50.0, 150.0, 1.0, DecimalFormat("0"), false, getString(R.string.action_percentage))
} else { } else {
val def = SafeParse.stringToDouble(editPercentage?.editText?.text.toString()) val def = SafeParse.stringToDouble(editPercentage?.editText?.text.toString())
PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 50.0, 150.0, 1.0, DecimalFormat("0"), false) PlusMinusEditText(viewAdapter, def, 50.0, 150.0, 1.0, DecimalFormat("0"), false, getString(R.string.action_percentage))
} }
setLabelToPlusMinusView(view, getString(R.string.action_percentage))
container.addView(view) container.addView(view)
view view
} else { }
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
view.findViewById<ImageView>(R.id.confirmbutton) view.findViewById<ImageView>(R.id.confirmbutton)
.setOnClickListener { .setOnClickListener {

View file

@ -0,0 +1,97 @@
package info.nightscout.androidaps.interaction.utils
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import info.nightscout.androidaps.R
import info.nightscout.androidaps.databinding.ActionEditplusminBinding
import info.nightscout.androidaps.databinding.ActionEditplusminMultiBinding
import info.nightscout.androidaps.databinding.ActionEditplusminQuickleftyMultiBinding
import info.nightscout.androidaps.databinding.ActionEditplusminQuickleftyBinding
import info.nightscout.androidaps.databinding.ActionEditplusminQuickrightyBinding
import info.nightscout.androidaps.databinding.ActionEditplusminQuickrightyMultiBinding
import info.nightscout.androidaps.databinding.ActionEditplusminViktoriaBinding
import info.nightscout.shared.sharedPreferences.SP
/**
* EditPlusMinusViewAdapter binds both ActionEditplusminBinding variants 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(
eD: ActionEditplusminBinding?,
eDP: ActionEditplusminMultiBinding?,
eQL: ActionEditplusminQuickleftyBinding?,
eQLP: ActionEditplusminQuickleftyMultiBinding?,
eQR: ActionEditplusminQuickrightyBinding?,
eQRP: ActionEditplusminQuickrightyMultiBinding?,
eV: ActionEditplusminViktoriaBinding?
) {
init {
if (eD == null && eDP == null && eQL == null && eQLP == null && eQR == null && eQRP == null && eV == null) {
throw IllegalArgumentException("Require at least on Binding parameter")
}
}
private val errorMessage = "Missing require View Binding parameter"
val editText =
eD?.editText ?: eDP?.editText ?: eQL?.editText ?: eQLP?.editText ?: eQR?.editText ?: eQRP?.editText ?: eV?.editText
?: throw IllegalArgumentException(errorMessage)
val minButton =
eD?.minButton ?: eDP?.minButton ?: eQL?.minButton ?: eQLP?.minButton ?: eQR?.minButton ?: eQRP?.minButton ?: eV?.minButton
?: throw IllegalArgumentException(errorMessage)
val plusButton1 =
eD?.plusButton1 ?: eDP?.plusButton1 ?: eQL?.plusButton1 ?: eQLP?.plusButton1 ?: eQR?.plusButton1 ?: eQRP?.plusButton1 ?: eV?.plusButton1
?: throw IllegalArgumentException(errorMessage)
val label =
eD?.label ?: eDP?.label ?: eQL?.label ?: eQLP?.label ?: eQR?.label ?: eQRP?.label ?: eV?.label
?: throw IllegalArgumentException(errorMessage)
val plusButton2 = eDP?.plusButton2 ?: eQLP?.plusButton2 ?: eQRP?.plusButton2
val plusButton3 = eDP?.plusButton3 ?: eQLP?.plusButton3 ?: eQRP?.plusButton3
val root =
eD?.root ?: eDP?.root ?: eQL?.root ?: eQLP?.root ?: eQR?.root ?: eQRP?.root ?: eV?.root
?: throw IllegalArgumentException(errorMessage)
companion object {
fun getViewAdapter(sp: SP, context: Context, container: ViewGroup, multiple: Boolean = false): EditPlusMinusViewAdapter {
val inflater = LayoutInflater.from(context)
return when (sp.getInt(R.string.key_input_design, 1)) {
2 -> {
if (multiple) {
val bindLayout = ActionEditplusminQuickrightyMultiBinding.inflate(inflater, container, false)
EditPlusMinusViewAdapter(null, null, null, null, null, bindLayout, null)
} else {
val bindLayout = ActionEditplusminQuickrightyBinding.inflate(inflater, container, false)
EditPlusMinusViewAdapter(null, null, null, null, bindLayout, null, null)
}
}
3 -> {
if (multiple) {
val bindLayout = ActionEditplusminQuickleftyMultiBinding.inflate(inflater, container, false)
EditPlusMinusViewAdapter(null, null, null, bindLayout, null, null, null)
} else {
val bindLayout = ActionEditplusminQuickleftyBinding.inflate(inflater, container, false)
EditPlusMinusViewAdapter(null, null, bindLayout, null, null, null, null)
}
}
4 -> {
val bindLayout = ActionEditplusminViktoriaBinding.inflate(inflater, container, false)
EditPlusMinusViewAdapter(null, null, null, null, null, null, bindLayout)
}
else -> {
if (multiple) {
val bindLayout = ActionEditplusminMultiBinding.inflate(inflater, container, false)
EditPlusMinusViewAdapter(null, bindLayout, null, null, null, null, null)
} else {
val bindLayout = ActionEditplusminBinding.inflate(inflater, container, false)
EditPlusMinusViewAdapter(bindLayout, null, null, null, null, null, null)
}
}
}
}
}
}

View file

@ -1,18 +1,16 @@
package info.nightscout.androidaps.interaction.utils package info.nightscout.androidaps.interaction.utils
import android.os.Handler import android.content.Context
import kotlin.jvm.JvmOverloads import android.os.*
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.view.KeyEvent import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View import android.view.View
import android.widget.ImageView import android.view.View.OnGenericMotionListener
import android.view.View.OnTouchListener
import android.widget.TextView
import androidx.core.view.InputDeviceCompat import androidx.core.view.InputDeviceCompat
import androidx.core.view.MotionEventCompat import androidx.core.view.MotionEventCompat
import java.text.DecimalFormat
import java.text.NumberFormat import java.text.NumberFormat
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.ScheduledExecutorService
@ -22,46 +20,52 @@ import java.util.concurrent.TimeUnit
* Created by mike on 28.06.2016. * Created by mike on 28.06.2016.
*/ */
class PlusMinusEditText @JvmOverloads constructor( class PlusMinusEditText @JvmOverloads constructor(
view: View, private val binding: EditPlusMinusViewAdapter,
editTextID: Int, initValue: Double,
plusID: Int, private val minValue: Double,
minusID: Int, private val maxValue: Double,
private val stepValues: List<Double>,
private val formatter: NumberFormat,
private val allowZero: Boolean,
label: String,
private val roundRobin: Boolean = false,
) : View.OnKeyListener, OnTouchListener, View.OnClickListener, OnGenericMotionListener {
constructor(
binding: EditPlusMinusViewAdapter,
initValue: Double, initValue: Double,
minValue: Double, minValue: Double,
maxValue: Double, maxValue: Double,
step: Double, step: Double,
formatter: NumberFormat, formatter: NumberFormat,
allowZero: Boolean, allowZero: Boolean,
label: String,
roundRobin: Boolean = false roundRobin: Boolean = false
) : View.OnKeyListener, OnTouchListener, View.OnClickListener, OnGenericMotionListener { ) : this(binding, initValue, minValue, maxValue, listOf(step), formatter, allowZero, label, roundRobin)
private val stepGeneral: Double = stepValues[0]
var editText: TextView var editText: TextView
private set private set
private var minusImage: ImageView
private var plusImage: ImageView
private var value: Double 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 var mChangeCounter = 0 private var mChangeCounter = 0
private var mLastChange: Long = 0 private var mLastChange: Long = 0
private val mHandler: Handler private val mHandler: Handler
private var mUpdater: ScheduledExecutorService? = null 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 repeated = 0
private var multiplier = 1 private var multiplier = 1
override fun run() { override fun run() {
val msg = Message() val msg = Message()
val doubleLimit = 5 val doubleLimit = 5
if (repeated % doubleLimit == 0) multiplier *= 2 val multipleButtons = mInc && (binding.plusButton2 != null || binding.plusButton3 != null)
repeated++ if (!multipleButtons && repeated % doubleLimit == 0) multiplier *= 2
msg.arg1 = multiplier val bundle = Bundle()
msg.arg2 = repeated bundle.putDouble(STEP, step)
bundle.putInt(MULTIPLIER, multiplier)
msg.data = bundle
if (mInc) { if (mInc) {
msg.what = MSG_INC msg.what = MSG_INC
} else { } else {
@ -71,7 +75,7 @@ class PlusMinusEditText @JvmOverloads constructor(
} }
} }
private fun inc(multiplier: Int) { private fun inc(multiplier: Int, step: Double, vibrate: Boolean = true) {
value += step * multiplier value += step * multiplier
if (value > maxValue) { if (value > maxValue) {
if (roundRobin) { if (roundRobin) {
@ -82,9 +86,10 @@ class PlusMinusEditText @JvmOverloads constructor(
} }
} }
updateEditText() updateEditText()
if (vibrate) vibrateDevice()
} }
private fun dec(multiplier: Int) { private fun dec(multiplier: Int, step: Double, vibrate: Boolean = true) {
value -= step * multiplier value -= step * multiplier
if (value < minValue) { if (value < minValue) {
if (roundRobin) { if (roundRobin) {
@ -95,20 +100,37 @@ class PlusMinusEditText @JvmOverloads constructor(
} }
} }
updateEditText() updateEditText()
if (vibrate) vibrateDevice()
}
private fun vibrateDevice() {
val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
(binding.root.context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager).defaultVibrator
} else {
@Suppress("DEPRECATION")
binding.root.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() { private fun updateEditText() {
if (value == 0.0 && !allowZero) editText.text = "" else editText.text = formatter.format(value) 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) { if (mUpdater != null) {
return return
} }
mUpdater = Executors.newSingleThreadScheduledExecutor() mUpdater = Executors.newSingleThreadScheduledExecutor()
mUpdater?.scheduleAtFixedRate( mUpdater?.scheduleAtFixedRate(
UpdateCounterTask(inc), 200, 200, UpdateCounterTask(inc, step), 200, 200,
TimeUnit.MILLISECONDS TimeUnit.MILLISECONDS
) )
} }
@ -118,12 +140,30 @@ class PlusMinusEditText @JvmOverloads constructor(
mUpdater = null mUpdater = null
} }
private fun getStep(v: View): Double {
return when (v) {
binding.plusButton1 -> stepValues[0]
binding.plusButton2 -> stepValues[1]
binding.plusButton3 -> stepValues[2]
else -> stepValues[0]
}
}
private fun isIncrement(v: View): Boolean {
return when (v) {
binding.plusButton1 -> true
binding.plusButton2 -> true
binding.plusButton3 -> true
else -> false
}
}
override fun onClick(v: View) { override fun onClick(v: View) {
if (mUpdater == null) { if (mUpdater == null) {
if (v === plusImage) { if (isIncrement(v)) {
inc(1) inc(1, getStep(v))
} else { } else {
dec(1) dec(1, getStep(v))
} }
} }
} }
@ -135,7 +175,7 @@ class PlusMinusEditText @JvmOverloads constructor(
if (isKeyOfInterest && isReleased) { if (isKeyOfInterest && isReleased) {
stopUpdating() stopUpdating()
} else if (isKeyOfInterest && isPressed) { } else if (isKeyOfInterest && isPressed) {
startUpdating(v === plusImage) startUpdating(isIncrement(v), stepGeneral)
} }
return false return false
} }
@ -146,7 +186,7 @@ class PlusMinusEditText @JvmOverloads constructor(
if (isReleased) { if (isReleased) {
stopUpdating() stopUpdating()
} else if (isPressed) { } else if (isPressed) {
startUpdating(v === plusImage) startUpdating(isIncrement(v), getStep(v))
} }
return false return false
} }
@ -158,9 +198,9 @@ class PlusMinusEditText @JvmOverloads constructor(
val dynamicMultiplier = if (mChangeCounter < THRESHOLD_COUNTER) 1 else if (mChangeCounter < THRESHOLD_COUNTER_LONG) 2 else 4 val dynamicMultiplier = if (mChangeCounter < THRESHOLD_COUNTER) 1 else if (mChangeCounter < THRESHOLD_COUNTER_LONG) 2 else 4
val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL)
if (delta > 0) { if (delta > 0) {
inc(dynamicMultiplier) inc(dynamicMultiplier, stepGeneral, false)
} else { } else {
dec(dynamicMultiplier) dec(dynamicMultiplier, stepGeneral, false)
} }
mLastChange = System.currentTimeMillis() mLastChange = System.currentTimeMillis()
mChangeCounter++ mChangeCounter++
@ -176,42 +216,54 @@ class PlusMinusEditText @JvmOverloads constructor(
private const val THRESHOLD_TIME = 100 private const val THRESHOLD_TIME = 100
private const val MSG_INC = 0 private const val MSG_INC = 0
private const val MSG_DEC = 1 private const val MSG_DEC = 1
private const val STEP = "step"
private const val MULTIPLIER = "multiplier"
} }
init { init {
editText = view.findViewById(editTextID) editText = binding.editText
minusImage = view.findViewById(minusID) binding.label.text = label
plusImage = view.findViewById(plusID) val format = DecimalFormat("#.#")
binding.plusButton2?.text = "+${format.format(stepValues[1]).replaceFirst("^0+(?!$)".toRegex(), "")}"
binding.plusButton3?.text = "+${format.format(stepValues[2]).replaceFirst("^0+(?!$)".toRegex(), "")}"
value = initValue 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()) { mHandler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) { override fun handleMessage(msg: Message) {
val multiplier = msg.data.getInt(MULTIPLIER)
val step = msg.data.getDouble(STEP)
when (msg.what) { when (msg.what) {
MSG_INC -> { MSG_INC -> {
inc(msg.arg1) inc(multiplier, step)
return return
} }
MSG_DEC -> { MSG_DEC -> {
dec(msg.arg1) dec(multiplier, step)
return return
} }
} }
super.handleMessage(msg) super.handleMessage(msg)
} }
} }
minusImage.setOnTouchListener(this)
minusImage.setOnKeyListener(this) editText.showSoftInputOnFocus = false
minusImage.setOnClickListener(this) editText.setTextIsSelectable(false)
plusImage.setOnTouchListener(this) binding.minButton.setOnTouchListener(this)
plusImage.setOnKeyListener(this) binding.minButton.setOnKeyListener(this)
plusImage.setOnClickListener(this) binding.minButton.setOnClickListener(this)
binding.plusButton1.setOnTouchListener(this)
binding.plusButton1.setOnKeyListener(this)
binding.plusButton1.setOnClickListener(this)
binding.plusButton2?.setOnTouchListener(this)
binding.plusButton2?.setOnKeyListener(this)
binding.plusButton2?.setOnClickListener(this)
binding.plusButton3?.setOnTouchListener(this)
binding.plusButton3?.setOnKeyListener(this)
binding.plusButton3?.setOnClickListener(this)
editText.setOnGenericMotionListener(this) editText.setOnGenericMotionListener(this)
updateEditText() updateEditText()
} }
} }

View file

@ -7,8 +7,8 @@
android:gravity="center" android:gravity="center"
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/minusbutton" android:id="@+id/min_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@ -25,7 +25,7 @@
android:orientation="vertical"> android:orientation="vertical">
<EditText <EditText
android:id="@+id/amountfield" android:id="@+id/edit_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@ -44,7 +44,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:gravity="center" android:gravity="center"
android:labelFor="@+id/amountfield" android:labelFor="@+id/edit_text"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="25sp" android:textSize="25sp"
@ -53,8 +53,8 @@
</LinearLayout> </LinearLayout>
<ImageView <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/plusbutton" android:id="@+id/plus_button1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@ -65,4 +65,3 @@
android:tint="@color/white" /> android:tint="@color/white" />
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/center"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/edit_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="-6dp"
android:cursorVisible="false"
android:gravity="center"
android:inputType="numberDecimal"
android:textColor="@color/white"
android:textSize="40sp"
app:layout_constraintEnd_toEndOf="@+id/value_background"
app:layout_constraintStart_toStartOf="@+id/value_background"
app:layout_constraintTop_toTopOf="@+id/value_background"
tools:text="123" />
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/edit_text"
android:layout_marginTop="-10dp"
android:gravity="center"
android:labelFor="@+id/edit_text"
android:textColor="@color/white"
android:textSize="25sp"
app:layout_constraintEnd_toEndOf="@+id/edit_text"
app:layout_constraintStart_toStartOf="@+id/edit_text"
app:layout_constraintTop_toBottomOf="@id/edit_text"
tools:ignore="LabelFor"
tools:text="label" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/min_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:contentDescription="@string/decrement"
android:src="@drawable/ic_action_minus"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="215"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintLeft_toLeftOf="parent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/plus_button3"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:gravity="center"
android:textColor="@color/white"
android:textSize="25sp"
android:visibility="visible"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="325"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="+10" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/plus_button2"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:gravity="center"
android:textColor="@color/white"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/plus_button1"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="35"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/plus_button3"
tools:text="+5" />
<View
android:id="@+id/value_background"
android:layout_width="108dp"
android:layout_height="108dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/plus_button1"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:contentDescription="@string/increment"
android:src="@drawable/ic_action_add"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="145"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -7,8 +7,15 @@
android:gravity="center" android:gravity="center"
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <LinearLayout
android:id="@+id/plusbutton" android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginEnd="-8dp"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/plus_button1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@ -18,6 +25,8 @@
android:src="@drawable/ic_action_add" android:src="@drawable/ic_action_add"
android:tint="@color/white" /> android:tint="@color/white" />
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -26,7 +35,7 @@
android:orientation="vertical"> android:orientation="vertical">
<EditText <EditText
android:id="@+id/amountfield" android:id="@+id/edit_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@ -45,15 +54,15 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:gravity="center" android:gravity="center"
android:labelFor="@+id/amountfield" android:labelFor="@+id/edit_text"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="25sp" android:textSize="25sp"
tools:ignore="LabelFor" tools:ignore="LabelFor"
tools:text="label" /> tools:text="label" />
<ImageView <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/minusbutton" android:id="@+id/min_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"

View file

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/center"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/edit_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="-5dp"
android:cursorVisible="false"
android:gravity="center"
android:inputType="numberDecimal"
android:textColor="@color/white"
android:textSize="40sp"
app:layout_constraintEnd_toEndOf="@+id/value_background"
app:layout_constraintStart_toStartOf="@+id/value_background"
app:layout_constraintTop_toTopOf="@+id/value_background"
tools:text="123" />
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/edit_text"
android:layout_marginTop="-9dp"
android:gravity="center"
android:labelFor="@+id/edit_text"
android:textColor="@color/white"
android:textSize="25sp"
app:layout_constraintEnd_toEndOf="@+id/edit_text"
app:layout_constraintStart_toStartOf="@+id/edit_text"
app:layout_constraintTop_toBottomOf="@id/edit_text"
tools:ignore="LabelFor"
tools:text="label" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/min_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:contentDescription="@string/decrement"
android:src="@drawable/ic_action_minus"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="145"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintLeft_toLeftOf="parent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/plus_button3"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:gravity="center"
android:textColor="@color/white"
android:textSize="25sp"
android:visibility="visible"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="325"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="+10" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/plus_button2"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:gravity="center"
android:textColor="@color/white"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/plus_button1"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="270"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/plus_button3"
tools:text="+5" />
<View
android:id="@+id/value_background"
android:layout_width="108dp"
android:layout_height="108dp"
app:layout_constraintBottom_toTopOf="@+id/min_button"
app:layout_constraintLeft_toLeftOf="@+id/min_button"
app:layout_constraintRight_toRightOf="@+id/min_button"/>
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/plus_button1"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:contentDescription="@string/increment"
android:src="@drawable/ic_action_add"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="215"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -15,7 +15,7 @@
android:orientation="vertical"> android:orientation="vertical">
<EditText <EditText
android:id="@+id/amountfield" android:id="@+id/edit_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@ -34,15 +34,15 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:gravity="center" android:gravity="center"
android:labelFor="@+id/amountfield" android:labelFor="@+id/edit_text"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="25sp" android:textSize="25sp"
tools:ignore="LabelFor" tools:ignore="LabelFor"
tools:text="label" /> tools:text="label" />
<ImageView <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/minusbutton" android:id="@+id/min_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@ -54,8 +54,16 @@
</LinearLayout> </LinearLayout>
<ImageView <LinearLayout
android:id="@+id/plusbutton" android:layout_width="70dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="-8dp"
android:orientation="vertical"
tools:visibility="visible">
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/plus_button1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
@ -66,3 +74,5 @@
android:tint="@color/white" /> android:tint="@color/white" />
</LinearLayout> </LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/center"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/edit_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="-5dp"
android:cursorVisible="false"
android:gravity="center"
android:inputType="numberDecimal"
android:textColor="@color/white"
android:textSize="40sp"
app:layout_constraintEnd_toEndOf="@+id/value_background"
app:layout_constraintStart_toStartOf="@+id/value_background"
app:layout_constraintTop_toTopOf="@+id/value_background"
tools:text="123" />
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/edit_text"
android:layout_marginTop="-9dp"
android:gravity="center"
android:labelFor="@+id/edit_text"
android:textColor="@color/white"
android:textSize="25sp"
app:layout_constraintEnd_toEndOf="@+id/edit_text"
app:layout_constraintStart_toStartOf="@+id/edit_text"
app:layout_constraintTop_toBottomOf="@id/edit_text"
tools:ignore="LabelFor"
tools:text="label" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/min_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:contentDescription="@string/decrement"
android:src="@drawable/ic_action_minus"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="215"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintLeft_toLeftOf="parent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/plus_button3"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:gravity="center"
android:textColor="@color/white"
android:textSize="25sp"
android:visibility="visible"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="35"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="+10" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/plus_button2"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:gravity="center"
android:textColor="@color/white"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/plus_button1"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="90"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/plus_button3"
tools:text="+5" />
<View
android:id="@+id/value_background"
android:layout_width="108dp"
android:layout_height="108dp"
app:layout_constraintBottom_toTopOf="@+id/min_button"
app:layout_constraintRight_toRightOf="@id/min_button"
app:layout_constraintLeft_toLeftOf="@id/min_button"/>
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/plus_button1"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:background="@drawable/circle"
android:backgroundTint="@color/white"
android:contentDescription="@string/increment"
android:src="@drawable/ic_action_add"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintCircle="@+id/center"
app:layout_constraintCircleAngle="145"
app:layout_constraintCircleRadius="70dp"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -11,13 +11,13 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="start|center_vertical" android:layout_gravity="start|center_vertical"
android:gravity="center" android:gravity="center"
android:labelFor="@+id/amountfield" android:labelFor="@+id/edit_text"
android:rotation="90" android:rotation="90"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="25sp" android:textSize="25sp"
tools:ignore="LabelFor" tools:ignore="LabelFor"
tools:text="labelx" /> tools:text="label" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -25,8 +25,8 @@
android:layout_gravity="start|center_vertical|center_horizontal" android:layout_gravity="start|center_vertical|center_horizontal"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/plusbutton" android:id="@+id/plus_button1"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal" android:layout_gravity="center_vertical|center_horizontal"
@ -36,7 +36,7 @@
android:tint="@color/white" /> android:tint="@color/white" />
<EditText <EditText
android:id="@+id/amountfield" android:id="@+id/edit_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="center_vertical|center_horizontal" android:layout_gravity="center_vertical|center_horizontal"
@ -50,8 +50,8 @@
android:textSize="45sp" android:textSize="45sp"
tools:text="112" /> tools:text="112" />
<ImageView <androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/minusbutton" android:id="@+id/min_button"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal" android:layout_gravity="center_vertical|center_horizontal"
@ -63,5 +63,3 @@
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -206,6 +206,10 @@
<string name="key_dark" translatable="false">dark</string> <string name="key_dark" translatable="false">dark</string>
<string name="key_input_design" translatable="false">input_design</string> <string name="key_input_design" translatable="false">input_design</string>
<string name="key_complication_tap_action" translatable="false">complication_tap_action</string> <string name="key_complication_tap_action" translatable="false">complication_tap_action</string>
<string name="key_insulin_button_increment_1" translatable="false">insulin_button_increment_1</string>
<string name="key_insulin_button_increment_2" translatable="false">insulin_button_increment_2</string>
<string name="key_carbs_button_increment_1" translatable="false">carbs_button_increment_1</string>
<string name="key_carbs_button_increment_2" translatable="false">carbs_button_increment_2</string>
<string name="increment">increment</string> <string name="increment">increment</string>
<string name="decrement">decrement</string> <string name="decrement">decrement</string>
<string name="first_char_high">H</string> <string name="first_char_high">H</string>