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 {
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

View file

@ -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

View file

@ -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),
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)
)
)
)
@ -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
}
}
}

View file

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

View file

@ -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"

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_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.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
.toObservable(EventData.QuickWizard::class.java)
@ -284,4 +288,4 @@ class DataHandlerWear @Inject constructor(
NotificationManagerCompat.from(context).cancel(DataLayerListenerServiceWear.BOLUS_PROGRESS_NOTIF_ID)
}.start()
}
}
}

View file

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

View file

@ -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,18 +35,25 @@ class BolusActivity : ViewSelectorActivity() {
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)
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
val stepValues = listOf(0.1, increment1, increment2)
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 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)
setLabelToPlusMinusView(view, getString(R.string.action_insulin))
val title = 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)
view.requestFocus()
} else {
view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
view
}
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
confirmButton.setOnClickListener {
rxBus.send(EventWearToMobile(ActionBolusPreCheck(SafeParse.stringToDouble(editInsulin?.editText?.text.toString()), 0)))
@ -52,8 +61,8 @@ class BolusActivity : ViewSelectorActivity() {
finishAffinity()
}
container.addView(view)
view
}
return view
}
override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) {
@ -62,4 +71,4 @@ class BolusActivity : ViewSelectorActivity() {
override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object`
}
}
}

View file

@ -10,6 +10,7 @@ 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.ActionECarbsPreCheck
@ -30,24 +31,30 @@ 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()
val stepValues = listOf(1.0, increment1, increment2)
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)
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
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)
setLabelToPlusMinusView(view, getString(R.string.action_carbs))
editCarbs = PlusMinusEditText(viewAdapter, def, 0.0, maxCarbs.toDouble(), stepValues, DecimalFormat("0"), true, getString(R.string.action_carbs))
container.addView(view)
view.requestFocus()
} else {
view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
view
}
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
confirmButton.setOnClickListener {
// With start time 0 and duration 0
@ -57,8 +64,8 @@ class CarbActivity : ViewSelectorActivity() {
finishAffinity()
}
container.addView(view)
view
}
return view
}
override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) {
@ -69,4 +76,4 @@ class CarbActivity : ViewSelectorActivity() {
override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object`
}
}
}

View file

@ -10,6 +10,7 @@ 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.stringToDouble
import info.nightscout.shared.SafeParse.stringToInt
@ -36,45 +37,54 @@ class ECarbActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = 4
override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any {
return if (col == 0) {
val view = getInflatedPlusMinusView(container)
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 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
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)
setLabelToPlusMinusView(view, getString(R.string.action_carbs))
editCarbs = PlusMinusEditText(viewAdapter, def, 0.0, maxCarbs.toDouble(), stepValues, DecimalFormat("0"), true, getString(R.string.action_carbs))
container.addView(view)
view.requestFocus()
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
if (editStartTime != null) {
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)
setLabelToPlusMinusView(view, getString(R.string.action_start_min))
editStartTime = PlusMinusEditText(viewAdapter, 15.0, def, -60.0, 300.0, DecimalFormat("0"), false, getString(R.string.action_start_min))
container.addView(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
if (editDuration != null) {
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)
setLabelToPlusMinusView(view, getString(R.string.action_duration_h))
editDuration = PlusMinusEditText(viewAdapter, 1.0, def, 0.0, 8.0, DecimalFormat("0"), false, getString(R.string.action_duration_h))
container.addView(view)
view
} else {
}
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
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)
val bolus = ActionECarbsPreCheck(
stringToInt(editCarbs?.editText?.text.toString()),

View file

@ -10,6 +10,7 @@ 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.stringToDouble
import info.nightscout.shared.weardata.EventData.ActionFillPreCheck
@ -33,23 +34,25 @@ class FillActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = 2
override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any {
return if (col == 0) {
val view = getInflatedPlusMinusView(container)
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) {
0 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
var def = 0.0
if (editInsulin != null) {
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)
setLabelToPlusMinusView(view, getString(R.string.action_insulin))
editInsulin = PlusMinusEditText(viewAdapter, def, 0.0, 30.0, 0.1, DecimalFormat("#0.0"), false, getString(R.string.action_insulin))
container.addView(view)
view.requestFocus()
view
} else {
}
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
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)
rxBus.send(EventWearToMobile(ActionFillPreCheck(stringToDouble(editInsulin?.editText?.text.toString()))))
showToast(this@FillActivity, R.string.action_fill_confirmation)
@ -68,4 +71,4 @@ class FillActivity : ViewSelectorActivity() {
override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object`
}
}
}

View file

@ -10,6 +10,7 @@ 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.ActionProfileSwitchPreCheck
@ -43,33 +44,38 @@ class ProfileSwitchActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = 3
override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any {
return if (col == 0) {
val view = getInflatedPlusMinusView(container)
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) {
0 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
var def = timeshift.toDouble()
if (editTimeshift != null) {
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)
setLabelToPlusMinusView(view, getString(R.string.action_timeshift))
editTimeshift = PlusMinusEditText(viewAdapter, def, 0.0, 23.0, 1.0, DecimalFormat("0"), true, getString(R.string.action_timeshift), true)
container.addView(view)
view.requestFocus()
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()
if (editPercentage != null) {
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)
setLabelToPlusMinusView(view, getString(R.string.action_percentage))
editPercentage = PlusMinusEditText(viewAdapter, def, 30.0, 250.0, 1.0, DecimalFormat("0"), false, getString(R.string.action_percentage))
container.addView(view)
view
} else {
}
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
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)
val ps = ActionProfileSwitchPreCheck(SafeParse.stringToInt(editTimeshift?.editText?.text.toString()), SafeParse.stringToInt(editPercentage?.editText?.text.toString()))
rxBus.send(EventWearToMobile(ps))

View file

@ -10,6 +10,7 @@ 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.ActionTempTargetPreCheck
@ -45,53 +46,59 @@ class TempTargetActivity : ViewSelectorActivity() {
return 1
}
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any {
return if (col == 0) {
val view = getInflatedPlusMinusView(container)
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when {
col == 0 -> {
val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false)
val view = viewAdapter.root
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 {
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)
view.requestFocus()
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) {
var def = 100.0
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 {
var def = 5.5
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)
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) {
var def = 100.0
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 {
var def = 5.5
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)
view
} else {
}
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
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)
val action = ActionTempTargetPreCheck(
ActionTempTargetPreCheck.TempTargetCommand.MANUAL,
@ -119,4 +126,4 @@ class TempTargetActivity : ViewSelectorActivity() {
return view === `object`
}
}
}
}

View file

@ -10,11 +10,13 @@ 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.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,31 +37,43 @@ class TreatmentActivity : ViewSelectorActivity() {
override fun getColumnCount(arg0: Int): Int = 3
override fun getRowCount(): Int = 1
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any {
return if (col == 0) {
val view = getInflatedPlusMinusView(container)
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 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
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)
setLabelToPlusMinusView(view, getString(R.string.action_insulin))
editInsulin = PlusMinusEditText(viewAdapter, def, 0.0, maxBolus, stepValuesInsulin, DecimalFormat("#0.0"), false, getString(R.string.action_insulin))
container.addView(view)
view.requestFocus()
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
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)
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)
view
} else {
}
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
val confirmButton = view.findViewById<ImageView>(R.id.confirmbutton)
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)
val bolus = ActionBolusPreCheck(stringToDouble(editInsulin?.editText?.text.toString()), stringToInt(editCarbs?.editText?.text.toString()))
rxBus.send(EventWearToMobile(bolus))
@ -79,4 +93,4 @@ class TreatmentActivity : ViewSelectorActivity() {
override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object`
}
}
}

View file

@ -73,20 +73,7 @@ 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) {
Toast.makeText(context, getString(text), Toast.LENGTH_LONG).show()
}
}
}

View file

@ -10,6 +10,7 @@ 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.ActionWizardPreCheck
@ -35,34 +36,41 @@ 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()
val stepValues = listOf(1.0, increment1, increment2)
override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any {
return if (col == 0) {
val 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 view = viewAdapter.root
val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48)
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 {
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)
view.requestFocus()
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)
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 {
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)
view
} else {
}
else -> {
val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false)
view.findViewById<ImageView>(R.id.confirmbutton)
.setOnClickListener {
@ -84,4 +92,4 @@ class WizardActivity : ViewSelectorActivity() {
override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object`
}
}
}

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
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.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.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
@ -22,46 +20,52 @@ import java.util.concurrent.TimeUnit
* Created by mike on 28.06.2016.
*/
class PlusMinusEditText @JvmOverloads constructor(
view: View,
editTextID: Int,
plusID: Int,
minusID: Int,
private val binding: EditPlusMinusViewAdapter,
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 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,
minValue: Double,
maxValue: Double,
step: Double,
formatter: NumberFormat,
allowZero: Boolean,
label: String,
roundRobin: Boolean = false
) : this(binding, initValue, minValue, maxValue, listOf(step), formatter, allowZero, label, roundRobin)
private val stepGeneral: Double = stepValues[0]
var editText: TextView
private set
private var minusImage: ImageView
private var plusImage: ImageView
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 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 && (binding.plusButton2 != null || binding.plusButton3 != 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 +75,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 +86,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 +100,37 @@ class PlusMinusEditText @JvmOverloads constructor(
}
}
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() {
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 +140,30 @@ class PlusMinusEditText @JvmOverloads constructor(
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) {
if (mUpdater == null) {
if (v === plusImage) {
inc(1)
if (isIncrement(v)) {
inc(1, getStep(v))
} else {
dec(1)
dec(1, getStep(v))
}
}
}
@ -135,7 +175,7 @@ class PlusMinusEditText @JvmOverloads constructor(
if (isKeyOfInterest && isReleased) {
stopUpdating()
} else if (isKeyOfInterest && isPressed) {
startUpdating(v === plusImage)
startUpdating(isIncrement(v), stepGeneral)
}
return false
}
@ -146,7 +186,7 @@ class PlusMinusEditText @JvmOverloads constructor(
if (isReleased) {
stopUpdating()
} else if (isPressed) {
startUpdating(v === plusImage)
startUpdating(isIncrement(v), getStep(v))
}
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 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++
@ -176,42 +216,54 @@ class PlusMinusEditText @JvmOverloads constructor(
private const val THRESHOLD_TIME = 100
private const val MSG_INC = 0
private const val MSG_DEC = 1
private const val STEP = "step"
private const val MULTIPLIER = "multiplier"
}
init {
editText = view.findViewById(editTextID)
minusImage = view.findViewById(minusID)
plusImage = view.findViewById(plusID)
editText = binding.editText
binding.label.text = label
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
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)
}
}
minusImage.setOnTouchListener(this)
minusImage.setOnKeyListener(this)
minusImage.setOnClickListener(this)
plusImage.setOnTouchListener(this)
plusImage.setOnKeyListener(this)
plusImage.setOnClickListener(this)
editText.showSoftInputOnFocus = false
editText.setTextIsSelectable(false)
binding.minButton.setOnTouchListener(this)
binding.minButton.setOnKeyListener(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)
updateEditText()
}
}

View file

@ -7,8 +7,8 @@
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/minusbutton"
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/min_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -25,7 +25,7 @@
android:orientation="vertical">
<EditText
android:id="@+id/amountfield"
android:id="@+id/edit_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -44,7 +44,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:labelFor="@+id/amountfield"
android:labelFor="@+id/edit_text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/white"
android:textSize="25sp"
@ -53,8 +53,8 @@
</LinearLayout>
<ImageView
android:id="@+id/plusbutton"
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/plus_button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -65,4 +65,3 @@
android:tint="@color/white" />
</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,16 +7,25 @@
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/plusbutton"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="70dp"
android:layout_height="wrap_content"
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" />
android:layout_marginEnd="-8dp"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/plus_button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
@ -26,7 +35,7 @@
android:orientation="vertical">
<EditText
android:id="@+id/amountfield"
android:id="@+id/edit_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -45,15 +54,15 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:labelFor="@+id/amountfield"
android:labelFor="@+id/edit_text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/white"
android:textSize="25sp"
tools:ignore="LabelFor"
tools:text="label" />
<ImageView
android:id="@+id/minusbutton"
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/min_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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">
<EditText
android:id="@+id/amountfield"
android:id="@+id/edit_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -34,15 +34,15 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:labelFor="@+id/amountfield"
android:labelFor="@+id/edit_text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/white"
android:textSize="25sp"
tools:ignore="LabelFor"
tools:text="label" />
<ImageView
android:id="@+id/minusbutton"
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/min_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -54,15 +54,25 @@
</LinearLayout>
<ImageView
android:id="@+id/plusbutton"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="70dp"
android:layout_height="wrap_content"
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" />
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_height="wrap_content"
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" />
</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_gravity="start|center_vertical"
android:gravity="center"
android:labelFor="@+id/amountfield"
android:labelFor="@+id/edit_text"
android:rotation="90"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/white"
android:textSize="25sp"
tools:ignore="LabelFor"
tools:text="labelx" />
tools:text="label" />
<LinearLayout
android:layout_width="match_parent"
@ -25,8 +25,8 @@
android:layout_gravity="start|center_vertical|center_horizontal"
android:orientation="vertical">
<ImageView
android:id="@+id/plusbutton"
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/plus_button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
@ -36,7 +36,7 @@
android:tint="@color/white" />
<EditText
android:id="@+id/amountfield"
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|center_horizontal"
@ -50,8 +50,8 @@
android:textSize="45sp"
tools:text="112" />
<ImageView
android:id="@+id/minusbutton"
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/min_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
@ -63,5 +63,3 @@
</LinearLayout>
</LinearLayout>

View file

@ -206,6 +206,10 @@
<string name="key_dark" translatable="false">dark</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_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="decrement">decrement</string>
<string name="first_char_high">H</string>