mirror of https://github.com/tasks/tasks
Deleted some cruft, fixed a bunch of unit tests
parent
8c2d742336
commit
c3025f355f
@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
* ASTRID: Android's Simple Task Recording Dashboard
|
|
||||||
*
|
|
||||||
* Copyright (c) 2009 Tim Su
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
package com.todoroo.andlib.widget;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.DialogInterface.OnClickListener;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.FrameLayout.LayoutParams;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.service.Autowired;
|
|
||||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
||||||
|
|
||||||
/** Dialog box with an arbitrary number of number pickers */
|
|
||||||
public class NNumberPickerDialog extends AlertDialog implements OnClickListener {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Integer nNumberPickerLayout;
|
|
||||||
|
|
||||||
public interface OnNNumberPickedListener {
|
|
||||||
void onNumbersPicked(int[] number);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final List<NumberPickerWidget> pickers = new LinkedList<NumberPickerWidget>();
|
|
||||||
private final OnNNumberPickedListener mCallback;
|
|
||||||
|
|
||||||
/** Instantiate the dialog box.
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param callBack callback function to get the numbers you requested
|
|
||||||
* @param title title of the dialog box
|
|
||||||
* @param initialValue initial picker values array
|
|
||||||
* @param incrementBy picker increment by array
|
|
||||||
* @param start picker range start array
|
|
||||||
* @param end picker range end array
|
|
||||||
* @param separators text separating the spinners. whole array, or individual
|
|
||||||
* elements can be null
|
|
||||||
*/
|
|
||||||
public NNumberPickerDialog(Context context, OnNNumberPickedListener callBack,
|
|
||||||
String title, int[] initialValue, int[] incrementBy, int[] start,
|
|
||||||
int[] end, String[] separators) {
|
|
||||||
super(context);
|
|
||||||
mCallback = callBack;
|
|
||||||
|
|
||||||
DependencyInjectionService.getInstance().inject(this);
|
|
||||||
|
|
||||||
setButton(context.getText(android.R.string.ok), this);
|
|
||||||
setButton2(context.getText(android.R.string.cancel), (OnClickListener) null);
|
|
||||||
|
|
||||||
LayoutInflater inflater = (LayoutInflater) context
|
|
||||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
View view = inflater.inflate(nNumberPickerLayout, null);
|
|
||||||
setView(view);
|
|
||||||
LinearLayout container = (LinearLayout)view;
|
|
||||||
|
|
||||||
setTitle(title);
|
|
||||||
LayoutParams npLayout = new LayoutParams(LayoutParams.WRAP_CONTENT,
|
|
||||||
LayoutParams.FILL_PARENT);
|
|
||||||
npLayout.gravity = 1;
|
|
||||||
LayoutParams sepLayout = new LayoutParams(LayoutParams.WRAP_CONTENT,
|
|
||||||
LayoutParams.FILL_PARENT);
|
|
||||||
for(int i = 0; i < incrementBy.length; i++) {
|
|
||||||
NumberPickerWidget np = new NumberPickerWidget(context, null);
|
|
||||||
np.setIncrementBy(incrementBy[i]);
|
|
||||||
np.setLayoutParams(npLayout);
|
|
||||||
np.setRange(start[i], end[i]);
|
|
||||||
np.setCurrent(initialValue[i]);
|
|
||||||
|
|
||||||
container.addView(np);
|
|
||||||
pickers.add(np);
|
|
||||||
|
|
||||||
if(separators != null && separators[i] != null) {
|
|
||||||
TextView text = new TextView(context);
|
|
||||||
text.setText(separators[i]);
|
|
||||||
if(separators[i].length() < 3)
|
|
||||||
text.setTextSize(48);
|
|
||||||
else
|
|
||||||
text.setTextSize(20);
|
|
||||||
text.setGravity(Gravity.CENTER);
|
|
||||||
text.setLayoutParams(sepLayout);
|
|
||||||
container.addView(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInitialValues(int[] values) {
|
|
||||||
for(int i = 0; i < pickers.size(); i++)
|
|
||||||
pickers.get(i).setCurrent(values[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
if (mCallback != null) {
|
|
||||||
int[] values = new int[pickers.size()];
|
|
||||||
for(int i = 0; i < pickers.size(); i++) {
|
|
||||||
pickers.get(i).clearFocus();
|
|
||||||
values[i] = pickers.get(i).getCurrent();
|
|
||||||
}
|
|
||||||
mCallback.onNumbersPicked(values);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* ASTRID: Android's Simple Task Recording Dashboard
|
|
||||||
*
|
|
||||||
* Copyright (c) 2009 Tim Su
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
package com.todoroo.andlib.widget;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.DialogInterface.OnClickListener;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.service.Autowired;
|
|
||||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
||||||
|
|
||||||
public class NumberPickerDialog extends AlertDialog implements OnClickListener {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Integer numberPickerDialogLayout;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Integer numberPickerId;
|
|
||||||
|
|
||||||
public interface OnNumberPickedListener {
|
|
||||||
void onNumberPicked(NumberPickerWidget view, int number);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final NumberPickerWidget mPicker;
|
|
||||||
private final OnNumberPickedListener mCallback;
|
|
||||||
|
|
||||||
public NumberPickerDialog(Context context, OnNumberPickedListener callBack,
|
|
||||||
String title, int initialValue, int incrementBy, int start, int end) {
|
|
||||||
super(context);
|
|
||||||
DependencyInjectionService.getInstance().inject(this);
|
|
||||||
|
|
||||||
mCallback = callBack;
|
|
||||||
|
|
||||||
setButton(context.getText(android.R.string.ok), this);
|
|
||||||
setButton2(context.getText(android.R.string.cancel), (OnClickListener) null);
|
|
||||||
|
|
||||||
LayoutInflater inflater = (LayoutInflater) context
|
|
||||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
View view = inflater.inflate(numberPickerDialogLayout, null);
|
|
||||||
setView(view);
|
|
||||||
|
|
||||||
setTitle(title);
|
|
||||||
mPicker = (NumberPickerWidget) view.findViewById(numberPickerId);
|
|
||||||
mPicker.setIncrementBy(incrementBy);
|
|
||||||
mPicker.setRange(start, end);
|
|
||||||
mPicker.setCurrent(initialValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInitialValue(int initialValue) {
|
|
||||||
mPicker.setCurrent(initialValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
if (mCallback != null) {
|
|
||||||
mPicker.clearFocus();
|
|
||||||
mCallback.onNumberPicked(mPicker, mPicker.getCurrent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,460 +0,0 @@
|
|||||||
/*
|
|
||||||
* ASTRID: Android's Simple Task Recording Dashboard
|
|
||||||
*
|
|
||||||
* Copyright (c) 2009 Tim Su
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
package com.todoroo.andlib.widget;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.text.InputFilter;
|
|
||||||
import android.text.Spanned;
|
|
||||||
import android.text.method.NumberKeyListener;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.View.OnFocusChangeListener;
|
|
||||||
import android.view.View.OnLongClickListener;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.view.animation.TranslateAnimation;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.service.Autowired;
|
|
||||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
||||||
|
|
||||||
public class NumberPickerWidget extends LinearLayout implements OnClickListener,
|
|
||||||
OnFocusChangeListener, OnLongClickListener {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Integer numberPickerLayout;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Integer numberPickerIncrementId;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Integer numberPickerDecrementId;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Integer numberPickerInputId;
|
|
||||||
|
|
||||||
public interface OnChangedListener {
|
|
||||||
void onChanged(NumberPickerWidget picker, int oldVal, int newVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Formatter {
|
|
||||||
String toString(int value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Use a custom NumberPicker formatting callback to use two-digit minutes
|
|
||||||
* strings like "01". Keeping a static formatter etc. is the most efficient
|
|
||||||
* way to do this; it avoids creating temporary objects on every call to
|
|
||||||
* format().
|
|
||||||
*/
|
|
||||||
public static final NumberPickerWidget.Formatter TWO_DIGIT_FORMATTER = new NumberPickerWidget.Formatter() {
|
|
||||||
final StringBuilder mBuilder = new StringBuilder();
|
|
||||||
final java.util.Formatter mFmt = new java.util.Formatter(mBuilder);
|
|
||||||
final Object[] mArgs = new Object[1];
|
|
||||||
|
|
||||||
public String toString(int value) {
|
|
||||||
mArgs[0] = value;
|
|
||||||
mBuilder.delete(0, mBuilder.length());
|
|
||||||
mFmt.format("%02d", mArgs); //$NON-NLS-1$
|
|
||||||
return mFmt.toString();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
protected int incrementBy = 1;
|
|
||||||
public void setIncrementBy(int incrementBy) {
|
|
||||||
this.incrementBy = incrementBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final Handler mHandler;
|
|
||||||
private final Runnable mRunnable = new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
if (mIncrement) {
|
|
||||||
changeCurrent(mCurrent + incrementBy, mSlideUpInAnimation, mSlideUpOutAnimation);
|
|
||||||
mHandler.postDelayed(this, mSpeed);
|
|
||||||
} else if (mDecrement) {
|
|
||||||
changeCurrent(mCurrent - incrementBy, mSlideDownInAnimation, mSlideDownOutAnimation);
|
|
||||||
mHandler.postDelayed(this, mSpeed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final LayoutInflater mInflater;
|
|
||||||
private final TextView mText;
|
|
||||||
protected final InputFilter mInputFilter;
|
|
||||||
protected final InputFilter mNumberInputFilter;
|
|
||||||
|
|
||||||
protected final Animation mSlideUpOutAnimation;
|
|
||||||
protected final Animation mSlideUpInAnimation;
|
|
||||||
protected final Animation mSlideDownOutAnimation;
|
|
||||||
protected final Animation mSlideDownInAnimation;
|
|
||||||
|
|
||||||
protected String[] mDisplayedValues;
|
|
||||||
protected int mStart;
|
|
||||||
protected int mEnd;
|
|
||||||
protected int mCurrent;
|
|
||||||
protected int mPrevious;
|
|
||||||
private OnChangedListener mListener;
|
|
||||||
private Formatter mFormatter;
|
|
||||||
protected long mSpeed = 500;
|
|
||||||
|
|
||||||
protected boolean mIncrement;
|
|
||||||
protected boolean mDecrement;
|
|
||||||
|
|
||||||
public NumberPickerWidget(Context context) {
|
|
||||||
this(context, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NumberPickerWidget(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
DependencyInjectionService.getInstance().inject(this);
|
|
||||||
|
|
||||||
setOrientation(VERTICAL);
|
|
||||||
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
mInflater.inflate(numberPickerLayout, this, true);
|
|
||||||
|
|
||||||
mHandler = new Handler(Looper.getMainLooper());
|
|
||||||
mInputFilter = new NumberPickerInputFilter();
|
|
||||||
mNumberInputFilter = new NumberRangeKeyListener();
|
|
||||||
mIncrementButton = (NumberPickerWidgetButton) findViewById(numberPickerIncrementId);
|
|
||||||
mIncrementButton.setOnClickListener(this);
|
|
||||||
mIncrementButton.setOnLongClickListener(this);
|
|
||||||
mIncrementButton.setNumberPicker(this);
|
|
||||||
mDecrementButton = (NumberPickerWidgetButton) findViewById(numberPickerDecrementId);
|
|
||||||
mDecrementButton.setOnClickListener(this);
|
|
||||||
mDecrementButton.setOnLongClickListener(this);
|
|
||||||
mDecrementButton.setNumberPicker(this);
|
|
||||||
|
|
||||||
mText = (TextView) findViewById(numberPickerInputId);
|
|
||||||
mText.setOnFocusChangeListener(this);
|
|
||||||
mText.setFilters(new InputFilter[] { mInputFilter });
|
|
||||||
|
|
||||||
mSlideUpOutAnimation = new TranslateAnimation(
|
|
||||||
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
|
|
||||||
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, -100);
|
|
||||||
mSlideUpOutAnimation.setDuration(200);
|
|
||||||
mSlideUpInAnimation = new TranslateAnimation(
|
|
||||||
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
|
|
||||||
Animation.RELATIVE_TO_SELF, 100, Animation.RELATIVE_TO_SELF, 0);
|
|
||||||
mSlideUpInAnimation.setDuration(200);
|
|
||||||
mSlideDownOutAnimation = new TranslateAnimation(
|
|
||||||
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
|
|
||||||
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 100);
|
|
||||||
mSlideDownOutAnimation.setDuration(200);
|
|
||||||
mSlideDownInAnimation = new TranslateAnimation(
|
|
||||||
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
|
|
||||||
Animation.RELATIVE_TO_SELF, -100, Animation.RELATIVE_TO_SELF, 0);
|
|
||||||
mSlideDownInAnimation.setDuration(200);
|
|
||||||
|
|
||||||
if (!isEnabled()) {
|
|
||||||
setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
super.setEnabled(enabled);
|
|
||||||
mIncrementButton.setEnabled(enabled);
|
|
||||||
mDecrementButton.setEnabled(enabled);
|
|
||||||
mText.setEnabled(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnChangeListener(OnChangedListener listener) {
|
|
||||||
mListener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFormatter(Formatter formatter) {
|
|
||||||
mFormatter = formatter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the range of numbers allowed for the number picker. The current value
|
|
||||||
* will be automatically set to the start.
|
|
||||||
*
|
|
||||||
* @param start
|
|
||||||
* the start of the range (inclusive)
|
|
||||||
* @param end
|
|
||||||
* the end of the range (inclusive)
|
|
||||||
*/
|
|
||||||
public void setRange(int start, int end) {
|
|
||||||
mStart = start;
|
|
||||||
mEnd = end;
|
|
||||||
mCurrent = start;
|
|
||||||
updateView();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the range of numbers allowed for the number picker. The current value
|
|
||||||
* will be automatically set to the start. Also provide a mapping for values
|
|
||||||
* used to display to the user.
|
|
||||||
*
|
|
||||||
* @param start
|
|
||||||
* the start of the range (inclusive)
|
|
||||||
* @param end
|
|
||||||
* the end of the range (inclusive)
|
|
||||||
* @param displayedValues
|
|
||||||
* the values displayed to the user.
|
|
||||||
*/
|
|
||||||
public void setRange(int start, int end, String[] displayedValues) {
|
|
||||||
mDisplayedValues = displayedValues;
|
|
||||||
mStart = start;
|
|
||||||
mEnd = end;
|
|
||||||
mCurrent = start;
|
|
||||||
updateView();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrent(int current) {
|
|
||||||
mCurrent = current;
|
|
||||||
updateView();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The speed (in milliseconds) at which the numbers will scroll when the the
|
|
||||||
* +/- buttons are longpressed. Default is 300ms.
|
|
||||||
*/
|
|
||||||
public void setSpeed(long speed) {
|
|
||||||
mSpeed = speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClick(View v) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text view may still have focus so clear it's focus which will
|
|
||||||
* trigger the on focus changed and any typed values to be pulled.
|
|
||||||
*/
|
|
||||||
mText.clearFocus();
|
|
||||||
|
|
||||||
// now perform the increment/decrement
|
|
||||||
if (numberPickerIncrementId == v.getId()) {
|
|
||||||
changeCurrent(mCurrent + incrementBy, mSlideUpInAnimation,
|
|
||||||
mSlideUpOutAnimation);
|
|
||||||
} else if (numberPickerDecrementId == v.getId()) {
|
|
||||||
changeCurrent(mCurrent - incrementBy, mSlideDownInAnimation,
|
|
||||||
mSlideDownOutAnimation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String formatNumber(int value) {
|
|
||||||
return (mFormatter != null) ? mFormatter.toString(value)
|
|
||||||
: String.valueOf(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void changeCurrent(int current,
|
|
||||||
@SuppressWarnings("unused") Animation in,
|
|
||||||
@SuppressWarnings("unused") Animation out) {
|
|
||||||
|
|
||||||
// Wrap around the values if we go past the start or end
|
|
||||||
if (current > mEnd) {
|
|
||||||
current = mStart;
|
|
||||||
} else if (current < mStart) {
|
|
||||||
current = mEnd;
|
|
||||||
}
|
|
||||||
mPrevious = mCurrent;
|
|
||||||
mCurrent = current;
|
|
||||||
notifyChange();
|
|
||||||
updateView();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyChange() {
|
|
||||||
if (mListener != null) {
|
|
||||||
mListener.onChanged(this, mPrevious, mCurrent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateView() {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we don't have displayed values then use the current number else
|
|
||||||
* find the correct value in the displayed values for the current
|
|
||||||
* number.
|
|
||||||
*/
|
|
||||||
if (mDisplayedValues == null) {
|
|
||||||
mText.setText(formatNumber(mCurrent));
|
|
||||||
} else {
|
|
||||||
mText.setText(mDisplayedValues[mCurrent - mStart]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateCurrentView(CharSequence str) {
|
|
||||||
int val = getSelectedPos(str.toString());
|
|
||||||
if ((val >= mStart) && (val <= mEnd)) {
|
|
||||||
mPrevious = mCurrent;
|
|
||||||
mCurrent = val;
|
|
||||||
notifyChange();
|
|
||||||
}
|
|
||||||
updateView();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onFocusChange(View v, boolean hasFocus) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When focus is lost check that the text field has valid values.
|
|
||||||
*/
|
|
||||||
if (!hasFocus && v instanceof TextView) {
|
|
||||||
String str = String.valueOf(((TextView) v).getText());
|
|
||||||
if ("".equals(str)) { //$NON-NLS-1$
|
|
||||||
|
|
||||||
// Restore to the old value as we don't allow empty values
|
|
||||||
updateView();
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Check the new value and ensure it's in range
|
|
||||||
validateCurrentView(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We start the long click here but rely on the {@link NumberPickerWidgetButton}
|
|
||||||
* to inform us when the long click has ended.
|
|
||||||
*/
|
|
||||||
public boolean onLongClick(View v) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The text view may still have focus so clear it's focus which will
|
|
||||||
* trigger the on focus changed and any typed values to be pulled.
|
|
||||||
*/
|
|
||||||
mText.clearFocus();
|
|
||||||
|
|
||||||
if (numberPickerIncrementId == v.getId()) {
|
|
||||||
mIncrement = true;
|
|
||||||
mHandler.post(mRunnable);
|
|
||||||
} else if (numberPickerDecrementId == v.getId()) {
|
|
||||||
mDecrement = true;
|
|
||||||
mHandler.post(mRunnable);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelIncrement() {
|
|
||||||
mIncrement = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cancelDecrement() {
|
|
||||||
mDecrement = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static final char[] DIGIT_CHARACTERS = new char[] { '0', '1', '2',
|
|
||||||
'3', '4', '5', '6', '7', '8', '9' };
|
|
||||||
|
|
||||||
private NumberPickerWidgetButton mIncrementButton;
|
|
||||||
private NumberPickerWidgetButton mDecrementButton;
|
|
||||||
|
|
||||||
class NumberPickerInputFilter implements InputFilter {
|
|
||||||
public CharSequence filter(CharSequence source, int start, int end,
|
|
||||||
Spanned dest, int dstart, int dend) {
|
|
||||||
if (mDisplayedValues == null) {
|
|
||||||
return mNumberInputFilter.filter(source, start, end, dest,
|
|
||||||
dstart, dend);
|
|
||||||
}
|
|
||||||
CharSequence filtered = String.valueOf(source.subSequence(start,
|
|
||||||
end));
|
|
||||||
String result = String.valueOf(dest.subSequence(0, dstart))
|
|
||||||
+ filtered + dest.subSequence(dend, dest.length());
|
|
||||||
String str = String.valueOf(result).toLowerCase();
|
|
||||||
for (String val : mDisplayedValues) {
|
|
||||||
val = val.toLowerCase();
|
|
||||||
if (val.startsWith(str)) {
|
|
||||||
return filtered;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""; //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NumberRangeKeyListener extends NumberKeyListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected char[] getAcceptedChars() {
|
|
||||||
return DIGIT_CHARACTERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence filter(CharSequence source, int start, int end,
|
|
||||||
Spanned dest, int dstart, int dend) {
|
|
||||||
|
|
||||||
CharSequence filtered = super.filter(source, start, end, dest,
|
|
||||||
dstart, dend);
|
|
||||||
if (filtered == null) {
|
|
||||||
filtered = source.subSequence(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
String result = String.valueOf(dest.subSequence(0, dstart))
|
|
||||||
+ filtered + dest.subSequence(dend, dest.length());
|
|
||||||
|
|
||||||
if ("".equals(result)) { //$NON-NLS-1$
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
int val = getSelectedPos(result);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ensure the user can't type in a value greater than the max
|
|
||||||
* allowed. We have to allow less than min as the user might want to
|
|
||||||
* delete some numbers and then type a new number.
|
|
||||||
*/
|
|
||||||
if (val > mEnd) {
|
|
||||||
return ""; //$NON-NLS-1$
|
|
||||||
} else {
|
|
||||||
return filtered;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getInputType() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int getSelectedPos(String str) {
|
|
||||||
if (mDisplayedValues == null) {
|
|
||||||
return Integer.parseInt(str);
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < mDisplayedValues.length; i++) {
|
|
||||||
|
|
||||||
/* Don't force the user to type in jan when ja will do */
|
|
||||||
str = str.toLowerCase();
|
|
||||||
if (mDisplayedValues[i].toLowerCase().startsWith(str)) {
|
|
||||||
return mStart + i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The user might have typed in a number into the month field i.e.
|
|
||||||
* 10 instead of OCT so support that too.
|
|
||||||
*/
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(str);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
|
|
||||||
/* Ignore as if it's not a number we don't care */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the current value.
|
|
||||||
*/
|
|
||||||
public int getCurrent() {
|
|
||||||
return mCurrent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
* ASTRID: Android's Simple Task Recording Dashboard
|
|
||||||
*
|
|
||||||
* Copyright (c) 2009 Tim Su
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along
|
|
||||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
package com.todoroo.andlib.widget;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.widget.ImageButton;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.service.Autowired;
|
|
||||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class exists purely to cancel long click events.
|
|
||||||
*/
|
|
||||||
public class NumberPickerWidgetButton extends ImageButton {
|
|
||||||
|
|
||||||
private NumberPickerWidget mNumberPicker;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Integer numberPickerIncrementId;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Integer numberPickerDecrementId;
|
|
||||||
|
|
||||||
public NumberPickerWidgetButton(Context context, AttributeSet attrs,
|
|
||||||
int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
DependencyInjectionService.getInstance().inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NumberPickerWidgetButton(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
DependencyInjectionService.getInstance().inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NumberPickerWidgetButton(Context context) {
|
|
||||||
super(context);
|
|
||||||
DependencyInjectionService.getInstance().inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNumberPicker(NumberPickerWidget picker) {
|
|
||||||
mNumberPicker = picker;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
cancelLongpressIfRequired(event);
|
|
||||||
return super.onTouchEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTrackballEvent(MotionEvent event) {
|
|
||||||
cancelLongpressIfRequired(event);
|
|
||||||
return super.onTrackballEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
|
||||||
if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER)
|
|
||||||
|| (keyCode == KeyEvent.KEYCODE_ENTER)) {
|
|
||||||
cancelLongpress();
|
|
||||||
}
|
|
||||||
return super.onKeyUp(keyCode, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancelLongpressIfRequired(MotionEvent event) {
|
|
||||||
if ((event.getAction() == MotionEvent.ACTION_CANCEL)
|
|
||||||
|| (event.getAction() == MotionEvent.ACTION_UP)) {
|
|
||||||
cancelLongpress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancelLongpress() {
|
|
||||||
if (numberPickerIncrementId == getId()) {
|
|
||||||
mNumberPicker.cancelIncrement();
|
|
||||||
} else if (numberPickerDecrementId == getId()) {
|
|
||||||
mNumberPicker.cancelDecrement();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
bin/
|
||||||
|
instrumented/
|
||||||
|
coverage.em
|
||||||
Loading…
Reference in New Issue