@ -1,253 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2012 Todoroo Inc
|
|
||||||
*
|
|
||||||
* See the file "LICENSE" for the full license governing this code.
|
|
||||||
*/
|
|
||||||
package com.todoroo.astrid.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.text.format.DateUtils;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.CompoundButton;
|
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ToggleButton;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.utility.DateUtilities;
|
|
||||||
import com.todoroo.andlib.utility.Preferences;
|
|
||||||
|
|
||||||
import org.tasks.R;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
|
|
||||||
public class AstridTimePicker extends LinearLayout {
|
|
||||||
|
|
||||||
private final ToggleButton noTimeCheck;
|
|
||||||
private final ToggleButton amButton;
|
|
||||||
private final ToggleButton pmButton;
|
|
||||||
private final NumberPicker hours;
|
|
||||||
private final NumberPicker minutes;
|
|
||||||
private TimePickerEnabledChangedListener listener;
|
|
||||||
private boolean is24Hour;
|
|
||||||
|
|
||||||
private boolean lastSelectionWasPm; // false for AM, true for PM
|
|
||||||
|
|
||||||
public interface TimePickerEnabledChangedListener {
|
|
||||||
void timePickerEnabledChanged(boolean hasTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AstridTimePicker(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
int layout = R.layout.astrid_time_picker_horizontal;
|
|
||||||
inflater.inflate(layout, this, true);
|
|
||||||
|
|
||||||
noTimeCheck = (ToggleButton) findViewById(R.id.hasTime);
|
|
||||||
amButton = (ToggleButton) findViewById(R.id.am_button);
|
|
||||||
pmButton = (ToggleButton) findViewById(R.id.pm_button);
|
|
||||||
hours = (NumberPicker) findViewById(R.id.hours);
|
|
||||||
minutes = (NumberPicker) findViewById(R.id.minutes);
|
|
||||||
|
|
||||||
if (Preferences.getBoolean(context, R.string.p_time_increment, false)) {
|
|
||||||
minutes.setIncrementBy(5);
|
|
||||||
} else {
|
|
||||||
minutes.setIncrementBy(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
setupButtonBackgrounds(context);
|
|
||||||
|
|
||||||
initialize(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupButtonBackgrounds(Context context) {
|
|
||||||
Resources r = context.getResources();
|
|
||||||
TypedValue onColor = new TypedValue();
|
|
||||||
context.getTheme().resolveAttribute(R.attr.asThemeTextColor, onColor, false);
|
|
||||||
|
|
||||||
int onColorValue = r.getColor(onColor.data);
|
|
||||||
int offColorValue = r.getColor(android.R.color.transparent);
|
|
||||||
int borderColorValue = r.getColor(android.R.color.transparent);
|
|
||||||
int cornerRadius = (int) (5 * r.getDisplayMetrics().density);
|
|
||||||
int strokeWidth = (int) (1 * r.getDisplayMetrics().density);
|
|
||||||
|
|
||||||
amButton.setBackgroundDrawable(CustomBorderDrawable.customButton(cornerRadius, 0, 0, cornerRadius,
|
|
||||||
onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
pmButton.setBackgroundDrawable(CustomBorderDrawable.customButton(0, cornerRadius, cornerRadius, 0,
|
|
||||||
onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
noTimeCheck.setBackgroundDrawable(CustomBorderDrawable.customButton(cornerRadius, cornerRadius, cornerRadius, cornerRadius,
|
|
||||||
onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
|
|
||||||
hours.findViewById(R.id.increment).setBackgroundDrawable(
|
|
||||||
CustomBorderDrawable.customButton(cornerRadius, 0, 0, 0, onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
hours.findViewById(R.id.decrement).setBackgroundDrawable(
|
|
||||||
CustomBorderDrawable.customButton(0, 0, 0, cornerRadius, onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
|
|
||||||
minutes.findViewById(R.id.increment).setBackgroundDrawable(
|
|
||||||
CustomBorderDrawable.customButton(0, cornerRadius, 0, 0, onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
minutes.findViewById(R.id.decrement).setBackgroundDrawable(
|
|
||||||
CustomBorderDrawable.customButton(0, 0, cornerRadius, 0, onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
|
|
||||||
View[] pickers = new View[] { hours, minutes };
|
|
||||||
for (View view : pickers) {
|
|
||||||
View v = view.findViewById(R.id.timepicker_input);
|
|
||||||
LayoutParams lp = (LayoutParams) v.getLayoutParams();
|
|
||||||
lp.height = (int) (46 * r.getDisplayMetrics().density);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initialize(Context context) {
|
|
||||||
if (DateUtilities.is24HourFormat(context)) {
|
|
||||||
hours.setRange(0, 23);
|
|
||||||
is24Hour = true;
|
|
||||||
findViewById(R.id.am_pm_container).setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
hours.setRange(1, 12);
|
|
||||||
is24Hour = false;
|
|
||||||
}
|
|
||||||
minutes.setRange(0, 59);
|
|
||||||
|
|
||||||
NumberPicker.OnChangedListener autoEnableTimeCheck = new NumberPicker.OnChangedListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onChanged(int newVal) {
|
|
||||||
setHasTime(true);
|
|
||||||
return newVal;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
String amString = DateUtils.getAMPMString(Calendar.AM).toUpperCase();
|
|
||||||
amButton.setTextOff(amString);
|
|
||||||
amButton.setTextOn(amString);
|
|
||||||
amButton.setChecked(false);
|
|
||||||
|
|
||||||
String pmString = DateUtils.getAMPMString(Calendar.PM).toUpperCase();
|
|
||||||
pmButton.setTextOff(pmString);
|
|
||||||
pmButton.setTextOn(pmString);
|
|
||||||
pmButton.setChecked(false);
|
|
||||||
|
|
||||||
amButton.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
noTimeCheck.setChecked(false);
|
|
||||||
amButton.setChecked(true);
|
|
||||||
pmButton.setChecked(false);
|
|
||||||
lastSelectionWasPm = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
pmButton.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
noTimeCheck.setChecked(false);
|
|
||||||
amButton.setChecked(false);
|
|
||||||
pmButton.setChecked(true);
|
|
||||||
lastSelectionWasPm = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
String noTime = context.getString(R.string.TEA_no_time);
|
|
||||||
noTimeCheck.setTextOff(noTime);
|
|
||||||
noTimeCheck.setTextOn(noTime);
|
|
||||||
|
|
||||||
hours.setOnChangeListener(autoEnableTimeCheck);
|
|
||||||
minutes.setOnChangeListener(autoEnableTimeCheck);
|
|
||||||
|
|
||||||
noTimeCheck.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
||||||
setHasTime(!isChecked, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
minutes.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHasTime(boolean hasTime) {
|
|
||||||
setHasTime(hasTime, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHasTime(boolean hasTime, boolean setChecked) {
|
|
||||||
if (setChecked) {
|
|
||||||
noTimeCheck.setChecked(!hasTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (noTimeCheck.isChecked()) {
|
|
||||||
hours.setText(""); //$NON-NLS-1$
|
|
||||||
minutes.setText(""); //$NON-NLS-1$
|
|
||||||
|
|
||||||
lastSelectionWasPm = pmButton.isChecked();
|
|
||||||
amButton.setChecked(false);
|
|
||||||
pmButton.setChecked(false);
|
|
||||||
} else {
|
|
||||||
hours.validateAndUpdate();
|
|
||||||
minutes.validateAndUpdate();
|
|
||||||
|
|
||||||
amButton.setChecked(!lastSelectionWasPm);
|
|
||||||
pmButton.setChecked(lastSelectionWasPm);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listener != null) {
|
|
||||||
listener.timePickerEnabledChanged(hasTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasTime() {
|
|
||||||
return !noTimeCheck.isChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void forceNoTime() {
|
|
||||||
if (!noTimeCheck.isChecked()) {
|
|
||||||
noTimeCheck.performClick();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHours(int hour) {
|
|
||||||
boolean pm = false;
|
|
||||||
if (!is24Hour) {
|
|
||||||
if (hour == 0) {
|
|
||||||
hour = 12;
|
|
||||||
} else if (hour == 12) {
|
|
||||||
pm = true;
|
|
||||||
} else if (hour > 12) {
|
|
||||||
hour -= 12;
|
|
||||||
pm = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
amButton.setChecked(!pm);
|
|
||||||
pmButton.setChecked(pm);
|
|
||||||
lastSelectionWasPm = pm;
|
|
||||||
hours.setCurrent(hour);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHours() {
|
|
||||||
int toReturn = hours.getCurrent();
|
|
||||||
if (!is24Hour) {
|
|
||||||
if (toReturn == 12) {
|
|
||||||
if (amButton.isChecked()) {
|
|
||||||
toReturn = 0;
|
|
||||||
}
|
|
||||||
} else if (pmButton.isChecked()) {
|
|
||||||
toReturn += 12;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return toReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMinutes(int minute) {
|
|
||||||
minutes.setCurrent(minute);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMinutes() {
|
|
||||||
return minutes.getCurrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimePickerEnabledChangedListener(TimePickerEnabledChangedListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,493 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2012 Todoroo Inc
|
|
||||||
*
|
|
||||||
* See the file "LICENSE" for the full license governing this code.
|
|
||||||
*/
|
|
||||||
package com.todoroo.astrid.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Paint.Style;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
|
||||||
import android.text.format.DateFormat;
|
|
||||||
import android.text.format.DateUtils;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.Display;
|
|
||||||
import android.view.GestureDetector;
|
|
||||||
import android.view.GestureDetector.SimpleOnGestureListener;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
import org.tasks.R;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import static org.tasks.date.DateTimeUtils.newDate;
|
|
||||||
|
|
||||||
public class CalendarView extends View {
|
|
||||||
|
|
||||||
private static final int PADDING = 0;
|
|
||||||
private static final int TEXT_PADDING = 2;
|
|
||||||
private final static int CURVE_RADIUS = 0;
|
|
||||||
private final static int TEXT_SIZE = 16;
|
|
||||||
private static final float MONTH_TEXT_SIZE = 22;
|
|
||||||
private static final float GESTURE_DELTAX_THRESHOLD = 100;
|
|
||||||
private float deltaX;
|
|
||||||
private boolean ignoreNextTouch;
|
|
||||||
|
|
||||||
private Paint calendarNumberRightAlignPaint;
|
|
||||||
private Paint calendarSelectedNumberRightAlignPaint;
|
|
||||||
private Paint backgroundColorPaint;
|
|
||||||
private Paint monthCenterAlignLargePaint;
|
|
||||||
private Paint rightAlignPaint;
|
|
||||||
private Paint todayCalendarPaint;
|
|
||||||
private Paint selectedCalendarPaint;
|
|
||||||
private float density;
|
|
||||||
|
|
||||||
private int leftArrowHeight;
|
|
||||||
private int leftArrowWidth;
|
|
||||||
private int rightArrowHeight;
|
|
||||||
private int rightArrowWidth;
|
|
||||||
private int leftArrowX = 0;
|
|
||||||
private int leftArrowY = 0;
|
|
||||||
private int rightArrowX = 0;
|
|
||||||
private int rightArrowY = 0;
|
|
||||||
|
|
||||||
private int[] dayLeftArr;
|
|
||||||
private int[] dayTopArr;
|
|
||||||
|
|
||||||
private float boxWidth;
|
|
||||||
private float boxHeight;
|
|
||||||
|
|
||||||
private Date calendarDate = newDate();
|
|
||||||
private int currentHighlightDay = -1;
|
|
||||||
|
|
||||||
public interface OnSelectedDateListener {
|
|
||||||
void onSelectedDate(Date date);
|
|
||||||
}
|
|
||||||
private OnSelectedDateListener onSelectedDateListener;
|
|
||||||
|
|
||||||
public void setOnSelectedDateListener(
|
|
||||||
OnSelectedDateListener onSelectedDateListener) {
|
|
||||||
this.onSelectedDateListener = onSelectedDateListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor. This version is only needed if you will be instantiating
|
|
||||||
* the object manually (not from a layout XML file).
|
|
||||||
*/
|
|
||||||
public CalendarView(Context context) {
|
|
||||||
super(context);
|
|
||||||
initCalendarView(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CalendarView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
initCalendarView(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initCalendarView(Context context) {
|
|
||||||
Display display = ((WindowManager) context.getSystemService(
|
|
||||||
Context.WINDOW_SERVICE)).getDefaultDisplay();
|
|
||||||
|
|
||||||
DisplayMetrics metrics = new DisplayMetrics();
|
|
||||||
display.getMetrics(metrics);
|
|
||||||
density = metrics.density;
|
|
||||||
|
|
||||||
Resources r = context.getResources();
|
|
||||||
|
|
||||||
Paint borderPaint = new Paint();
|
|
||||||
borderPaint.setAntiAlias(true);
|
|
||||||
borderPaint.setColor(r.getColor(R.color.task_edit_deadline_gray));
|
|
||||||
borderPaint.setStyle(Style.STROKE);
|
|
||||||
|
|
||||||
calendarNumberRightAlignPaint = new Paint();
|
|
||||||
calendarNumberRightAlignPaint.setAntiAlias(true);
|
|
||||||
calendarNumberRightAlignPaint.setColor(r.getColor(R.color.task_edit_deadline_gray));
|
|
||||||
calendarNumberRightAlignPaint.setTextSize(TEXT_SIZE * density);
|
|
||||||
calendarNumberRightAlignPaint.setTextAlign(Paint.Align.RIGHT);
|
|
||||||
|
|
||||||
calendarSelectedNumberRightAlignPaint = new Paint();
|
|
||||||
calendarSelectedNumberRightAlignPaint.setAntiAlias(true);
|
|
||||||
calendarSelectedNumberRightAlignPaint.setColor(Color.WHITE);
|
|
||||||
calendarSelectedNumberRightAlignPaint.setTextSize(TEXT_SIZE * density);
|
|
||||||
calendarSelectedNumberRightAlignPaint.setTextAlign(Paint.Align.RIGHT);
|
|
||||||
|
|
||||||
Paint dayPaint = new Paint();
|
|
||||||
dayPaint.setAntiAlias(true);
|
|
||||||
dayPaint.setColor(Color.rgb(137, 135, 132));
|
|
||||||
|
|
||||||
monthCenterAlignLargePaint = new Paint();
|
|
||||||
monthCenterAlignLargePaint.setAntiAlias(true);
|
|
||||||
monthCenterAlignLargePaint.setColor(r.getColor(R.color.task_edit_deadline_gray));
|
|
||||||
monthCenterAlignLargePaint.setTextAlign(Paint.Align.CENTER);
|
|
||||||
monthCenterAlignLargePaint.setTextSize(MONTH_TEXT_SIZE * density);
|
|
||||||
|
|
||||||
Paint centerAlignPaint = new Paint();
|
|
||||||
centerAlignPaint.setAntiAlias(true);
|
|
||||||
centerAlignPaint.setColor(r.getColor(R.color.task_edit_deadline_gray));
|
|
||||||
centerAlignPaint.setTextAlign(Paint.Align.CENTER);
|
|
||||||
centerAlignPaint.setTextSize(TEXT_SIZE * density);
|
|
||||||
|
|
||||||
rightAlignPaint = new Paint();
|
|
||||||
rightAlignPaint.setAntiAlias(true);
|
|
||||||
rightAlignPaint.setColor(r.getColor(R.color.task_edit_deadline_gray));
|
|
||||||
rightAlignPaint.setTextAlign(Paint.Align.RIGHT);
|
|
||||||
rightAlignPaint.setTextSize(TEXT_SIZE * density);
|
|
||||||
|
|
||||||
todayCalendarPaint = new Paint();
|
|
||||||
todayCalendarPaint.setAntiAlias(true);
|
|
||||||
todayCalendarPaint.setColor(r.getColor(R.color.task_edit_deadline_gray));
|
|
||||||
|
|
||||||
TypedValue selectedColor = new TypedValue();
|
|
||||||
context.getTheme().resolveAttribute(R.attr.asThemeTextColor, selectedColor, false);
|
|
||||||
selectedCalendarPaint = new Paint();
|
|
||||||
selectedCalendarPaint.setAntiAlias(true);
|
|
||||||
selectedCalendarPaint.setColor(r.getColor(selectedColor.data));
|
|
||||||
|
|
||||||
backgroundColorPaint = new Paint();
|
|
||||||
backgroundColorPaint.setAntiAlias(true);
|
|
||||||
backgroundColorPaint.setColor(Color.TRANSPARENT);
|
|
||||||
|
|
||||||
setPadding(PADDING, PADDING, PADDING, PADDING);
|
|
||||||
|
|
||||||
final GestureDetector swipeCalendarListener = new GestureDetector(new SimpleOnGestureListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
|
||||||
if (distanceX < 0 && deltaX > 0 || distanceX > 0 && deltaX < 0) { // Reset if direction changed
|
|
||||||
deltaX = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Math.abs(deltaX) > GESTURE_DELTAX_THRESHOLD) {
|
|
||||||
if (deltaX > 0) {
|
|
||||||
performClick(rightArrowX + rightArrowWidth / 2, rightArrowY + rightArrowHeight / 2);
|
|
||||||
} else {
|
|
||||||
performClick(leftArrowX + leftArrowWidth / 2, leftArrowY + leftArrowHeight / 2);
|
|
||||||
}
|
|
||||||
ignoreNextTouch = true;
|
|
||||||
deltaX = 0;
|
|
||||||
} else {
|
|
||||||
deltaX += distanceX;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final OnTouchListener swipeTouchListener = new OnTouchListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
return swipeCalendarListener.onTouchEvent(event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setOnTouchListener(swipeTouchListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see android.view.View#measure(int, int)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
setMeasuredDimension(measureWidth(widthMeasureSpec),
|
|
||||||
measureHeight(heightMeasureSpec));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the width of this view
|
|
||||||
* @param measureSpec A measureSpec packed into an int
|
|
||||||
* @return The width of the view, honoring constraints from measureSpec
|
|
||||||
*/
|
|
||||||
private int measureWidth(int measureSpec) {
|
|
||||||
int result = 0;
|
|
||||||
int specMode = MeasureSpec.getMode(measureSpec);
|
|
||||||
int specSize = MeasureSpec.getSize(measureSpec);
|
|
||||||
|
|
||||||
if (specMode == MeasureSpec.EXACTLY) {
|
|
||||||
// We were told how big to be
|
|
||||||
result = specSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the height of this view
|
|
||||||
* @param measureSpec A measureSpec packed into an int
|
|
||||||
* @return The height of the view, honoring constraints from measureSpec
|
|
||||||
*/
|
|
||||||
private int measureHeight(int measureSpec) {
|
|
||||||
int result = 0;
|
|
||||||
int specMode = MeasureSpec.getMode(measureSpec);
|
|
||||||
int specSize = MeasureSpec.getSize(measureSpec);
|
|
||||||
|
|
||||||
if (specMode == MeasureSpec.EXACTLY) {
|
|
||||||
// We were told how big to be
|
|
||||||
result = specSize;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see android.view.View#onDraw(android.graphics.Canvas)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
super.onDraw(canvas);
|
|
||||||
|
|
||||||
// Background
|
|
||||||
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), backgroundColorPaint);
|
|
||||||
|
|
||||||
// Outermost border -- Start
|
|
||||||
// RectF outerMostBorder = new RectF();
|
|
||||||
//
|
|
||||||
// outerMostBorder.set(5, 5, getMeasuredWidth() - 5, getMeasuredHeight() - 5);
|
|
||||||
// canvas.drawRoundRect(outerMostBorder, OUTER_BORDER_RADIUS, OUTER_BORDER_RADIUS, borderPaint);
|
|
||||||
//
|
|
||||||
// outerMostBorder.set(6, 6, getMeasuredWidth() - 6, getMeasuredHeight() - 6);
|
|
||||||
// canvas.drawRoundRect(outerMostBorder, CURVE_RADIUS, CURVE_RADIUS, backColorPaint);
|
|
||||||
// Outermost border -- end
|
|
||||||
|
|
||||||
// Month border -- Start
|
|
||||||
RectF rectF = new RectF();
|
|
||||||
|
|
||||||
float monthTitleHeight = (MONTH_TEXT_SIZE + 10) * density;
|
|
||||||
rectF.set(15, 15, getMeasuredWidth() - 15, monthTitleHeight);
|
|
||||||
canvas.drawRoundRect(rectF, CURVE_RADIUS, CURVE_RADIUS, backgroundColorPaint);
|
|
||||||
|
|
||||||
rectF.set(16, 16, getMeasuredWidth() - 16, monthTitleHeight - 1);
|
|
||||||
// canvas.drawRoundRect(rectF, CURVE_RADIUS, CURVE_RADIUS, backColorPaint);
|
|
||||||
// Month border -- end
|
|
||||||
|
|
||||||
// Month left arrow -- Start
|
|
||||||
Bitmap leftArrow = ((BitmapDrawable)getResources().getDrawable(R.drawable.icn_arrow_left)).getBitmap();
|
|
||||||
leftArrowHeight = (int)(leftArrow.getHeight()*density / 2);
|
|
||||||
leftArrowWidth = (int)(leftArrow.getWidth()*density / 2);
|
|
||||||
leftArrowX = 5;
|
|
||||||
leftArrowY = 4 + (int)((monthTitleHeight / 2 - leftArrowHeight/2));
|
|
||||||
canvas.drawBitmap(leftArrow, new Rect(0,0,leftArrow.getWidth(),leftArrow.getHeight()),
|
|
||||||
new Rect(leftArrowX, leftArrowY, leftArrowX + leftArrowWidth,
|
|
||||||
leftArrowY + leftArrowHeight), null);
|
|
||||||
// Month left arrow -- End
|
|
||||||
|
|
||||||
// Month right arrow -- Start
|
|
||||||
Bitmap rightArrow = ((BitmapDrawable)getResources().getDrawable(R.drawable.icn_arrow_right)).getBitmap();
|
|
||||||
rightArrowHeight = (int)(rightArrow.getHeight()*density / 2);
|
|
||||||
rightArrowWidth = (int)(rightArrow.getWidth()*density / 2);
|
|
||||||
rightArrowX = (int) (getMeasuredWidth() - (2 * density) - (PADDING*3) - rightArrow.getWidth());
|
|
||||||
rightArrowY = 4 + (int)((monthTitleHeight / 2 - rightArrowHeight/2));
|
|
||||||
canvas.drawBitmap(rightArrow, new Rect(0,0,rightArrow.getWidth(),rightArrow.getHeight()),
|
|
||||||
new Rect(rightArrowX, rightArrowY, rightArrowX + rightArrowWidth,
|
|
||||||
rightArrowY + rightArrowHeight), null);
|
|
||||||
// Month right arrow -- End
|
|
||||||
|
|
||||||
Calendar calendar = Calendar.getInstance();
|
|
||||||
|
|
||||||
// Month text -- Start
|
|
||||||
int monthX = getMeasuredWidth() / 2;
|
|
||||||
int monthY = (int) (monthTitleHeight / 2 + 15);
|
|
||||||
String monthYear = (String) DateFormat.format("MMMM yyyy", getCoercedDate(calendar.getTime(), calendarDate)); //$NON-NLS-1$
|
|
||||||
canvas.drawText(monthYear, monthX, monthY, monthCenterAlignLargePaint);
|
|
||||||
// Month text -- End
|
|
||||||
|
|
||||||
// Day heading -- Start
|
|
||||||
int dayLeft = 3;
|
|
||||||
int dayTop = (int)(monthTitleHeight + PADDING * 2);
|
|
||||||
|
|
||||||
boxWidth = (getMeasuredWidth() - (PADDING*2)) / 7.0f;
|
|
||||||
boxHeight = (int) (((getMeasuredHeight() - (monthTitleHeight) - 16) - (PADDING * 8)) / 7);
|
|
||||||
|
|
||||||
float textX;
|
|
||||||
float textY;
|
|
||||||
|
|
||||||
int firstDayOfWeek = calendar.getFirstDayOfWeek();
|
|
||||||
calendar.set(Calendar.DAY_OF_WEEK, firstDayOfWeek);
|
|
||||||
for(int i = 0; i < 7; i++) {
|
|
||||||
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
|
|
||||||
String day = DateUtils.getDayOfWeekString(dayOfWeek, DateUtils.LENGTH_SHORT);
|
|
||||||
calendar.add(Calendar.DATE, 1);
|
|
||||||
|
|
||||||
textX = dayLeft + boxWidth - TEXT_PADDING * 3;
|
|
||||||
textY = dayTop + (boxHeight - boxHeight/8) - TEXT_PADDING * 2;
|
|
||||||
canvas.drawText(day, textX, textY, rightAlignPaint);
|
|
||||||
|
|
||||||
dayLeft += boxWidth;
|
|
||||||
}
|
|
||||||
// Day heading -- End
|
|
||||||
|
|
||||||
// Calendar -- Start
|
|
||||||
calendar.setTime(getCoercedDate(newDate(), calendarDate)); // Reset the calendar to either today or the specified date
|
|
||||||
|
|
||||||
if (currentHighlightDay == -1) {
|
|
||||||
currentHighlightDay = calendarDate.getTime() == 0 ? 0 : calendar.get(Calendar.DATE);
|
|
||||||
}
|
|
||||||
int today = -1;
|
|
||||||
Calendar todayCalendar = Calendar.getInstance();
|
|
||||||
if(calendar.get(Calendar.MONTH) == todayCalendar.get(Calendar.MONTH) &&
|
|
||||||
calendar.get(Calendar.YEAR) == todayCalendar.get(Calendar.YEAR)) {
|
|
||||||
today = todayCalendar.get(Calendar.DATE);
|
|
||||||
}
|
|
||||||
int lastDateOfThisMonth = calendar.getActualMaximum(Calendar.DATE);
|
|
||||||
|
|
||||||
calendar.set(Calendar.DATE, 1);
|
|
||||||
// offset for day of week
|
|
||||||
int firstDayOfMonth = calendar.get(Calendar.DAY_OF_WEEK) - firstDayOfWeek + Calendar.SUNDAY;
|
|
||||||
if(firstDayOfMonth == 0) {
|
|
||||||
firstDayOfMonth = 7;
|
|
||||||
}
|
|
||||||
boolean firstTime = true;
|
|
||||||
int dayOfMonth = 1;
|
|
||||||
Paint colorPaint;
|
|
||||||
Paint textPaint;
|
|
||||||
|
|
||||||
dayLeftArr = new int[lastDateOfThisMonth];
|
|
||||||
dayTopArr = new int[lastDateOfThisMonth];
|
|
||||||
for (int i = 1; i <= 6; i++) {
|
|
||||||
dayLeft = 1;
|
|
||||||
dayTop += boxHeight + PADDING;
|
|
||||||
for (int j = 1; j <= 7; j++) {
|
|
||||||
if (firstTime && j != firstDayOfMonth) {
|
|
||||||
dayLeft += boxWidth + PADDING;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
firstTime = false;
|
|
||||||
|
|
||||||
if (dayOfMonth <= lastDateOfThisMonth) {
|
|
||||||
if (currentHighlightDay == dayOfMonth) {
|
|
||||||
colorPaint = selectedCalendarPaint;
|
|
||||||
textPaint = calendarSelectedNumberRightAlignPaint;
|
|
||||||
} else if(today == dayOfMonth) {
|
|
||||||
colorPaint = todayCalendarPaint;
|
|
||||||
textPaint = calendarSelectedNumberRightAlignPaint;
|
|
||||||
} else {
|
|
||||||
colorPaint = backgroundColorPaint;
|
|
||||||
textPaint = calendarNumberRightAlignPaint;
|
|
||||||
}
|
|
||||||
dayLeftArr[dayOfMonth-1] = dayLeft;
|
|
||||||
dayTopArr[dayOfMonth-1] = dayTop;
|
|
||||||
rectF.set(dayLeft, dayTop, dayLeft + boxWidth, dayTop + boxHeight);
|
|
||||||
// if (j != 1)
|
|
||||||
// canvas.drawLine(rectF.left, rectF.top, rectF.left, rectF.bottom, borderPaint);
|
|
||||||
|
|
||||||
rectF.set(dayLeft+1, dayTop, dayLeft + boxWidth - 1, dayTop + boxHeight);
|
|
||||||
canvas.drawRoundRect(rectF, CURVE_RADIUS, CURVE_RADIUS, colorPaint);
|
|
||||||
|
|
||||||
textX = dayLeft + boxWidth - TEXT_PADDING * 3;
|
|
||||||
textY = dayTop + calendarNumberRightAlignPaint.getTextSize() + TEXT_PADDING;
|
|
||||||
canvas.drawText(String.valueOf(dayOfMonth), textX, textY, textPaint);
|
|
||||||
|
|
||||||
dayLeft += boxWidth + PADDING;
|
|
||||||
|
|
||||||
dayOfMonth++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Calendar -- End
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
switch (event.getAction()) {
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
int x = (int) event.getX();
|
|
||||||
int y = (int) event.getY();
|
|
||||||
performClick(x, y);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void performClick(int x, int y) {
|
|
||||||
// System.out.println("---------------------Current x, y : " + x + ", " + y);
|
|
||||||
// Handle left-right arrow click -- start
|
|
||||||
if ((x > leftArrowX && x < (leftArrowX + leftArrowWidth * 2))
|
|
||||||
&& (y > leftArrowY - leftArrowHeight / 2 && y < (leftArrowY + 3 * leftArrowHeight / 2))) {
|
|
||||||
Calendar calendar = Calendar.getInstance();
|
|
||||||
calendar.setTime(getCoercedDate(getToday(calendar), calendarDate));
|
|
||||||
int currentDay = calendar.get(Calendar.DATE);
|
|
||||||
calendar.set(Calendar.DATE, 1);
|
|
||||||
calendar.add(Calendar.MONTH, -1);
|
|
||||||
int lastDay = calendar.getActualMaximum(Calendar.DATE);
|
|
||||||
calendar.set(Calendar.DATE, Math.min(currentDay, lastDay));
|
|
||||||
calendarDate = calendar.getTime();
|
|
||||||
currentHighlightDay = calendar.get(Calendar.DATE);
|
|
||||||
this.invalidate();
|
|
||||||
|
|
||||||
if(onSelectedDateListener != null) {
|
|
||||||
onSelectedDateListener.onSelectedDate(calendarDate);
|
|
||||||
}
|
|
||||||
} else if ((x > rightArrowX - rightArrowWidth && x < (rightArrowX + rightArrowWidth))
|
|
||||||
&& (y > rightArrowY - rightArrowHeight / 2 && y < (rightArrowY + 3 * rightArrowHeight / 2))) {
|
|
||||||
Calendar calendar = Calendar.getInstance();
|
|
||||||
calendar.setTime(getCoercedDate(getToday(calendar), calendarDate));
|
|
||||||
int currentDay = calendar.get(Calendar.DATE);
|
|
||||||
calendar.set(Calendar.DATE, 1);
|
|
||||||
calendar.add(Calendar.MONTH, 1);
|
|
||||||
int lastDay = calendar.getActualMaximum(Calendar.DATE);
|
|
||||||
calendar.set(Calendar.DATE, Math.min(currentDay, lastDay));
|
|
||||||
calendarDate = calendar.getTime();
|
|
||||||
currentHighlightDay = calendar.get(Calendar.DATE);
|
|
||||||
this.invalidate();
|
|
||||||
|
|
||||||
if(onSelectedDateListener != null) {
|
|
||||||
onSelectedDateListener.onSelectedDate(calendarDate);
|
|
||||||
}
|
|
||||||
// Handle left-right arrow click -- end
|
|
||||||
} else if(dayLeftArr != null) {
|
|
||||||
// Check if clicked on date
|
|
||||||
if (ignoreNextTouch) {
|
|
||||||
ignoreNextTouch = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int i=0; i<dayLeftArr.length; i++) {
|
|
||||||
if ((x > dayLeftArr[i] && x < dayLeftArr[i]+boxWidth) && (y > dayTopArr[i] && y < dayTopArr[i] + boxHeight)) {
|
|
||||||
currentHighlightDay = i+1;
|
|
||||||
Calendar calendar = Calendar.getInstance();
|
|
||||||
Date today = getToday(calendar);
|
|
||||||
calendar.setTime(getCoercedDate(today, calendarDate));
|
|
||||||
calendar.set(Calendar.DATE, currentHighlightDay);
|
|
||||||
|
|
||||||
calendarDate = calendar.getTime();
|
|
||||||
this.invalidate();
|
|
||||||
|
|
||||||
if(onSelectedDateListener != null) {
|
|
||||||
onSelectedDateListener.onSelectedDate(calendarDate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Date getToday(Calendar calendar) {
|
|
||||||
Date today = calendar.getTime();
|
|
||||||
today.setTime(today.getTime() / 1000L * 1000L);
|
|
||||||
today.setHours(12);
|
|
||||||
today.setMinutes(0);
|
|
||||||
today.setSeconds(0);
|
|
||||||
return today;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getCoercedDate(Date ifZero, Date ifNotZero) {
|
|
||||||
return (calendarDate.getTime() == 0 ? ifZero : ifNotZero);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getCalendarDate() {
|
|
||||||
return calendarDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCalendarDate(Date calendarDate) {
|
|
||||||
this.calendarDate = calendarDate;
|
|
||||||
currentHighlightDay = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,264 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2012 Todoroo Inc
|
|
||||||
*
|
|
||||||
* See the file "LICENSE" for the full license governing this code.
|
|
||||||
*/
|
|
||||||
package com.todoroo.astrid.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ToggleButton;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.utility.DateUtilities;
|
|
||||||
import com.todoroo.astrid.data.Task;
|
|
||||||
import com.todoroo.astrid.ui.AstridTimePicker.TimePickerEnabledChangedListener;
|
|
||||||
import com.todoroo.astrid.ui.CalendarView.OnSelectedDateListener;
|
|
||||||
|
|
||||||
import org.tasks.R;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import static org.tasks.date.DateTimeUtils.newDate;
|
|
||||||
|
|
||||||
public class DateAndTimePicker extends LinearLayout {
|
|
||||||
|
|
||||||
private static final int SHORTCUT_PADDING = 8;
|
|
||||||
|
|
||||||
private class UrgencyValue {
|
|
||||||
public String label;
|
|
||||||
public int setting;
|
|
||||||
public long dueDate;
|
|
||||||
|
|
||||||
public UrgencyValue(String label, int setting) {
|
|
||||||
this.label = label;
|
|
||||||
this.setting = setting;
|
|
||||||
dueDate = Task.createDueDate(setting, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final CalendarView calendarView;
|
|
||||||
private final AstridTimePicker timePicker;
|
|
||||||
private final LinearLayout dateShortcuts;
|
|
||||||
private UrgencyValue todayUrgency;
|
|
||||||
|
|
||||||
public DateAndTimePicker(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
|
|
||||||
inflater.inflate(R.layout.date_time_picker_no_shortcuts, this, true);
|
|
||||||
|
|
||||||
calendarView = (CalendarView) findViewById(R.id.calendar);
|
|
||||||
timePicker = (AstridTimePicker) findViewById(R.id.time_picker);
|
|
||||||
|
|
||||||
findViewById(R.id.date_shortcuts).setVisibility(View.GONE);
|
|
||||||
dateShortcuts = (LinearLayout) timePicker.findViewById(R.id.date_shortcuts);
|
|
||||||
|
|
||||||
setUpListeners();
|
|
||||||
constructShortcutList(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initializeWithDate(long dateValue) {
|
|
||||||
Date date = newDate(dateValue);
|
|
||||||
Date forCalendar;
|
|
||||||
if (dateValue> 0) {
|
|
||||||
forCalendar = getDateForCalendar(date);
|
|
||||||
} else {
|
|
||||||
forCalendar = date;
|
|
||||||
}
|
|
||||||
calendarView.setCalendarDate(forCalendar);
|
|
||||||
if (Task.hasDueTime(dateValue)) {
|
|
||||||
timePicker.setHours(date.getHours());
|
|
||||||
timePicker.setMinutes(date.getMinutes());
|
|
||||||
timePicker.setHasTime(true);
|
|
||||||
} else {
|
|
||||||
timePicker.setHours(18);
|
|
||||||
timePicker.setMinutes(0);
|
|
||||||
timePicker.setHasTime(false);
|
|
||||||
}
|
|
||||||
updateShortcutView(forCalendar);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Date getDateForCalendar(Date date) {
|
|
||||||
Date forCalendar = newDate(date.getTime() / 1000L * 1000L);
|
|
||||||
forCalendar.setHours(12);
|
|
||||||
forCalendar.setMinutes(0);
|
|
||||||
forCalendar.setSeconds(0);
|
|
||||||
return forCalendar;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpListeners() {
|
|
||||||
calendarView.setOnSelectedDateListener(new OnSelectedDateListener() {
|
|
||||||
@Override
|
|
||||||
public void onSelectedDate(Date date) {
|
|
||||||
updateShortcutView(date);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
timePicker.setTimePickerEnabledChangedListener(new TimePickerEnabledChangedListener() {
|
|
||||||
@Override
|
|
||||||
public void timePickerEnabledChanged(boolean hasTime) {
|
|
||||||
if (hasTime) {
|
|
||||||
forceDateSelected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void forceDateSelected() {
|
|
||||||
ToggleButton none = (ToggleButton) dateShortcuts.getChildAt(dateShortcuts.getChildCount() - 1);
|
|
||||||
if (none.isChecked()) {
|
|
||||||
Date date = newDate(todayUrgency.dueDate);
|
|
||||||
calendarView.setCalendarDate(date);
|
|
||||||
calendarView.invalidate();
|
|
||||||
if (todayUrgency.setting == Task.URGENCY_NONE) {
|
|
||||||
timePicker.forceNoTime();
|
|
||||||
}
|
|
||||||
updateShortcutView(date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void constructShortcutList(Context context, AttributeSet attrs) {
|
|
||||||
int arrayResource = R.array.TEA_urgency;
|
|
||||||
TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.DateAndTimePicker);
|
|
||||||
for (int i = 0; i < t.getIndexCount(); i++) {
|
|
||||||
int attr = t.getIndex(i);
|
|
||||||
switch(attr) {
|
|
||||||
case R.styleable.DateAndTimePicker_shortcutLabels:
|
|
||||||
arrayResource = t.getResourceId(attr, R.array.TEA_urgency);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] labels = context.getResources().getStringArray(arrayResource);
|
|
||||||
ArrayList<UrgencyValue> urgencyValues = new ArrayList<>();
|
|
||||||
todayUrgency = new UrgencyValue(labels[2],
|
|
||||||
Task.URGENCY_TODAY);
|
|
||||||
urgencyValues.add(new UrgencyValue(labels[0],
|
|
||||||
Task.URGENCY_NONE));
|
|
||||||
|
|
||||||
Resources r = context.getResources();
|
|
||||||
DisplayMetrics metrics = r.getDisplayMetrics();
|
|
||||||
TypedValue onColor = new TypedValue();
|
|
||||||
context.getTheme().resolveAttribute(R.attr.asThemeTextColor, onColor, false);
|
|
||||||
|
|
||||||
int onColorValue = r.getColor(onColor.data);
|
|
||||||
int offColorValue = r.getColor(android.R.color.transparent);
|
|
||||||
int borderColorValue = r.getColor(android.R.color.transparent);
|
|
||||||
int cornerRadius = (int) (5 * r.getDisplayMetrics().density);
|
|
||||||
int strokeWidth = (int) (1 * r.getDisplayMetrics().density);
|
|
||||||
|
|
||||||
for (int i = 0; i < urgencyValues.size(); i++) {
|
|
||||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, (int) ((38) * metrics.density), 0);
|
|
||||||
UrgencyValue uv = urgencyValues.get(i);
|
|
||||||
|
|
||||||
ToggleButton tb = new ToggleButton(context);
|
|
||||||
String label = uv.label;
|
|
||||||
tb.setTextOff(label);
|
|
||||||
tb.setTextOn(label);
|
|
||||||
tb.setTag(uv);
|
|
||||||
if (i == 0) {
|
|
||||||
tb.setBackgroundDrawable(CustomBorderDrawable.customButton(cornerRadius, cornerRadius, cornerRadius, cornerRadius, onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
} else if (i == urgencyValues.size() - 2) {
|
|
||||||
lp.topMargin = (int) (-1 * metrics.density);
|
|
||||||
tb.setBackgroundDrawable(CustomBorderDrawable.customButton(cornerRadius, cornerRadius, cornerRadius, cornerRadius, onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
} else if (i == urgencyValues.size() - 1) {
|
|
||||||
lp.topMargin = (int) (5 * metrics.density);
|
|
||||||
tb.setBackgroundDrawable(CustomBorderDrawable.customButton(cornerRadius, cornerRadius, cornerRadius, cornerRadius, onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
} else {
|
|
||||||
lp.topMargin = (int) (-1 * metrics.density);
|
|
||||||
tb.setBackgroundDrawable(CustomBorderDrawable.customButton(cornerRadius, cornerRadius, cornerRadius, cornerRadius, onColorValue, offColorValue, borderColorValue, strokeWidth));
|
|
||||||
}
|
|
||||||
int verticalPadding = (int) (SHORTCUT_PADDING * metrics.density);
|
|
||||||
tb.setPadding(0, verticalPadding, 0, verticalPadding);
|
|
||||||
tb.setLayoutParams(lp);
|
|
||||||
tb.setGravity(Gravity.CENTER);
|
|
||||||
tb.setTextSize(18);
|
|
||||||
tb.setTextColor(context.getResources().getColorStateList(R.color.task_edit_toggle_button_text));
|
|
||||||
|
|
||||||
tb.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
UrgencyValue value = (UrgencyValue) v.getTag();
|
|
||||||
Date date = newDate(value.dueDate);
|
|
||||||
calendarView.setCalendarDate(date);
|
|
||||||
calendarView.invalidate();
|
|
||||||
if (value.setting == Task.URGENCY_NONE) {
|
|
||||||
timePicker.forceNoTime();
|
|
||||||
}
|
|
||||||
updateShortcutView(date);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
dateShortcuts.addView(tb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateShortcutView(Date date) {
|
|
||||||
for (int i = 0; i < dateShortcuts.getChildCount(); i++) {
|
|
||||||
View child = dateShortcuts.getChildAt(i);
|
|
||||||
if (child instanceof ToggleButton) {
|
|
||||||
ToggleButton tb = (ToggleButton) child;
|
|
||||||
UrgencyValue uv = (UrgencyValue) tb.getTag();
|
|
||||||
if (uv != null) {
|
|
||||||
if (uv.dueDate == date.getTime()) {
|
|
||||||
tb.setChecked(true);
|
|
||||||
} else {
|
|
||||||
tb.setChecked(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long constructDueDate() {
|
|
||||||
Date calendarDate = newDate(calendarView.getCalendarDate().getTime());
|
|
||||||
if (timePicker.hasTime() && calendarDate.getTime() > 0) {
|
|
||||||
calendarDate.setHours(timePicker.getHours());
|
|
||||||
calendarDate.setMinutes(timePicker.getMinutes());
|
|
||||||
calendarDate.setSeconds(1);
|
|
||||||
} else {
|
|
||||||
calendarDate.setSeconds(0);
|
|
||||||
}
|
|
||||||
return calendarDate.getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAfterNow() {
|
|
||||||
long dueDate = constructDueDate();
|
|
||||||
return dueDate > DateUtilities.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDisplayString(Context context) {
|
|
||||||
long dueDate = constructDueDate();
|
|
||||||
return getDisplayString(context, dueDate, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getDisplayString(Context context, long forDate, boolean hideYear, boolean hideTime) {
|
|
||||||
StringBuilder displayString = new StringBuilder();
|
|
||||||
Date d = newDate(forDate);
|
|
||||||
if (d.getTime() > 0) {
|
|
||||||
if (hideYear) {
|
|
||||||
displayString.append(DateUtilities.getDateStringHideYear(d));
|
|
||||||
} else {
|
|
||||||
displayString.append(DateUtilities.getDateString(d));
|
|
||||||
}
|
|
||||||
if (Task.hasDueTime(forDate) && !hideTime) {
|
|
||||||
displayString.append(", "); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
displayString.append(DateUtilities.getTimeString(context, d));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return displayString.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2012 Todoroo Inc
|
|
||||||
*
|
|
||||||
* See the file "LICENSE" for the full license governing this code.
|
|
||||||
*/
|
|
||||||
package com.todoroo.astrid.ui;
|
|
||||||
|
|
||||||
import android.support.v4.app.FragmentActivity;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.todoroo.andlib.utility.DateUtilities;
|
|
||||||
import com.todoroo.astrid.data.Task;
|
|
||||||
|
|
||||||
import org.tasks.R;
|
|
||||||
import org.tasks.dialogs.DialogBuilder;
|
|
||||||
import org.tasks.preferences.ActivityPreferences;
|
|
||||||
|
|
||||||
public class DeadlineControlSet extends PopupControlSet {
|
|
||||||
|
|
||||||
private DateAndTimePicker dateAndTimePicker;
|
|
||||||
|
|
||||||
public DeadlineControlSet(ActivityPreferences preferences, FragmentActivity activity, DialogBuilder dialogBuilder) {
|
|
||||||
super(preferences, activity, R.layout.control_set_deadline_dialog, R.layout.control_set_deadline, 0, dialogBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void refreshDisplayView() {
|
|
||||||
StringBuilder displayString = new StringBuilder();
|
|
||||||
boolean isOverdue;
|
|
||||||
if (initialized) {
|
|
||||||
isOverdue = !dateAndTimePicker.isAfterNow();
|
|
||||||
displayString.append(dateAndTimePicker.getDisplayString(activity));
|
|
||||||
} else {
|
|
||||||
isOverdue = model.getDueDate() < DateUtilities.now();
|
|
||||||
displayString.append(DateAndTimePicker.getDisplayString(activity, model.getDueDate(), false, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
TextView dateDisplay = (TextView) getView().findViewById(R.id.display_row_edit);
|
|
||||||
if (TextUtils.isEmpty(displayString)) {
|
|
||||||
dateDisplay.setText(R.string.TEA_deadline_hint);
|
|
||||||
dateDisplay.setTextColor(unsetColor);
|
|
||||||
} else {
|
|
||||||
dateDisplay.setText(displayString);
|
|
||||||
if (isOverdue) {
|
|
||||||
dateDisplay.setTextColor(activity.getResources().getColor(R.color.red_theme_color));
|
|
||||||
} else {
|
|
||||||
dateDisplay.setTextColor(themeColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void afterInflate() {
|
|
||||||
dateAndTimePicker = (DateAndTimePicker) getDialogView().findViewById(R.id.date_and_time);
|
|
||||||
LinearLayout body = (LinearLayout) getDialogView().findViewById(R.id.datetime_body);
|
|
||||||
body.setGravity(Gravity.CENTER_HORIZONTAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void readFromTaskOnInitialize() {
|
|
||||||
long dueDate = model.getDueDate();
|
|
||||||
initializeWithDate(dueDate);
|
|
||||||
refreshDisplayView();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeToModelAfterInitialized(Task task) {
|
|
||||||
long dueDate = dateAndTimePicker.constructDueDate();
|
|
||||||
if (dueDate != task.getDueDate()) // Clear snooze if due date has changed
|
|
||||||
{
|
|
||||||
task.setReminderSnooze(0L);
|
|
||||||
}
|
|
||||||
task.setDueDate(dueDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeWithDate(long dueDate) {
|
|
||||||
dateAndTimePicker.initializeWithDate(dueDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getIcon() {
|
|
||||||
return R.attr.ic_action_clock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,385 @@
|
|||||||
|
package org.tasks.ui;
|
||||||
|
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.support.v4.app.FragmentActivity;
|
||||||
|
import android.text.format.DateFormat;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.fourmob.datetimepicker.date.DatePickerDialog;
|
||||||
|
import com.sleepbot.datetimepicker.time.RadialPickerLayout;
|
||||||
|
import com.sleepbot.datetimepicker.time.TimePickerDialog;
|
||||||
|
import com.todoroo.andlib.utility.DateUtilities;
|
||||||
|
import com.todoroo.astrid.data.Task;
|
||||||
|
import com.todoroo.astrid.helper.TaskEditControlSetBase;
|
||||||
|
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.tasks.R;
|
||||||
|
import org.tasks.dialogs.MyDatePickerDialog;
|
||||||
|
import org.tasks.dialogs.MyTimePickerDialog;
|
||||||
|
import org.tasks.preferences.Preferences;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastHoneycomb;
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static org.tasks.date.DateTimeUtils.newDate;
|
||||||
|
import static org.tasks.date.DateTimeUtils.newDateTime;
|
||||||
|
|
||||||
|
public class DeadlineControlSet extends TaskEditControlSetBase {
|
||||||
|
|
||||||
|
private static final String FRAG_TAG_PICK_A_DATE = "frag_tag_pick_a_date";
|
||||||
|
private static final String FRAG_TAG_PICK_A_TIME = "frag_tag_pick_a_time";
|
||||||
|
|
||||||
|
private final List<String> dueDateOptions = new ArrayList<>();
|
||||||
|
private final List<String> dueTimeOptions = new ArrayList<>();
|
||||||
|
private final List<String> dueTimeHint;
|
||||||
|
private final int dateShortcutMorning;
|
||||||
|
private final int dateShortcutAfternoon;
|
||||||
|
private final int dateShortcutEvening;
|
||||||
|
private final int dateShortcutNight;
|
||||||
|
private final String nightString;
|
||||||
|
private final String eveningString;
|
||||||
|
private final String afternoonString;
|
||||||
|
private final String morningString;
|
||||||
|
private final String noTimeString;
|
||||||
|
private final String todayString;
|
||||||
|
private final String tomorrowString;
|
||||||
|
|
||||||
|
private FragmentActivity activity;
|
||||||
|
private Spinner dueDateSpinner;
|
||||||
|
private Spinner dueTimeSpinner;
|
||||||
|
private ArrayAdapter<String> dueDateAdapter;
|
||||||
|
private ArrayAdapter<String> dueTimeAdapter;
|
||||||
|
private long date = 0;
|
||||||
|
private int time = -1;
|
||||||
|
|
||||||
|
public DeadlineControlSet(FragmentActivity activity, Preferences preferences) {
|
||||||
|
super(activity, R.layout.control_set_deadline);
|
||||||
|
this.activity = activity;
|
||||||
|
dateShortcutMorning = preferences.getDateShortcutMorning();
|
||||||
|
dateShortcutAfternoon = preferences.getDateShortcutAfternoon();
|
||||||
|
dateShortcutEvening = preferences.getDateShortcutEvening();
|
||||||
|
dateShortcutNight = preferences.getDateShortcutNight();
|
||||||
|
dueTimeHint = asList(
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
getTimeHint(dateShortcutMorning),
|
||||||
|
getTimeHint(dateShortcutAfternoon),
|
||||||
|
getTimeHint(dateShortcutEvening),
|
||||||
|
getTimeHint(dateShortcutNight));
|
||||||
|
nightString = activity.getString(R.string.date_shortcut_night);
|
||||||
|
eveningString = activity.getString(R.string.date_shortcut_evening);
|
||||||
|
afternoonString = activity.getString(R.string.date_shortcut_afternoon);
|
||||||
|
morningString = activity.getString(R.string.date_shortcut_morning);
|
||||||
|
noTimeString = activity.getString(R.string.TEA_no_time);
|
||||||
|
todayString = activity.getString(R.string.today);
|
||||||
|
tomorrowString = activity.getString(R.string.tomorrow);
|
||||||
|
dueDateOptions.addAll(asList(
|
||||||
|
"",
|
||||||
|
activity.getString(R.string.TEA_no_date),
|
||||||
|
todayString,
|
||||||
|
tomorrowString,
|
||||||
|
"",
|
||||||
|
activity.getString(R.string.pick_a_date)));
|
||||||
|
dueTimeOptions.addAll(asList(
|
||||||
|
"",
|
||||||
|
noTimeString,
|
||||||
|
morningString,
|
||||||
|
afternoonString,
|
||||||
|
eveningString,
|
||||||
|
nightString,
|
||||||
|
activity.getString(R.string.pick_a_time)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTimeHint(int millisOfDay) {
|
||||||
|
DateTime dateTime = newDateTime().withMillisOfDay(millisOfDay);
|
||||||
|
return DateUtilities.getTimeString(activity, dateTime.toDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshDisplayView() {
|
||||||
|
updateDueDateOptions();
|
||||||
|
updateDueTimeOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDueDateOptions() {
|
||||||
|
DateTime today = newDateTime().withMillisOfDay(0);
|
||||||
|
String nextWeekString = activity.getString(R.string.next, today.plusWeeks(1).toString("EEEE"));
|
||||||
|
if (date == 0) {
|
||||||
|
dueDateOptions.set(0, activity.getString(R.string.TEA_no_date));
|
||||||
|
} else {
|
||||||
|
if (date == today.getMillis()) {
|
||||||
|
dueDateOptions.set(0, todayString);
|
||||||
|
} else if (date == today.plusDays(1).getMillis()) {
|
||||||
|
dueDateOptions.set(0, tomorrowString);
|
||||||
|
} else if (date == today.plusWeeks(1).getMillis()) {
|
||||||
|
dueDateOptions.set(0, nextWeekString);
|
||||||
|
} else {
|
||||||
|
dueDateOptions.set(0, DateUtilities.getLongDateStringHideYear(newDate(date)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dueDateOptions.set(4, nextWeekString);
|
||||||
|
dueDateAdapter.notifyDataSetChanged();
|
||||||
|
dueDateSpinner.setSelection(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDueTimeOptions() {
|
||||||
|
if (time == -1) {
|
||||||
|
dueTimeOptions.set(0, noTimeString);
|
||||||
|
} else {
|
||||||
|
int compareTime = newDateTime()
|
||||||
|
.withMillisOfDay(time)
|
||||||
|
.withSecondOfMinute(0)
|
||||||
|
.withMillisOfSecond(0)
|
||||||
|
.getMillisOfDay();
|
||||||
|
if (compareTime == dateShortcutMorning) {
|
||||||
|
dueTimeOptions.set(0, morningString);
|
||||||
|
} else if (compareTime == dateShortcutAfternoon) {
|
||||||
|
dueTimeOptions.set(0, afternoonString);
|
||||||
|
} else if (compareTime == dateShortcutEvening) {
|
||||||
|
dueTimeOptions.set(0, eveningString);
|
||||||
|
} else if (compareTime == dateShortcutNight) {
|
||||||
|
dueTimeOptions.set(0, nightString);
|
||||||
|
} else {
|
||||||
|
dueTimeOptions.set(0, DateUtilities.getTimeString(activity, newDateTime().withMillisOfDay(time).toDate()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dueTimeAdapter.notifyDataSetChanged();
|
||||||
|
dueTimeSpinner.setSelection(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterInflate() {
|
||||||
|
View view = getView();
|
||||||
|
dueDateSpinner = (Spinner) view.findViewById(R.id.due_date);
|
||||||
|
dueDateAdapter = new ArrayAdapter<String>(activity, android.R.layout.simple_spinner_item, dueDateOptions) {
|
||||||
|
@Override
|
||||||
|
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||||
|
int selectedItemPosition = position;
|
||||||
|
if (parent instanceof AdapterView) {
|
||||||
|
selectedItemPosition = ((AdapterView) parent).getSelectedItemPosition();
|
||||||
|
}
|
||||||
|
TextView tv = (TextView) LayoutInflater.from(activity).inflate(android.R.layout.simple_spinner_item, parent, false);
|
||||||
|
tv.setText(dueDateOptions.get(selectedItemPosition));
|
||||||
|
if (atLeastHoneycomb()) {
|
||||||
|
dueDateSpinner.setAlpha(date == 0 ? 0.5f : 1f);
|
||||||
|
} else {
|
||||||
|
tv.setTextColor(date == 0 ? unsetColor : themeColor);
|
||||||
|
}
|
||||||
|
return tv;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getDropDownView(final int position, final View convertView, final ViewGroup parent) {
|
||||||
|
View v;
|
||||||
|
|
||||||
|
if (position == 0) {
|
||||||
|
TextView tv = new TextView(getContext());
|
||||||
|
tv.setHeight(0);
|
||||||
|
tv.setVisibility(View.GONE);
|
||||||
|
v = tv;
|
||||||
|
} else {
|
||||||
|
TextView tv = (TextView) LayoutInflater.from(activity).inflate(android.R.layout.simple_spinner_dropdown_item, parent, false);
|
||||||
|
tv.setText(dueDateOptions.get(position));
|
||||||
|
tv.setTextColor(themeColor);
|
||||||
|
v = tv;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.setVerticalScrollBarEnabled(false);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dueDateSpinner.setAdapter(dueDateAdapter);
|
||||||
|
|
||||||
|
dueTimeSpinner = (Spinner) view.findViewById(R.id.due_time);
|
||||||
|
dueTimeAdapter = new ArrayAdapter<String>(activity, android.R.layout.simple_spinner_item, dueTimeOptions) {
|
||||||
|
@Override
|
||||||
|
public View getView(final int position, final View convertView, final ViewGroup parent) {
|
||||||
|
int selectedItemPosition = position;
|
||||||
|
if (parent instanceof AdapterView) {
|
||||||
|
selectedItemPosition = ((AdapterView) parent).getSelectedItemPosition();
|
||||||
|
}
|
||||||
|
TextView tv = (TextView) LayoutInflater.from(activity).inflate(android.R.layout.simple_spinner_item, parent, false);
|
||||||
|
tv.setText(dueTimeOptions.get(selectedItemPosition));
|
||||||
|
if (atLeastHoneycomb()) {
|
||||||
|
dueTimeSpinner.setAlpha(time == -1 ? 0.5f : 1.0f);
|
||||||
|
} else {
|
||||||
|
tv.setTextColor(time >= 0 ? themeColor : unsetColor);
|
||||||
|
}
|
||||||
|
return tv;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getDropDownView(final int position, final View convertView, final ViewGroup parent) {
|
||||||
|
View v;
|
||||||
|
|
||||||
|
if (position == 0) {
|
||||||
|
TextView tv = new TextView(getContext());
|
||||||
|
tv.setHeight(0);
|
||||||
|
tv.setVisibility(View.GONE);
|
||||||
|
v = tv;
|
||||||
|
} else {
|
||||||
|
ViewGroup vg = (ViewGroup) LayoutInflater.from(activity).inflate(R.layout.simple_spinner_dropdown_item, parent, false);
|
||||||
|
((TextView) vg.findViewById(R.id.text1)).setText(dueTimeOptions.get(position));
|
||||||
|
if (position < dueTimeHint.size()) {
|
||||||
|
((TextView) vg.findViewById(R.id.text2)).setText(dueTimeHint.get(position));
|
||||||
|
}
|
||||||
|
v = vg;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.setVerticalScrollBarEnabled(false);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dueTimeSpinner.setAdapter(dueTimeAdapter);
|
||||||
|
|
||||||
|
dueDateSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
DateTime today = newDateTime().withMillisOfDay(0);
|
||||||
|
switch (position) {
|
||||||
|
case 0:
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
date = 0;
|
||||||
|
setTime(-1);
|
||||||
|
dueDateAdapter.notifyDataSetChanged();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
date = today.getMillis();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
date = today.plusDays(1).getMillis();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
date = today.plusWeeks(1).getMillis();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
MyDatePickerDialog dialog = new MyDatePickerDialog();
|
||||||
|
dialog.initialize(new DatePickerDialog.OnDateSetListener() {
|
||||||
|
@Override
|
||||||
|
public void onDateSet(DatePickerDialog datePickerDialog, int year, int month, int day) {
|
||||||
|
date = new DateTime(year, month + 1, day, 0, 0, 0, 0).getMillis();
|
||||||
|
refreshDisplayView();
|
||||||
|
}
|
||||||
|
}, today.getYear(), today.getMonthOfYear() - 1, today.getDayOfMonth(), false);
|
||||||
|
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||||
|
@Override
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
refreshDisplayView();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.show(activity.getSupportFragmentManager(), FRAG_TAG_PICK_A_DATE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dueDateAdapter.notifyDataSetChanged();
|
||||||
|
updateDueTimeOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dueTimeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
switch (position) {
|
||||||
|
case 0:
|
||||||
|
return;
|
||||||
|
case 1:
|
||||||
|
setTime(-1);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
setTime(dateShortcutMorning);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
setTime(dateShortcutAfternoon);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
setTime(dateShortcutEvening);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
setTime(dateShortcutNight);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
MyTimePickerDialog dialog = new MyTimePickerDialog();
|
||||||
|
dialog.initialize(new TimePickerDialog.OnTimeSetListener() {
|
||||||
|
@Override
|
||||||
|
public void onTimeSet(RadialPickerLayout radialPickerLayout, int hour, int minute) {
|
||||||
|
setTime((int) TimeUnit.HOURS.toMillis(hour) + (int) TimeUnit.MINUTES.toMillis(minute));
|
||||||
|
}
|
||||||
|
}, 0, 0, DateFormat.is24HourFormat(activity), false);
|
||||||
|
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||||
|
@Override
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
updateDueTimeOptions();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.show(activity.getSupportFragmentManager(), FRAG_TAG_PICK_A_TIME);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTime(int millisOfDay) {
|
||||||
|
time = millisOfDay;
|
||||||
|
|
||||||
|
if (date == 0 && time >= 0) {
|
||||||
|
DateTime dateTime = newDateTime().withMillisOfDay(time);
|
||||||
|
if (dateTime.isBeforeNow()) {
|
||||||
|
dateTime = dateTime.plusDays(1);
|
||||||
|
}
|
||||||
|
date = dateTime.withMillisOfDay(0).getMillis();
|
||||||
|
updateDueDateOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDueTimeOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void readFromTaskOnInitialize() {
|
||||||
|
Long dueDate = model.getDueDate();
|
||||||
|
if (dueDate > 0) {
|
||||||
|
DateTime dateTime = newDateTime(dueDate);
|
||||||
|
date = dateTime.withMillisOfDay(0).getMillis();
|
||||||
|
if (Task.hasDueTime(dateTime.getMillis())) {
|
||||||
|
setTime(dateTime.getMillisOfDay());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
refreshDisplayView();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeToModelAfterInitialized(Task task) {
|
||||||
|
DateTime dateTime = newDateTime(date);
|
||||||
|
if (time >= 0) {
|
||||||
|
dateTime = dateTime.withMillisOfDay(time + 1);
|
||||||
|
}
|
||||||
|
long millis = dateTime.getMillis();
|
||||||
|
if (millis != task.getDueDate()) {
|
||||||
|
task.setReminderSnooze(0L);
|
||||||
|
}
|
||||||
|
task.setDueDate(millis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIcon() {
|
||||||
|
return R.attr.ic_action_clock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 165 B |
|
After Width: | Height: | Size: 93 B |
|
After Width: | Height: | Size: 176 B |
|
After Width: | Height: | Size: 105 B |
|
After Width: | Height: | Size: 168 B |
|
Before Width: | Height: | Size: 930 B |
|
Before Width: | Height: | Size: 308 B |
|
After Width: | Height: | Size: 96 B |
|
After Width: | Height: | Size: 171 B |
@ -1,58 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
** Copyright (c) 2012 Todoroo Inc
|
|
||||||
**
|
|
||||||
** See the file "LICENSE" for the full license governing this code.
|
|
||||||
-->
|
|
||||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<ScrollView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:minWidth="320dip"
|
|
||||||
android:paddingLeft="10dip"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:paddingTop="5dip"
|
|
||||||
android:paddingBottom="5dip">
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/datetime_body"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"/>
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginLeft="5dip"
|
|
||||||
android:layout_gravity="center_vertical">
|
|
||||||
<com.todoroo.astrid.ui.CalendarView
|
|
||||||
android:id="@+id/calendar"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="280dip"
|
|
||||||
android:layout_weight="50"
|
|
||||||
android:layout_marginRight="5dip"/>
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/date_shortcuts"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_marginTop="5dip"
|
|
||||||
android:layout_marginRight="5dip"
|
|
||||||
android:layout_weight="25"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:orientation="vertical"/>
|
|
||||||
<com.todoroo.astrid.ui.AstridTimePicker
|
|
||||||
android:id="@+id/time_picker"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_marginTop="5dip"
|
|
||||||
android:layout_marginLeft="5dip"
|
|
||||||
android:layout_weight="50"
|
|
||||||
android:orientation="vertical"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
</merge>
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
** Copyright (c) 2012 Todoroo Inc
|
|
||||||
**
|
|
||||||
** See the file "LICENSE" for the full license governing this code.
|
|
||||||
-->
|
|
||||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/timeComponents"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="122dip"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginBottom="5dip"
|
|
||||||
android:layout_marginRight="4dip"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
<com.todoroo.astrid.ui.DeadlineNumberPicker
|
|
||||||
android:id="@+id/hours"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:text=":"
|
|
||||||
android:textColor="?attr/asTextColor"
|
|
||||||
android:gravity="center"
|
|
||||||
/>
|
|
||||||
<com.todoroo.astrid.ui.DeadlineNumberPicker
|
|
||||||
android:id="@+id/minutes"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/date_shortcuts"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginLeft="4dip"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/am_pm_container"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="4dip">
|
|
||||||
<ToggleButton
|
|
||||||
android:id="@+id/am_button"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="38dip"
|
|
||||||
android:paddingTop="8dip"
|
|
||||||
android:paddingBottom="8dip"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textColor="@color/task_edit_toggle_button_text"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginRight="-1dip"/>
|
|
||||||
<ToggleButton
|
|
||||||
android:id="@+id/pm_button"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="38dip"
|
|
||||||
android:paddingTop="8dip"
|
|
||||||
android:paddingBottom="8dip"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textColor="@color/task_edit_toggle_button_text"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_marginLeft="-1dip"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ToggleButton
|
|
||||||
android:id="@+id/hasTime"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_marginBottom="4dip"
|
|
||||||
android:layout_height="38dip"
|
|
||||||
android:paddingTop="8dip"
|
|
||||||
android:paddingBottom="8dip"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textColor="@color/task_edit_toggle_button_text"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</merge>
|
|
||||||
@ -1,15 +1,22 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
** Copyright (c) 2012 Todoroo Inc
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
**
|
|
||||||
** See the file "LICENSE" for the full license governing this code.
|
|
||||||
-->
|
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/display_row_edit"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="top"
|
android:layout_gravity="top"
|
||||||
android:gravity="start"
|
android:orientation="horizontal">
|
||||||
android:textColor="?attr/asThemeTextColor"
|
|
||||||
android:textSize="@dimen/task_edit_text_size"
|
<Spinner
|
||||||
android:paddingRight="@dimen/task_edit_padding_right"
|
android:id="@+id/due_date"
|
||||||
android:paddingEnd="@dimen/task_edit_padding_right" />
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/textfield_underline" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/due_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="15dp"
|
||||||
|
android:layout_marginStart="15dp"
|
||||||
|
android:background="?attr/textfield_underline" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
** Copyright (c) 2012 Todoroo Inc
|
|
||||||
**
|
|
||||||
** See the file "LICENSE" for the full license governing this code.
|
|
||||||
-->
|
|
||||||
<com.todoroo.astrid.ui.DateAndTimePicker xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/date_and_time"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:orientation="vertical" />
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!--
|
|
||||||
** Copyright (c) 2012 Todoroo Inc
|
|
||||||
**
|
|
||||||
** See the file "LICENSE" for the full license governing this code.
|
|
||||||
-->
|
|
||||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<ScrollView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_weight="100"
|
|
||||||
android:paddingLeft="10dip"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:paddingTop="4dip"
|
|
||||||
android:paddingBottom="5dip">
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/datetime_body"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
<com.todoroo.astrid.ui.CalendarView
|
|
||||||
android:id="@+id/calendar"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="250dip"
|
|
||||||
android:layout_weight="1" />
|
|
||||||
<View
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="1px"
|
|
||||||
android:layout_marginBottom="1dip"
|
|
||||||
android:background="?android:attr/listDivider" />
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_weight="1">
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/date_shortcuts"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_marginTop="5dip"
|
|
||||||
android:layout_marginRight="5dip"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical"/>
|
|
||||||
<com.todoroo.astrid.ui.AstridTimePicker
|
|
||||||
android:id="@+id/time_picker"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_marginTop="5dip"
|
|
||||||
android:layout_marginLeft="5dip"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
</merge>
|
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml
|
||||||
|
**
|
||||||
|
** Copyright 2008, The Android Open Source Project
|
||||||
|
**
|
||||||
|
** Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
** you may not use this file except in compliance with the License.
|
||||||
|
** You may obtain a copy of the License at
|
||||||
|
**
|
||||||
|
** http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
**
|
||||||
|
** Unless required by applicable law or agreed to in writing, software
|
||||||
|
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
** See the License for the specific language governing permissions and
|
||||||
|
** limitations under the License.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="?attr/dropdownListPreferredItemHeight"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<CheckedTextView
|
||||||
|
android:id="@+id/text1"
|
||||||
|
style="?attr/spinnerDropDownItemStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="marquee"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical|end"
|
||||||
|
android:layout_alignBaseline="@id/text1"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="8dp"
|
||||||
|
android:paddingRight="8dp"
|
||||||
|
android:layout_toRightOf="@id/text1"
|
||||||
|
android:layout_toEndOf="@id/text1"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||