From fa4d4c9fa90c536ad88c436c4ad401bbe863c132 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 5 Jan 2020 17:19:03 +0100 Subject: [PATCH] automation improvement --- .../dependencyInjection/AppComponent.kt | 7 +- .../dependencyInjection/AppModule.kt | 6 +- .../automation/elements/InputDateTime.kt | 89 +++++++++++++++ .../automation/elements/InputProfileName.kt | 2 +- .../automation/elements/InputTimeRange.kt | 80 +++++++++++++ .../automation/triggers/TriggerTime.kt | 99 +++------------- .../automation/triggers/TriggerTimeRange.kt | 108 ++++-------------- 7 files changed, 218 insertions(+), 173 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDateTime.kt create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTimeRange.kt diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt index 315acdb618..13429c4989 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt @@ -4,7 +4,6 @@ import dagger.BindsInstance import dagger.Component import dagger.android.AndroidInjectionModule import dagger.android.AndroidInjector -import dagger.android.ContributesAndroidInjector import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.db.BgReading import info.nightscout.androidaps.plugins.aps.openAPSMA.LoggerCallback @@ -76,10 +75,11 @@ interface AppComponent : AndroidInjector { fun injectActionStopTempTarget(action: ActionStopTempTarget) fun injectElement(element: Element) - fun injectElement(comparator: Comparator) - fun injectElement(comparatorExists: ComparatorExists) fun injectElement(inputBg: InputBg) fun injectElement(inputButton: InputButton) + fun injectElement(comparator: Comparator) + fun injectElement(comparatorExists: ComparatorExists) + fun injectElement(inputDateTime: InputDateTime) fun injectElement(inputDelta: InputDelta) fun injectElement(inputDouble: InputDouble) fun injectElement(inputDuration: InputDuration) @@ -89,6 +89,7 @@ interface AppComponent : AndroidInjector { fun injectElement(inputProfileName: InputProfileName) fun injectElement(inputString: InputString) fun injectElement(inputTempTarget: InputTempTarget) + fun injectElement(inputTimeRange: InputTimeRange) fun injectElement(labelWithElement: LabelWithElement) fun injectElement(staticLabel: StaticLabel) diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt index 3f8228e35e..aedaf8ae79 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt @@ -108,10 +108,11 @@ open class AppModule { @ContributesAndroidInjector fun actionDummyInjector(): ActionDummy @ContributesAndroidInjector fun elementInjector(): Element - @ContributesAndroidInjector fun comparatorInjector(): Comparator - @ContributesAndroidInjector fun comparatorExistsInjector(): ComparatorExists @ContributesAndroidInjector fun inputBgInjector(): InputBg @ContributesAndroidInjector fun inputButtonInjector(): InputButton + @ContributesAndroidInjector fun comparatorInjector(): Comparator + @ContributesAndroidInjector fun comparatorExistsInjector(): ComparatorExists + @ContributesAndroidInjector fun inputTimeInjector(): InputDateTime @ContributesAndroidInjector fun inputDeltaInjector(): InputDelta @ContributesAndroidInjector fun inputDoubleInjector(): InputDouble @ContributesAndroidInjector fun inputDurationInjector(): InputDuration @@ -121,6 +122,7 @@ open class AppModule { @ContributesAndroidInjector fun inputProfileNameInjector(): InputProfileName @ContributesAndroidInjector fun inputStringInjector(): InputString @ContributesAndroidInjector fun inputTempTargetInjector(): InputTempTarget + @ContributesAndroidInjector fun inputTimeRangeInjector(): InputTimeRange @ContributesAndroidInjector fun labelWithElementInjector(): LabelWithElement @ContributesAndroidInjector fun staticLabelInjector(): StaticLabel diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDateTime.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDateTime.kt new file mode 100644 index 0000000000..59324aa0c5 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDateTime.kt @@ -0,0 +1,89 @@ +package info.nightscout.androidaps.plugins.general.automation.elements + +import android.app.DatePickerDialog +import android.app.TimePickerDialog +import android.graphics.Typeface +import android.text.format.DateFormat +import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.TextView +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.utils.DateUtil +import java.util.* + +class InputDateTime(mainApp: MainApp) : Element(mainApp) { + var value : Long = DateUtil.now() + + constructor(mainApp: MainApp, value : Long) : this(mainApp) { + this.value = value + } + override fun addToLayout(root: LinearLayout) { + val label = TextView(root.context) + val dateButton = TextView(root.context) + val timeButton = TextView(root.context) + dateButton.text = DateUtil.dateString(value) + timeButton.text = DateUtil.timeString(value) + + // create an OnDateSetListener + val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth -> + val cal = Calendar.getInstance() + cal.timeInMillis = value + cal.set(Calendar.YEAR, year) + cal.set(Calendar.MONTH, monthOfYear) + cal.set(Calendar.DAY_OF_MONTH, dayOfMonth) + value = cal.timeInMillis + dateButton.text = DateUtil.dateString(value) + } + + dateButton.setOnClickListener { + root.context?.let { + val cal = Calendar.getInstance() + cal.timeInMillis = value + DatePickerDialog(it, dateSetListener, + cal.get(Calendar.YEAR), + cal.get(Calendar.MONTH), + cal.get(Calendar.DAY_OF_MONTH) + ).show() + } + } + + // create an OnTimeSetListener + val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute -> + val cal = Calendar.getInstance() + cal.timeInMillis = value + cal.set(Calendar.HOUR_OF_DAY, hour) + cal.set(Calendar.MINUTE, minute) + cal.set(Calendar.SECOND, 0) // randomize seconds to prevent creating record of the same time, if user choose time manually + value = cal.timeInMillis + timeButton.text = DateUtil.timeString(value) + } + + timeButton.setOnClickListener { + root.context?.let { + val cal = Calendar.getInstance() + cal.timeInMillis = value + TimePickerDialog(it, timeSetListener, + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), + DateFormat.is24HourFormat(mainApp) + ).show() + } + } + + val px = resourceHelper.dpToPx(10) + label.text = resourceHelper.gs(R.string.atspecifiedtime, "") + label.setTypeface(label.typeface, Typeface.BOLD) + label.setPadding(px, px, px, px) + dateButton.setPadding(px, px, px, px) + timeButton.setPadding(px, px, px, px) + val l = LinearLayout(root.context) + l.orientation = LinearLayout.HORIZONTAL + l.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + l.addView(label) + l.addView(dateButton) + l.addView(timeButton) + root.addView(l) + } + +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputProfileName.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputProfileName.kt index bacd1cb3a8..04daea5c66 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputProfileName.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputProfileName.kt @@ -18,7 +18,7 @@ class InputProfileName(mainApp: MainApp) : Element(mainApp) { } override fun addToLayout(root: LinearLayout) { - val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface.profile ?: return + val profileStore = configBuilderPlugin.activeProfileInterface.profile ?: return val profileList = profileStore.getProfileList() val adapter = ArrayAdapter(root.context, R.layout.spinner_centered, profileList) adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTimeRange.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTimeRange.kt new file mode 100644 index 0000000000..b97ed8a1b7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTimeRange.kt @@ -0,0 +1,80 @@ +package info.nightscout.androidaps.plugins.general.automation.elements + +import android.app.TimePickerDialog +import android.graphics.Typeface +import android.text.format.DateFormat +import android.view.ViewGroup +import android.widget.LinearLayout +import android.widget.TextView +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.MidnightTime +import info.nightscout.androidaps.utils.T +import java.util.* + +class InputTimeRange(mainApp: MainApp) : Element(mainApp) { + var start: Int = getMinSinceMidnight(DateUtil.now()) + var end: Int = getMinSinceMidnight(DateUtil.now()) + + override fun addToLayout(root: LinearLayout) { + val label = TextView(root.context) + val startButton = TextView(root.context) + val endButton = TextView(root.context) + startButton.text = DateUtil.timeString(toMills(start)) + @Suppress("SetTextI18n") + endButton.text = resourceHelper.gs(R.string.and) + " " + DateUtil.timeString(toMills(end)) + + val startTimeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute -> + start = 60 * hour + minute + startButton.text = DateUtil.timeString(toMills(start)) + } + + startButton.setOnClickListener { + root.context?.let { + val cal = Calendar.getInstance() + cal.timeInMillis = toMills(start) + TimePickerDialog(it, startTimeSetListener, + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), + DateFormat.is24HourFormat(mainApp) + ).show() + } + } + + val endTimeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute -> + end = 60 * hour + minute + endButton.text = DateUtil.timeString(toMills(end)) + } + + endButton.setOnClickListener { + root.context?.let { + val cal = Calendar.getInstance() + cal.timeInMillis = toMills(end) + TimePickerDialog(it, endTimeSetListener, + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), + DateFormat.is24HourFormat(mainApp) + ).show() + } + } + + val px = resourceHelper.dpToPx(10) + label.text = resourceHelper.gs(R.string.between) + label.setTypeface(label.typeface, Typeface.BOLD) + startButton.setPadding(px, px, px, px) + endButton.setPadding(px, px, px, px) + val l = LinearLayout(root.context) + l.orientation = LinearLayout.HORIZONTAL + l.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + l.addView(label) + l.addView(startButton) + l.addView(endButton) + root.addView(l) + } + + private fun toMills(minutesSinceMidnight: Int): Long = MidnightTime.calc() + T.mins(minutesSinceMidnight.toLong()).msecs() + + private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60 +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.kt index 4e5af1db97..7f7d137eb4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.kt @@ -1,36 +1,32 @@ package info.nightscout.androidaps.plugins.general.automation.triggers -import android.app.DatePickerDialog -import android.app.TimePickerDialog -import android.graphics.Typeface -import android.text.format.DateFormat -import android.view.ViewGroup import android.widget.LinearLayout -import android.widget.TextView import com.google.common.base.Optional import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.general.automation.elements.InputDateTime +import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder +import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.JsonHelper.safeGetLong +import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.T import org.json.JSONObject -import java.util.* class TriggerTime(mainApp: MainApp) : Trigger(mainApp) { - var runAt = DateUtil.now() + var time = InputDateTime(mainApp) constructor(mainApp: MainApp, runAt: Long) : this(mainApp) { - this.runAt = runAt + this.time.value = runAt } - constructor(mainApp: MainApp, triggerTime : TriggerTime) : this(mainApp) { - this.runAt = triggerTime.runAt + constructor(mainApp: MainApp, triggerTime: TriggerTime) : this(mainApp) { + this.time.value = triggerTime.time.value } override fun shouldRun(): Boolean { val now = DateUtil.now() - if (now >= runAt && now - runAt < T.mins(5).msecs()) { + if (now >= time.value && now - time.value < T.mins(5).msecs()) { aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription()) return true } @@ -40,7 +36,7 @@ class TriggerTime(mainApp: MainApp) : Trigger(mainApp) { override fun toJSON(): String { val data = JSONObject() - .put("runAt", runAt) + .put("runAt", time.value) return JSONObject() .put("type", this::class.java.name) .put("data", data) @@ -49,84 +45,23 @@ class TriggerTime(mainApp: MainApp) : Trigger(mainApp) { override fun fromJSON(data: String): Trigger { val o = JSONObject(data) - runAt = safeGetLong(o, "runAt") + time.value = JsonHelper.safeGetLong(o, "runAt") return this } override fun friendlyName(): Int = R.string.time override fun friendlyDescription(): String = - resourceHelper.gs(R.string.atspecifiedtime, DateUtil.dateAndTimeString(runAt)) + resourceHelper.gs(R.string.atspecifiedtime, DateUtil.dateAndTimeString(time.value)) override fun icon(): Optional = Optional.of(R.drawable.ic_access_alarm_24dp) - override fun duplicate(): Trigger = TriggerTime(mainApp, runAt) + override fun duplicate(): Trigger = TriggerTime(mainApp, time.value) override fun generateDialog(root: LinearLayout) { - val label = TextView(root.context) - val dateButton = TextView(root.context) - val timeButton = TextView(root.context) - dateButton.text = DateUtil.dateString(runAt) - timeButton.text = DateUtil.timeString(runAt) - - // create an OnDateSetListener - val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth -> - val cal = Calendar.getInstance() - cal.timeInMillis = runAt - cal.set(Calendar.YEAR, year) - cal.set(Calendar.MONTH, monthOfYear) - cal.set(Calendar.DAY_OF_MONTH, dayOfMonth) - runAt = cal.timeInMillis - dateButton.text = DateUtil.dateString(runAt) - } - - dateButton.setOnClickListener { - root.context?.let { - val cal = Calendar.getInstance() - cal.timeInMillis = runAt - DatePickerDialog(it, dateSetListener, - cal.get(Calendar.YEAR), - cal.get(Calendar.MONTH), - cal.get(Calendar.DAY_OF_MONTH) - ).show() - } - } - - // create an OnTimeSetListener - val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute -> - val cal = Calendar.getInstance() - cal.timeInMillis = runAt - cal.set(Calendar.HOUR_OF_DAY, hour) - cal.set(Calendar.MINUTE, minute) - cal.set(Calendar.SECOND, 0) // randomize seconds to prevent creating record of the same time, if user choose time manually - runAt = cal.timeInMillis - timeButton.text = DateUtil.timeString(runAt) - } - - timeButton.setOnClickListener { - root.context?.let { - val cal = Calendar.getInstance() - cal.timeInMillis = runAt - TimePickerDialog(it, timeSetListener, - cal.get(Calendar.HOUR_OF_DAY), - cal.get(Calendar.MINUTE), - DateFormat.is24HourFormat(mainApp) - ).show() - } - } - - val px = resourceHelper.dpToPx(10) - label.text = resourceHelper.gs(R.string.atspecifiedtime, "") - label.setTypeface(label.typeface, Typeface.BOLD) - label.setPadding(px, px, px, px) - dateButton.setPadding(px, px, px, px) - timeButton.setPadding(px, px, px, px) - val l = LinearLayout(root.context) - l.orientation = LinearLayout.HORIZONTAL - l.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) - l.addView(label) - l.addView(dateButton) - l.addView(timeButton) - root.addView(l) + LayoutBuilder() + .add(StaticLabel(mainApp, R.string.time)) + .add(time) + .build(root) } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.kt index d42de467e7..79fcc0876d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.kt @@ -1,44 +1,41 @@ package info.nightscout.androidaps.plugins.general.automation.triggers -import android.app.TimePickerDialog -import android.graphics.Typeface -import android.text.format.DateFormat -import android.view.ViewGroup import android.widget.LinearLayout -import android.widget.TextView import com.google.common.base.Optional import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.general.automation.elements.InputTimeRange +import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder +import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.JsonHelper.safeGetInt +import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.T import org.json.JSONObject -import java.util.* // Trigger for time range ( from 10:00AM till 13:00PM ) class TriggerTimeRange(mainApp: MainApp) : Trigger(mainApp) { // in minutes since midnight 60 means 1AM - var start: Int = getMinSinceMidnight(DateUtil.now()) - var end: Int = getMinSinceMidnight(DateUtil.now()) + var range = InputTimeRange(mainApp) - constructor(mainApp: MainApp, start : Int, end :Int) : this(mainApp) { - this.start = start - this.end = end + constructor(mainApp: MainApp, start: Int, end: Int) : this(mainApp) { + range.start = start + range.end = end } constructor(mainApp: MainApp, triggerTimeRange: TriggerTimeRange) : this(mainApp) { - this.start = triggerTimeRange.start - this.end = triggerTimeRange.end + range.start = triggerTimeRange.range.start + range.end = triggerTimeRange.range.end } override fun shouldRun(): Boolean { val currentMinSinceMidnight = getMinSinceMidnight(DateUtil.now()) var doRun = false - if (start < end && start < currentMinSinceMidnight && currentMinSinceMidnight < end) doRun = true - else if (start > end && (start < currentMinSinceMidnight || currentMinSinceMidnight < end)) doRun = true + if (range.start < range.end && range.start < currentMinSinceMidnight && currentMinSinceMidnight < range.end) doRun = true + else if (range.start > range.end && (range.start < currentMinSinceMidnight || currentMinSinceMidnight < range.end)) doRun = true if (doRun) { aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription()) return true @@ -49,8 +46,8 @@ class TriggerTimeRange(mainApp: MainApp) : Trigger(mainApp) { override fun toJSON(): String { val data = JSONObject() - .put("start", getMinSinceMidnight(start.toLong())) - .put("end", getMinSinceMidnight(end.toLong())) + .put("start", getMinSinceMidnight(range.start.toLong())) + .put("end", getMinSinceMidnight(range.end.toLong())) return JSONObject() .put("type", this::class.java.name) .put("data", data) @@ -59,87 +56,28 @@ class TriggerTimeRange(mainApp: MainApp) : Trigger(mainApp) { override fun fromJSON(data: String): TriggerTimeRange { val o = JSONObject(data) - start = safeGetInt(o, "start") - end = safeGetInt(o, "end") + range.start = safeGetInt(o, "start") + range.end = safeGetInt(o, "end") return this } override fun friendlyName(): Int = R.string.time_range override fun friendlyDescription(): String = - resourceHelper.gs(R.string.timerange_value, DateUtil.timeString(toMills(start)), DateUtil.timeString(toMills(end))) + resourceHelper.gs(R.string.timerange_value, DateUtil.timeString(toMills(range.start)), DateUtil.timeString(toMills(range.end))) override fun icon(): Optional = Optional.of(R.drawable.ic_access_alarm_24dp) - override fun duplicate(): Trigger = TriggerTimeRange(mainApp, start, end) + override fun duplicate(): Trigger = TriggerTimeRange(mainApp, range.start, range.end) - private fun toMills(minutesSinceMidnight: Int): Long = T.secs(minutesSinceMidnight.toLong()).msecs() + private fun toMills(minutesSinceMidnight: Int): Long = MidnightTime.calc() + T.mins(minutesSinceMidnight.toLong()).msecs() private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60 override fun generateDialog(root: LinearLayout) { - val label = TextView(root.context) - val startButton = TextView(root.context) - val endButton = TextView(root.context) - startButton.text = DateUtil.timeString(toMills(start)) - @Suppress("SetTextI18n") - endButton.text = resourceHelper.gs(R.string.and) + " " + DateUtil.timeString(toMills(end)) - - val startTimeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute -> - val cal = Calendar.getInstance() - cal.timeInMillis = toMills(start) - cal.set(Calendar.HOUR_OF_DAY, hour) - cal.set(Calendar.MINUTE, minute) - cal.set(Calendar.SECOND, 0) - start = getMinSinceMidnight(cal.timeInMillis) - startButton.text = DateUtil.timeString(toMills(start)) - } - - startButton.setOnClickListener { - root.context?.let { - val cal = Calendar.getInstance() - cal.timeInMillis = toMills(start) - TimePickerDialog(it, startTimeSetListener, - cal.get(Calendar.HOUR_OF_DAY), - cal.get(Calendar.MINUTE), - DateFormat.is24HourFormat(mainApp) - ).show() - } - } - - val endTimeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute -> - val cal = Calendar.getInstance() - cal.timeInMillis = toMills(end) - cal.set(Calendar.HOUR_OF_DAY, hour) - cal.set(Calendar.MINUTE, minute) - cal.set(Calendar.SECOND, 0) // randomize seconds to prevent creating record of the same time, if user choose time manually - end = getMinSinceMidnight(cal.timeInMillis) - endButton.text = DateUtil.timeString(toMills(end)) - } - - endButton.setOnClickListener { - root.context?.let { - val cal = Calendar.getInstance() - cal.timeInMillis = toMills(end) - TimePickerDialog(it, endTimeSetListener, - cal.get(Calendar.HOUR_OF_DAY), - cal.get(Calendar.MINUTE), - DateFormat.is24HourFormat(mainApp) - ).show() - } - } - - val px = resourceHelper.dpToPx(10) - label.text = resourceHelper.gs(R.string.between) - label.setTypeface(label.typeface, Typeface.BOLD) - startButton.setPadding(px, px, px, px) - endButton.setPadding(px, px, px, px) - val l = LinearLayout(root.context) - l.orientation = LinearLayout.HORIZONTAL - l.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) - l.addView(label) - l.addView(startButton) - l.addView(endButton) - root.addView(l) + LayoutBuilder() + .add(StaticLabel(mainApp, R.string.time_range)) + .add(range) + .build(root) } } \ No newline at end of file