More progress on calendar picker

New and awesome date and time picker for deadlines, alarms, etc.
pull/14/head
Sam Bosley 13 years ago
parent 1741dd34ee
commit 4cd6321fa3

@ -83,8 +83,9 @@ public class DatabaseDao<TYPE extends AbstractModel> {
}
protected void onModelUpdated(TYPE model) {
TYPE modelCopy = (TYPE) model.clone();
for(ModelUpdateListener<TYPE> listener : listeners) {
listener.onModelUpdated(model);
listener.onModelUpdated(modelCopy);
}
}

@ -6,17 +6,19 @@ import java.util.LinkedHashSet;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.widget.DateControlSet;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.helper.TaskEditControlSet;
import com.todoroo.astrid.ui.DateAndTimeDialog;
import com.todoroo.astrid.ui.DateAndTimeDialog.DateAndTimeDialogListener;
/**
* Control set to manage adding and removing tags
@ -30,6 +32,7 @@ public final class AlarmControlSet extends TaskEditControlSet {
private final LinearLayout alertsContainer;
private final Activity activity;
private final DateAndTimeDialog pickerDialog;
public AlarmControlSet(Activity activity, int layout) {
//View v = LayoutInflater.from(activity).inflate(R.layout.alarm_control, parent, true);
@ -42,6 +45,8 @@ public final class AlarmControlSet extends TaskEditControlSet {
addAlarm(new Date());
}
});
pickerDialog = new DateAndTimeDialog(activity, 0);
}
@Override
@ -60,12 +65,10 @@ public final class AlarmControlSet extends TaskEditControlSet {
public String writeToModel(Task task) {
LinkedHashSet<Long> alarms = new LinkedHashSet<Long>();
for(int i = 0; i < alertsContainer.getChildCount(); i++) {
DateControlSet set = (DateControlSet) alertsContainer.getChildAt(i).getTag();
if(set == null)
Long dateValue = (Long) alertsContainer.getChildAt(i).getTag();
if(dateValue == null)
continue;
Date date = set.getDate();
if(date != null)
alarms.add(set.getDate().getTime());
alarms.add(dateValue);
}
if(AlarmService.getInstance().synchronizeAlarms(task.getId(), alarms))
@ -78,10 +81,39 @@ public final class AlarmControlSet extends TaskEditControlSet {
final View alertItem = LayoutInflater.from(activity).inflate(R.layout.alarm_edit_row, null);
alertsContainer.addView(alertItem);
DateControlSet dcs = new DateControlSet(activity, (Button)alertItem.findViewById(R.id.date),
(Button)alertItem.findViewById(R.id.time));
dcs.setDate(alert);
alertItem.setTag(dcs);
alertItem.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
pickerDialog.setSelectedDateAndTime((Long) alertItem.getTag());
pickerDialog.setDateAndTimeDialogListener(new DateAndTimeDialogListener() {
@Override
public void onDateAndTimeSelected(long date) {
if (date > 0) {
if (!pickerDialog.hasTime()) {
Date d = new Date(date);
d.setHours(18);
d.setMinutes(0);
d.setSeconds(0);
date = d.getTime();
}
v.setTag(date);
TextView label = (TextView) v.findViewById(R.id.alarm_string);
label.setText(pickerDialog.getDisplayString(activity, date));
}
}
@Override
public void onDateAndTimeCancelled() {
// Do nothing
}
});
pickerDialog.show();
}
});
alertItem.setTag(alert.getTime());
TextView display = (TextView) alertItem.findViewById(R.id.alarm_string);
display.setText(pickerDialog.getDisplayString(activity, alert.getTime()));
ImageButton reminderRemoveButton;
reminderRemoveButton = (ImageButton)alertItem.findViewById(R.id.button1);

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true"
android:color="@android:color/white"/>
<item android:state_checked="false"
android:color="@android:color/darker_gray"/>
</selector>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false"
android:state_enabled="true"
android:drawable="@drawable/date_shortcut_bottom_off" />
<item android:state_checked="true"
android:state_enabled="true"
android:drawable="@drawable/date_shortcut_bottom_on" />
</selector>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<corners
android:bottomRightRadius="5dip"
android:bottomLeftRadius="5dip"/>
</shape>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<solid
android:color="@color/task_edit_date_shortcuts_bg"/>
<corners
android:bottomRightRadius="5dip"
android:bottomLeftRadius="5dip"/>
</shape>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false"
android:state_enabled="true"
android:drawable="@drawable/date_shortcut_middle_off" />
<item android:state_checked="true"
android:state_enabled="true"
android:drawable="@drawable/date_shortcut_middle_on" />
</selector>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
</shape>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="@color/task_edit_date_shortcuts_bg"/>
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
</shape>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false"
android:state_enabled="true"
android:drawable="@drawable/date_shortcut_standalone_off" />
<item android:state_checked="true"
android:state_enabled="true"
android:drawable="@drawable/date_shortcut_standalone_on" />
</selector>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<corners
android:topLeftRadius="5dip"
android:topRightRadius="5dip"
android:bottomLeftRadius="5dip"
android:bottomRightRadius="5dip"/>
</shape>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<solid
android:color="@color/task_edit_date_shortcuts_bg"/>
<corners
android:topLeftRadius="5dip"
android:topRightRadius="5dip"
android:bottomLeftRadius="5dip"
android:bottomRightRadius="5dip"/>
</shape>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false"
android:state_enabled="true"
android:drawable="@drawable/date_shortcut_top_off" />
<item android:state_checked="true"
android:state_enabled="true"
android:drawable="@drawable/date_shortcut_top_on" />
</selector>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<corners
android:topLeftRadius="5dip"
android:topRightRadius="5dip"/>
</shape>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<solid
android:color="@color/task_edit_date_shortcuts_bg"/>
<corners
android:topLeftRadius="5dip"
android:topRightRadius="5dip"/>
</shape>

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
android:drawable="@drawable/deadline_timepicker_button_bl_off" />
<item android:state_pressed="true"
android:drawable="@drawable/deadline_timepicker_button_bl_on" />
</selector>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<corners
android:bottomRightRadius="5dip"/>
</shape>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<solid
android:color="@color/task_edit_date_shortcuts_bg"/>
<corners
android:bottomRightRadius="5dip"/>
</shape>

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
android:drawable="@drawable/deadline_timepicker_button_br_off" />
<item android:state_pressed="true"
android:drawable="@drawable/deadline_timepicker_button_br_on" />
</selector>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<corners
android:bottomLeftRadius="5dip"/>
</shape>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<solid
android:color="@color/task_edit_date_shortcuts_bg"/>
<corners
android:bottomLeftRadius="5dip"/>
</shape>

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
android:drawable="@drawable/deadline_timepicker_button_tl_off" />
<item android:state_pressed="true"
android:drawable="@drawable/deadline_timepicker_button_tl_on" />
</selector>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<corners
android:topLeftRadius="5dip"/>
</shape>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<solid
android:color="@color/task_edit_date_shortcuts_bg"/>
<corners
android:topLeftRadius="5dip"/>
</shape>

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false"
android:drawable="@drawable/deadline_timepicker_button_tr_off" />
<item android:state_pressed="true"
android:drawable="@drawable/deadline_timepicker_button_tr_on" />
</selector>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<corners
android:topRightRadius="5dip"/>
</shape>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<solid
android:color="@color/task_edit_date_shortcuts_bg"/>
<corners
android:topRightRadius="5dip"/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Before

Width:  |  Height:  |  Size: 308 B

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -17,7 +17,7 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:state_enabled="true"
android:state_focused="false" android:drawable="@drawable/icn_arrow" />
android:state_focused="false" android:drawable="@drawable/icn_arrow_right" />
<item android:state_pressed="true" android:state_enabled="true"
android:drawable="@drawable/icn_arrow_over" />
<item android:state_pressed="false" android:state_enabled="true"

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/white"/>
<solid
android:color="@android:color/black"/>
<corners
android:topLeftRadius="5dip"
android:topRightRadius="5dip"
android:bottomLeftRadius="5dip"
android:bottomRightRadius="5dip"/>
</shape>

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false"
android:drawable="@drawable/timepicker_am_btn_off" />
<item android:state_checked="true"
android:drawable="@drawable/timepicker_am_btn_on" />
</selector>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<corners
android:topLeftRadius="5dip"
android:bottomRightRadius="5dip"/>
</shape>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<solid
android:color="@color/task_edit_date_shortcuts_bg"/>
<corners
android:topLeftRadius="5dip"
android:bottomRightRadius="5dip"/>
</shape>

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false"
android:drawable="@drawable/timepicker_pm_btn_off" />
<item android:state_checked="true"
android:drawable="@drawable/timepicker_pm_btn_on" />
</selector>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<corners
android:topRightRadius="5dip"
android:bottomLeftRadius="5dip"/>
</shape>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dip"
android:color="@android:color/darker_gray"/>
<solid
android:color="@color/task_edit_date_shortcuts_bg"/>
<corners
android:topRightRadius="5dip"
android:bottomLeftRadius="5dip"/>
</shape>

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<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/reminders_body"
android:orientation="horizontal"
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="280dip"
android:layout_weight="1"
android:layout_marginRight="5dip"/>
<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">
<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>

@ -15,25 +15,38 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:id="@+id/date"
android:layout_weight="0.7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button android:id="@+id/time"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageButton android:id="@+id/button1"
android:background="@drawable/btn_dismiss"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_gravity="center"
android:layout_margin="4dip"
/>
android:layout_height="wrap_content"
android:paddingLeft="5dip"
android:paddingRight="5dip">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:id="@+id/alarm_string"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="100"
android:paddingTop="15dip"
android:paddingBottom="15dip"
style="@style/TextAppearance.GEN_EditLabel.DLG_EditLabel"/>
<ImageButton android:id="@+id/button1"
android:background="@drawable/btn_dismiss"
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_gravity="center"
android:layout_margin="4dip"
android:layout_weight="1"
/>
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="1px"
android:padding="5dip"
style="@style/TEA_Separator" />
</LinearLayout>

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:id="@+id/timeComponents"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="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/black"
android:text=":"
android:textColor="@android:color/white"
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/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="wrap_content"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:textSize="18sp"
android:background="@drawable/timepicker_am_btn"
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="wrap_content"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:textSize="18sp"
android:background="@drawable/timepicker_pm_btn"
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_height="wrap_content"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:textSize="18sp"
android:gravity="center"
android:textColor="@color/task_edit_toggle_button_text"/>
</merge>

@ -17,7 +17,7 @@
android:drawSelectorOnTop="false"
tlv:normal_height="52dip"
tlv:grabber="@+id/grabber" />
tlv:grabber="@+id/row_body" />
<Button
android:id="@+id/reset"

@ -24,7 +24,8 @@
<Button android:id="@+id/alarms_add"
android:text="+"
android:layout_width="50dip"
android:layout_height="50dip"/>
android:layout_height="50dip"
android:layout_marginTop="10dip"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<com.todoroo.astrid.ui.DateAndTimePicker
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:astrid="http://schemas.android.com/apk/res/com.timsu.astrid"
android:id="@+id/date_and_time"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"/>

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- tags -->
<LinearLayout
android:id="@+id/repeat_body"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:gravity="center_vertical">
<ImageView
style="@style/EditRowImage"
android:src="@drawable/icn_edit_reminders"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dip"
android:text="@string/TEA_date_and_time"
style="@style/TextAppearance.GEN_EditLabel.DLG_EditLabel" />
<TextView
android:id="@+id/deadline_display"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:paddingLeft="10dip"
style="@style/TextAppearance.EditRowDisplay" />
<include layout="@layout/task_edit_arrow"/>
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="1px"
android:padding="5dip"
style="@style/TEA_Separator" />
</LinearLayout>

@ -17,6 +17,7 @@
style="@style/EditRowImage"
android:src="@drawable/icn_edit_priority"/>
<TextView
android:id="@+id/importance_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/TEA_importance_label"

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:astrid="http://schemas.android.com/apk/res/com.timsu.astrid"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.todoroo.astrid.ui.DateAndTimePicker
android:id="@+id/date_and_time"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="7dip"
android:paddingRight="7dip"
android:orientation="horizontal">
<Button
android:id="@+id/ok"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:layout_weight="1"
android:text="@string/DLG_ok"/>
<Button
android:id="@+id/cancel"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:layout_weight="1"
android:text="@string/DLG_cancel"/>
</LinearLayout>
</LinearLayout>
</ScrollView>

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<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/reminders_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="300dip"
android:layout_weight="1" />
<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,66 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** 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.
*/
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<com.todoroo.astrid.ui.NumberPickerButton android:id="@+id/increment"
android:layout_width="fill_parent"
android:layout_height="36dip"
android:src="@drawable/icn_arrow_up"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<View
android:id="@+id/timepicker_left_border"
android:layout_height="fill_parent"
android:layout_width="2dip"
android:background="@android:color/darker_gray"
android:visibility="gone"
/>
<EditText android:id="@+id/timepicker_input"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/textAppearanceLarge"
android:gravity="center"
android:inputType="phone"
android:textSize="30sp"
android:textColor="@android:color/white"
android:background="@android:color/transparent"
/>
<View
android:id="@+id/timepicker_right_border"
android:layout_height="fill_parent"
android:layout_width="2dip"
android:background="@android:color/darker_gray"
android:visibility="gone"
/>
</LinearLayout>
<com.todoroo.astrid.ui.NumberPickerButton android:id="@+id/decrement"
android:layout_width="fill_parent"
android:layout_height="36dip"
android:src="@drawable/icn_arrow_down"
android:paddingTop="15dip"
/>
</merge>

@ -8,21 +8,26 @@
android:paddingBottom="2dip"
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:gravity="center"
android:orientation="horizontal">
<!-- grabber -->
<ImageView android:id="@+id/grabber"
<LinearLayout
android:id="@+id/row_body"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:scaleType="center"
android:src="@drawable/grabber"/>
<TextView
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:paddingRight="5dip"
android:textAppearance="?android:attr/textAppearanceLarge"/>
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView android:id="@+id/grabber"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:scaleType="center"
android:src="@drawable/grabber"/>
<TextView
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dip"
android:textAppearance="?android:attr/textAppearanceLarge"/>
</LinearLayout>
</LinearLayout>

@ -130,16 +130,23 @@
android:layout_width="fill_parent"
android:layout_height="50dip"
android:gravity="center_vertical">
<ImageView
android:id="@+id/when_image"
style="@style/EditRowImage"
android:src="@drawable/icn_edit_when"/>
<TextView
android:id="@+id/when_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance.GEN_EditLabel"
android:text="When"/>
<LinearLayout
android:id="@+id/when_shortcut_container"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:id="@+id/when_image"
style="@style/EditRowImage"
android:src="@drawable/icn_edit_when"/>
<TextView
android:id="@+id/when_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance.GEN_EditLabel"
android:text="@string/TEA_when_header_label"/>
</LinearLayout>
<TextView
android:id="@+id/aux_date"
android:layout_width="fill_parent"

@ -4,4 +4,4 @@
android:layout_height="20dip"
android:layout_marginTop="1dip"
android:layout_marginLeft="7dip"
android:src="@drawable/icn_arrow" />
android:src="@drawable/icn_arrow_right" />

@ -6,13 +6,17 @@
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="10dip">
<LinearLayout
android:id="@+id/when_controls"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="100"
android:orientation="vertical">
</LinearLayout>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="100">
<LinearLayout
android:id="@+id/when_controls"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<Button
android:id="@+id/when_dismiss"
android:layout_width="150dip"

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2007, 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.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:orientation="vertical">
<TimePicker android:id="@+id/timePicker"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<CheckBox android:id="@+id/hasTime"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/TEA_urgency_specific_time"/>
</LinearLayout>

@ -23,6 +23,8 @@
<color name="view_table_overdue">#ffff0000</color>
<color name="task_edit_selected">#438cb6</color>
<color name="task_edit_date_shortcuts_bg">#0b78a5</color>
</resources>

@ -271,6 +271,9 @@
<!-- Task title label -->
<string name="TEA_title_label">Title</string>
<!-- Task when label (note the <u> tags - be sure to leave those in when localizing! -->
<string name="TEA_when_header_label"><u>When</u></string>
<!-- Task title hint (displayed when edit box is empty) -->
<string name="TEA_title_hint">Task Summary</string>
@ -327,7 +330,7 @@
<string-array name="TEA_urgency">
<!-- urgency: labels for edit page. item #4 -> auto filled -->
<item>None</item>
<item>No deadline</item>
<item>Specific Day</item>
<item>Today</item>
<item>Tomorrow</item>
@ -337,6 +340,8 @@
<item>Next Month</item>
</string-array>
<string name="TEA_no_time">No time</string>
<string-array name="TEA_hideUntil">
<!-- hideUntil: labels for edit page. -->
<item>Always</item>
@ -385,6 +390,8 @@
<!-- When controls dialog -->
<string name="TEA_when_dialog_title">When is this due?</string>
<string name="TEA_date_and_time">Date/Time</string>
<!-- ============================================= IntroductionActivity == -->
<!-- Introduction Window title -->

@ -158,6 +158,25 @@
<item name="android:windowEnterAnimation">@anim/slide_left_in</item>
<item name="android:windowExitAnimation">@anim/slide_right_out</item>
</style>
<style name="Theme.TEA_Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowTitleStyle">@style/TEA_DialogWindowTitle</item>
<item name="android:windowBackground">@drawable/task_edit_dialog_background</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
</style>
<style name="TEA_DialogWindowTitle">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:textSize">18sp</item>
<item name="android:textStyle">normal</item>
<item name="android:textColor">#ffffff</item>
</style>
<!-- ==================================================== TaskAdapter == -->
<style name="TextAppearance.TAd_ItemTitle">

@ -88,12 +88,12 @@ import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.tags.TagsControlSet;
import com.todoroo.astrid.timers.TimerActionControlSet;
import com.todoroo.astrid.timers.TimerControlSet;
import com.todoroo.astrid.ui.DeadlineControlSet;
import com.todoroo.astrid.ui.EditNotesControlSet;
import com.todoroo.astrid.ui.EditTitleControlSet;
import com.todoroo.astrid.ui.HideUntilControlSet;
import com.todoroo.astrid.ui.ImportanceControlSet;
import com.todoroo.astrid.ui.ReminderControlSet;
import com.todoroo.astrid.ui.UrgencyControlSet;
import com.todoroo.astrid.voice.VoiceInputAssistant;
/**
@ -255,6 +255,7 @@ public final class TaskEditActivity extends Activity {
LinearLayout basicControls = (LinearLayout) findViewById(R.id.basic_controls);
LinearLayout whenDialogView = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.task_edit_when_controls, null);
LinearLayout whenControls = (LinearLayout) whenDialogView.findViewById(R.id.when_controls);
LinearLayout whenHeader = (LinearLayout) findViewById(R.id.when_header);
LinearLayout moreControls = (LinearLayout) findViewById(R.id.more_controls);
constructWhenDialog(whenDialogView);
@ -275,10 +276,9 @@ public final class TaskEditActivity extends Activity {
//basicControls.addView(peopleControlSet.getDisplayView());
controlSetMap.put(getString(R.string.TEA_control_who), peopleControlSet);
UrgencyControlSet urgencyControl = new UrgencyControlSet(TaskEditActivity.this, R.layout.control_set_urgency, R.id.when_header, R.id.aux_date, R.id.when_label, R.id.when_image);
controls.add(urgencyControl);
whenControls.addView(urgencyControl.getDisplayView());
DeadlineControlSet deadlineControl = new DeadlineControlSet(TaskEditActivity.this, R.layout.control_set_deadline, R.layout.control_set_deadline_display, whenHeader, R.id.aux_date, R.id.when_shortcut_container, R.id.when_label, R.id.when_image);
controls.add(deadlineControl);
whenControls.addView(deadlineControl.getDisplayView());
RepeatControlSet repeatControls = new RepeatControlSet(TaskEditActivity.this, R.layout.control_set_repeat, R.layout.control_set_repeat_display, R.string.repeat_enabled);
controls.add(repeatControls);
@ -328,7 +328,7 @@ public final class TaskEditActivity extends Activity {
controls.add(producteevControl);
basicControls.addView(producteevControl.getDisplayView());
notesEditText.setHint(R.string.producteev_TEA_notes);
((TextView) notesControlSet.getView().findViewById(R.id.notes_label)).setHint(R.string.producteev_TEA_notes);
//((TextView) notesControlSet.getView().findViewById(R.id.notes_label)).setHint(R.string.producteev_TEA_notes);
}
} catch (Exception e) {
Log.e("astrid-error", "loading-control-set", e); //$NON-NLS-1$ //$NON-NLS-2$
@ -340,7 +340,7 @@ public final class TaskEditActivity extends Activity {
controls.add(ocrxControl);
basicControls.addView(ocrxControl.getDisplayView());
notesEditText.setHint(R.string.opencrx_TEA_notes);
((TextView) notesControlSet.getView().findViewById(R.id.notes_label)).setHint(R.string.opencrx_TEA_notes);
//((TextView) notesControlSet.getView().findViewById(R.id.notes_label)).setHint(R.string.opencrx_TEA_notes);
}
} catch (Exception e) {
Log.e("astrid-error", "loading-control-set", e); //$NON-NLS-1$ //$NON-NLS-2$
@ -475,10 +475,10 @@ public final class TaskEditActivity extends Activity {
private void constructWhenDialog(View whenDialogView) {
int theme = ThemeService.getTheme();
if (theme == R.style.Theme || theme == R.style.Theme_Transparent) {
whenDialog = new Dialog(this, 0);//R.style.Theme_WhenDialog
whenDialog = new Dialog(this, R.style.Theme_TEA_Dialog);//R.style.Theme_WhenDialog
//whenDialogView.setBackgroundColor(getResources().getColor(android.R.color.black));
} else {
whenDialog = new Dialog(this, 0); //R.style.Theme_White_WhenDialog
whenDialog = new Dialog(this, R.style.Theme_TEA_Dialog); //R.style.Theme_White_WhenDialog
//whenDialogView.setBackgroundColor(getResources().getColor(android.R.color.white));
}

@ -0,0 +1,199 @@
package com.todoroo.astrid.ui;
import java.util.Calendar;
import android.content.Context;
import android.text.format.DateUtils;
import android.util.AttributeSet;
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.timsu.astrid.R;
import com.todoroo.andlib.utility.DateUtilities;
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 {
public void timePickerEnabledChanged(boolean hasTime);
}
public AstridTimePicker(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.astrid_time_picker, 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);
initialize(context);
}
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(NumberPicker picker, int oldVal, int newVal) {
setHasTime(true);
return newVal;
}
};
hours.findViewById(R.id.increment).setBackgroundResource(R.drawable.deadline_timepicker_button_tl);
hours.findViewById(R.id.decrement).setBackgroundResource(R.drawable.deadline_timepicker_button_bl);
hours.findViewById(R.id.timepicker_left_border).setVisibility(View.VISIBLE);
minutes.findViewById(R.id.increment).setBackgroundResource(R.drawable.deadline_timepicker_button_tr);
minutes.findViewById(R.id.decrement).setBackgroundResource(R.drawable.deadline_timepicker_button_br);
minutes.findViewById(R.id.timepicker_right_border).setVisibility(View.VISIBLE);
String amString = DateUtils.getAMPMString(Calendar.AM).toLowerCase();
amButton.setTextOff(amString);
amButton.setTextOn(amString);
amButton.setChecked(false);
String pmString = DateUtils.getAMPMString(Calendar.PM).toLowerCase();
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);
}
});
pmButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
noTimeCheck.setChecked(false);
amButton.setChecked(false);
pmButton.setChecked(true);
}
});
noTimeCheck.setBackgroundResource(R.drawable.date_shortcut_standalone);
String noTime = context.getString(R.string.TEA_no_time).toLowerCase();
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.updateView();
minutes.updateView();
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;
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;
}
}

@ -4,6 +4,7 @@ import java.util.Calendar;
import java.util.Date;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@ -16,6 +17,8 @@ import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
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;
@ -24,17 +27,23 @@ import com.timsu.astrid.R;
public class CalendarView extends View {
private static final int PADDING = 3;
private final static int CURVE_RADIUS = 5;
private static final int PADDING = 0;
private static final int TEXT_PADDING = 2;
private final static int OUTER_BORDER_RADIUS = 5;
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 borderPaint;
private Paint borderRightAlignPaint;
private Paint backColorPaint;
private Paint whiteCenterAlignLargePaint;
private Paint darkRightAlignPaint;
private Paint centerAlignPaint;
private Paint todayCalendarPaint;
private Paint selectedCalendarPaint;
private Paint dayPaint;
private Paint calendarPaint;
private float density;
@ -51,8 +60,8 @@ public class CalendarView extends View {
private int[] dayLeftArr;
private int[] dayTopArr;
private int boxWidth;
private int boxHeight;
private float boxWidth;
private float boxHeight;
private Date calendarDate = new Date();
private int currentHighlightDay = -1;
@ -90,9 +99,11 @@ public class CalendarView extends View {
display.getMetrics(metrics);
density = metrics.density;
Resources r = context.getResources();
borderPaint = new Paint();
borderPaint.setAntiAlias(true);
borderPaint.setColor(Color.BLACK);
borderPaint.setColor(Color.WHITE);
borderRightAlignPaint = new Paint();
borderRightAlignPaint.setAntiAlias(true);
@ -106,7 +117,7 @@ public class CalendarView extends View {
calendarPaint = new Paint();
calendarPaint.setAntiAlias(true);
calendarPaint.setColor(Color.rgb(202, 201, 194));
calendarPaint.setColor(Color.BLACK);
whiteCenterAlignLargePaint = new Paint();
whiteCenterAlignLargePaint.setAntiAlias(true);
@ -114,21 +125,56 @@ public class CalendarView extends View {
whiteCenterAlignLargePaint.setTextAlign(Paint.Align.CENTER);
whiteCenterAlignLargePaint.setTextSize(MONTH_TEXT_SIZE * density);
darkRightAlignPaint = new Paint();
darkRightAlignPaint.setAntiAlias(true);
darkRightAlignPaint.setColor(Color.rgb(40, 40, 40));
darkRightAlignPaint.setTextAlign(Paint.Align.RIGHT);
darkRightAlignPaint.setTextSize(TEXT_SIZE * density);
centerAlignPaint = new Paint();
centerAlignPaint.setAntiAlias(true);
centerAlignPaint.setColor(Color.WHITE);
centerAlignPaint.setTextAlign(Paint.Align.CENTER);
centerAlignPaint.setTextSize(TEXT_SIZE * density);
todayCalendarPaint = new Paint();
todayCalendarPaint.setAntiAlias(true);
todayCalendarPaint.setColor(Color.rgb(222, 221, 154));
todayCalendarPaint.setColor(r.getColor(android.R.color.darker_gray));
selectedCalendarPaint = new Paint();
selectedCalendarPaint.setAntiAlias(true);
selectedCalendarPaint.setColor(r.getColor(R.color.task_edit_date_shortcuts_bg));
backColorPaint = new Paint();
backColorPaint.setAntiAlias(true);
backColorPaint.setColor(Color.rgb(68, 68, 68));
backColorPaint.setColor(Color.BLACK);
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() {
public boolean onTouch(View v, MotionEvent event) {
return swipeCalendarListener.onTouchEvent(event);
}
};
this.setOnTouchListener(swipeTouchListener);
}
/**
@ -186,13 +232,13 @@ public class CalendarView extends View {
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), backColorPaint);
// Outermost border -- Start
RectF outerMostBorder = new RectF();
outerMostBorder.set(5, 5, getMeasuredWidth() - 5, getMeasuredHeight() - 5);
canvas.drawRoundRect(outerMostBorder, CURVE_RADIUS, CURVE_RADIUS, borderPaint);
outerMostBorder.set(6, 6, getMeasuredWidth() - 6, getMeasuredHeight() - 6);
canvas.drawRoundRect(outerMostBorder, CURVE_RADIUS, CURVE_RADIUS, backColorPaint);
// 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
@ -200,17 +246,17 @@ public class CalendarView extends View {
float monthTitleHeight = (MONTH_TEXT_SIZE + 30) * density;
rectF.set(15, 15, getMeasuredWidth() - 15, monthTitleHeight);
canvas.drawRoundRect(rectF, CURVE_RADIUS, CURVE_RADIUS, borderPaint);
canvas.drawRoundRect(rectF, CURVE_RADIUS, CURVE_RADIUS, backColorPaint);
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.cal_left)).getBitmap();
leftArrowHeight = (int)(leftArrow.getHeight()*density);
leftArrowWidth = (int)(leftArrow.getWidth()*density);
leftArrowX = 24;
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 = 8 + (int)((monthTitleHeight / 2 - leftArrowHeight/2));
canvas.drawBitmap(leftArrow, new Rect(0,0,leftArrow.getWidth(),leftArrow.getHeight()),
new Rect(leftArrowX, leftArrowY, leftArrowX + leftArrowWidth,
@ -218,34 +264,35 @@ public class CalendarView extends View {
// Month left arrow -- End
// Month right arrow -- Start
Bitmap rightArrow = ((BitmapDrawable)getResources().getDrawable(R.drawable.cal_right)).getBitmap();
rightArrowHeight = (int)(rightArrow.getHeight()*density);
rightArrowWidth = (int)(rightArrow.getWidth()*density);
rightArrowX = (int) (getMeasuredWidth() - (16 * density) - (PADDING*3) - rightArrow.getWidth());
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 = 8 + (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", calendarDate); //$NON-NLS-1$
String monthYear = (String) DateFormat.format("MMMM yyyy", calendarDate.getTime() == 0 ? calendar.getTime() : calendarDate); //$NON-NLS-1$
canvas.drawText(monthYear, monthX, monthY, whiteCenterAlignLargePaint);
// Month text -- End
// Day heading -- Start
int dayLeft = 15;
int dayLeft = 3;
int dayTop = (int)(monthTitleHeight + PADDING * 2);
boxWidth = (getMeasuredWidth() - 38 - (PADDING*2)) / 7;
boxWidth = (getMeasuredWidth() - (PADDING*2)) / 7.0f;
boxHeight = (int) (((getMeasuredHeight() - (monthTitleHeight) - 16) - (PADDING * 8)) / 7);
int textX = 0;
int textY = 0;
float textX = 0;
float textY = 0;
Calendar calendar = Calendar.getInstance();
int firstDayOfWeek = calendar.getFirstDayOfWeek();
calendar.set(Calendar.DAY_OF_WEEK, firstDayOfWeek);
for(int i = 0; i < 7; i++) {
@ -253,25 +300,19 @@ public class CalendarView extends View {
String day = DateUtils.getDayOfWeekString(dayOfWeek, DateUtils.LENGTH_SHORT);
calendar.add(Calendar.DATE, 1);
rectF.set(dayLeft, dayTop, dayLeft + boxWidth, dayTop + boxHeight);
canvas.drawRoundRect(rectF, CURVE_RADIUS, CURVE_RADIUS, borderPaint);
rectF.set(dayLeft+1, dayTop+1, dayLeft + boxWidth - 1, dayTop + boxHeight - 1);
canvas.drawRoundRect(rectF, CURVE_RADIUS, CURVE_RADIUS, dayPaint);
textX = dayLeft + boxWidth / 2;
textY = dayTop + (boxHeight - boxHeight/8) - TEXT_PADDING * 2;
canvas.drawText(day, textX, textY, centerAlignPaint);
textX = dayLeft + boxWidth - PADDING * 2;
textY = dayTop + (boxHeight - boxHeight/8) - PADDING * 2;
canvas.drawText(day, textX, textY, darkRightAlignPaint);
dayLeft += boxWidth + PADDING;
dayLeft += boxWidth;
}
// Day heading -- End
// Calendar -- Start
calendar.setTime(calendarDate);
calendar.setTime(calendarDate.getTime() == 0 ? calendar.getTime() : calendarDate);
if (currentHighlightDay == -1) {
currentHighlightDay = calendar.get(Calendar.DATE);
currentHighlightDay = calendarDate.getTime() == 0 ? 0 : calendar.get(Calendar.DATE);
}
int today = -1;
Calendar todayCalendar = Calendar.getInstance();
@ -287,12 +328,12 @@ public class CalendarView extends View {
firstDayOfMonth = 7;
boolean firstTime = true;
int dayOfMonth = 1;
Paint colorPaint, textPaint;
Paint colorPaint;
dayLeftArr = new int[lastDateOfThisMonth];
dayTopArr = new int[lastDateOfThisMonth];
for (int i = 1; i <= 6; i++) {
dayLeft = 15;
dayLeft = 1;
dayTop += boxHeight + PADDING;
for (int j = 1; j <= 7; j++) {
if (firstTime && j != firstDayOfMonth) {
@ -304,14 +345,11 @@ public class CalendarView extends View {
if (dayOfMonth <= lastDateOfThisMonth) {
if (currentHighlightDay == dayOfMonth) {
colorPaint = darkRightAlignPaint;
textPaint = borderRightAlignPaint;
colorPaint = selectedCalendarPaint;
} else if(today == dayOfMonth) {
colorPaint = todayCalendarPaint;
textPaint = darkRightAlignPaint;
} else {
colorPaint = calendarPaint;
textPaint = darkRightAlignPaint;
}
dayLeftArr[dayOfMonth-1] = dayLeft;
dayTopArr[dayOfMonth-1] = dayTop;
@ -321,9 +359,9 @@ public class CalendarView extends View {
rectF.set(dayLeft+1, dayTop+1, dayLeft + boxWidth - 1, dayTop + boxHeight - 1);
canvas.drawRoundRect(rectF, CURVE_RADIUS, CURVE_RADIUS, colorPaint);
textX = dayLeft + boxWidth - PADDING * 2;
textY = dayTop + (boxHeight - boxHeight/8) - PADDING * 2;
canvas.drawText(String.valueOf(dayOfMonth), textX, textY, textPaint);
textX = dayLeft + boxWidth - TEXT_PADDING * 3;
textY = dayTop + borderRightAlignPaint.getTextSize() + TEXT_PADDING;
canvas.drawText(String.valueOf(dayOfMonth), textX, textY, borderRightAlignPaint);
dayLeft += boxWidth + PADDING;
@ -350,7 +388,7 @@ public class CalendarView extends View {
// System.out.println("---------------------Current x, y : " + x + ", " + y);
// Handle left-right arrow click -- start
if ((x > leftArrowX && x < (leftArrowX + leftArrowWidth * 2))
&& (y > 5 && y < (leftArrowY * 2))) {
&& (y > leftArrowY - leftArrowHeight / 2 && y < (leftArrowY + 3 * leftArrowHeight / 2))) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(calendarDate);
int currentDay = calendar.get(Calendar.DATE);
@ -361,8 +399,11 @@ public class CalendarView extends View {
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 > 5 && y < (rightArrowY * 2))) {
&& (y > rightArrowY - rightArrowHeight / 2 && y < (rightArrowY + 3 * rightArrowHeight / 2))) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(calendarDate);
int currentDay = calendar.get(Calendar.DATE);
@ -373,14 +414,26 @@ public class CalendarView extends View {
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();
calendar.setTime(calendarDate);
Date today = calendar.getTime();
today.setTime(today.getTime() / 1000L * 1000L);
today.setHours(23);
today.setMinutes(59);
today.setSeconds(59);
calendar.setTime(calendarDate.getTime() == 0 ? today : calendarDate);
calendar.set(Calendar.DATE, currentHighlightDay);
calendarDate = calendar.getTime();
@ -399,5 +452,6 @@ public class CalendarView extends View {
public void setCalendarDate(Date calendarDate) {
this.calendarDate = calendarDate;
currentHighlightDay = -1;
}
}

@ -0,0 +1,101 @@
package com.todoroo.astrid.ui;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.View;
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
import com.timsu.astrid.R;
public class DateAndTimeDialog extends Dialog {
public interface DateAndTimeDialogListener {
public void onDateAndTimeSelected(long date);
public void onDateAndTimeCancelled();
}
private final DateAndTimePicker dateAndTimePicker;
private final Button okButton;
private final Button cancelButton;
private boolean cancelled = false;
private DateAndTimeDialogListener listener;
public DateAndTimeDialog(Context context, long startDate) {
super(context);
/** 'Window.FEATURE_NO_TITLE' - Used to hide the title */
requestWindowFeature(Window.FEATURE_NO_TITLE);
/** Design the dialog in main.xml file */
setContentView(R.layout.date_time_dialog);
LayoutParams params = getWindow().getAttributes();
params.height = LayoutParams.FILL_PARENT;
params.width = LayoutParams.FILL_PARENT;
getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
dateAndTimePicker = (DateAndTimePicker) findViewById(R.id.date_and_time);
dateAndTimePicker.initializeWithDate(startDate);
okButton = (Button) findViewById(R.id.ok);
cancelButton = (Button) findViewById(R.id.cancel);
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
if (listener != null)
listener.onDateAndTimeSelected(dateAndTimePicker.constructDueDate());
}
});
cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cancelled = true;
cancel();
if (listener != null)
listener.onDateAndTimeCancelled();
}
});
setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
if (!cancelled) { // i.e. if back button pressed, which we treat as an "OK"
if (listener != null)
listener.onDateAndTimeSelected(dateAndTimePicker.constructDueDate());
} else {
cancelled = false; // reset
}
}
});
}
public long getSelectedDate() {
return dateAndTimePicker.constructDueDate();
}
public void setSelectedDateAndTime(long date) {
dateAndTimePicker.initializeWithDate(date);
}
public boolean hasTime() {
return dateAndTimePicker.hasTime();
}
public void setDateAndTimeDialogListener(DateAndTimeDialogListener listener) {
this.listener = listener;
}
public String getDisplayString(Context context) {
return dateAndTimePicker.getDisplayString(context);
}
public String getDisplayString(Context context, long forDate) {
return dateAndTimePicker.getDisplayString(context, forDate);
}
}

@ -0,0 +1,233 @@
package com.todoroo.astrid.ui;
import java.util.ArrayList;
import java.util.Date;
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ToggleButton;
import com.timsu.astrid.R;
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;
public class DateAndTimePicker extends LinearLayout {
public interface OnDateChangedListener {
public void onDateChanged();
}
private static final int SHORTCUT_PADDING = 8;
ArrayList<UrgencyValue> urgencyValues;
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 OnDateChangedListener listener;
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, this, true);
calendarView = (CalendarView) findViewById(R.id.calendar);
timePicker = (AstridTimePicker) findViewById(R.id.time_picker);
dateShortcuts = (LinearLayout) findViewById(R.id.date_shortcuts);
setUpListeners();
constructShortcutList(context);
}
public void initializeWithDate(long dateValue) {
Date date = new Date(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 = new Date(date.getTime() / 1000L * 1000L);
forCalendar.setHours(23);
forCalendar.setMinutes(59);
forCalendar.setSeconds(59);
return forCalendar;
}
private void setUpListeners() {
calendarView.setOnSelectedDateListener(new OnSelectedDateListener() {
@Override
public void onSelectedDate(Date date) {
updateShortcutView(date);
otherCallbacks();
}
});
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()) {
dateShortcuts.getChildAt(0).performClick();
}
}
private void constructShortcutList(Context context) {
String[] labels = context.getResources().getStringArray(R.array.TEA_urgency);
urgencyValues = new ArrayList<UrgencyValue>();
urgencyValues.add(new UrgencyValue(labels[2],
Task.URGENCY_TODAY));
urgencyValues.add(new UrgencyValue(labels[3],
Task.URGENCY_TOMORROW));
urgencyValues.add(new UrgencyValue(labels[5],
Task.URGENCY_NEXT_WEEK));
urgencyValues.add(new UrgencyValue(labels[7],
Task.URGENCY_NEXT_MONTH));
urgencyValues.add(new UrgencyValue(labels[0],
Task.URGENCY_NONE));
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
for (int i = 0; i < urgencyValues.size(); i++) {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 0);
UrgencyValue uv = urgencyValues.get(i);
ToggleButton tb = new ToggleButton(context);
String label = uv.label.toLowerCase();
tb.setTextOff(label);
tb.setTextOn(label);
tb.setTag(uv);
if (i == 0) {
tb.setBackgroundResource(R.drawable.date_shortcut_top);
} else if (i == urgencyValues.size() - 2) {
lp.topMargin = (int) (-2 * metrics.density);
tb.setBackgroundResource(R.drawable.date_shortcut_bottom);
} else if (i == urgencyValues.size() - 1) {
lp.topMargin = (int) (5 * metrics.density);
tb.setBackgroundResource(R.drawable.date_shortcut_standalone);
} else {
lp.topMargin = (int) (-2 * metrics.density);
tb.setBackgroundResource(R.drawable.date_shortcut_middle);
}
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 = new Date(value.dueDate);
calendarView.setCalendarDate(date);
calendarView.invalidate();
if (value.setting == Task.URGENCY_NONE)
timePicker.forceNoTime();
updateShortcutView(date);
otherCallbacks();
}
});
dateShortcuts.addView(tb);
}
}
private void updateShortcutView(Date date) {
for (int i = 0; i < dateShortcuts.getChildCount(); i++) {
ToggleButton tb = (ToggleButton) dateShortcuts.getChildAt(i);
UrgencyValue uv = (UrgencyValue) tb.getTag();
if (uv.dueDate == date.getTime()) {
tb.setChecked(true);
} else {
tb.setChecked(false);
}
}
}
private void otherCallbacks() {
if (listener != null)
listener.onDateChanged();
}
public long constructDueDate() {
Date calendarDate = new Date(calendarView.getCalendarDate().getTime());
if (timePicker.hasTime() && calendarDate.getTime() > 0) {
calendarDate.setHours(timePicker.getHours());
calendarDate.setMinutes(timePicker.getMinutes());
}
return calendarDate.getTime();
}
public boolean hasTime() {
return timePicker.hasTime();
}
public void setOnDateChangedListener(OnDateChangedListener listener) {
this.listener = listener;
}
public String getDisplayString(Context context) {
long dueDate = constructDueDate();
return getDisplayString(context, dueDate);
}
public static String getDisplayString(Context context, long forDate) {
StringBuilder displayString = new StringBuilder();
Date d = new Date(forDate);
if (d.getTime() > 0) {
displayString.append(DateUtilities.getDateString(context, d));
if (Task.hasDueTime(forDate)) {
displayString.append(", ");
displayString.append(DateUtilities.getTimeString(context, d));
}
}
return displayString.toString();
}
}

@ -0,0 +1,69 @@
package com.todoroo.astrid.ui;
import android.app.Activity;
import android.view.View;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.ui.DateAndTimePicker.OnDateChangedListener;
public class DeadlineControlSet extends PopupControlSet {
private final DateAndTimePicker dateAndTimePicker;
private final TextView auxDisplay;
public DeadlineControlSet(Activity activity, int viewLayout, int displayViewLayout, View extensionView, int auxDisplayId, int...dateShortcutViews) {
super(activity, viewLayout, displayViewLayout, 0);
dateAndTimePicker = (DateAndTimePicker) getView().findViewById(R.id.date_and_time);
auxDisplay = (TextView) extensionView.findViewById(auxDisplayId);
setUpListeners(dateShortcutViews);
}
private void setUpListeners(int[] dateShortcutViews) {
dateAndTimePicker.setOnDateChangedListener(new OnDateChangedListener() {
@Override
public void onDateChanged() {
refreshDisplayView();
}
});
View.OnClickListener dateShortcutListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.show();
}
};
for (int i : dateShortcutViews) {
View v = activity.findViewById(i);
if (v != null)
v.setOnClickListener(dateShortcutListener);
}
}
@Override
protected void refreshDisplayView() {
TextView dateDisplay = (TextView) getDisplayView().findViewById(R.id.deadline_display);
String toDisplay = dateAndTimePicker.getDisplayString(activity);
dateDisplay.setText(toDisplay);
auxDisplay.setText(toDisplay);
}
@Override
public void readFromTask(Task task) {
long dueDate = task.getValue(Task.DUE_DATE);
dateAndTimePicker.initializeWithDate(dueDate);
refreshDisplayView();
}
@Override
public String writeToModel(Task task) {
long dueDate = dateAndTimePicker.constructDueDate();
task.setValue(Task.DUE_DATE, dueDate);
return null;
}
}

@ -0,0 +1,27 @@
package com.todoroo.astrid.ui;
import android.content.Context;
import android.util.AttributeSet;
import com.timsu.astrid.R;
public class DeadlineNumberPicker extends NumberPicker {
public DeadlineNumberPicker(Context context) {
super(context);
}
public DeadlineNumberPicker(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DeadlineNumberPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected int getLayout() {
return R.layout.deadline_number_picker;
}
}

@ -3,9 +3,6 @@ package com.todoroo.astrid.ui;
import java.util.Date;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
@ -15,13 +12,12 @@ import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.ui.DeadlineTimePickerDialog.OnDeadlineTimeSetListener;
import com.todoroo.astrid.ui.DateAndTimeDialog.DateAndTimeDialogListener;
/**
* Control set for specifying when a task should be hidden
@ -29,9 +25,7 @@ import com.todoroo.astrid.ui.DeadlineTimePickerDialog.OnDeadlineTimeSetListener;
* @author Tim Su <tim@todoroo.com>
*
*/
public class HideUntilControlSet extends PopupControlSet
implements OnItemSelectedListener, OnCancelListener,
OnDeadlineTimeSetListener {
public class HideUntilControlSet extends PopupControlSet implements OnItemSelectedListener {
private static final int SPECIFIC_DATE = -1;
private static final int EXISTING_TIME_UNSET = -2;
@ -44,8 +38,6 @@ public class HideUntilControlSet extends PopupControlSet
private int existingDateHour = EXISTING_TIME_UNSET;
private int existingDateMinutes = EXISTING_TIME_UNSET;
private boolean cancelled = false;
public HideUntilControlSet(Activity activity, int viewLayout, int displayViewLayout, int title) {
super(activity, viewLayout, displayViewLayout, title);
this.spinner = (Spinner) getView().findViewById(R.id.hideUntil);
@ -129,22 +121,27 @@ public class HideUntilControlSet extends PopupControlSet
customDate = new Date(existingDate == EXISTING_TIME_UNSET ? DateUtilities.now() : existingDate);
customDate.setSeconds(0);
final CalendarDialog calendarDialog = new CalendarDialog(activity, customDate);
calendarDialog.show();
calendarDialog.setOnDismissListener(new OnDismissListener() {
final DateAndTimeDialog dateAndTimeDialog = new DateAndTimeDialog(activity, customDate.getTime());
dateAndTimeDialog.show();
dateAndTimeDialog.setDateAndTimeDialogListener(new DateAndTimeDialogListener() {
@Override
public void onDismiss(DialogInterface arg0) {
if (!cancelled) {
setDate(calendarDialog);
public void onDateAndTimeSelected(long date) {
if (date > 0) {
customDate = new Date(date);
if (!dateAndTimeDialog.hasTime()) {
customDate.setHours(0);
customDate.setMinutes(0);
customDate.setSeconds(0);
}
customDateFinished();
}
cancelled = false;
}
});
calendarDialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
cancelled = true;
public void onDateAndTimeCancelled() {
// user canceled, restore previous choice
spinner.setSelection(previousSetting);
refreshDisplayView();
}
});
@ -162,43 +159,6 @@ public class HideUntilControlSet extends PopupControlSet
Date customDate;
private void setDate(CalendarDialog calendarDialog) {
customDate = calendarDialog.getCalendarDate();
if(existingDateHour < 0) {
existingDateHour = customDate.getHours();
existingDateMinutes= customDate.getMinutes();
}
DeadlineTimePickerDialog timePicker = new DeadlineTimePickerDialog(activity, this,
existingDateHour, existingDateMinutes,
DateUtilities.is24HourFormat(activity), true);
timePicker.setOnCancelListener(this);
timePicker.show();
}
public void onTimeSet(TimePicker view, boolean hasTime, int hourOfDay, int minute) {
if(!hasTime) {
customDate.setHours(0);
customDate.setMinutes(0);
customDate.setSeconds(0);
} else {
customDate.setHours(hourOfDay);
customDate.setMinutes(minute);
existingDateHour = hourOfDay;
existingDateMinutes = minute;
}
customDateFinished();
}
@Override
public void onCancel(DialogInterface dialog) {
// user canceled, restore previous choice
spinner.setSelection(previousSetting);
refreshDisplayView();
}
private void customDateFinished() {
HideUntilValue[] list = createHideUntilList(customDate.getTime());
adapter = new ArrayAdapter<HideUntilValue>(

@ -45,16 +45,24 @@ public class ImportanceControlSet extends TaskEditControlSet {
//else
//colors[max] = activity.getResources().getColor(android.R.color.white);
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = (int) (metrics.widthPixels / metrics.density) - 20;
int usedWidth = 0;
for(int i = min; i <= max; i++) {
final ToggleButton button = new ToggleButton(activity);
LinearLayout.LayoutParams params;
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
if (ProducteevUtilities.INSTANCE.isLoggedIn())
params = new LinearLayout.LayoutParams((int) (metrics.density * 30), (int) (metrics.density * 30));
else
params = new LinearLayout.LayoutParams((int) (metrics.density * 40), (int) (metrics.density * 40));
int dimension;
if (ProducteevUtilities.INSTANCE.isLoggedIn()) {
dimension = 38;
} else {
dimension = 38;
}
params = new LinearLayout.LayoutParams((int) (metrics.density * dimension), (int) (metrics.density * dimension));
usedWidth += dimension;
button.setLayoutParams(params);
StringBuilder label = new StringBuilder();
@ -82,6 +90,10 @@ public class ImportanceControlSet extends TaskEditControlSet {
buttons.add(button);
container.addView(button);
}
if (usedWidth > width * 2 /3 ) {
getView().findViewById(R.id.importance_label).setVisibility(View.GONE);
}
}
public void setImportance(Integer i) {

@ -119,11 +119,15 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
this(context, attrs, 0);
}
protected int getLayout() {
return R.layout.number_picker;
}
public NumberPicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs);
setOrientation(VERTICAL);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mInflater.inflate(R.layout.number_picker, this, true);
mInflater.inflate(getLayout(), this, true);
mHandler = new Handler();
mInputFilter = new NumberPickerInputFilter();
mNumberInputFilter = new NumberRangeKeyListener();
@ -276,7 +280,7 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
}
private void updateView() {
public void updateView() {
/*
* If we don't have displayed values then use the current number else
@ -446,6 +450,14 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
return mStart;
}
/**
* Override the number picker's text
* @param text
*/
public void setText(String text) {
mText.setText(text);
}
/**
* @return the current value.
*/

@ -8,6 +8,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.Button;
import com.timsu.astrid.R;
@ -52,13 +53,17 @@ public abstract class PopupControlSet extends TaskEditControlSet {
}
}
@Override
public View getDisplayView() {
return displayView;
}
protected Dialog buildDialog(int title, final DialogInterface.OnClickListener okListener, DialogInterface.OnCancelListener cancelListener) {
final Dialog d= new Dialog(activity, 0);
d.setTitle(title);
final Dialog d = new Dialog(activity, R.style.Theme_TEA_Dialog);
if (title == 0)
d.requestWindowFeature(Window.FEATURE_NO_TITLE);
else
d.setTitle(title);
View v = getView();
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

Loading…
Cancel
Save