From 68793233e8a04c9ea7be27a52a8a3daef84dcc8a Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 23 Nov 2021 19:53:45 +0100 Subject: [PATCH] NumberPicker -> kt --- .../activities/ProfileHelperActivity.kt | 4 +- .../androidaps/dialogs/CalibrationDialog.kt | 2 +- .../androidaps/dialogs/CarbsDialog.kt | 2 +- .../androidaps/dialogs/ExtendedBolusDialog.kt | 2 +- .../androidaps/dialogs/FillDialog.kt | 2 +- .../androidaps/dialogs/InsulinDialog.kt | 2 +- .../androidaps/dialogs/ProfileSwitchDialog.kt | 2 +- .../androidaps/dialogs/TempBasalDialog.kt | 14 +- .../androidaps/dialogs/TreatmentDialog.kt | 4 +- .../androidaps/dialogs/WizardDialog.kt | 5 +- .../profile/local/LocalProfileFragment.kt | 2 +- .../utils/ui/NumberPickerVertical.kt | 5 +- app/src/main/res/layout/dialog_tempbasal.xml | 4 +- .../androidaps/utils/ToastUtils.java | 1 + .../utils/ui/MinutesNumberPicker.kt | 12 +- .../androidaps/utils/ui/NumberPicker.java | 343 ------------------ .../androidaps/utils/ui/NumberPicker.kt | 299 +++++++++++++++ .../comm/MsgInitConnStatusTime_k.kt | 1 + 18 files changed, 330 insertions(+), 376 deletions(-) delete mode 100644 core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.java create mode 100644 core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.kt diff --git a/app/src/main/java/info/nightscout/androidaps/activities/ProfileHelperActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/ProfileHelperActivity.kt index eb69d5658f..38d103af77 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/ProfileHelperActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/ProfileHelperActivity.kt @@ -1,5 +1,6 @@ package info.nightscout.androidaps.activities +import android.annotation.SuppressLint import android.content.res.ColorStateList import android.os.Bundle import android.text.Editable @@ -168,7 +169,8 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() { binding.basalpctfromtdd.setParams(32.0, 32.0, 37.0, 1.0, DecimalFormat("0"), false, null) - binding.tdds.text = getString(R.string.tdd) + ": " + rh.gs(R.string.calculation_in_progress); + @SuppressLint("SetTextI18n") + binding.tdds.text = getString(R.string.tdd) + ": " + rh.gs(R.string.calculation_in_progress) Thread { val tdds = tddCalculator.stats() runOnUiThread { binding.tdds.text = tdds } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt index 9b967dfe7d..35f387144c 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CalibrationDialog.kt @@ -76,7 +76,7 @@ class CalibrationDialog : DialogFragmentWithDate() { val units = profileFunction.getUnits() val unitLabel = if (units == GlucoseUnit.MMOL) rh.gs(R.string.mmol) else rh.gs(R.string.mgdl) val actions: LinkedList = LinkedList() - val bg = binding.bg.value ?: return false + val bg = binding.bg.value actions.add(rh.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, bg) + " " + unitLabel) if (bg > 0) { activity?.let { activity -> diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt index 7a5e116933..f17c6a0a11 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt @@ -189,7 +189,7 @@ class CarbsDialog : DialogFragmentWithDate() { override fun submit(): Boolean { if (_binding == null) return false - val carbs = binding.carbs.value?.toInt() ?: return false + val carbs = binding.carbs.value.toInt() val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value() val units = profileFunction.getUnits() val activityTTDuration = defaultValueHelper.determineActivityTTDuration() diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt index ac86d3b982..152295027f 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt @@ -79,7 +79,7 @@ class ExtendedBolusDialog : DialogFragmentWithDate() { override fun submit(): Boolean { if (_binding == null) return false - val insulin = SafeParse.stringToDouble(binding.insulin.text ?: return false) + val insulin = SafeParse.stringToDouble(binding.insulin.text) val durationInMinutes = binding.duration.value.toInt() val actions: LinkedList = LinkedList() val insulinAfterConstraint = constraintChecker.applyExtendedBolusConstraints(Constraint(insulin)).value() diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt index ad35ffe612..1ab91a7abc 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt @@ -106,7 +106,7 @@ class FillDialog : DialogFragmentWithDate() { override fun submit(): Boolean { if (_binding == null) return false - val insulin = SafeParse.stringToDouble(binding.fillInsulinamount.text ?: return false) + val insulin = SafeParse.stringToDouble(binding.fillInsulinamount.text) val actions: LinkedList = LinkedList() val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(insulin)).value() diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt index 99bdfacd9a..56d6784870 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt @@ -149,7 +149,7 @@ class InsulinDialog : DialogFragmentWithDate() { override fun submit(): Boolean { if (_binding == null) return false val pumpDescription = activePlugin.activePump.pumpDescription - val insulin = SafeParse.stringToDouble(binding.amount.text ?: return false) + val insulin = SafeParse.stringToDouble(binding.amount.text) val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(insulin)).value() val actions: LinkedList = LinkedList() val units = profileFunction.getUnits() diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt index 9d3a9e20da..128dd9e588 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt @@ -162,7 +162,7 @@ class ProfileSwitchDialog : DialogFragmentWithDate() { ?: return false val actions: LinkedList = LinkedList() - val duration = binding.duration.value?.toInt() ?: return false + val duration = binding.duration.value.toInt() if (duration > 0L) actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, duration)) val profileName = binding.profile.selectedItem.toString() diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt index 1b6676f8b3..cb87789269 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt @@ -47,8 +47,8 @@ class TempBasalDialog : DialogFragmentWithDate() { override fun onSaveInstanceState(savedInstanceState: Bundle) { super.onSaveInstanceState(savedInstanceState) savedInstanceState.putDouble("duration", binding.duration.value) - savedInstanceState.putDouble("basalpercentinput", binding.basalpercentinput.value) - savedInstanceState.putDouble("basalabsoluteinput", binding.basalabsoluteinput.value) + savedInstanceState.putDouble("basalPercentInput", binding.basalPercentInput.value) + savedInstanceState.putDouble("basalAbsoluteInput", binding.basalAbsoluteInput.value) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, @@ -67,10 +67,10 @@ class TempBasalDialog : DialogFragmentWithDate() { val maxTempPercent = pumpDescription.maxTempPercent.toDouble() val tempPercentStep = pumpDescription.tempPercentStep.toDouble() - binding.basalpercentinput.setParams(savedInstanceState?.getDouble("basalpercentinput") + binding.basalPercentInput.setParams(savedInstanceState?.getDouble("basalPercentInput") ?: 100.0, 0.0, maxTempPercent, tempPercentStep, DecimalFormat("0"), true, binding.okcancel.ok) - binding.basalabsoluteinput.setParams(savedInstanceState?.getDouble("basalabsoluteinput") + binding.basalAbsoluteInput.setParams(savedInstanceState?.getDouble("basalAbsoluteInput") ?: profile.getBasal(), 0.0, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, DecimalFormat("0.00"), true, binding.okcancel.ok) val tempDurationStep = pumpDescription.tempDurationStep.toDouble() @@ -97,17 +97,17 @@ class TempBasalDialog : DialogFragmentWithDate() { if (_binding == null) return false var percent = 0 var absolute = 0.0 - val durationInMinutes = binding.duration.value?.toInt() ?: return false + val durationInMinutes = binding.duration.value.toInt() val profile = profileFunction.getProfile() ?: return false val actions: LinkedList = LinkedList() if (isPercentPump) { - val basalPercentInput = SafeParse.stringToInt(binding.basalpercentinput.text) + val basalPercentInput = SafeParse.stringToInt(binding.basalPercentInput.text) percent = constraintChecker.applyBasalPercentConstraints(Constraint(basalPercentInput), profile).value() actions.add(rh.gs(R.string.tempbasal_label) + ": $percent%") actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, durationInMinutes)) if (percent != basalPercentInput) actions.add(rh.gs(R.string.constraintapllied)) } else { - val basalAbsoluteInput = SafeParse.stringToDouble(binding.basalabsoluteinput.text) + val basalAbsoluteInput = SafeParse.stringToDouble(binding.basalAbsoluteInput.text) absolute = constraintChecker.applyBasalConstraints(Constraint(basalAbsoluteInput), profile).value() actions.add(rh.gs(R.string.tempbasal_label) + ": " + rh.gs(R.string.pump_basebasalrate, absolute)) actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, durationInMinutes)) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt index 2bf693c1e8..9f185d270b 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt @@ -115,7 +115,7 @@ class TreatmentDialog : DialogFragmentWithDate() { override fun submit(): Boolean { if (_binding == null) return false val pumpDescription = activePlugin.activePump.pumpDescription - val insulin = SafeParse.stringToDouble(binding.insulin.text ?: return false) + val insulin = SafeParse.stringToDouble(binding.insulin.text) val carbs = SafeParse.stringToInt(binding.carbs.text) val recordOnlyChecked = binding.recordOnly.isChecked val actions: LinkedList = LinkedList() @@ -139,7 +139,7 @@ class TreatmentDialog : DialogFragmentWithDate() { OKDialog.showConfirmation(activity, rh.gs(R.string.overview_treatment_label), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), { val action = when { insulinAfterConstraints.equals(0.0) -> Action.CARBS - carbsAfterConstraints.equals(0) -> Action.BOLUS + carbsAfterConstraints == 0 -> Action.BOLUS else -> Action.TREATMENT } val detailedBolusInfo = DetailedBolusInfo() diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt index 82c3a07da1..92afb1141e 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt @@ -258,10 +258,7 @@ class WizardDialog : DaggerDialogFragment() { val units = profileFunction.getUnits() binding.bgunits.text = units.asText - if (units == GlucoseUnit.MGDL) - binding.bgInput.setStep(1.0) - else - binding.bgInput.setStep(0.1) + binding.bgInput.step = if (units == GlucoseUnit.MGDL) 1.0 else 0.1 // Set BG if not old binding.bgInput.value = iobCobCalculator.ads.actualBg()?.valueToUnits(units) ?: 0.0 diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt index cf0c2b67cc..d7a7d1bfbf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt @@ -65,7 +65,7 @@ class LocalProfileFragment : DaggerFragment() { override fun afterTextChanged(s: Editable) {} override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { - localProfilePlugin.currentProfile()?.dia = SafeParse.stringToDouble(binding.dia.text.toString()) + localProfilePlugin.currentProfile()?.dia = SafeParse.stringToDouble(binding.dia.text) localProfilePlugin.currentProfile()?.name = binding.name.text.toString() doEdit() } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/ui/NumberPickerVertical.kt b/app/src/main/java/info/nightscout/androidaps/utils/ui/NumberPickerVertical.kt index 495dc01e7f..4f26a9b3b1 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/ui/NumberPickerVertical.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/ui/NumberPickerVertical.kt @@ -5,10 +5,7 @@ import android.util.AttributeSet import android.view.LayoutInflater import info.nightscout.androidaps.R -class NumberPickerVertical : NumberPicker { - - constructor(context: Context?) : super(context) - constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) +class NumberPickerVertical(context: Context, attrs: AttributeSet? = null) : NumberPicker(context, attrs) { override fun inflate(context: Context) { LayoutInflater.from(context).inflate(R.layout.number_picker_layout_vertical, this, true) diff --git a/app/src/main/res/layout/dialog_tempbasal.xml b/app/src/main/res/layout/dialog_tempbasal.xml index 5bf64dd423..4e8f6e2a31 100644 --- a/app/src/main/res/layout/dialog_tempbasal.xml +++ b/app/src/main/res/layout/dialog_tempbasal.xml @@ -64,7 +64,7 @@ android:textStyle="bold" /> @@ -98,7 +98,7 @@ android:textStyle="bold" /> diff --git a/core/src/main/java/info/nightscout/androidaps/utils/ToastUtils.java b/core/src/main/java/info/nightscout/androidaps/utils/ToastUtils.java index 994998ef90..3f2d483227 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/ToastUtils.java +++ b/core/src/main/java/info/nightscout/androidaps/utils/ToastUtils.java @@ -34,6 +34,7 @@ public class ToastUtils { graphicalToast(ctx, string, R.drawable.ic_toast_info, false); } + @SuppressWarnings("unused") public static void okToast(final Context ctx, final String string) { graphicalToast(ctx, string, R.drawable.ic_toast_check, false); } diff --git a/core/src/main/java/info/nightscout/androidaps/utils/ui/MinutesNumberPicker.kt b/core/src/main/java/info/nightscout/androidaps/utils/ui/MinutesNumberPicker.kt index 45e9d3d694..fa809b5480 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/ui/MinutesNumberPicker.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/ui/MinutesNumberPicker.kt @@ -13,16 +13,16 @@ class MinutesNumberPicker constructor(context: Context, attrs: AttributeSet? = n } override fun updateEditText() { - if (value == 0.0 && !allowZero) editText.setText("") + if (currentValue == 0.0 && !allowZero) editText?.setText("") else { - if (focused) editText.setText(DecimalFormat("0").format(value)) + if (focused) editText?.setText(DecimalFormat("0").format(currentValue)) else { - val hours = (value / 60).toInt() - val minutes = (value - hours * 60).toInt() + val hours = (currentValue / 60).toInt() + val minutes = (currentValue - hours * 60).toInt() val formatted = if (hours != 0) String.format(context.getString(R.string.format_hour_minute), hours, minutes) - else DecimalFormat("0").format(value) - editText.setText(formatted) + else DecimalFormat("0").format(currentValue) + editText?.setText(formatted) } } } diff --git a/core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.java b/core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.java deleted file mode 100644 index ad8ed67049..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.java +++ /dev/null @@ -1,343 +0,0 @@ -package info.nightscout.androidaps.utils.ui; - -import android.app.Service; -import android.content.Context; -import android.os.Handler; -import android.os.Message; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.AttributeSet; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.LinearLayout; - -import java.text.NumberFormat; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import info.nightscout.androidaps.core.R; -import info.nightscout.androidaps.utils.SafeParse; -import info.nightscout.androidaps.utils.ToastUtils; - -public class NumberPicker extends LinearLayout implements View.OnKeyListener, - View.OnTouchListener, View.OnClickListener { - - public interface OnValueChangedListener { - void onValueChanged(double value); - } - - EditText editText; - Button minusButton; - Button plusButton; - - double value = 0; - double minValue = 0d; - double maxValue = 1d; - double step = 1d; - NumberFormat formatter; - boolean allowZero = false; - TextWatcher textWatcher = null; - - Button okButton = null; - - protected Boolean focused = false; - - private Handler mHandler; - private ScheduledExecutorService mUpdater; - private OnValueChangedListener mOnValueChangedListener; - - private class UpdateCounterTask implements Runnable { - private final boolean mInc; - private int repeated = 0; - private int multiplier = 1; - - private final int doubleLimit = 5; - - UpdateCounterTask(boolean inc) { - mInc = inc; - } - - public void run() { - Message msg = new Message(); - if (repeated % doubleLimit == 0) multiplier *= 2; - repeated++; - msg.arg1 = multiplier; - msg.arg2 = repeated; - if (mInc) { - msg.what = MSG_INC; - } else { - msg.what = MSG_DEC; - } - mHandler.sendMessage(msg); - } - } - - private static final int MSG_INC = 0; - private static final int MSG_DEC = 1; - - public NumberPicker(Context context) { - super(context, null); - this.initialize(context); - } - - public NumberPicker(Context context, AttributeSet attrs) { - super(context, attrs); - - this.initialize(context); - } - - protected void inflate(Context context) { - LayoutInflater.from(context).inflate(R.layout.number_picker_layout, this, true); - } - - protected void initialize(Context context) { - // set layout view - inflate(context); - - // init ui components - minusButton = findViewById(R.id.decrement); - minusButton.setId(View.generateViewId()); - plusButton = findViewById(R.id.increment); - plusButton.setId(View.generateViewId()); - editText = findViewById(R.id.display); - editText.setId(View.generateViewId()); - - mHandler = new Handler(msg -> { - switch (msg.what) { - case MSG_INC: - inc(msg.arg1); - return true; - case MSG_DEC: - dec(msg.arg1); - return true; - } - return false; - }); - - minusButton.setOnTouchListener(this); - minusButton.setOnKeyListener(this); - minusButton.setOnClickListener(this); - plusButton.setOnTouchListener(this); - plusButton.setOnKeyListener(this); - plusButton.setOnClickListener(this); - setTextWatcher(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void afterTextChanged(Editable s) { - if (focused) value = SafeParse.stringToDouble(editText.getText().toString()); - callValueChangedListener(); - if (okButton != null) { - if (value > maxValue || value < minValue) - okButton.setVisibility(INVISIBLE); - else - okButton.setVisibility(VISIBLE); - } - } - }); - - editText.setOnFocusChangeListener((v, hasFocus) -> { - focused = hasFocus; - if (!focused) getValue(); // check min/max - updateEditText(); - }); - } - - @Override - public void setTag(Object tag) { - editText.setTag(tag); - } - - public void setOnValueChangedListener(OnValueChangedListener onValueChangedListener) { - mOnValueChangedListener = onValueChangedListener; - } - - public void setTextWatcher(TextWatcher textWatcher) { - this.textWatcher = textWatcher; - editText.addTextChangedListener(textWatcher); - editText.setOnFocusChangeListener((v, hasFocus) -> { - if (!hasFocus) { - value = SafeParse.stringToDouble(editText.getText().toString()); - if (value > maxValue) { - value = maxValue; - ToastUtils.showToastInUiThread(getContext(), getContext().getString(R.string.youareonallowedlimit)); - updateEditText(); - if (okButton != null) - okButton.setVisibility(VISIBLE); - } - if (value < minValue) { - value = minValue; - ToastUtils.showToastInUiThread(getContext(), getContext().getString(R.string.youareonallowedlimit)); - updateEditText(); - if (okButton != null) - okButton.setVisibility(VISIBLE); - } - } - }); - } - - public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formatter, boolean allowZero, Button okButton, TextWatcher textWatcher) { - if (this.textWatcher != null) { - editText.removeTextChangedListener(this.textWatcher); - } - setParams(initValue, minValue, maxValue, step, formatter, allowZero, okButton); - this.textWatcher = textWatcher; - if (textWatcher != null) - editText.addTextChangedListener(textWatcher); - } - - public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formatter, boolean allowZero, Button okButton) { - this.value = initValue; - this.minValue = minValue; - this.maxValue = maxValue; - this.step = step; - this.formatter = formatter; - this.allowZero = allowZero; - callValueChangedListener(); - this.okButton = okButton; - - editText.setKeyListener(DigitsKeyListenerWithComma.getInstance(minValue < 0, step != Math.rint(step))); - - if (textWatcher != null) - editText.removeTextChangedListener(textWatcher); - updateEditText(); - if (textWatcher != null) - editText.addTextChangedListener(textWatcher); - } - - public void setValue(Double value) { - if (textWatcher != null) - editText.removeTextChangedListener(textWatcher); - this.value = value; - callValueChangedListener(); - updateEditText(); - if (textWatcher != null) - editText.addTextChangedListener(textWatcher); - } - - public Double getValue() { - if (value > maxValue) { - value = maxValue; - ToastUtils.showToastInUiThread(getContext(), getContext().getString(R.string.youareonallowedlimit)); - } - if (value < minValue) { - value = minValue; - ToastUtils.showToastInUiThread(getContext(), getContext().getString(R.string.youareonallowedlimit)); - } - return value; - } - - public String getText() { - return editText.getText().toString(); - } - - public void setStep(Double step) { - this.step = step; - } - - private void inc(int multiplier) { - value += step * multiplier; - if (value > maxValue) { - value = maxValue; - callValueChangedListener(); - ToastUtils.showToastInUiThread(getContext(), getContext().getString(R.string.youareonallowedlimit)); - stopUpdating(); - } - updateEditText(); - } - - private void dec(int multiplier) { - value -= step * multiplier; - if (value < minValue) { - value = minValue; - callValueChangedListener(); - ToastUtils.showToastInUiThread(getContext(), getContext().getString(R.string.youareonallowedlimit)); - stopUpdating(); - } - updateEditText(); - } - - protected void updateEditText() { - if (value == 0d && !allowZero) - editText.setText(""); - else - editText.setText(formatter.format(value)); - } - - private void callValueChangedListener() { - if (mOnValueChangedListener != null) - mOnValueChangedListener.onValueChanged(value); - } - - private void startUpdating(boolean inc) { - if (mUpdater != null) { - //log.debug("Another executor is still active"); - return; - } - mUpdater = Executors.newSingleThreadScheduledExecutor(); - mUpdater.scheduleAtFixedRate(new UpdateCounterTask(inc), 200, 200, - TimeUnit.MILLISECONDS); - } - - private void stopUpdating() { - if (mUpdater != null) { - mUpdater.shutdownNow(); - mUpdater = null; - } - } - - @Override - public void onClick(View v) { - if (mUpdater == null) { - InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Service.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - editText.clearFocus(); - if (v == plusButton) { - inc(1); - } else { - dec(1); - } - } - } - - @Override - public boolean onKey(View v, int keyCode, KeyEvent event) { - boolean isKeyOfInterest = keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER; - boolean isReleased = event.getAction() == KeyEvent.ACTION_UP; - boolean isPressed = event.getAction() == KeyEvent.ACTION_DOWN - && event.getAction() != KeyEvent.ACTION_MULTIPLE; - - if (isKeyOfInterest && isReleased) { - stopUpdating(); - } else if (isKeyOfInterest && isPressed) { - startUpdating(v == plusButton); - } - return false; - } - - @Override - public boolean onTouch(View v, MotionEvent event) { - boolean isReleased = event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL; - boolean isPressed = event.getAction() == MotionEvent.ACTION_DOWN; - - if (isReleased) { - stopUpdating(); - } else if (isPressed) { - startUpdating(v == plusButton); - } - return false; - } - -} diff --git a/core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.kt b/core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.kt new file mode 100644 index 0000000000..e498e610b9 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.kt @@ -0,0 +1,299 @@ +package info.nightscout.androidaps.utils.ui + +import android.annotation.SuppressLint +import android.app.Service +import android.content.Context +import android.os.Handler +import android.os.Looper +import android.os.Message +import android.text.Editable +import android.text.TextWatcher +import android.util.AttributeSet +import android.view.KeyEvent +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.View.OnFocusChangeListener +import android.view.View.OnTouchListener +import android.view.inputmethod.InputMethodManager +import android.widget.Button +import android.widget.EditText +import android.widget.LinearLayout +import info.nightscout.androidaps.core.R +import info.nightscout.androidaps.utils.SafeParse +import info.nightscout.androidaps.utils.ToastUtils +import java.text.NumberFormat +import java.util.concurrent.Executors +import java.util.concurrent.ScheduledExecutorService +import java.util.concurrent.TimeUnit +import kotlin.math.round + +@SuppressLint("ClickableViewAccessibility") +open class NumberPicker(context: Context, attrs: AttributeSet? = null) : LinearLayout(context, attrs), View.OnKeyListener, OnTouchListener, View.OnClickListener { + + fun interface OnValueChangedListener { + + fun onValueChanged(value: Double) + } + + var editText: EditText? = null + private var minusButton: Button? = null + private var plusButton: Button? = null + var currentValue = 0.0 + var minValue = 0.0 + var maxValue = 1.0 + var step = 1.0 + var formatter: NumberFormat? = null + var allowZero = false + private var watcher: TextWatcher? = null + var okButton: Button? = null + protected var focused = false + private var mUpdater: ScheduledExecutorService? = null + private var mOnValueChangedListener: OnValueChangedListener? = null + + private var mHandler: Handler = Handler(Looper.getMainLooper(), Handler.Callback { msg: Message -> + when (msg.what) { + MSG_INC -> { + inc(msg.arg1) + return@Callback true + } + + MSG_DEC -> { + dec(msg.arg1) + return@Callback true + } + } + false + }) + + private inner class UpdateCounterTask(private val mInc: Boolean) : Runnable { + + private var repeated = 0 + private var multiplier = 1 + private val doubleLimit = 5 + override fun run() { + val msg = Message() + if (repeated % doubleLimit == 0) multiplier *= 2 + repeated++ + msg.arg1 = multiplier + msg.arg2 = repeated + if (mInc) { + msg.what = MSG_INC + } else { + msg.what = MSG_DEC + } + mHandler.sendMessage(msg) + } + } + + protected open fun inflate(context: Context) { + LayoutInflater.from(context).inflate(R.layout.number_picker_layout, this, true) + } + + protected fun initialize(context: Context) { + // set layout view + inflate(context) + + // init ui components + minusButton = findViewById(R.id.decrement) + minusButton?.id = generateViewId() + plusButton = findViewById(R.id.increment) + plusButton?.id = generateViewId() + editText = findViewById(R.id.display) + editText?.id = generateViewId() + minusButton?.setOnTouchListener(this) + minusButton?.setOnKeyListener(this) + minusButton?.setOnClickListener(this) + plusButton?.setOnTouchListener(this) + plusButton?.setOnKeyListener(this) + plusButton?.setOnClickListener(this) + setTextWatcher(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {} + override fun afterTextChanged(s: Editable) { + if (focused) currentValue = SafeParse.stringToDouble(editText?.text.toString()) + callValueChangedListener() + if (okButton != null) { + if (currentValue > maxValue || currentValue < minValue) okButton!!.visibility = INVISIBLE else okButton!!.visibility = VISIBLE + } + } + }) + editText?.setOnFocusChangeListener { _: View?, hasFocus: Boolean -> + focused = hasFocus + if (!focused) value // check min/max + updateEditText() + } + } + + override fun setTag(tag: Any) { + editText?.tag = tag + } + + fun setOnValueChangedListener(onValueChangedListener: OnValueChangedListener?) { + mOnValueChangedListener = onValueChangedListener + } + + fun setTextWatcher(textWatcher: TextWatcher) { + watcher = textWatcher + editText?.addTextChangedListener(textWatcher) + editText?.onFocusChangeListener = OnFocusChangeListener { _: View?, hasFocus: Boolean -> + if (!hasFocus) { + currentValue = SafeParse.stringToDouble(editText?.text.toString()) + if (currentValue > maxValue) { + currentValue = maxValue + ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit)) + updateEditText() + if (okButton != null) okButton?.visibility = VISIBLE + } + if (currentValue < minValue) { + currentValue = minValue + ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit)) + updateEditText() + if (okButton != null) okButton?.visibility = VISIBLE + } + } + } + } + + fun setParams(initValue: Double, minValue: Double, maxValue: Double, step: Double, formatter: NumberFormat?, allowZero: Boolean, okButton: Button?, textWatcher: TextWatcher?) { + if (watcher != null) { + editText?.removeTextChangedListener(watcher) + } + setParams(initValue, minValue, maxValue, step, formatter, allowZero, okButton) + watcher = textWatcher + if (textWatcher != null) editText?.addTextChangedListener(textWatcher) + } + + fun setParams(initValue: Double, minValue: Double, maxValue: Double, step: Double, formatter: NumberFormat?, allowZero: Boolean, okButton: Button?) { + currentValue = initValue + this.minValue = minValue + this.maxValue = maxValue + this.step = step + this.formatter = formatter + this.allowZero = allowZero + callValueChangedListener() + this.okButton = okButton + editText?.keyListener = DigitsKeyListenerWithComma.getInstance(minValue < 0, step != round(step)) + if (watcher != null) editText?.removeTextChangedListener(watcher) + updateEditText() + if (watcher != null) editText?.addTextChangedListener(watcher) + } + + var value: Double + get() { + if (currentValue > maxValue) { + currentValue = maxValue + ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit)) + } + if (currentValue < minValue) { + currentValue = minValue + ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit)) + } + return currentValue + } + set(value) { + if (watcher != null) editText?.removeTextChangedListener(watcher) + currentValue = value + callValueChangedListener() + updateEditText() + if (watcher != null) editText?.addTextChangedListener(watcher) + } + + val text: String + get() = editText?.text.toString() + + private fun inc(multiplier: Int) { + currentValue += step * multiplier + if (currentValue > maxValue) { + currentValue = maxValue + callValueChangedListener() + ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit)) + stopUpdating() + } + updateEditText() + } + + private fun dec(multiplier: Int) { + currentValue -= step * multiplier + if (currentValue < minValue) { + currentValue = minValue + callValueChangedListener() + ToastUtils.showToastInUiThread(context, context.getString(R.string.youareonallowedlimit)) + stopUpdating() + } + updateEditText() + } + + protected open fun updateEditText() { + if (currentValue == 0.0 && !allowZero) editText?.setText("") else editText?.setText(formatter?.format(currentValue)) + } + + private fun callValueChangedListener() { + if (mOnValueChangedListener != null) mOnValueChangedListener?.onValueChanged(currentValue) + } + + private fun startUpdating(inc: Boolean) { + if (mUpdater != null) { + //log.debug("Another executor is still active"); + return + } + mUpdater = Executors.newSingleThreadScheduledExecutor() + mUpdater?.scheduleAtFixedRate( + UpdateCounterTask(inc), 200, 200, + TimeUnit.MILLISECONDS + ) + } + + private fun stopUpdating() { + if (mUpdater != null) { + mUpdater?.shutdownNow() + mUpdater = null + } + } + + override fun onClick(v: View) { + if (mUpdater == null) { + val imm = context.getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(editText?.windowToken, 0) + editText?.clearFocus() + if (v === plusButton) { + inc(1) + } else { + dec(1) + } + } + } + + override fun onKey(v: View, keyCode: Int, event: KeyEvent): Boolean { + val isKeyOfInterest = keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER + val isReleased = event.action == KeyEvent.ACTION_UP + val isPressed = (event.action == KeyEvent.ACTION_DOWN) + if (isKeyOfInterest && isReleased) { + stopUpdating() + } else if (isKeyOfInterest && isPressed) { + startUpdating(v === plusButton) + } + return false + } + + override fun onTouch(v: View, event: MotionEvent): Boolean { + val isReleased = event.action == MotionEvent.ACTION_UP || event.action == MotionEvent.ACTION_CANCEL + val isPressed = event.action == MotionEvent.ACTION_DOWN + if (isReleased) { + stopUpdating() + } else if (isPressed) { + startUpdating(v === plusButton) + } + return false + } + + companion object { + + private const val MSG_INC = 0 + private const val MSG_DEC = 1 + } + + init { + initialize(context) + } +} \ No newline at end of file diff --git a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusTime_k.kt b/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusTime_k.kt index 0bf840dccc..bdc345d957 100644 --- a/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusTime_k.kt +++ b/danar/src/main/java/info/nightscout/androidaps/danaRKorean/comm/MsgInitConnStatusTime_k.kt @@ -1,6 +1,7 @@ package info.nightscout.androidaps.danaRKorean.comm import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.dana.DanaPump import info.nightscout.androidaps.danar.R import info.nightscout.androidaps.danar.comm.MessageBase import info.nightscout.androidaps.events.EventRebuildTabs