2016-06-28 11:19:27 +02:00
|
|
|
package info.nightscout.utils;
|
|
|
|
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.Message;
|
|
|
|
import android.view.KeyEvent;
|
|
|
|
import android.view.MotionEvent;
|
|
|
|
import android.view.View;
|
|
|
|
|
|
|
|
import android.widget.ImageView;
|
|
|
|
import android.widget.TextView;
|
|
|
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
import java.text.NumberFormat;
|
|
|
|
import java.util.concurrent.Executors;
|
|
|
|
import java.util.concurrent.ScheduledExecutorService;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
2016-08-08 10:08:30 +02:00
|
|
|
import info.nightscout.androidaps.MainApp;
|
|
|
|
import info.nightscout.androidaps.R;
|
|
|
|
|
2016-06-28 11:19:27 +02:00
|
|
|
/**
|
|
|
|
* Created by mike on 28.06.2016.
|
|
|
|
*/
|
|
|
|
public class PlusMinusEditText implements View.OnKeyListener,
|
|
|
|
View.OnTouchListener, View.OnClickListener {
|
|
|
|
private static Logger log = LoggerFactory.getLogger(PlusMinusEditText.class);
|
|
|
|
|
|
|
|
Integer editTextID;
|
|
|
|
TextView editText;
|
|
|
|
ImageView minusImage;
|
|
|
|
ImageView plusImage;
|
|
|
|
|
|
|
|
Double value;
|
|
|
|
Double minValue = 0d;
|
|
|
|
Double maxValue = 1d;
|
|
|
|
Double step = 1d;
|
|
|
|
NumberFormat formater;
|
2016-07-02 23:58:57 +02:00
|
|
|
boolean allowZero = false;
|
2016-06-28 11:19:27 +02:00
|
|
|
|
|
|
|
private Handler mHandler;
|
|
|
|
private ScheduledExecutorService mUpdater;
|
|
|
|
|
|
|
|
private class UpdateCounterTask implements Runnable {
|
|
|
|
private boolean mInc;
|
2016-08-08 16:03:03 +02:00
|
|
|
private int repeated = 0;
|
|
|
|
private int multiplier = 1;
|
|
|
|
|
|
|
|
private final int doubleLimit = 5;
|
2016-06-28 11:19:27 +02:00
|
|
|
|
|
|
|
public UpdateCounterTask(boolean inc) {
|
|
|
|
mInc = inc;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void run() {
|
2016-08-08 16:03:03 +02:00
|
|
|
Message msg = new Message();
|
|
|
|
if (repeated % doubleLimit == 0) multiplier *= 2;
|
|
|
|
repeated++;
|
|
|
|
msg.arg1 = multiplier;
|
|
|
|
msg.arg2 = repeated;
|
2016-06-28 11:19:27 +02:00
|
|
|
if (mInc) {
|
2016-08-08 16:03:03 +02:00
|
|
|
msg.what = MSG_INC;
|
2016-06-28 11:19:27 +02:00
|
|
|
} else {
|
2016-08-08 16:03:03 +02:00
|
|
|
msg.what = MSG_DEC;
|
2016-06-28 11:19:27 +02:00
|
|
|
}
|
2016-08-08 16:03:03 +02:00
|
|
|
mHandler.sendMessage(msg);
|
2016-06-28 11:19:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static final int MSG_INC = 0;
|
|
|
|
private static final int MSG_DEC = 1;
|
|
|
|
|
2016-07-02 23:58:57 +02:00
|
|
|
public PlusMinusEditText(View view, int editTextID, int plusID, int minusID, Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formater, boolean allowZero) {
|
2016-06-28 11:19:27 +02:00
|
|
|
editText = (TextView) view.findViewById(editTextID);
|
|
|
|
minusImage = (ImageView) view.findViewById(minusID);
|
|
|
|
plusImage = (ImageView) view.findViewById(plusID);
|
|
|
|
|
|
|
|
this.value = initValue;
|
|
|
|
this.minValue = minValue;
|
|
|
|
this.maxValue = maxValue;
|
|
|
|
this.step = step;
|
|
|
|
this.formater = formater;
|
2016-07-02 23:58:57 +02:00
|
|
|
this.allowZero = allowZero;
|
2016-06-28 11:19:27 +02:00
|
|
|
|
|
|
|
mHandler = new Handler() {
|
|
|
|
@Override
|
|
|
|
public void handleMessage(Message msg) {
|
|
|
|
switch (msg.what) {
|
|
|
|
case MSG_INC:
|
2016-08-08 16:03:03 +02:00
|
|
|
inc(msg.arg1);
|
2016-06-28 11:19:27 +02:00
|
|
|
return;
|
|
|
|
case MSG_DEC:
|
2016-08-08 16:03:03 +02:00
|
|
|
dec(msg.arg1);
|
2016-06-28 11:19:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
super.handleMessage(msg);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
minusImage.setOnTouchListener(this);
|
|
|
|
minusImage.setOnKeyListener(this);
|
|
|
|
minusImage.setOnClickListener(this);
|
|
|
|
plusImage.setOnTouchListener(this);
|
|
|
|
plusImage.setOnKeyListener(this);
|
|
|
|
plusImage.setOnClickListener(this);
|
2016-07-02 23:58:57 +02:00
|
|
|
updateEditText();
|
2016-06-28 11:19:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setValue(Double value) {
|
|
|
|
this.value = value;
|
|
|
|
updateEditText();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Double getValue() {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2017-05-30 15:07:44 +02:00
|
|
|
public String getText() {
|
|
|
|
return editText.getText().toString();
|
|
|
|
}
|
|
|
|
|
2016-06-28 11:19:27 +02:00
|
|
|
public void setStep(Double step) {
|
|
|
|
this.step = step;
|
|
|
|
}
|
|
|
|
|
2016-08-08 16:03:03 +02:00
|
|
|
private void inc(int multiplier) {
|
|
|
|
value += step * multiplier;
|
2016-08-08 10:08:30 +02:00
|
|
|
if (value > maxValue) {
|
|
|
|
value = maxValue;
|
|
|
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.youareonallowedlimit));
|
|
|
|
stopUpdating();
|
|
|
|
}
|
2016-06-28 11:19:27 +02:00
|
|
|
updateEditText();
|
|
|
|
}
|
|
|
|
|
2016-08-08 16:03:03 +02:00
|
|
|
private void dec( int multiplier) {
|
|
|
|
value -= step * multiplier;
|
2016-08-08 10:08:30 +02:00
|
|
|
if (value < minValue) {
|
|
|
|
value = minValue;
|
|
|
|
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.youareonallowedlimit));
|
|
|
|
stopUpdating();
|
|
|
|
}
|
2016-06-28 11:19:27 +02:00
|
|
|
updateEditText();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void updateEditText() {
|
2016-07-02 23:58:57 +02:00
|
|
|
if (value == 0d && !allowZero)
|
2016-06-28 11:19:27 +02:00
|
|
|
editText.setText("");
|
|
|
|
else
|
|
|
|
editText.setText(formater.format(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
private void startUpdating(boolean inc) {
|
|
|
|
if (mUpdater != null) {
|
2016-08-08 16:03:03 +02:00
|
|
|
log.debug("Another executor is still active");
|
2016-06-28 11:19:27 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
mUpdater = Executors.newSingleThreadScheduledExecutor();
|
|
|
|
mUpdater.scheduleAtFixedRate(new UpdateCounterTask(inc), 200, 200,
|
|
|
|
TimeUnit.MILLISECONDS);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void stopUpdating() {
|
2016-08-08 10:08:30 +02:00
|
|
|
if (mUpdater != null) {
|
|
|
|
mUpdater.shutdownNow();
|
|
|
|
mUpdater = null;
|
|
|
|
}
|
2016-06-28 11:19:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
if (mUpdater == null) {
|
|
|
|
if (v == plusImage) {
|
2016-08-08 16:03:03 +02:00
|
|
|
inc(1);
|
2016-06-28 11:19:27 +02:00
|
|
|
} else {
|
2016-08-08 16:03:03 +02:00
|
|
|
dec(1);
|
2016-06-28 11:19:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
|
|
|
boolean isKeyOfInterest = keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER;
|
|
|
|
boolean isReleased = event.getAction() == KeyEvent.ACTION_UP;
|
|
|
|
boolean isPressed = event.getAction() == KeyEvent.ACTION_DOWN
|
|
|
|
&& event.getAction() != KeyEvent.ACTION_MULTIPLE;
|
|
|
|
|
|
|
|
if (isKeyOfInterest && isReleased) {
|
|
|
|
stopUpdating();
|
|
|
|
} else if (isKeyOfInterest && isPressed) {
|
|
|
|
startUpdating(v == plusImage);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onTouch(View v, MotionEvent event) {
|
|
|
|
boolean isReleased = event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL;
|
|
|
|
boolean isPressed = event.getAction() == MotionEvent.ACTION_DOWN;
|
|
|
|
|
|
|
|
if (isReleased) {
|
|
|
|
stopUpdating();
|
|
|
|
} else if (isPressed) {
|
|
|
|
startUpdating(v == plusImage);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|