From 1eb375af09c4272f9ea288ecaa380c34323e1432 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 6 Jan 2020 00:38:37 +0100 Subject: [PATCH] adding, removing triggers properly --- .../general/automation/AutomationEvent.kt | 2 +- .../general/automation/AutomationPlugin.kt | 1 + .../automation/dialogs/EditTriggerDialog.kt | 62 +++++- .../dialogs/TriggerListAdapter.java | 185 ------------------ .../automation/elements/StaticLabel.kt | 29 ++- .../events/EventAutomationUpdateAction.kt | 3 +- .../automation/events/EventTriggerChanged.kt | 5 + .../automation/events/EventTriggerClone.kt | 6 + .../automation/events/EventTriggerRemove.kt | 6 + .../general/automation/triggers/Trigger.kt | 84 +++++++- .../triggers/TriggerAutosensValue.kt | 2 +- .../general/automation/triggers/TriggerBg.kt | 6 +- .../automation/triggers/TriggerBolusAgo.kt | 2 +- .../general/automation/triggers/TriggerCOB.kt | 2 +- .../automation/triggers/TriggerConnector.kt | 107 +++++----- .../automation/triggers/TriggerDelta.kt | 2 +- .../general/automation/triggers/TriggerIob.kt | 2 +- .../automation/triggers/TriggerLocation.kt | 2 +- .../triggers/TriggerProfilePercent.kt | 2 +- .../triggers/TriggerPumpLastConnection.kt | 2 +- .../triggers/TriggerRecurringTime.kt | 2 +- .../automation/triggers/TriggerTempTarget.kt | 2 +- .../automation/triggers/TriggerTime.kt | 2 +- .../automation/triggers/TriggerTimeRange.kt | 2 +- .../automation/triggers/TriggerWifiSsid.kt | 4 +- 25 files changed, 244 insertions(+), 280 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/TriggerListAdapter.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerChanged.kt create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerClone.kt create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerRemove.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.kt index 26e4f74278..9dada7980d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.kt @@ -30,7 +30,7 @@ class AutomationEvent(private val mainApp: MainApp) { fun getPreconditions(): TriggerConnector { val trigger = TriggerConnector(mainApp, TriggerConnector.Type.AND) for (action in actions) { - action.precondition?.let { trigger.add(it) } + action.precondition?.let { trigger.list.add(it) } } return trigger } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt index 8678192f33..5b6bf4e3e8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt @@ -213,6 +213,7 @@ class AutomationPlugin @Inject constructor( fun getTriggerDummyObjects(): List { return listOf( + TriggerConnector(mainApp), TriggerTime(mainApp), TriggerRecurringTime(mainApp), TriggerTimeRange(mainApp), diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditTriggerDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditTriggerDialog.kt index 1b56362902..550e7f4ad6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditTriggerDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditTriggerDialog.kt @@ -9,8 +9,16 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger +import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerChanged +import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerClone +import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerRemove import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger +import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDummy +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.extensions.plusAssign +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable import kotlinx.android.synthetic.main.automation_dialog_edit_trigger.* import org.json.JSONObject import javax.inject.Inject @@ -18,14 +26,17 @@ import javax.inject.Inject class EditTriggerDialog : DialogFragmentWithDate() { @Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var mainApp: MainApp + @Inject lateinit var fabricPrivacy: FabricPrivacy - private var trigger: Trigger? = null + private var disposable: CompositeDisposable = CompositeDisposable() + + private var triggers: Trigger? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { // load data from bundle (savedInstanceState ?: arguments)?.let { bundle -> - bundle.getString("trigger")?.let { trigger = TriggerDummy(mainApp).instantiate(JSONObject(it)) } + bundle.getString("trigger")?.let { triggers = TriggerDummy(mainApp).instantiate(JSONObject(it)) } } onCreateViewGeneral() @@ -35,17 +46,58 @@ class EditTriggerDialog : DialogFragmentWithDate() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + disposable += rxBus + .toObservable(EventTriggerChanged::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + automation_layoutTrigger.removeAllViews() + triggers?.generateDialog(automation_layoutTrigger) + }, { fabricPrivacy.logException(it) }) + disposable += rxBus + .toObservable(EventTriggerRemove::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + findParent(triggers, it.trigger)?.list?.remove(it.trigger) + automation_layoutTrigger.removeAllViews() + triggers?.generateDialog(automation_layoutTrigger) + }, { fabricPrivacy.logException(it) }) + + disposable += rxBus + .toObservable(EventTriggerClone::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ + findParent(triggers, it.trigger)?.list?.add(it.trigger.duplicate()) + automation_layoutTrigger.removeAllViews() + triggers?.generateDialog(automation_layoutTrigger) + }, { fabricPrivacy.logException(it) }) + // display root trigger - trigger?.generateDialog(automation_layoutTrigger) + triggers?.generateDialog(automation_layoutTrigger) + } + + override fun onDestroyView() { + super.onDestroyView() + disposable.clear() } override fun submit(): Boolean { - trigger?.let { trigger -> rxBus.send(EventAutomationUpdateTrigger(trigger)) } + triggers?.let { trigger -> rxBus.send(EventAutomationUpdateTrigger(trigger)) } return true } override fun onSaveInstanceState(savedInstanceState: Bundle) { super.onSaveInstanceState(savedInstanceState) - trigger?.let { savedInstanceState.putString("trigger", it.toJSON()) } + triggers?.let { savedInstanceState.putString("trigger", it.toJSON()) } + } + + private fun findParent(where: Trigger?, what: Trigger): TriggerConnector? { + if (where == null) return null + if (where is TriggerConnector) { + for (i in where.list) { + if (i == what) return where + if (i is TriggerConnector) return findParent(i, what) + } + } + return null } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/TriggerListAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/TriggerListAdapter.java deleted file mode 100644 index 78b285e5d4..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/TriggerListAdapter.java +++ /dev/null @@ -1,185 +0,0 @@ -package info.nightscout.androidaps.plugins.general.automation.dialogs; - -import android.content.Context; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.Spinner; - -import androidx.fragment.app.FragmentManager; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger; -import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector; -import info.nightscout.androidaps.utils.resources.ResourceHelper; - -public class TriggerListAdapter { - private final LinearLayout mRootLayout; - private final Context mContext; - private final TriggerConnector rootTrigger; - private final MainApp mainApp; - private final ResourceHelper resourceHelper; - - public TriggerListAdapter(MainApp mainApp, ResourceHelper resourceHelper, LinearLayout rootLayout, TriggerConnector rootTrigger) { - mRootLayout = rootLayout; - this.mainApp = mainApp; - this.resourceHelper = resourceHelper; - mContext = rootLayout.getContext(); - this.rootTrigger = rootTrigger; - build(rootLayout.getContext()); - } - - private void destroy() { - mRootLayout.removeAllViews(); - } - - private void rebuild(Context context) { - destroy(); - build(context); - } - - private void build(Context context) { - FragmentManager fragmentManager = Trigger.scanForActivity(context).getSupportFragmentManager(); - for (int i = 0; i < rootTrigger.size(); ++i) { - final Trigger trigger = rootTrigger.get(i); - - // spinner - if (i > 0) { - createSpinner(trigger, context); - } - - // trigger layout - trigger.generateDialog(mRootLayout); - - // buttons - createButtons(mRootLayout, trigger, context); - } - - if (rootTrigger.size() == 0) { - Button buttonAdd = new Button(mContext); - buttonAdd.setText(resourceHelper.gs(R.string.addnew)); - buttonAdd.setOnClickListener(v -> { - ChooseTriggerDialog dialog = new ChooseTriggerDialog(); - dialog.setOnClickListener(newTriggerObject -> { - rootTrigger.add(newTriggerObject); - rebuild(context); - }); - dialog.show(fragmentManager, "ChooseTriggerDialog"); - }); - mRootLayout.addView(buttonAdd); - } - } - - private Spinner createSpinner() { - Spinner spinner = new Spinner(mContext); - ArrayAdapter spinnerArrayAdapter = new ArrayAdapter<>(mContext, R.layout.spinner_centered, TriggerConnector.Type.AND.labels(resourceHelper)); - spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - spinner.setAdapter(spinnerArrayAdapter); - return spinner; - } - - private void createSpinner(Trigger trigger, Context context) { - final TriggerConnector connector = trigger.getConnector(); - final int initialPosition = connector.getConnectorType().ordinal(); - Spinner spinner = createSpinner(); - spinner.setSelection(initialPosition); - spinner.setBackgroundColor(resourceHelper.gc(R.color.black_overlay)); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT - ); - params.setMargins(0, resourceHelper.dpToPx(8), 0, resourceHelper.dpToPx(8)); - spinner.setLayoutParams(params); - spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - if (position != initialPosition) { - // connector type changed - changeConnector(context, trigger, connector, TriggerConnector.Type.values()[position]); - } - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - mRootLayout.addView(spinner); - } - - private void createButtons(LinearLayout rootLayout, Trigger trigger, Context context) { - FragmentManager fragmentManager = Trigger.scanForActivity(context).getSupportFragmentManager(); - // do not create buttons for TriggerConnector - if (trigger instanceof TriggerConnector) { - return; - } - - // Button Layout - LinearLayout buttonLayout = new LinearLayout(mContext); - buttonLayout.setOrientation(LinearLayout.HORIZONTAL); - buttonLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); - - // Button [-] - Button buttonRemove = new Button(mContext); - buttonRemove.setText(resourceHelper.gs(R.string.delete_short)); - buttonRemove.setOnClickListener(v -> { - final TriggerConnector connector = trigger.getConnector(); - connector.remove(trigger); - connector.simplify(); - rebuild(context); - }); - buttonLayout.addView(buttonRemove); - - // Button [+] - Button buttonAdd = new Button(mContext); - buttonAdd.setText(resourceHelper.gs(R.string.add_short)); - buttonAdd.setOnClickListener(v -> { - ChooseTriggerDialog dialog = new ChooseTriggerDialog(); - dialog.show(fragmentManager, "ChooseTriggerDialog"); - dialog.setOnClickListener(newTriggerObject -> { - TriggerConnector connector = trigger.getConnector(); - connector.add(connector.pos(trigger) + 1, newTriggerObject); - connector.simplify(); - rebuild(context); - }); - }); - buttonLayout.addView(buttonAdd); - - // Button [*] - Button buttonCopy = new Button(mContext); - buttonCopy.setText(resourceHelper.gs(R.string.copy_short)); - buttonCopy.setOnClickListener(v -> { - TriggerConnector connector = trigger.getConnector(); - connector.add(connector.pos(trigger) + 1, trigger.duplicate()); - connector.simplify(); - rebuild(context); - }); - buttonLayout.addView(buttonCopy); - rootLayout.addView(buttonLayout); - } - - public void changeConnector(final Context context, final Trigger trigger, final TriggerConnector connector, final TriggerConnector.Type newConnectorType) { - if (connector.size() > 2) { - // split connector - int pos = connector.pos(trigger) - 1; - - TriggerConnector newConnector = new TriggerConnector(mainApp, newConnectorType); - - // move trigger from pos and pos+1 into new connector - for (int i = 0; i < 2; ++i) { - Trigger t = connector.get(pos); - newConnector.add(t); - connector.remove(t); - } - - connector.add(pos, newConnector); - } else { - connector.setType(newConnectorType); - } - connector.simplify(); - rebuild(context); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/StaticLabel.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/StaticLabel.kt index 807e4cc7f0..f949a16722 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/StaticLabel.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/StaticLabel.kt @@ -1,30 +1,45 @@ package info.nightscout.androidaps.plugins.general.automation.elements import android.graphics.Typeface +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.plugins.general.automation.triggers.Trigger class StaticLabel(mainApp: MainApp) : Element(mainApp) { var label = "" + var trigger: Trigger? = null - constructor(mainApp: MainApp, label: String) : this(mainApp) { + constructor(mainApp: MainApp, label: String, trigger: Trigger) : this(mainApp) { this.label = label + this.trigger = trigger } - constructor(mainApp: MainApp, resourceId: Int) : this(mainApp) { + constructor(mainApp: MainApp, resourceId: Int, trigger: Trigger) : this(mainApp) { label = resourceHelper.gs(resourceId) + this.trigger = trigger } - override fun addToLayout(root: LinearLayout) { // text view pre element + override fun addToLayout(root: LinearLayout) { + val headerLayout = LinearLayout(root.context) + headerLayout.orientation = LinearLayout.HORIZONTAL + headerLayout.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + headerLayout.setBackgroundColor(resourceHelper.gc(android.R.color.black)) + // text val px = resourceHelper.dpToPx(10) val textView = TextView(root.context) textView.text = label - // textViewPre.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + val params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) + params.weight = 1.0f + textView.layoutParams = params textView.setPadding(px, px, px, px) textView.setTypeface(textView.typeface, Typeface.BOLD) - textView.setBackgroundColor(resourceHelper.gc(R.color.mdtp_line_dark)) - root.addView(textView) + headerLayout.addView(textView) + trigger?.let { + headerLayout.addView(it.createDeleteButton(root.context, it)) + headerLayout.addView(it.createCloneButton(root.context, it)) + } + root.addView(headerLayout) } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventAutomationUpdateAction.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventAutomationUpdateAction.kt index 6fa6709cf1..3def1053ac 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventAutomationUpdateAction.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventAutomationUpdateAction.kt @@ -3,5 +3,4 @@ package info.nightscout.androidaps.plugins.general.automation.events import info.nightscout.androidaps.events.Event import info.nightscout.androidaps.plugins.general.automation.actions.Action -class EventAutomationUpdateAction(val action: Action, val position : Int) : Event() { -} \ No newline at end of file +class EventAutomationUpdateAction(val action: Action, val position: Int) : Event() \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerChanged.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerChanged.kt new file mode 100644 index 0000000000..7e0eaaad45 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerChanged.kt @@ -0,0 +1,5 @@ +package info.nightscout.androidaps.plugins.general.automation.events + +import info.nightscout.androidaps.events.Event + +class EventTriggerChanged : Event() \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerClone.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerClone.kt new file mode 100644 index 0000000000..3bb996a642 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerClone.kt @@ -0,0 +1,6 @@ +package info.nightscout.androidaps.plugins.general.automation.events + +import info.nightscout.androidaps.events.Event +import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger + +class EventTriggerClone(val trigger: Trigger) : Event() \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerRemove.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerRemove.kt new file mode 100644 index 0000000000..6c502a10f5 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/events/EventTriggerRemove.kt @@ -0,0 +1,6 @@ +package info.nightscout.androidaps.plugins.general.automation.events + +import info.nightscout.androidaps.events.Event +import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger + +class EventTriggerRemove(val trigger: Trigger) : Event() \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.kt index 782121af3d..0c214e384c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.kt @@ -2,14 +2,22 @@ package info.nightscout.androidaps.plugins.general.automation.triggers import android.content.Context import android.content.ContextWrapper +import android.view.Gravity +import android.widget.ImageButton import android.widget.LinearLayout import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import com.google.common.base.Optional import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction +import info.nightscout.androidaps.plugins.general.automation.dialogs.ChooseTriggerDialog +import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerChanged +import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerClone +import info.nightscout.androidaps.plugins.general.automation.events.EventTriggerRemove import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.services.LocationService @@ -22,16 +30,15 @@ import kotlin.reflect.full.primaryConstructor abstract class Trigger(val mainApp: MainApp) { @Inject lateinit var aapsLogger: AAPSLogger + @Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var profileFunction: ProfileFunction - @Inject lateinit var sp : SP + @Inject lateinit var sp: SP @Inject lateinit var locationService: LocationService @Inject lateinit var treatmentsPlugin: TreatmentsPlugin @Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin @Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin - var connector: TriggerConnector? = null - init { mainApp.androidInjector().inject(this) } @@ -45,14 +52,15 @@ abstract class Trigger(val mainApp: MainApp) { abstract fun icon(): Optional abstract fun duplicate(): Trigger - companion object { @JvmStatic fun scanForActivity(cont: Context?): AppCompatActivity? { - if (cont == null) return null - else if (cont is AppCompatActivity) return cont - else if (cont is ContextWrapper) return scanForActivity(cont.baseContext) - return null + when (cont) { + null -> return null + is AppCompatActivity -> return cont + is ContextWrapper -> return scanForActivity(cont.baseContext) + else -> return null + } } } @@ -80,4 +88,64 @@ abstract class Trigger(val mainApp: MainApp) { } return null } + + fun createAddButton(context: Context, trigger: TriggerConnector): ImageButton { + // Button [+] + val buttonAdd = ImageButton(context) + val params = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ) + params.gravity = Gravity.CENTER + buttonAdd.layoutParams = params + buttonAdd.setImageResource(R.drawable.add) + buttonAdd.contentDescription = resourceHelper.gs(R.string.add_short) + buttonAdd.setOnClickListener { + scanForActivity(context)?.supportFragmentManager?.let { + val dialog = ChooseTriggerDialog() + dialog.show(it, "ChooseTriggerDialog") + dialog.setOnClickListener(object : ChooseTriggerDialog.OnClickListener { + override fun onClick(newTriggerObject: Trigger) { + trigger.list.add(newTriggerObject) + rxBus.send(EventTriggerChanged()) + } + }) + } + } + return buttonAdd + } + + fun createDeleteButton(context: Context, trigger: Trigger): ImageButton { + // Button [-] + val buttonRemove = ImageButton(context) + val params = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ) + params.gravity = Gravity.CENTER + buttonRemove.layoutParams = params + buttonRemove.setImageResource(R.drawable.remove) + buttonRemove.contentDescription = resourceHelper.gs(R.string.delete_short) + buttonRemove.setOnClickListener { + rxBus.send(EventTriggerRemove(trigger)) + } + return buttonRemove + } + + fun createCloneButton(context: Context, trigger: Trigger): ImageButton { + // Button [*] + val buttonClone = ImageButton(context) + val params = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ) + params.gravity = Gravity.CENTER + buttonClone.layoutParams = params + buttonClone.setImageResource(R.drawable.clone) + buttonClone.contentDescription = resourceHelper.gs(R.string.copy_short) + buttonClone.setOnClickListener { + rxBus.send(EventTriggerClone(trigger)) + } + return buttonClone + } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValue.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValue.kt index c2e552e7de..3ce4d72950 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValue.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValue.kt @@ -74,7 +74,7 @@ class TriggerAutosensValue(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.autosenslabel)) + .add(StaticLabel(mainApp, R.string.autosenslabel, this)) .add(comparator) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.autosenslabel) + ": ", "", autosens)) .build(root) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBg.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBg.kt index 1346ed7daa..f5e3e17d04 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBg.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBg.kt @@ -20,12 +20,12 @@ class TriggerBg(mainApp: MainApp) : Trigger(mainApp) { private var bg = InputBg(mainApp) var comparator = Comparator(mainApp) - constructor(mainApp: MainApp, value : Double, units : String, compare: Comparator.Compare) : this(mainApp){ + constructor(mainApp: MainApp, value: Double, units: String, compare: Comparator.Compare) : this(mainApp) { bg = InputBg(mainApp, value, units) comparator = Comparator(mainApp, compare) } - constructor(mainApp: MainApp, triggerBg: TriggerBg) : this(mainApp){ + constructor(mainApp: MainApp, triggerBg: TriggerBg) : this(mainApp) { bg = InputBg(mainApp, triggerBg.bg.value, triggerBg.bg.units) comparator = Comparator(mainApp, triggerBg.comparator.value) } @@ -82,7 +82,7 @@ class TriggerBg(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.glucose)) + .add(StaticLabel(mainApp, R.string.glucose, this)) .add(comparator) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.glucose_u, bg.units), "", bg)) .build(root) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt index 4edbd03bc7..fc1888a0f6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt @@ -73,7 +73,7 @@ class TriggerBolusAgo(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.lastboluslabel)) + .add(StaticLabel(mainApp, R.string.lastboluslabel, this)) .add(comparator) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.lastboluslabel) + ": ", "", minutesAgo)) .build(root) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerCOB.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerCOB.kt index 54df75427c..58ae143167 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerCOB.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerCOB.kt @@ -73,7 +73,7 @@ class TriggerCOB(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.triggercoblabel)) + .add(StaticLabel(mainApp, R.string.triggercoblabel, this)) .add(comparator) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.triggercoblabel) + ": ", "", cob)) .build(root) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerConnector.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerConnector.kt index cd0913e6c4..612916b522 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerConnector.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerConnector.kt @@ -1,13 +1,17 @@ package info.nightscout.androidaps.plugins.general.automation.triggers +import android.content.Context +import android.view.View import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.ArrayAdapter import android.widget.LinearLayout +import android.widget.Spinner import androidx.annotation.StringRes 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.dialogs.TriggerListAdapter import info.nightscout.androidaps.utils.JsonHelper.safeGetString import info.nightscout.androidaps.utils.resources.ResourceHelper import org.json.JSONArray @@ -16,7 +20,9 @@ import java.util.* class TriggerConnector(mainApp: MainApp) : Trigger(mainApp) { var list: MutableList = ArrayList() - var connectorType: Type = Type.AND + private var connectorType: Type = Type.AND + // TODO move to TriggerConnector + //var connector: TriggerConnector = TriggerConnector(mainApp, TriggerConnector.Type.AND) enum class Type { AND, OR, XOR; @@ -35,12 +41,14 @@ class TriggerConnector(mainApp: MainApp) : Trigger(mainApp) { AND -> R.string.and } - fun labels(resourceHelper: ResourceHelper): List { - val list: MutableList = ArrayList() - for (t in values()) { - list.add(resourceHelper.gs(t.stringRes)) + companion object { + fun labels(resourceHelper: ResourceHelper): List { + val list: MutableList = ArrayList() + for (t in values()) { + list.add(resourceHelper.gs(t.stringRes)) + } + return list } - return list } } @@ -52,25 +60,8 @@ class TriggerConnector(mainApp: MainApp) : Trigger(mainApp) { connectorType = type } - @Synchronized - fun add(t: Trigger) { - list.add(t) - t.connector = this - } - - @Synchronized - fun add(pos: Int, t: Trigger) { - list.add(pos, t) - t.connector = this - } - - @Synchronized - fun remove(t: Trigger): Boolean = list.remove(t) - fun size(): Int = list.size - operator fun get(i: Int): Trigger = list[i] - fun pos(trigger: Trigger): Int { for (i in list.indices) { if (list[i] === trigger) return i @@ -109,7 +100,7 @@ class TriggerConnector(mainApp: MainApp) : Trigger(mainApp) { list.clear() for (i in 0 until array.length()) { instantiate(JSONObject(array.getString(i)))?.let { - add(it) + list.add(it) } } return this @@ -135,42 +126,48 @@ class TriggerConnector(mainApp: MainApp) : Trigger(mainApp) { val padding = resourceHelper.dpToPx(5) root.setPadding(padding, padding, padding, padding) root.setBackgroundResource(R.drawable.border_automation_unit) + // Header with spinner + val headerLayout = LinearLayout(root.context) + headerLayout.orientation = LinearLayout.HORIZONTAL + headerLayout.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + headerLayout.addView(createSpinner(root.context)) + headerLayout.addView(createAddButton(root.context, this)) + headerLayout.addView(createDeleteButton(root.context, this)) + root.addView(headerLayout) + // Child triggers val listLayout = LinearLayout(root.context) listLayout.orientation = LinearLayout.VERTICAL - listLayout.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + listLayout.setBackgroundColor(resourceHelper.gc(R.color.mdtp_line_dark)) + //listLayout.setPadding(resourceHelper.dpToPx(5), resourceHelper.dpToPx(5), resourceHelper.dpToPx(5), 0) + val params = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + params.setMargins(resourceHelper.dpToPx(15), 0, resourceHelper.dpToPx(5), resourceHelper.dpToPx(4)) + listLayout.layoutParams = params + for (t in list) t.generateDialog(listLayout) root.addView(listLayout) - TriggerListAdapter(mainApp, resourceHelper, listLayout, this) } - fun simplify(): TriggerConnector { // simplify children - for (i in 0 until size()) { - if (get(i) is TriggerConnector) { - val t = get(i) as TriggerConnector - t.simplify() + private fun createSpinner(context: Context): Spinner { + val initialPosition = connectorType.ordinal + val spinner = Spinner(context) + val spinnerArrayAdapter = ArrayAdapter(context, R.layout.spinner_centered, Type.labels(resourceHelper)) + spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + spinner.adapter = spinnerArrayAdapter + spinner.setSelection(initialPosition) + spinner.setBackgroundColor(resourceHelper.gc(R.color.black_overlay)) + val params = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ) + params.setMargins(0, resourceHelper.dpToPx(8), 0, resourceHelper.dpToPx(8)) + params.weight = 1.0f + spinner.layoutParams = params + spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) { + setType(Type.values()[position]) } + + override fun onNothingSelected(parent: AdapterView<*>?) {} } - // drop connector with only 1 element - if (size() == 1 && get(0) is TriggerConnector) { - val c = get(0) as TriggerConnector - remove(c) - connectorType = c.connectorType - for (t in c.list) add(t) - c.list.clear() - return simplify() - } - // merge connectors - connector?.let { connector -> - if (connector.connectorType == connectorType || size() == 1) { - val pos = connector.pos(this) - connector.remove(this) - // move triggers of child connector into parent connector - for (i in size() - 1 downTo 0) { - connector.add(pos, get(i)) - } - list.clear() - return connector.simplify() - } - } - return this + return spinner } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.kt index d44ab280c7..4470f94fe3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.kt @@ -98,7 +98,7 @@ class TriggerDelta(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.deltalabel)) + .add(StaticLabel(mainApp, R.string.deltalabel, this)) .add(comparator) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.deltalabel_u, units) + ": ", "", delta)) .build(root) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerIob.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerIob.kt index 9c81937ed9..04c4b49ed4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerIob.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerIob.kt @@ -64,7 +64,7 @@ class TriggerIob(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.iob)) + .add(StaticLabel(mainApp, R.string.iob, this)) .add(comparator) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.iob_u), "", insulin)) .build(root) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerLocation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerLocation.kt index 5a7c48db3d..82bbf89556 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerLocation.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerLocation.kt @@ -92,7 +92,7 @@ class TriggerLocation(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.location)) + .add(StaticLabel(mainApp, R.string.location, this)) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.name_short), "", name)) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.latitude_short), "", latitude)) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.longitude_short), "", longitude)) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerProfilePercent.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerProfilePercent.kt index bcdcf48af3..9de445e790 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerProfilePercent.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerProfilePercent.kt @@ -73,7 +73,7 @@ class TriggerProfilePercent(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.profilepercentage)) + .add(StaticLabel(mainApp, R.string.profilepercentage, this)) .add(comparator) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.percent_u), "", pct)) .build(root) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerPumpLastConnection.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerPumpLastConnection.kt index aec4cfee4f..4a4e62f2c3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerPumpLastConnection.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerPumpLastConnection.kt @@ -73,7 +73,7 @@ class TriggerPumpLastConnection(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.automation_trigger_pump_last_connection_label)) + .add(StaticLabel(mainApp, R.string.automation_trigger_pump_last_connection_label, this)) .add(comparator) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.automation_trigger_pump_last_connection_description) + ": ", "", minutesAgo)) .build(root) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt index 678b6ccf62..e3f1029af9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt @@ -94,7 +94,7 @@ class TriggerRecurringTime(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.recurringTime)) + .add(StaticLabel(mainApp, R.string.recurringTime, this)) .add(days) .add(time) .build(root) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTempTarget.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTempTarget.kt index edd144f14f..1a4d5593c8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTempTarget.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTempTarget.kt @@ -62,7 +62,7 @@ class TriggerTempTarget(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.careportal_temporarytarget)) + .add(StaticLabel(mainApp, R.string.careportal_temporarytarget, this)) .add(comparator) .build(root) } 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 7f7d137eb4..a4fa0dce0e 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 @@ -60,7 +60,7 @@ class TriggerTime(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.time)) + .add(StaticLabel(mainApp, R.string.time, this)) .add(time) .build(root) } 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 79fcc0876d..543c4096d4 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 @@ -76,7 +76,7 @@ class TriggerTimeRange(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.time_range)) + .add(StaticLabel(mainApp, R.string.time_range, this)) .add(range) .build(root) } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerWifiSsid.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerWifiSsid.kt index 83da0d1f44..54aacf8199 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerWifiSsid.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerWifiSsid.kt @@ -44,7 +44,7 @@ class TriggerWifiSsid(mainApp: MainApp) : Trigger(mainApp) { override fun toJSON(): String { val data = JSONObject() - .put("ssid", ssid) + .put("ssid", ssid.value) .put("comparator", comparator.value.toString()) return JSONObject() .put("type", this::class.java.name) @@ -70,7 +70,7 @@ class TriggerWifiSsid(mainApp: MainApp) : Trigger(mainApp) { override fun generateDialog(root: LinearLayout) { LayoutBuilder() - .add(StaticLabel(mainApp, R.string.ns_wifi_ssids)) + .add(StaticLabel(mainApp, R.string.ns_wifi_ssids, this)) .add(comparator) .add(LabelWithElement(mainApp, resourceHelper.gs(R.string.ns_wifi_ssids) + ": ", "", ssid)) .build(root)