Work on automation plugin.
- Add MainApp.dpToPx() helper function - Remove trigger layout resources - Generate trigger layout programmatically - Improve ux (when composing trigger logic) - Refactoring
This commit is contained in:
parent
c60aae8630
commit
f98d40f71b
12 changed files with 324 additions and 189 deletions
|
@ -397,4 +397,9 @@ public class MainApp extends Application {
|
|||
sDatabaseHelper = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static int dpToPx(int dp) {
|
||||
float scale = sResources.getDisplayMetrics().density;
|
||||
return (int) (dp*scale + 0.5f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
|
@ -9,7 +10,10 @@ import android.support.v7.widget.RecyclerView;
|
|||
import android.view.LayoutInflater;
|
||||
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 android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -18,10 +22,12 @@ import java.util.List;
|
|||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
|
||||
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;
|
||||
|
||||
public class AutomationFragment extends SubscriberFragment {
|
||||
|
||||
|
@ -110,35 +116,98 @@ public class AutomationFragment extends SubscriberFragment {
|
|||
*/
|
||||
public static class TriggerListAdapter {
|
||||
private final LinearLayout mRootLayout;
|
||||
private final LayoutInflater mInflater;
|
||||
private final Context mContext;
|
||||
private final List<Trigger> mTriggerList;
|
||||
|
||||
public TriggerListAdapter(LayoutInflater inflater, LinearLayout rootLayout, List<Trigger> triggers) {
|
||||
public TriggerListAdapter(Context context, LinearLayout rootLayout, List<Trigger> triggers) {
|
||||
mRootLayout = rootLayout;
|
||||
mInflater = inflater;
|
||||
mContext = context;
|
||||
mTriggerList = triggers;
|
||||
build();
|
||||
}
|
||||
|
||||
public TriggerListAdapter(LayoutInflater inflater, LinearLayout rootLayout, Trigger trigger) {
|
||||
public TriggerListAdapter(Context context, LinearLayout rootLayout, Trigger trigger) {
|
||||
mRootLayout = rootLayout;
|
||||
mInflater = inflater;
|
||||
mContext = context;
|
||||
mTriggerList = new ArrayList<>();
|
||||
mTriggerList.add(trigger);
|
||||
build();
|
||||
}
|
||||
|
||||
|
||||
public void destroy() {
|
||||
mRootLayout.removeAllViews();
|
||||
for(Trigger trigger : mTriggerList) {
|
||||
trigger.destroyViewHolder();
|
||||
}
|
||||
}
|
||||
|
||||
private Spinner createSpinner() {
|
||||
Spinner spinner = new Spinner(mContext);
|
||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(mContext, android.R.layout.simple_spinner_item, TriggerConnector.Type.labels());
|
||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(spinnerArrayAdapter);
|
||||
return spinner;
|
||||
}
|
||||
|
||||
private void build() {
|
||||
boolean isFirstItem = true;
|
||||
for(Trigger trigger : mTriggerList) {
|
||||
Trigger.ViewHolder viewHolder = trigger.createViewHolder(mInflater);
|
||||
mRootLayout.addView(viewHolder.getView());
|
||||
if (!isFirstItem) {
|
||||
final TriggerConnector connector = trigger.getConnector();
|
||||
final int initialPosition = connector.getConnectorType().ordinal();
|
||||
Spinner spinner = createSpinner();
|
||||
spinner.setSelection(initialPosition);
|
||||
spinner.setBackgroundColor(MainApp.gc(R.color.black_overlay));
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
params.setMargins(0, MainApp.dpToPx(8), 0, MainApp.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) {
|
||||
// conector type changed
|
||||
final TriggerConnector.Type newConnectorType = TriggerConnector.Type.values()[position];
|
||||
|
||||
if (connector.size() > 2) {
|
||||
// split connector
|
||||
int pos = connector.pos(trigger) - 1;
|
||||
|
||||
TriggerConnector newConnector = new TriggerConnector(newConnectorType);
|
||||
{
|
||||
Trigger t = connector.get(pos);
|
||||
newConnector.add(t);
|
||||
connector.remove(t);
|
||||
}
|
||||
|
||||
TriggerConnector subConnector = new TriggerConnector(connector.getConnectorType());
|
||||
int count = connector.size() - pos;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Trigger t = connector.get(pos);
|
||||
subConnector.add(t);
|
||||
connector.remove(t);
|
||||
}
|
||||
newConnector.add(subConnector);
|
||||
connector.add(newConnector);
|
||||
} else {
|
||||
connector.changeConnectorType(newConnectorType);
|
||||
}
|
||||
|
||||
connector.simplify().rebuildView();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
mRootLayout.addView(spinner);
|
||||
} else {
|
||||
isFirstItem = false;
|
||||
}
|
||||
|
||||
mRootLayout.addView(trigger.createView(mContext));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import info.nightscout.androidaps.R;
|
|||
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent;
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationFragment;
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerBg;
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTime;
|
||||
|
||||
|
@ -50,21 +51,19 @@ public class EditEventDialog extends DialogFragment {
|
|||
|
||||
// dummy initialization
|
||||
TriggerConnector to = new TriggerConnector(TriggerConnector.Type.OR);
|
||||
to.add(new TriggerBg());
|
||||
to.add(new TriggerTime());
|
||||
to.add(new TriggerTime());
|
||||
TriggerConnector ta = new TriggerConnector();
|
||||
ta.add(to);
|
||||
mEvent.setTrigger(ta);
|
||||
mEvent.setTrigger(to);
|
||||
|
||||
// display triggers
|
||||
mTriggerListAdapter = new AutomationFragment.TriggerListAdapter(getLayoutInflater(), mLayoutTrigger, mEvent.getTrigger());
|
||||
mTriggerListAdapter = new AutomationFragment.TriggerListAdapter(getContext(), mLayoutTrigger, mEvent.getTrigger());
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
mTriggerListAdapter.destroy();
|
||||
//mTriggerListAdapter.destroy();
|
||||
mUnbinder.unbind();
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.Unbinder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
public abstract class Trigger {
|
||||
|
@ -61,16 +65,22 @@ public abstract class Trigger {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ViewHolder viewHolder = null;
|
||||
public static List<String> labels() {
|
||||
List<String> list = new ArrayList<>();
|
||||
for(Comparator c : values()) {
|
||||
list.add(MainApp.gs(c.getStringRes()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
protected TriggerConnector connector = null;
|
||||
|
||||
Trigger() {
|
||||
}
|
||||
|
||||
public Trigger getConnector() {
|
||||
public TriggerConnector getConnector() {
|
||||
return connector;
|
||||
}
|
||||
|
||||
|
@ -99,31 +109,18 @@ public abstract class Trigger {
|
|||
return null;
|
||||
}
|
||||
|
||||
public abstract ViewHolder createViewHolder(LayoutInflater inflater);
|
||||
public View createView(Context context) {
|
||||
final int padding = MainApp.dpToPx(4);
|
||||
|
||||
public ViewHolder getViewHolder() {
|
||||
return viewHolder;
|
||||
}
|
||||
LinearLayout root = new LinearLayout(context);
|
||||
root.setPadding(padding, padding, padding, padding);
|
||||
root.setOrientation(LinearLayout.VERTICAL);
|
||||
root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
|
||||
public void destroyViewHolder() {
|
||||
if (viewHolder != null) {
|
||||
viewHolder.destroy();
|
||||
}
|
||||
}
|
||||
TextView title = new TextView(context);
|
||||
title.setText(friendlyName());
|
||||
root.addView(title);
|
||||
|
||||
public static abstract class ViewHolder {
|
||||
final View view;
|
||||
final Unbinder unbinder;
|
||||
|
||||
public ViewHolder(LayoutInflater inflater, @LayoutRes int layout) {
|
||||
view = inflater.inflate(layout, null);
|
||||
unbinder = ButterKnife.bind(this, view);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
unbinder.unbind();
|
||||
}
|
||||
|
||||
public View getView() { return view; }
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.content.Context;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.utils.JsonHelper;
|
||||
import info.nightscout.utils.NumberPicker;
|
||||
|
||||
public class TriggerBg extends Trigger {
|
||||
|
||||
|
@ -18,6 +30,21 @@ public class TriggerBg extends Trigger {
|
|||
protected Comparator comparator = Comparator.IS_EQUAL;
|
||||
protected String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||
|
||||
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) {
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
|
||||
|
@ -72,11 +99,6 @@ public class TriggerBg extends Trigger {
|
|||
return MainApp.gs(R.string.glucosecompared, comparator.getStringRes(), threshold, units);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder createViewHolder(LayoutInflater inflater) {
|
||||
return null;
|
||||
}
|
||||
|
||||
TriggerBg threshold(double threshold) {
|
||||
this.threshold = threshold;
|
||||
return this;
|
||||
|
@ -91,4 +113,48 @@ public class TriggerBg extends Trigger {
|
|||
this.units = units;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View createView(Context context) {
|
||||
LinearLayout root = (LinearLayout) super.createView(context);
|
||||
|
||||
// spinner for comparator
|
||||
Spinner spinner = new Spinner(context);
|
||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item, Comparator.labels());
|
||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(spinnerArrayAdapter);
|
||||
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
spinnerParams.setMargins(0, MainApp.dpToPx(4), 0, MainApp.dpToPx(4));
|
||||
spinner.setLayoutParams(spinnerParams);
|
||||
root.addView(spinner);
|
||||
|
||||
// horizontal layout
|
||||
LinearLayout layout = new LinearLayout(context);
|
||||
layout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
layout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
root.addView(layout);
|
||||
|
||||
// input filed for threshold
|
||||
NumberPicker numberPicker = new NumberPicker(context, null);
|
||||
numberPicker.setParams(0d, 0d, (double) 500, 1d, new DecimalFormat("0"), false, textWatcher);
|
||||
numberPicker.setValue(100.0);
|
||||
layout.addView(numberPicker);
|
||||
|
||||
// text view for unit
|
||||
TextView tvUnits = new TextView(context);
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.MATCH_PARENT
|
||||
);
|
||||
params.setMargins(MainApp.dpToPx(6), 0, 0, 0);
|
||||
tvUnits.setLayoutParams(params);
|
||||
tvUnits.setText(units);
|
||||
tvUnits.setGravity(Gravity.CENTER_VERTICAL);
|
||||
layout.addView(tvUnits);
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
@ -13,8 +14,7 @@ import org.json.JSONObject;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.OnClick;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationFragment;
|
||||
import info.nightscout.utils.JsonHelper;
|
||||
|
@ -22,7 +22,8 @@ import info.nightscout.utils.JsonHelper;
|
|||
public class TriggerConnector extends Trigger {
|
||||
public enum Type {
|
||||
AND,
|
||||
OR;
|
||||
OR,
|
||||
XOR;
|
||||
|
||||
public boolean apply(boolean a, boolean b) {
|
||||
switch (this) {
|
||||
|
@ -30,6 +31,8 @@ public class TriggerConnector extends Trigger {
|
|||
return a && b;
|
||||
case OR:
|
||||
return a || b;
|
||||
case XOR:
|
||||
return a ^ b;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -38,12 +41,22 @@ public class TriggerConnector extends Trigger {
|
|||
switch (this) {
|
||||
case OR:
|
||||
return R.string.or;
|
||||
case XOR:
|
||||
return R.string.xor;
|
||||
|
||||
default:
|
||||
case AND:
|
||||
return R.string.and;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> labels() {
|
||||
List<String> list = new ArrayList<>();
|
||||
for(Type t : values()) {
|
||||
list.add(MainApp.gs(t.getStringRes()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Trigger> list = new ArrayList<>();
|
||||
|
@ -78,6 +91,13 @@ public class TriggerConnector extends Trigger {
|
|||
return list.get(i);
|
||||
}
|
||||
|
||||
public int pos(Trigger trigger) {
|
||||
for(int i = 0; i < list.size(); ++i) {
|
||||
if (list.get(i) == trigger) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
boolean result = false;
|
||||
|
@ -139,67 +159,104 @@ public class TriggerConnector extends Trigger {
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder createViewHolder(LayoutInflater inflater) {
|
||||
ViewHolder v = new ViewHolder(inflater);
|
||||
viewHolder = v;
|
||||
return v;
|
||||
private AutomationFragment.TriggerListAdapter adapter;
|
||||
|
||||
public void rebuildView() {
|
||||
if (adapter != null)
|
||||
adapter.rebuild();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View createView(Context context) {
|
||||
final int padding = MainApp.dpToPx(5);
|
||||
|
||||
class ViewHolder extends Trigger.ViewHolder {
|
||||
LinearLayout root = new LinearLayout(context);
|
||||
root.setOrientation(LinearLayout.VERTICAL);
|
||||
root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
root.setPadding(padding,padding,padding,padding);
|
||||
root.setBackgroundResource(R.drawable.border_automation_unit);
|
||||
|
||||
@BindView(R.id.triggerListLayout)
|
||||
LinearLayout triggerListLayout;
|
||||
LinearLayout triggerListLayout = new LinearLayout(context);
|
||||
triggerListLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
triggerListLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
root.addView(triggerListLayout);
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView titleView;
|
||||
adapter = new AutomationFragment.TriggerListAdapter(context, triggerListLayout, list);
|
||||
|
||||
AutomationFragment.TriggerListAdapter adapter;
|
||||
LinearLayout buttonLayout = new LinearLayout(context);
|
||||
buttonLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
buttonLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
root.addView(buttonLayout);
|
||||
|
||||
public ViewHolder(LayoutInflater inflater) {
|
||||
super(inflater, R.layout.automation_trigger_connector);
|
||||
titleView.setText(friendlyName());
|
||||
adapter = new AutomationFragment.TriggerListAdapter(inflater, triggerListLayout, list);
|
||||
}
|
||||
|
||||
@OnClick(R.id.buttonRemove)
|
||||
public void onButtonClickRemove(View view) {
|
||||
Button buttonRemove = new Button(context);
|
||||
buttonRemove.setText("-");
|
||||
buttonRemove.setOnClickListener(v -> {
|
||||
if (connector != null) {
|
||||
connector.remove(TriggerConnector.this);
|
||||
((TriggerConnector.ViewHolder)connector.getViewHolder()).adapter.rebuild();
|
||||
connector.simplify();
|
||||
connector.adapter.rebuild();
|
||||
} else {
|
||||
// no parent
|
||||
list.clear();
|
||||
simplify();
|
||||
adapter.rebuild();
|
||||
}
|
||||
});
|
||||
buttonLayout.addView(buttonRemove);
|
||||
|
||||
Button buttonAdd = new Button(context);
|
||||
buttonAdd.setText("+");
|
||||
buttonAdd.setOnClickListener(v -> {
|
||||
addTrigger(adapter, new TriggerTime(), getConnectorType());
|
||||
});
|
||||
buttonLayout.addView(buttonAdd);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private void addTrigger(AutomationFragment.TriggerListAdapter adapter, Trigger trigger, Type connection) {
|
||||
if (getConnectorType().equals(connection)) {
|
||||
add(trigger);
|
||||
} else {
|
||||
TriggerConnector t = new TriggerConnector(connection);
|
||||
t.add(trigger);
|
||||
add(t);
|
||||
}
|
||||
adapter.rebuild();
|
||||
}
|
||||
|
||||
public TriggerConnector simplify() {
|
||||
// simplify children
|
||||
for(int i = 0; i < size(); ++i) {
|
||||
if (get(i) instanceof TriggerConnector) {
|
||||
TriggerConnector t = (TriggerConnector) get(i);
|
||||
t.simplify();
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.buttonAddAnd)
|
||||
public void onButtonClickAnd(View view) {
|
||||
addTrigger(new TriggerTime(), Type.AND);
|
||||
}
|
||||
|
||||
@OnClick(R.id.buttonAddOr)
|
||||
public void onButtonClickOr(View view) {
|
||||
addTrigger(new TriggerTime(), Type.OR);
|
||||
}
|
||||
|
||||
private void addTrigger(Trigger trigger, Type connection) {
|
||||
if (getConnectorType().equals(connection)) {
|
||||
add(trigger);
|
||||
} else {
|
||||
TriggerConnector t = new TriggerConnector(connection);
|
||||
t.add(trigger);
|
||||
// drop connector with only 1 element
|
||||
if (size() == 1 && get(0) instanceof TriggerConnector) {
|
||||
TriggerConnector c = (TriggerConnector) get(0);
|
||||
remove(c);
|
||||
changeConnectorType(c.getConnectorType());
|
||||
for (Trigger t : c.list) {
|
||||
add(t);
|
||||
}
|
||||
adapter.rebuild();
|
||||
c.list.clear();
|
||||
return simplify();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
adapter.destroy();
|
||||
super.destroy();
|
||||
// merge connectors
|
||||
if (connector != null && (connector.getConnectorType().equals(connectorType) || size() == 1)) {
|
||||
connector.remove(this);
|
||||
for (Trigger t : list) {
|
||||
connector.add(t);
|
||||
}
|
||||
list.clear();
|
||||
return connector.simplify();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.dpro.widgets.WeekdaysPicker;
|
||||
|
||||
|
@ -12,7 +15,6 @@ import java.util.ArrayList;
|
|||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
|
@ -97,7 +99,7 @@ public class TriggerTime extends Trigger {
|
|||
|
||||
public TriggerTime() {
|
||||
for(DayOfWeek day : DayOfWeek.values()) {
|
||||
set(day, true);
|
||||
set(day, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,34 +233,27 @@ public class TriggerTime extends Trigger {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewHolder createViewHolder(LayoutInflater inflater) {
|
||||
ViewHolder v = new ViewHolder(inflater);
|
||||
viewHolder = v;
|
||||
return v;
|
||||
}
|
||||
|
||||
class ViewHolder extends Trigger.ViewHolder {
|
||||
|
||||
@BindView(R.id.weekdays)
|
||||
WeekdaysPicker weekdaysPicker;
|
||||
|
||||
public ViewHolder(LayoutInflater inflater) {
|
||||
super(inflater, R.layout.automation_trigger_time);
|
||||
|
||||
List<Integer> selectedDays = new ArrayList<>();
|
||||
for(int i = 0; i < weekdays.length; ++i) {
|
||||
DayOfWeek day = DayOfWeek.values()[i];
|
||||
boolean selected = weekdays[i];
|
||||
if (selected) selectedDays.add(day.toCalendarInt());
|
||||
}
|
||||
weekdaysPicker.setSelectedDays(selectedDays);
|
||||
|
||||
weekdaysPicker.setOnWeekdaysChangeListener((view, i, list) -> {
|
||||
set(DayOfWeek.fromCalendarInt(i), list.contains(i));
|
||||
});
|
||||
private List<Integer> getSelectedDays() {
|
||||
List<Integer> selectedDays = new ArrayList<>();
|
||||
for(int i = 0; i < weekdays.length; ++i) {
|
||||
DayOfWeek day = DayOfWeek.values()[i];
|
||||
boolean selected = weekdays[i];
|
||||
if (selected) selectedDays.add(day.toCalendarInt());
|
||||
}
|
||||
|
||||
return selectedDays;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View createView(Context context) {
|
||||
LinearLayout root = (LinearLayout) super.createView(context);
|
||||
|
||||
WeekdaysPicker weekdaysPicker = new WeekdaysPicker(context);
|
||||
weekdaysPicker.setEditable(true);
|
||||
weekdaysPicker.setSelectedDays(getSelectedDays());
|
||||
weekdaysPicker.setOnWeekdaysChangeListener((view, i, list) -> set(DayOfWeek.fromCalendarInt(i), list.contains(i)));
|
||||
weekdaysPicker.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
root.addView(weekdaysPicker);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<stroke
|
||||
android:width="5dip"
|
||||
android:width="3dip"
|
||||
android:color="@android:color/white" />
|
||||
</shape>
|
|
@ -5,6 +5,10 @@
|
|||
android:layout_height="match_parent"
|
||||
tools:context="info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -28,4 +32,6 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</FrameLayout>
|
|
@ -1,46 +0,0 @@
|
|||
<?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:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:background="@drawable/border_automation_unit">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/triggerListLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonAddAnd"
|
||||
android:text="@string/and"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonAddOr"
|
||||
android:text="@string/or"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonRemove"
|
||||
android:text="-"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,14 +0,0 @@
|
|||
<?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"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.dpro.widgets.WeekdaysPicker
|
||||
android:id="@+id/weekdays"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:sunday_first_day="false" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1224,6 +1224,7 @@
|
|||
<string name="glucosecompared">Glucose %1$s %2$.2f %3$s</string>
|
||||
<string name="and">And</string>
|
||||
<string name="or">Or</string>
|
||||
<string name="xor">Exclusive or</string>
|
||||
<string name="atspecifiedtime">At %1$s</string>
|
||||
<string name="use_network_location">Use network location</string>
|
||||
<string name="use_gps_location">Use GPS location</string>
|
||||
|
|
Loading…
Reference in a new issue