Preconditions, code cleanup
This commit is contained in:
parent
67b06f51fe
commit
58da7fc854
21 changed files with 546 additions and 438 deletions
|
@ -33,6 +33,15 @@ public class AutomationEvent {
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TriggerConnector getPreconditions() {
|
||||||
|
TriggerConnector trigger = new TriggerConnector(TriggerConnector.Type.AND);
|
||||||
|
for (Action action : actions) {
|
||||||
|
if (action.precondition != null)
|
||||||
|
trigger.add(action.precondition);
|
||||||
|
}
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
|
||||||
public void addAction(Action action) {
|
public void addAction(Action action) {
|
||||||
actions.add(action);
|
actions.add(action);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,44 +1,26 @@
|
||||||
package info.nightscout.androidaps.plugins.general.automation;
|
package info.nightscout.androidaps.plugins.general.automation;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.Spinner;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes;
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.FragmentManager;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.squareup.otto.Subscribe;
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.plugins.common.SubscriberFragment;
|
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.dialogs.EditEventDialog;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui;
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
|
||||||
|
|
||||||
public class AutomationFragment extends SubscriberFragment {
|
public class AutomationFragment extends SubscriberFragment {
|
||||||
|
|
||||||
|
@ -49,8 +31,6 @@ public class AutomationFragment extends SubscriberFragment {
|
||||||
|
|
||||||
private EventListAdapter mEventListAdapter;
|
private EventListAdapter mEventListAdapter;
|
||||||
|
|
||||||
FragmentManager mFragmentManager;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
|
@ -58,17 +38,11 @@ public class AutomationFragment extends SubscriberFragment {
|
||||||
View view = inflater.inflate(R.layout.automation_fragment, container, false);
|
View view = inflater.inflate(R.layout.automation_fragment, container, false);
|
||||||
unbinder = ButterKnife.bind(this, view);
|
unbinder = ButterKnife.bind(this, view);
|
||||||
|
|
||||||
mFragmentManager = getFragmentManager();
|
|
||||||
|
|
||||||
final AutomationPlugin plugin = AutomationPlugin.getPlugin();
|
final AutomationPlugin plugin = AutomationPlugin.getPlugin();
|
||||||
mEventListAdapter = new EventListAdapter(plugin.getAutomationEvents(), getFragmentManager());
|
mEventListAdapter = new EventListAdapter(plugin.getAutomationEvents(), getFragmentManager());
|
||||||
mEventListView.setLayoutManager(new LinearLayoutManager(getContext()));
|
mEventListView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
mEventListView.setAdapter(mEventListAdapter);
|
mEventListView.setAdapter(mEventListAdapter);
|
||||||
|
|
||||||
EditEventDialog.setOnClickListener(event -> mEventListAdapter.notifyDataSetChanged());
|
|
||||||
|
|
||||||
updateGUI();
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +51,15 @@ public class AutomationFragment extends SubscriberFragment {
|
||||||
updateGUI();
|
updateGUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onEvent(EventAutomationDataChanged unused) {
|
||||||
|
Activity activity = getActivity();
|
||||||
|
if (activity != null)
|
||||||
|
activity.runOnUiThread(() -> {
|
||||||
|
mEventListAdapter.notifyDataSetChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateGUI() {
|
public void updateGUI() {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
|
@ -93,331 +76,10 @@ public class AutomationFragment extends SubscriberFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.fabAddEvent)
|
@OnClick(R.id.fabAddEvent)
|
||||||
@SuppressWarnings("unused")
|
void onClickAddEvent(View unused) {
|
||||||
void onClickAddEvent(View v) {
|
|
||||||
EditEventDialog dialog = EditEventDialog.newInstance(new AutomationEvent(), true);
|
EditEventDialog dialog = EditEventDialog.newInstance(new AutomationEvent(), true);
|
||||||
if (getFragmentManager() != null) {
|
if (getFragmentManager() != null)
|
||||||
dialog.show(getFragmentManager(), "EditEventDialog");
|
dialog.show(getFragmentManager(), "EditEventDialog");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void changeConnector(final FragmentManager fragmentManager, 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(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.changeConnectorType(newConnectorType);
|
|
||||||
}
|
|
||||||
|
|
||||||
connector.simplify().rebuildView(fragmentManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RecyclerViewAdapter to display event lists.
|
|
||||||
*/
|
|
||||||
public static class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder> {
|
|
||||||
private final List<AutomationEvent> mEventList;
|
|
||||||
private final FragmentManager mFragmentManager;
|
|
||||||
|
|
||||||
EventListAdapter(List<AutomationEvent> events, FragmentManager fragmentManager) {
|
|
||||||
this.mEventList = events;
|
|
||||||
this.mFragmentManager = fragmentManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
|
||||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.automation_event_item, parent, false);
|
|
||||||
return new ViewHolder(v, parent.getContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addImage(@DrawableRes int res, Context context, LinearLayout layout) {
|
|
||||||
ImageView iv = new ImageView(context);
|
|
||||||
iv.setImageResource(res);
|
|
||||||
iv.setLayoutParams(new LinearLayout.LayoutParams(MainApp.dpToPx(24), MainApp.dpToPx(24)));
|
|
||||||
layout.addView(iv);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
|
||||||
final AutomationEvent event = mEventList.get(position);
|
|
||||||
holder.eventTitle.setText(event.getTitle());
|
|
||||||
holder.iconLayout.removeAllViews();
|
|
||||||
|
|
||||||
// trigger icons
|
|
||||||
HashSet<Integer> triggerIcons = new HashSet<>();
|
|
||||||
TriggerConnector.fillIconSet((TriggerConnector) event.getTrigger(), triggerIcons);
|
|
||||||
for (int res : triggerIcons) {
|
|
||||||
addImage(res, holder.context, holder.iconLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
// arrow icon
|
|
||||||
ImageView iv = new ImageView(holder.context);
|
|
||||||
iv.setImageResource(R.drawable.ic_arrow_forward_white_24dp);
|
|
||||||
iv.setLayoutParams(new LinearLayout.LayoutParams(MainApp.dpToPx(24), MainApp.dpToPx(24)));
|
|
||||||
iv.setPadding(MainApp.dpToPx(4), 0, MainApp.dpToPx(4), 0);
|
|
||||||
holder.iconLayout.addView(iv);
|
|
||||||
|
|
||||||
// action icons
|
|
||||||
HashSet<Integer> actionIcons = new HashSet<>();
|
|
||||||
for (Action action : event.getActions()) {
|
|
||||||
if (action.icon().isPresent())
|
|
||||||
actionIcons.add(action.icon().get());
|
|
||||||
}
|
|
||||||
for (int res : actionIcons) {
|
|
||||||
addImage(res, holder.context, holder.iconLayout);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove event
|
|
||||||
holder.iconTrash.setOnClickListener(v -> {
|
|
||||||
mEventList.remove(event);
|
|
||||||
notifyDataSetChanged();
|
|
||||||
});
|
|
||||||
|
|
||||||
// edit event
|
|
||||||
holder.rootLayout.setOnClickListener(v -> {
|
|
||||||
EditEventDialog dialog = EditEventDialog.newInstance(event, false);
|
|
||||||
dialog.show(mFragmentManager, "EditEventDialog");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return mEventList.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
final RelativeLayout rootLayout;
|
|
||||||
final LinearLayout iconLayout;
|
|
||||||
final TextView eventTitle;
|
|
||||||
final Context context;
|
|
||||||
final ImageView iconTrash;
|
|
||||||
|
|
||||||
ViewHolder(View view, Context context) {
|
|
||||||
super(view);
|
|
||||||
this.context = context;
|
|
||||||
eventTitle = view.findViewById(R.id.viewEventTitle);
|
|
||||||
rootLayout = view.findViewById(R.id.rootLayout);
|
|
||||||
iconLayout = view.findViewById(R.id.iconLayout);
|
|
||||||
iconTrash = view.findViewById(R.id.iconTrash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RecyclerViewAdapter to display action lists.
|
|
||||||
*/
|
|
||||||
public static class ActionListAdapter extends RecyclerView.Adapter<ActionListAdapter.ViewHolder> {
|
|
||||||
private final List<Action> mActionList;
|
|
||||||
private final FragmentManager mFragmentManager;
|
|
||||||
|
|
||||||
public ActionListAdapter(FragmentManager manager, List<Action> events) {
|
|
||||||
this.mActionList = events;
|
|
||||||
this.mFragmentManager = manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
|
||||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.automation_action_item, parent, false);
|
|
||||||
return new ViewHolder(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
|
||||||
final Action action = mActionList.get(position);
|
|
||||||
holder.actionTitle.setText(action.shortDescription());
|
|
||||||
holder.layoutText.setOnClickListener(v -> {
|
|
||||||
if (action.hasDialog()) {
|
|
||||||
EditActionDialog dialog = EditActionDialog.newInstance(action);
|
|
||||||
dialog.show(mFragmentManager, "EditActionDialog");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
holder.iconTrash.setOnClickListener(v -> {
|
|
||||||
mActionList.remove(action);
|
|
||||||
notifyDataSetChanged();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return mActionList.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
|
||||||
TextView actionTitle;
|
|
||||||
TextView actionDescription;
|
|
||||||
LinearLayout layoutText;
|
|
||||||
ImageView iconTrash;
|
|
||||||
|
|
||||||
ViewHolder(View view) {
|
|
||||||
super(view);
|
|
||||||
layoutText = view.findViewById(R.id.layoutText);
|
|
||||||
actionTitle = view.findViewById(R.id.viewActionTitle);
|
|
||||||
actionDescription = view.findViewById(R.id.viewActionDescription);
|
|
||||||
iconTrash = view.findViewById(R.id.iconTrash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom Adapter to display triggers dynamically with nested linear layouts.
|
|
||||||
*/
|
|
||||||
public class TriggerListAdapter {
|
|
||||||
private final LinearLayout mRootLayout;
|
|
||||||
private final FragmentManager mFragmentManager;
|
|
||||||
private final Context mContext;
|
|
||||||
private final TriggerConnector mRootConnector;
|
|
||||||
|
|
||||||
public TriggerListAdapter(FragmentManager fragmentManager, Context context, LinearLayout rootLayout, TriggerConnector rootTrigger) {
|
|
||||||
mRootLayout = rootLayout;
|
|
||||||
mFragmentManager = fragmentManager;
|
|
||||||
mContext = context;
|
|
||||||
mRootConnector = rootTrigger;
|
|
||||||
build(fragmentManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context getContext() {
|
|
||||||
return mContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
FragmentManager getFM() {
|
|
||||||
return mFragmentManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy() {
|
|
||||||
mRootLayout.removeAllViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void build(FragmentManager fragmentManager) {
|
|
||||||
for (int i = 0; i < mRootConnector.size(); ++i) {
|
|
||||||
final Trigger trigger = mRootConnector.get(i);
|
|
||||||
|
|
||||||
// spinner
|
|
||||||
if (i > 0) {
|
|
||||||
createSpinner(trigger);
|
|
||||||
}
|
|
||||||
|
|
||||||
// trigger layout
|
|
||||||
trigger.generateDialog(mRootLayout, fragmentManager);
|
|
||||||
|
|
||||||
// buttons
|
|
||||||
createButtons(fragmentManager, trigger);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mRootConnector.size() == 0) {
|
|
||||||
Button buttonAdd = new Button(mContext);
|
|
||||||
buttonAdd.setText(MainApp.gs(R.string.addnew));
|
|
||||||
buttonAdd.setOnClickListener(v -> {
|
|
||||||
ChooseTriggerDialog dialog = ChooseTriggerDialog.newInstance();
|
|
||||||
dialog.setOnClickListener(newTriggerObject -> {
|
|
||||||
mRootConnector.add(newTriggerObject);
|
|
||||||
rebuild(fragmentManager);
|
|
||||||
});
|
|
||||||
dialog.show(fragmentManager, "ChooseTriggerDialog");
|
|
||||||
});
|
|
||||||
mRootLayout.addView(buttonAdd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 createSpinner(Trigger trigger) {
|
|
||||||
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) {
|
|
||||||
// connector type changed
|
|
||||||
changeConnector(getFM(), trigger, connector, TriggerConnector.Type.values()[position]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNothingSelected(AdapterView<?> parent) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mRootLayout.addView(spinner);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createButtons(FragmentManager fragmentManager, Trigger trigger) {
|
|
||||||
// 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));
|
|
||||||
mRootLayout.addView(buttonLayout);
|
|
||||||
|
|
||||||
// Button [-]
|
|
||||||
Button buttonRemove = new Button(mContext);
|
|
||||||
buttonRemove.setText(MainApp.gs(R.string.delete_short));
|
|
||||||
buttonRemove.setOnClickListener(v -> {
|
|
||||||
final TriggerConnector connector = trigger.getConnector();
|
|
||||||
connector.remove(trigger);
|
|
||||||
connector.simplify().rebuildView(getFM());
|
|
||||||
});
|
|
||||||
buttonLayout.addView(buttonRemove);
|
|
||||||
|
|
||||||
// Button [+]
|
|
||||||
Button buttonAdd = new Button(mContext);
|
|
||||||
buttonAdd.setText(MainApp.gs(R.string.add_short));
|
|
||||||
buttonAdd.setOnClickListener(v -> {
|
|
||||||
ChooseTriggerDialog dialog = ChooseTriggerDialog.newInstance();
|
|
||||||
dialog.show(fragmentManager, "ChooseTriggerDialog");
|
|
||||||
dialog.setOnClickListener(newTriggerObject -> {
|
|
||||||
TriggerConnector connector = trigger.getConnector();
|
|
||||||
connector.add(connector.pos(trigger) + 1, newTriggerObject);
|
|
||||||
connector.simplify().rebuildView(getFM());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
buttonLayout.addView(buttonAdd);
|
|
||||||
|
|
||||||
// Button [*]
|
|
||||||
Button buttonCopy = new Button(mContext);
|
|
||||||
buttonCopy.setText(MainApp.gs(R.string.copy_short));
|
|
||||||
buttonCopy.setOnClickListener(v -> {
|
|
||||||
TriggerConnector connector = trigger.getConnector();
|
|
||||||
connector.add(connector.pos(trigger) + 1, trigger.duplicate());
|
|
||||||
connector.simplify().rebuildView(getFM());
|
|
||||||
});
|
|
||||||
buttonLayout.addView(buttonCopy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void rebuild(FragmentManager fragmentManager) {
|
|
||||||
destroy();
|
|
||||||
build(fragmentManager);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,6 @@ import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.logging.L;
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopDisable;
|
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable;
|
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopResume;
|
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopSuspend;
|
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.ActionNotification;
|
import info.nightscout.androidaps.plugins.general.automation.actions.ActionNotification;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.ActionProfileSwitchPercent;
|
import info.nightscout.androidaps.plugins.general.automation.actions.ActionProfileSwitchPercent;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.ActionStartTempTarget;
|
import info.nightscout.androidaps.plugins.general.automation.actions.ActionStartTempTarget;
|
||||||
|
@ -194,7 +190,7 @@ public class AutomationPlugin extends PluginBase {
|
||||||
if (L.isEnabled(L.AUTOMATION))
|
if (L.isEnabled(L.AUTOMATION))
|
||||||
log.debug("processActions");
|
log.debug("processActions");
|
||||||
for (AutomationEvent event : getAutomationEvents()) {
|
for (AutomationEvent event : getAutomationEvents()) {
|
||||||
if (event.getTrigger().shouldRun()) {
|
if (event.getTrigger().shouldRun() && event.getPreconditions().shouldRun()) {
|
||||||
List<Action> actions = event.getActions();
|
List<Action> actions = event.getActions();
|
||||||
for (Action action : actions) {
|
for (Action action : actions) {
|
||||||
action.doAction(new Callback() {
|
action.doAction(new Callback() {
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.automation;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
||||||
|
|
||||||
|
class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder> {
|
||||||
|
private final List<AutomationEvent> mEventList;
|
||||||
|
private final FragmentManager mFragmentManager;
|
||||||
|
|
||||||
|
EventListAdapter(List<AutomationEvent> events, FragmentManager fragmentManager) {
|
||||||
|
this.mEventList = events;
|
||||||
|
this.mFragmentManager = fragmentManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.automation_event_item, parent, false);
|
||||||
|
return new ViewHolder(v, parent.getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addImage(@DrawableRes int res, Context context, LinearLayout layout) {
|
||||||
|
ImageView iv = new ImageView(context);
|
||||||
|
iv.setImageResource(res);
|
||||||
|
iv.setLayoutParams(new LinearLayout.LayoutParams(MainApp.dpToPx(24), MainApp.dpToPx(24)));
|
||||||
|
layout.addView(iv);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
final AutomationEvent event = mEventList.get(position);
|
||||||
|
holder.eventTitle.setText(event.getTitle());
|
||||||
|
holder.iconLayout.removeAllViews();
|
||||||
|
|
||||||
|
// trigger icons
|
||||||
|
HashSet<Integer> triggerIcons = new HashSet<>();
|
||||||
|
TriggerConnector.fillIconSet((TriggerConnector) event.getTrigger(), triggerIcons);
|
||||||
|
for (int res : triggerIcons) {
|
||||||
|
addImage(res, holder.context, holder.iconLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// arrow icon
|
||||||
|
ImageView iv = new ImageView(holder.context);
|
||||||
|
iv.setImageResource(R.drawable.ic_arrow_forward_white_24dp);
|
||||||
|
iv.setLayoutParams(new LinearLayout.LayoutParams(MainApp.dpToPx(24), MainApp.dpToPx(24)));
|
||||||
|
iv.setPadding(MainApp.dpToPx(4), 0, MainApp.dpToPx(4), 0);
|
||||||
|
holder.iconLayout.addView(iv);
|
||||||
|
|
||||||
|
// action icons
|
||||||
|
HashSet<Integer> actionIcons = new HashSet<>();
|
||||||
|
for (Action action : event.getActions()) {
|
||||||
|
if (action.icon().isPresent())
|
||||||
|
actionIcons.add(action.icon().get());
|
||||||
|
}
|
||||||
|
for (int res : actionIcons) {
|
||||||
|
addImage(res, holder.context, holder.iconLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove event
|
||||||
|
holder.iconTrash.setOnClickListener(v -> {
|
||||||
|
mEventList.remove(event);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
// edit event
|
||||||
|
holder.rootLayout.setOnClickListener(v -> {
|
||||||
|
EditEventDialog dialog = EditEventDialog.newInstance(event, false);
|
||||||
|
dialog.show(mFragmentManager, "EditEventDialog");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mEventList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
final RelativeLayout rootLayout;
|
||||||
|
final LinearLayout iconLayout;
|
||||||
|
final TextView eventTitle;
|
||||||
|
final Context context;
|
||||||
|
final ImageView iconTrash;
|
||||||
|
|
||||||
|
ViewHolder(View view, Context context) {
|
||||||
|
super(view);
|
||||||
|
this.context = context;
|
||||||
|
eventTitle = view.findViewById(R.id.viewEventTitle);
|
||||||
|
rootLayout = view.findViewById(R.id.rootLayout);
|
||||||
|
iconLayout = view.findViewById(R.id.iconLayout);
|
||||||
|
iconTrash = view.findViewById(R.id.iconTrash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import org.json.JSONObject;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -44,6 +45,8 @@ import info.nightscout.androidaps.queue.Callback;
|
||||||
|
|
||||||
public abstract class Action {
|
public abstract class Action {
|
||||||
|
|
||||||
|
public Trigger precondition = null;
|
||||||
|
|
||||||
public abstract int friendlyName();
|
public abstract int friendlyName();
|
||||||
|
|
||||||
public abstract String shortDescription();
|
public abstract String shortDescription();
|
||||||
|
|
|
@ -11,10 +11,12 @@ import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration;
|
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputPercent;
|
import info.nightscout.androidaps.plugins.general.automation.elements.InputPercent;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerProfilePercent;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
|
|
||||||
|
@ -22,6 +24,10 @@ public class ActionProfileSwitchPercent extends Action {
|
||||||
InputPercent pct = new InputPercent();
|
InputPercent pct = new InputPercent();
|
||||||
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
public ActionProfileSwitchPercent() {
|
||||||
|
precondition = new TriggerProfilePercent().comparator(Comparator.Compare.IS_EQUAL).setValue(100);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int friendlyName() {
|
public int friendlyName() {
|
||||||
return R.string.profilepercentage;
|
return R.string.profilepercentage;
|
||||||
|
@ -29,7 +35,10 @@ public class ActionProfileSwitchPercent extends Action {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String shortDescription() {
|
public String shortDescription() {
|
||||||
return MainApp.gs(R.string.startprofile, (int) pct.getValue(), (int) duration.getValue());
|
if (duration.getMinutes() == 0)
|
||||||
|
return MainApp.gs(R.string.startprofileforever, (int) pct.getValue());
|
||||||
|
else
|
||||||
|
return MainApp.gs(R.string.startprofile, (int) pct.getValue(), duration.getMinutes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,10 +14,12 @@ import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||||
import info.nightscout.androidaps.db.Source;
|
import info.nightscout.androidaps.db.Source;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.elements.ComparatorExists;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputBg;
|
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.InputDuration;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTempTarget;
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.queue.Callback;
|
import info.nightscout.androidaps.queue.Callback;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
|
@ -29,6 +31,10 @@ public class ActionStartTempTarget extends Action {
|
||||||
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
||||||
private TempTarget tempTarget;
|
private TempTarget tempTarget;
|
||||||
|
|
||||||
|
public ActionStartTempTarget() {
|
||||||
|
precondition = new TriggerTempTarget().comparator(ComparatorExists.Compare.NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int friendlyName() {
|
public int friendlyName() {
|
||||||
return R.string.starttemptarget;
|
return R.string.starttemptarget;
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.automation.dialogs;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui;
|
||||||
|
|
||||||
|
public class ActionListAdapter extends RecyclerView.Adapter<ActionListAdapter.ViewHolder> {
|
||||||
|
private final List<Action> mActionList;
|
||||||
|
private final FragmentManager mFragmentManager;
|
||||||
|
|
||||||
|
public ActionListAdapter(FragmentManager manager, List<Action> events) {
|
||||||
|
this.mActionList = events;
|
||||||
|
this.mFragmentManager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.automation_action_item, parent, false);
|
||||||
|
return new ViewHolder(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
final Action action = mActionList.get(position);
|
||||||
|
holder.actionTitle.setText(action.shortDescription());
|
||||||
|
holder.layoutText.setOnClickListener(v -> {
|
||||||
|
if (action.hasDialog()) {
|
||||||
|
EditActionDialog dialog = EditActionDialog.newInstance(action);
|
||||||
|
dialog.show(mFragmentManager, "EditActionDialog");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
holder.iconTrash.setOnClickListener(v -> {
|
||||||
|
mActionList.remove(action);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
MainApp.bus().post(new EventAutomationUpdateGui());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return mActionList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
TextView actionTitle;
|
||||||
|
TextView actionDescription;
|
||||||
|
LinearLayout layoutText;
|
||||||
|
ImageView iconTrash;
|
||||||
|
|
||||||
|
ViewHolder(View view) {
|
||||||
|
super(view);
|
||||||
|
layoutText = view.findViewById(R.id.layoutText);
|
||||||
|
actionTitle = view.findViewById(R.id.viewActionTitle);
|
||||||
|
actionDescription = view.findViewById(R.id.viewActionDescription);
|
||||||
|
iconTrash = view.findViewById(R.id.iconTrash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,9 +14,12 @@ import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import butterknife.Unbinder;
|
import butterknife.Unbinder;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
|
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationAddAction;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui;
|
||||||
|
|
||||||
public class ChooseActionDialog extends DialogFragment {
|
public class ChooseActionDialog extends DialogFragment {
|
||||||
|
|
||||||
|
@ -24,22 +27,11 @@ public class ChooseActionDialog extends DialogFragment {
|
||||||
void onClick(Action newActionObject);
|
void onClick(Action newActionObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OnClickListener mClickListener = null;
|
|
||||||
|
|
||||||
private Unbinder mUnbinder;
|
private Unbinder mUnbinder;
|
||||||
|
|
||||||
@BindView(R.id.radioGroup)
|
@BindView(R.id.radioGroup)
|
||||||
RadioGroup mRadioGroup;
|
RadioGroup mRadioGroup;
|
||||||
|
|
||||||
public static ChooseActionDialog newInstance() {
|
|
||||||
Bundle args = new Bundle();
|
|
||||||
|
|
||||||
ChooseActionDialog fragment = new ChooseActionDialog();
|
|
||||||
fragment.setArguments(args);
|
|
||||||
|
|
||||||
return fragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.automation_dialog_choose_action, container, false);
|
View view = inflater.inflate(R.layout.automation_dialog_choose_action, container, false);
|
||||||
|
@ -95,10 +87,6 @@ public class ChooseActionDialog extends DialogFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void setOnClickListener(OnClickListener clickListener) {
|
|
||||||
mClickListener = clickListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
mUnbinder.unbind();
|
mUnbinder.unbind();
|
||||||
|
@ -106,17 +94,14 @@ public class ChooseActionDialog extends DialogFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.ok)
|
@OnClick(R.id.ok)
|
||||||
@SuppressWarnings("unused")
|
public void onButtonOk(View unused) {
|
||||||
public void onButtonOk(View view) {
|
|
||||||
if (mClickListener != null)
|
|
||||||
mClickListener.onClick(instantiateAction());
|
|
||||||
|
|
||||||
dismiss();
|
dismiss();
|
||||||
|
MainApp.bus().post(new EventAutomationAddAction(instantiateAction()));
|
||||||
|
MainApp.bus().post(new EventAutomationUpdateGui());
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.cancel)
|
@OnClick(R.id.cancel)
|
||||||
@SuppressWarnings("unused")
|
public void onButtonCancel(View unused) {
|
||||||
public void onButtonCancel(View view) {
|
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,16 +80,14 @@ public class EditActionDialog extends DialogFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.ok)
|
@OnClick(R.id.ok)
|
||||||
@SuppressWarnings("unused")
|
public void onButtonOk(View unused) {
|
||||||
public void onButtonOk(View view) {
|
|
||||||
resultAction.apply(mAction);
|
resultAction.apply(mAction);
|
||||||
dismiss();
|
dismiss();
|
||||||
MainApp.bus().post(new EventAutomationUpdateGui());
|
MainApp.bus().post(new EventAutomationUpdateGui());
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.cancel)
|
@OnClick(R.id.cancel)
|
||||||
@SuppressWarnings("unused")
|
public void onButtonCancel(View unused) {
|
||||||
public void onButtonCancel(View view) {
|
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,12 @@ import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
@ -24,10 +24,11 @@ import butterknife.Unbinder;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent;
|
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.AutomationPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationAddAction;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged;
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui;
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
||||||
|
|
||||||
public class EditEventDialog extends DialogFragment {
|
public class EditEventDialog extends DialogFragment {
|
||||||
|
@ -35,30 +36,31 @@ public class EditEventDialog extends DialogFragment {
|
||||||
void onClick(AutomationEvent event);
|
void onClick(AutomationEvent event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OnClickListener mClickListener = null;
|
|
||||||
private static AutomationEvent staticEvent;
|
private static AutomationEvent staticEvent;
|
||||||
|
|
||||||
public static void setOnClickListener(OnClickListener clickListener) {
|
|
||||||
mClickListener = clickListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@BindView(R.id.inputEventTitle)
|
@BindView(R.id.inputEventTitle)
|
||||||
TextInputEditText mEditEventTitle;
|
TextInputEditText mEditEventTitle;
|
||||||
|
|
||||||
@BindView(R.id.editTrigger)
|
@BindView(R.id.editTrigger)
|
||||||
TextView mEditTrigger;
|
TextView mEditTrigger;
|
||||||
|
|
||||||
@BindView(R.id.editAction)
|
@BindView(R.id.addAction)
|
||||||
TextView mEditAction;
|
TextView mAddAction;
|
||||||
|
|
||||||
@BindView(R.id.triggerDescription)
|
@BindView(R.id.triggerDescription)
|
||||||
TextView mTriggerDescription;
|
TextView mTriggerDescription;
|
||||||
|
|
||||||
|
@BindView(R.id.forcedtriggerdescription)
|
||||||
|
TextView mForcedTriggerDescription;
|
||||||
|
|
||||||
|
@BindView(R.id.forcedtriggerdescriptionlabel)
|
||||||
|
TextView mForcedTriggerDescriptionLabel;
|
||||||
|
|
||||||
@BindView(R.id.actionListView)
|
@BindView(R.id.actionListView)
|
||||||
RecyclerView mActionListView;
|
RecyclerView mActionListView;
|
||||||
|
|
||||||
private Unbinder mUnbinder;
|
private Unbinder mUnbinder;
|
||||||
private AutomationFragment.ActionListAdapter mActionListAdapter;
|
private ActionListAdapter mActionListAdapter;
|
||||||
private AutomationEvent mEvent;
|
private AutomationEvent mEvent;
|
||||||
private boolean mAddNew;
|
private boolean mAddNew;
|
||||||
|
|
||||||
|
@ -99,11 +101,6 @@ public class EditEventDialog extends DialogFragment {
|
||||||
// display root trigger
|
// display root trigger
|
||||||
mTriggerDescription.setText(mEvent.getTrigger().friendlyDescription());
|
mTriggerDescription.setText(mEvent.getTrigger().friendlyDescription());
|
||||||
|
|
||||||
// setup trigger click event listener
|
|
||||||
EditTriggerDialog.setOnClickListener(trigger -> {
|
|
||||||
mEvent.setTrigger(trigger);
|
|
||||||
mTriggerDescription.setText(mEvent.getTrigger().friendlyDescription());
|
|
||||||
});
|
|
||||||
mEditTrigger.setOnClickListener(v -> {
|
mEditTrigger.setOnClickListener(v -> {
|
||||||
EditTriggerDialog dialog = EditTriggerDialog.newInstance(mEvent.getTrigger());
|
EditTriggerDialog dialog = EditTriggerDialog.newInstance(mEvent.getTrigger());
|
||||||
if (getFragmentManager() != null)
|
if (getFragmentManager() != null)
|
||||||
|
@ -111,21 +108,18 @@ public class EditEventDialog extends DialogFragment {
|
||||||
});
|
});
|
||||||
|
|
||||||
// setup action list view
|
// setup action list view
|
||||||
mActionListAdapter = new AutomationFragment.ActionListAdapter(getFragmentManager(), mEvent.getActions());
|
mActionListAdapter = new ActionListAdapter(getFragmentManager(), mEvent.getActions());
|
||||||
mActionListView.setLayoutManager(new LinearLayoutManager(getContext()));
|
mActionListView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
mActionListView.setAdapter(mActionListAdapter);
|
mActionListView.setAdapter(mActionListAdapter);
|
||||||
|
|
||||||
// setup action click event listener
|
mAddAction.setOnClickListener(v -> {
|
||||||
ChooseActionDialog.setOnClickListener(newActionObject -> {
|
FragmentManager fragmentManager = getFragmentManager();
|
||||||
mEvent.addAction(newActionObject);
|
if (fragmentManager != null)
|
||||||
mActionListAdapter.notifyDataSetChanged();
|
new ChooseActionDialog().show(fragmentManager, "ChooseActionDialog");
|
||||||
});
|
|
||||||
mEditAction.setOnClickListener(v -> {
|
|
||||||
ChooseActionDialog dialog = ChooseActionDialog.newInstance();
|
|
||||||
if (getFragmentManager() != null)
|
|
||||||
dialog.show(getFragmentManager(), "ChooseActionDialog");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
showPreconditions();
|
||||||
|
|
||||||
MainApp.bus().register(this);
|
MainApp.bus().register(this);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
|
@ -142,12 +136,34 @@ public class EditEventDialog extends DialogFragment {
|
||||||
public void onEventAutomationUpdateGui(EventAutomationUpdateGui ignored) {
|
public void onEventAutomationUpdateGui(EventAutomationUpdateGui ignored) {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
if (activity != null)
|
if (activity != null)
|
||||||
activity.runOnUiThread(() -> mActionListAdapter.notifyDataSetChanged());
|
activity.runOnUiThread(() -> {
|
||||||
|
mActionListAdapter.notifyDataSetChanged();
|
||||||
|
showPreconditions();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onEventAutomationAddAction(EventAutomationAddAction event) {
|
||||||
|
Activity activity = getActivity();
|
||||||
|
if (activity != null)
|
||||||
|
activity.runOnUiThread(() -> {
|
||||||
|
mEvent.addAction(event.getAction());
|
||||||
|
mActionListAdapter.notifyDataSetChanged();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onEventAutomationUpdateTrigger(EventAutomationUpdateTrigger event) {
|
||||||
|
Activity activity = getActivity();
|
||||||
|
if (activity != null)
|
||||||
|
activity.runOnUiThread(() -> {
|
||||||
|
mEvent.setTrigger(event.getTrigger());
|
||||||
|
mTriggerDescription.setText(mEvent.getTrigger().friendlyDescription());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.ok)
|
@OnClick(R.id.ok)
|
||||||
@SuppressWarnings("unused")
|
public void onButtonOk(View unused) {
|
||||||
public void onButtonOk(View view) {
|
|
||||||
// check for title
|
// check for title
|
||||||
String title = mEditEventTitle.getText().toString();
|
String title = mEditEventTitle.getText().toString();
|
||||||
if (title.isEmpty()) {
|
if (title.isEmpty()) {
|
||||||
|
@ -178,14 +194,12 @@ public class EditEventDialog extends DialogFragment {
|
||||||
plugin.getAutomationEvents().add(mEvent);
|
plugin.getAutomationEvents().add(mEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mClickListener != null) mClickListener.onClick(mEvent);
|
|
||||||
dismiss();
|
dismiss();
|
||||||
MainApp.bus().post(new EventAutomationDataChanged());
|
MainApp.bus().post(new EventAutomationDataChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.cancel)
|
@OnClick(R.id.cancel)
|
||||||
@SuppressWarnings("unused")
|
public void onButtonCancel(View unused) {
|
||||||
public void onButtonCancel(View view) {
|
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,4 +209,15 @@ public class EditEventDialog extends DialogFragment {
|
||||||
bundle.putBoolean("addNew", mAddNew);
|
bundle.putBoolean("addNew", mAddNew);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showPreconditions() {
|
||||||
|
TriggerConnector forcedTriggers = mEvent.getPreconditions();
|
||||||
|
if (forcedTriggers.size() > 0) {
|
||||||
|
mForcedTriggerDescription.setVisibility(View.VISIBLE);
|
||||||
|
mForcedTriggerDescriptionLabel.setVisibility(View.VISIBLE);
|
||||||
|
mForcedTriggerDescription.setText(forcedTriggers.friendlyDescription());
|
||||||
|
} else {
|
||||||
|
mForcedTriggerDescription.setVisibility(View.GONE);
|
||||||
|
mForcedTriggerDescriptionLabel.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,9 @@ import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import butterknife.Unbinder;
|
import butterknife.Unbinder;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
||||||
|
|
||||||
public class EditTriggerDialog extends DialogFragment {
|
public class EditTriggerDialog extends DialogFragment {
|
||||||
|
@ -22,8 +24,6 @@ public class EditTriggerDialog extends DialogFragment {
|
||||||
void onClick(Trigger newTriggerObject);
|
void onClick(Trigger newTriggerObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OnClickListener mClickListener = null;
|
|
||||||
|
|
||||||
@BindView(R.id.layoutTrigger)
|
@BindView(R.id.layoutTrigger)
|
||||||
LinearLayout mLayoutTrigger;
|
LinearLayout mLayoutTrigger;
|
||||||
|
|
||||||
|
@ -58,10 +58,6 @@ public class EditTriggerDialog extends DialogFragment {
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setOnClickListener(OnClickListener clickListener) {
|
|
||||||
mClickListener = clickListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
mUnbinder.unbind();
|
mUnbinder.unbind();
|
||||||
|
@ -69,17 +65,13 @@ public class EditTriggerDialog extends DialogFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.ok)
|
@OnClick(R.id.ok)
|
||||||
@SuppressWarnings("unused")
|
public void onButtonOk(View unused) {
|
||||||
public void onButtonOk(View view) {
|
|
||||||
if (mClickListener != null)
|
|
||||||
mClickListener.onClick(mTrigger);
|
|
||||||
|
|
||||||
dismiss();
|
dismiss();
|
||||||
|
MainApp.bus().post(new EventAutomationUpdateTrigger(mTrigger));
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.cancel)
|
@OnClick(R.id.cancel)
|
||||||
@SuppressWarnings("unused")
|
public void onButtonCancel(View unused) {
|
||||||
public void onButtonCancel(View view) {
|
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class TriggerListAdapter {
|
||||||
|
private final LinearLayout mRootLayout;
|
||||||
|
private final FragmentManager mFragmentManager;
|
||||||
|
private final Context mContext;
|
||||||
|
private final TriggerConnector mRootConnector;
|
||||||
|
|
||||||
|
public TriggerListAdapter(FragmentManager fragmentManager, Context context, LinearLayout rootLayout, TriggerConnector rootTrigger) {
|
||||||
|
mRootLayout = rootLayout;
|
||||||
|
mFragmentManager = fragmentManager;
|
||||||
|
mContext = context;
|
||||||
|
mRootConnector = rootTrigger;
|
||||||
|
build(fragmentManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context getContext() {
|
||||||
|
return mContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FragmentManager getFM() {
|
||||||
|
return mFragmentManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy() {
|
||||||
|
mRootLayout.removeAllViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void build(FragmentManager fragmentManager) {
|
||||||
|
for (int i = 0; i < mRootConnector.size(); ++i) {
|
||||||
|
final Trigger trigger = mRootConnector.get(i);
|
||||||
|
|
||||||
|
// spinner
|
||||||
|
if (i > 0) {
|
||||||
|
createSpinner(trigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
// trigger layout
|
||||||
|
trigger.generateDialog(mRootLayout, fragmentManager);
|
||||||
|
|
||||||
|
// buttons
|
||||||
|
createButtons(fragmentManager, trigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRootConnector.size() == 0) {
|
||||||
|
Button buttonAdd = new Button(mContext);
|
||||||
|
buttonAdd.setText(MainApp.gs(R.string.addnew));
|
||||||
|
buttonAdd.setOnClickListener(v -> {
|
||||||
|
ChooseTriggerDialog dialog = ChooseTriggerDialog.newInstance();
|
||||||
|
dialog.setOnClickListener(newTriggerObject -> {
|
||||||
|
mRootConnector.add(newTriggerObject);
|
||||||
|
rebuild(fragmentManager);
|
||||||
|
});
|
||||||
|
dialog.show(fragmentManager, "ChooseTriggerDialog");
|
||||||
|
});
|
||||||
|
mRootLayout.addView(buttonAdd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 createSpinner(Trigger trigger) {
|
||||||
|
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) {
|
||||||
|
// connector type changed
|
||||||
|
changeConnector(getFM(), trigger, connector, TriggerConnector.Type.values()[position]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mRootLayout.addView(spinner);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createButtons(FragmentManager fragmentManager, Trigger trigger) {
|
||||||
|
// 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));
|
||||||
|
mRootLayout.addView(buttonLayout);
|
||||||
|
|
||||||
|
// Button [-]
|
||||||
|
Button buttonRemove = new Button(mContext);
|
||||||
|
buttonRemove.setText(MainApp.gs(R.string.delete_short));
|
||||||
|
buttonRemove.setOnClickListener(v -> {
|
||||||
|
final TriggerConnector connector = trigger.getConnector();
|
||||||
|
connector.remove(trigger);
|
||||||
|
connector.simplify().rebuildView(getFM());
|
||||||
|
});
|
||||||
|
buttonLayout.addView(buttonRemove);
|
||||||
|
|
||||||
|
// Button [+]
|
||||||
|
Button buttonAdd = new Button(mContext);
|
||||||
|
buttonAdd.setText(MainApp.gs(R.string.add_short));
|
||||||
|
buttonAdd.setOnClickListener(v -> {
|
||||||
|
ChooseTriggerDialog dialog = ChooseTriggerDialog.newInstance();
|
||||||
|
dialog.show(fragmentManager, "ChooseTriggerDialog");
|
||||||
|
dialog.setOnClickListener(newTriggerObject -> {
|
||||||
|
TriggerConnector connector = trigger.getConnector();
|
||||||
|
connector.add(connector.pos(trigger) + 1, newTriggerObject);
|
||||||
|
connector.simplify().rebuildView(getFM());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
buttonLayout.addView(buttonAdd);
|
||||||
|
|
||||||
|
// Button [*]
|
||||||
|
Button buttonCopy = new Button(mContext);
|
||||||
|
buttonCopy.setText(MainApp.gs(R.string.copy_short));
|
||||||
|
buttonCopy.setOnClickListener(v -> {
|
||||||
|
TriggerConnector connector = trigger.getConnector();
|
||||||
|
connector.add(connector.pos(trigger) + 1, trigger.duplicate());
|
||||||
|
connector.simplify().rebuildView(getFM());
|
||||||
|
});
|
||||||
|
buttonLayout.addView(buttonCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rebuild(FragmentManager fragmentManager) {
|
||||||
|
destroy();
|
||||||
|
build(fragmentManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeConnector(final FragmentManager fragmentManager, 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(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.changeConnectorType(newConnectorType);
|
||||||
|
}
|
||||||
|
|
||||||
|
connector.simplify().rebuildView(fragmentManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -13,8 +13,8 @@ public class InputPercent extends Element {
|
||||||
final TextWatcher textWatcher = new TextWatcher() {
|
final TextWatcher textWatcher = new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
value = Math.max(value, 0d);
|
value = Math.max(value, 70d);
|
||||||
value = Math.min(value, 500d);
|
value = Math.min(value, 130d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,7 +41,7 @@ public class InputPercent extends Element {
|
||||||
@Override
|
@Override
|
||||||
public void addToLayout(LinearLayout root) {
|
public void addToLayout(LinearLayout root) {
|
||||||
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
|
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
|
||||||
numberPicker.setParams(100d, 0d, 500d, 10d, new DecimalFormat("0"), true, textWatcher);
|
numberPicker.setParams(100d, 70d, 130d, 5d, new DecimalFormat("0"), true, textWatcher);
|
||||||
numberPicker.setValue(value);
|
numberPicker.setValue(value);
|
||||||
numberPicker.setOnValueChangedListener(value -> this.value = value);
|
numberPicker.setOnValueChangedListener(value -> this.value = value);
|
||||||
root.addView(numberPicker);
|
root.addView(numberPicker);
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.automation.events;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.events.Event;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||||
|
|
||||||
|
public class EventAutomationAddAction extends Event {
|
||||||
|
private Action action;
|
||||||
|
|
||||||
|
public EventAutomationAddAction(Action action) {
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.automation.events;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.events.Event;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
||||||
|
|
||||||
|
public class EventAutomationUpdateTrigger extends Event {
|
||||||
|
private Trigger trigger;
|
||||||
|
|
||||||
|
public EventAutomationUpdateTrigger(Trigger trigger) {
|
||||||
|
this.trigger = trigger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Trigger getTrigger() {
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ import java.util.List;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.logging.L;
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.AutomationFragment;
|
import info.nightscout.androidaps.plugins.general.automation.dialogs.TriggerListAdapter;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
|
|
||||||
public class TriggerConnector extends Trigger {
|
public class TriggerConnector extends Trigger {
|
||||||
|
@ -217,7 +217,7 @@ public class TriggerConnector extends Trigger {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AutomationFragment.TriggerListAdapter adapter;
|
private TriggerListAdapter adapter;
|
||||||
|
|
||||||
public void rebuildView(FragmentManager fragmentManager) {
|
public void rebuildView(FragmentManager fragmentManager) {
|
||||||
if (adapter != null)
|
if (adapter != null)
|
||||||
|
@ -236,7 +236,7 @@ public class TriggerConnector extends Trigger {
|
||||||
triggerListLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
triggerListLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
root.addView(triggerListLayout);
|
root.addView(triggerListLayout);
|
||||||
|
|
||||||
adapter = new AutomationFragment().new TriggerListAdapter(fragmentManager, root.getContext(), triggerListLayout, this);
|
adapter = new TriggerListAdapter(fragmentManager, root.getContext(), triggerListLayout, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TriggerConnector simplify() {
|
public TriggerConnector simplify() {
|
||||||
|
|
|
@ -126,7 +126,7 @@ public class TriggerProfilePercent extends Trigger {
|
||||||
return new TriggerProfilePercent(this);
|
return new TriggerProfilePercent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerProfilePercent setValue(double value) {
|
public TriggerProfilePercent setValue(double value) {
|
||||||
pct.setValue(value);
|
pct.setValue(value);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ public class TriggerProfilePercent extends Trigger {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerProfilePercent comparator(Comparator.Compare compare) {
|
public TriggerProfilePercent comparator(Comparator.Compare compare) {
|
||||||
this.comparator = new Comparator().setValue(compare);
|
this.comparator = new Comparator().setValue(compare);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ public class TriggerTempTarget extends Trigger {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerTempTarget comparator(ComparatorExists.Compare compare) {
|
public TriggerTempTarget comparator(ComparatorExists.Compare compare) {
|
||||||
this.comparator = new ComparatorExists().setValue(compare);
|
this.comparator = new ComparatorExists().setValue(compare);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,8 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/condition" />
|
android:text="@string/condition"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/editTrigger"
|
android:id="@+id/editTrigger"
|
||||||
|
@ -54,6 +55,21 @@
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:orientation="vertical" />
|
android:orientation="vertical" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/forcedtriggerdescriptionlabel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/preconditions"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/forcedtriggerdescription"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:orientation="vertical" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="2dip"
|
android:layout_height="2dip"
|
||||||
|
@ -68,10 +84,11 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/action" />
|
android:text="@string/action"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/editAction"
|
android:id="@+id/addAction"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
|
|
|
@ -1442,6 +1442,7 @@
|
||||||
<string name="profilepercentage">Profile percentage</string>
|
<string name="profilepercentage">Profile percentage</string>
|
||||||
<string name="percent_u">Percent [%]:</string>
|
<string name="percent_u">Percent [%]:</string>
|
||||||
<string name="startprofile">Start profile %1$d%% for %2$d min</string>
|
<string name="startprofile">Start profile %1$d%% for %2$d min</string>
|
||||||
|
<string name="startprofileforever">Start profile %1$d%%</string>
|
||||||
<string name="exists">exists</string>
|
<string name="exists">exists</string>
|
||||||
<string name="notexists">not exists</string>
|
<string name="notexists">not exists</string>
|
||||||
<string name="temptargetcompared">Temp target %1$s</string>
|
<string name="temptargetcompared">Temp target %1$s</string>
|
||||||
|
@ -1470,6 +1471,7 @@
|
||||||
<string name="then_label">Then:</string>
|
<string name="then_label">Then:</string>
|
||||||
<string name="triggers">Triggers:</string>
|
<string name="triggers">Triggers:</string>
|
||||||
<string name="remove_label">REMOVE</string>
|
<string name="remove_label">REMOVE</string>
|
||||||
|
<string name="preconditions">Preconditions:</string>
|
||||||
|
|
||||||
<plurals name="objective_days">
|
<plurals name="objective_days">
|
||||||
<item quantity="one">%1$d day</item>
|
<item quantity="one">%1$d day</item>
|
||||||
|
|
Loading…
Reference in a new issue