Implement temp target dialog for automation action
This commit is contained in:
parent
91e4b01f10
commit
c074ec36c4
11 changed files with 359 additions and 12 deletions
|
@ -27,6 +27,7 @@ import info.nightscout.androidaps.R;
|
|||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.ChooseTriggerDialog;
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditActionDialog;
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog;
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
||||
|
@ -134,7 +135,10 @@ public class AutomationFragment extends SubscriberFragment {
|
|||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
final Action action = mActionList.get(position);
|
||||
holder.actionTitle.setText(action.friendlyName());
|
||||
holder.itemRoot.setOnClickListener(v -> action.openConfigurationDialog(mFragmentManager));
|
||||
holder.itemRoot.setOnClickListener(v -> {
|
||||
EditActionDialog dialog = EditActionDialog.newInstance(action);
|
||||
dialog.show(mFragmentManager, "EditActionDialog");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.actions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
@ -13,7 +16,9 @@ public abstract class Action {
|
|||
|
||||
abstract void doAction(Callback callback);
|
||||
|
||||
public void openConfigurationDialog(FragmentManager manager) { }
|
||||
public void generateDialog(LinearLayout root) { }
|
||||
|
||||
public void saveFromDialog() { }
|
||||
|
||||
public String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
|
|
|
@ -1,23 +1,38 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.actions;
|
||||
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputBg;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Label;
|
||||
import info.nightscout.androidaps.queue.Callback;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
|
||||
public class ActionStartTempTarget extends Action {
|
||||
|
||||
private double value;
|
||||
private int durationInMinutes;
|
||||
private String reason;
|
||||
private String units = Constants.MGDL;
|
||||
private double valueInMgdl;
|
||||
private String units;
|
||||
private int durationInMinutes;
|
||||
|
||||
private InputBg inputBg;
|
||||
private InputDuration inputDuration;
|
||||
|
||||
public ActionStartTempTarget() {
|
||||
units = Constants.MGDL;
|
||||
}
|
||||
|
||||
public ActionStartTempTarget(String units) {
|
||||
this.units = Constants.MGDL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
|
@ -26,15 +41,29 @@ public class ActionStartTempTarget extends Action {
|
|||
|
||||
@Override
|
||||
void doAction(Callback callback) {
|
||||
double converted = Profile.toMgdl(value, units);
|
||||
TempTarget tempTarget = new TempTarget().date(DateUtil.now()).duration(durationInMinutes).reason(reason).source(Source.USER).low(converted).high(converted);
|
||||
TempTarget tempTarget = new TempTarget().date(DateUtil.now()).duration(durationInMinutes).reason(reason).source(Source.USER).low(valueInMgdl).high(valueInMgdl);
|
||||
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
|
||||
if (callback != null)
|
||||
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openConfigurationDialog(FragmentManager manager) {
|
||||
public void generateDialog(LinearLayout root) {
|
||||
inputBg = new InputBg(units);
|
||||
if (valueInMgdl != 0d) inputBg.setMgdl(valueInMgdl);
|
||||
inputDuration = new InputDuration(durationInMinutes, InputDuration.TimeUnit.MINUTES);
|
||||
|
||||
int unitResId = units.equals(Constants.MGDL) ? R.string.mgdl : R.string.mmol;
|
||||
Label labelBg = new Label(MainApp.gs(R.string.careportal_newnstreatment_percentage_label), MainApp.gs(unitResId), inputBg);
|
||||
labelBg.generateDialog(root);
|
||||
|
||||
Label labelDuration = new Label(MainApp.gs(R.string.careportal_newnstreatment_duration_min_label), "min", inputDuration);
|
||||
labelDuration.generateDialog(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveFromDialog() {
|
||||
valueInMgdl = inputBg.getMgdl();
|
||||
durationInMinutes = inputDuration.getMinutes();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.dialogs;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.Unbinder;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||
|
||||
public class EditActionDialog extends DialogFragment {
|
||||
private Unbinder mUnbinder;
|
||||
private Action mAction;
|
||||
|
||||
@BindView(R.id.layout_root)
|
||||
LinearLayout mRootLayout;
|
||||
|
||||
@BindView(R.id.viewActionTitle)
|
||||
TextView mViewActionTitle;
|
||||
|
||||
public static EditActionDialog newInstance(Action action) {
|
||||
Bundle args = new Bundle();
|
||||
EditActionDialog fragment = new EditActionDialog();
|
||||
fragment.setArguments(args);
|
||||
fragment.mAction = action;
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.automation_dialog_action, container, false);
|
||||
mUnbinder = ButterKnife.bind(this, view);
|
||||
|
||||
mViewActionTitle.setText(mAction.friendlyName());
|
||||
mRootLayout.removeAllViews();
|
||||
mAction.generateDialog(mRootLayout);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
mUnbinder.unbind();
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
@OnClick(R.id.ok)
|
||||
public void onButtonOk(View view) {
|
||||
mAction.saveFromDialog();
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@OnClick(R.id.cancel)
|
||||
public void onButtonCancel(View view) {
|
||||
dismiss();
|
||||
}
|
||||
}
|
|
@ -22,7 +22,6 @@ import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
|
|||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
||||
|
||||
public class EditEventDialog extends DialogFragment {
|
||||
|
||||
private static AutomationEvent mEvent;
|
||||
|
||||
@BindView(R.id.inputEventTitle)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
public class Element {
|
||||
public void generateDialog(LinearLayout root) { }
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
|
||||
public class InputBg extends Element {
|
||||
final private TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
// TODO: validate inputs
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
};
|
||||
|
||||
private String units;
|
||||
private double value;
|
||||
private final double minValue, maxValue, step;
|
||||
private final DecimalFormat decimalFormat;
|
||||
|
||||
public InputBg(String units) {
|
||||
this.units = units;
|
||||
|
||||
// set default initial value
|
||||
if (units.equals(Constants.MMOL)) {
|
||||
// mmol
|
||||
value = 5.5;
|
||||
minValue = 2;
|
||||
maxValue = 30;
|
||||
step = 0.1;
|
||||
decimalFormat = new DecimalFormat("0.0");
|
||||
} else {
|
||||
// mg/dL
|
||||
value = 100;
|
||||
minValue = 36;
|
||||
maxValue = 540;
|
||||
step = 1;
|
||||
decimalFormat = new DecimalFormat("0");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root) {
|
||||
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
|
||||
numberPicker.setParams(0d, minValue, maxValue, step, decimalFormat, false, textWatcher);
|
||||
numberPicker.setValue(value);
|
||||
numberPicker.setOnValueChangedListener(value -> this.value = value);
|
||||
root.addView(numberPicker);
|
||||
}
|
||||
|
||||
public String getUnits() {
|
||||
return units;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public double getMgdl() {
|
||||
return Profile.toMgdl(value, units);
|
||||
}
|
||||
|
||||
public void setMgdl(double value) {
|
||||
this.value = Profile.fromMgdlToUnits(value, units);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
|
||||
public class InputDuration extends Element {
|
||||
public enum TimeUnit {
|
||||
MINUTES,
|
||||
HOURS
|
||||
}
|
||||
|
||||
private TimeUnit unit;
|
||||
private double value;
|
||||
|
||||
public InputDuration(double value, TimeUnit unit) {
|
||||
this.unit = unit;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root) {
|
||||
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
|
||||
if (unit.equals(TimeUnit.MINUTES)) {
|
||||
// Minutes
|
||||
numberPicker.setParams(0d, 0d, 24 * 60d, 10d, new DecimalFormat("0"), false);
|
||||
} else {
|
||||
// Hours
|
||||
numberPicker.setParams(0d, 0d, 24d, 1d, new DecimalFormat("0"), false);
|
||||
}
|
||||
numberPicker.setValue(value);
|
||||
numberPicker.setOnValueChangedListener(value -> this.value = value);
|
||||
root.addView(numberPicker);
|
||||
}
|
||||
|
||||
public TimeUnit getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public int getMinutes() {
|
||||
if (unit.equals(TimeUnit.MINUTES)) {
|
||||
return (int)value;
|
||||
} else {
|
||||
return (int)(value * 60d);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
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;
|
||||
|
||||
public class Label extends Element {
|
||||
private final Element element;
|
||||
private final String textPre;
|
||||
private final String textPost;
|
||||
|
||||
public Label(String textPre, String textPost, Element element) {
|
||||
this.element = element;
|
||||
this.textPre = textPre;
|
||||
this.textPost = textPost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root) {
|
||||
// container layout
|
||||
LinearLayout layout = new LinearLayout(root.getContext());
|
||||
layout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
layout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
// text view pre element
|
||||
int px = MainApp.dpToPx(10);
|
||||
TextView textViewPre = new TextView(root.getContext());
|
||||
textViewPre.setText(textPre);
|
||||
textViewPre.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
textViewPre.setWidth(MainApp.dpToPx(120));
|
||||
textViewPre.setPadding(px, px, px, px);
|
||||
textViewPre.setTypeface(textViewPre.getTypeface(), Typeface.BOLD);
|
||||
layout.addView(textViewPre);
|
||||
|
||||
// add element to layout
|
||||
element.generateDialog(layout);
|
||||
|
||||
// text view post element
|
||||
if (textPost != null) {
|
||||
px = MainApp.dpToPx(5);
|
||||
TextView textViewPost = new TextView(root.getContext());
|
||||
textViewPost.setText(textPost);
|
||||
textViewPost.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
textViewPost.setWidth(MainApp.dpToPx(45));
|
||||
textViewPost.setPadding(px, px, px, px);
|
||||
textViewPost.setTypeface(textViewPost.getTypeface(), Typeface.BOLD);
|
||||
layout.addView(textViewPost);
|
||||
}
|
||||
|
||||
// add layout to root layout
|
||||
root.addView(layout);
|
||||
}
|
||||
}
|
|
@ -177,7 +177,7 @@ public class TriggerBg extends Trigger {
|
|||
layout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
root.addView(layout);
|
||||
|
||||
// input filed for threshold
|
||||
// input field for threshold
|
||||
NumberPicker numberPicker = new NumberPicker(context, null);
|
||||
numberPicker.setParams(0d, 0d, (double) 500, 1d, new DecimalFormat("0"), false, textWatcher);
|
||||
numberPicker.setValue(threshold);
|
||||
|
|
39
app/src/main/res/layout/automation_dialog_action.xml
Normal file
39
app/src/main/res/layout/automation_dialog_action.xml
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:minWidth="300dp"
|
||||
android:padding="10dp">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/viewActionTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:paddingBottom="10dp"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:focusableInTouchMode="true"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp"
|
||||
android:id="@+id/layout_root" />
|
||||
|
||||
<include layout="@layout/mdtp_done_button" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
Loading…
Reference in a new issue