Updated look & feel with graphical icons, added hours:minutes to snooze dialog, and two new preferences: font size, and default deadline time

pull/14/head
Tim Su 16 years ago
parent 1617ad35b7
commit b6f44dd53a

@ -1,8 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.timsu.astrid"
android:versionCode="43"
android:versionName="1.10.4">
android:versionCode="44"
android:versionName="1.11.0">
<meta-data android:name="com.a0soft.gphone.aTrackDog.webURL"
android:value="http://www.weloveastrid.com" />
<meta-data android:name="com.a0soft.gphone.aTrackDog.testVersion"
android:value="44" />
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.INTERNET"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

@ -13,6 +13,7 @@
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:orientation="horizontal"
android:layout_width="fill_parent"

@ -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.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ToggleButton android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="18px"
android:disabledAlpha="0.3"/>
</FrameLayout>

@ -51,9 +51,11 @@
android:text="@string/importance_label"
style="@style/TextAppearance.EditEvent_Label"/>
<Spinner android:id="@+id/importance"
<LinearLayout android:id="@+id/importance_container"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content">
</LinearLayout>
<TextView android:id="@+id/estimatedDuration_label"
android:layout_width="wrap_content"

@ -23,7 +23,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:focusable="true"
android:background="@drawable/transparent_button"
android:background="@android:drawable/list_selector_background"
android:padding="6dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
@ -31,19 +32,18 @@
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:minWidth="41px"
android:paddingLeft="5dip" />
android:minWidth="41px" />
<ImageView android:id="@+id/image1"
<ImageView android:id="@+id/imageLeft"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingLeft="5dip"/>
<LinearLayout android:id="@+id/text_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:paddingLeft="5dip"
android:layout_weight="1.0"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
@ -80,5 +80,11 @@
</LinearLayout>
</LinearLayout>
<ImageView android:id="@+id/imageRight"
android:gravity="center_vertical"
android:layout_width="26px"
android:layout_height="fill_parent"
android:paddingLeft="6dip"/>
</LinearLayout>

@ -20,10 +20,11 @@
-->
<resources>
<color name="task_list_overdue">#FFFB0000</color>
<color name="task_list_overdue">#FFFB6666</color>
<color name="task_list_normal">#FFFFFFFF</color>
<color name="task_list_done">#ff777777</color>
<color name="taskList_dueDateOverdue">#ffFFBF9E</color>
<color name="taskList_dueDateOverdue">#FFFB6666</color>
<color name="taskList_dueDate">#ffF0E89E</color>
<color name="taskList_completedDate">#ff888888</color>
<color name="taskList_tags">#ff888888</color>
@ -32,9 +33,9 @@
<color name="view_table_values">#ffbbbbbb</color>
<color name="view_table_overdue">#ffff0000</color>
<color name="importance_1">#ffffffff</color>
<color name="importance_2">#ffc0c4dc</color>
<color name="importance_3">#ff7381c8</color>
<color name="importance_4">#ff446592</color>
<color name="importance_1">#ffff5555</color>
<color name="importance_2">#fffea400</color>
<color name="importance_3">#ff33a5e8</color>
<color name="importance_4">#ff808080</color>
</resources>

@ -27,10 +27,10 @@
<skip />
<!-- Importance Labels -->
<string name="importance_1">I need to do this</string>
<string name="importance_2">I really should do this</string>
<string name="importance_3">It would be nice to do this</string>
<string name="importance_4">Who cares!</string>
<string name="importance_1">!!!!</string>
<string name="importance_2">!!!</string>
<string name="importance_3">!!</string>
<string name="importance_4">!</string>
<!-- Repeat Interval Labels -->
<string name="repeat_days">Day(s)</string>
@ -197,7 +197,7 @@ If you don\'t want to see the new task right after you complete the old one, you
<string name="notify_yes">Let's do it!</string>
<string name="notify_snooze">Snooze!</string>
<string name="notify_no">No, quit.</string>
<string name="notify_snooze_title">Minutes to snooze?</string>
<string name="notify_snooze_title">Hours/minutes to snooze?</string>
<string name="delete_title">Delete</string>
<string name="delete_this_task_title">Delete this task?</string>
@ -224,15 +224,19 @@ If you don\'t want to see the new task right after you complete the old one, you
<string name="p_notif_quietEnd">notif_qend</string>
<string name="p_notif_annoy">notif_annoy</string>
<string name="key_notification_ringtone">notification_ringtone</string>
<string name="p_fontSize">font_size</string>
<string name="p_deadlineTime">deadline_time</string>
<string name="prefs_quietStart_title">Quiet Hours Start</string>
<string name="prefs_quietStart_desc">Starting hour when Astrid should be quiet (e.g. 22)</string>
<string name="prefs_quietEnd_title">Quiet Hours End</string>
<string name="prefs_quietEnd_desc">Ending hour when Astrid should be quiet (e.g. 08)</string>
<string name="prefs_annoy_title">Persistence Mode</string>
<string name="prefs_annoy_desc">
If checked, Astrid will try a bit harder to get your attention
</string>
<string name="prefs_annoy_desc">If checked, Astrid will try a bit harder to get your attention</string>
<string name="prefs_notification_title">Notification Ringtone</string>
<string name="prefs_notification_desc">Choose how Astrid alerts you!</string>
<string name="prefs_fontSize_title">Task List Font</string>
<string name="prefs_fontSize_desc">Font on the main listing page (i.e. 22)</string>
<string name="prefs_deadlineTime_title">Default Deadline Time</string>
<string name="prefs_deadlineTime_desc"># of days from now to set new deadlines (i.e. 7)</string>
</resources>

@ -29,7 +29,7 @@
</style>
<style name="TextAppearance.TaskList_Task">
<item name="android:textSize">26sp</item>
<item name="android:textSize">20sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@android:color/white</item>
</style>

@ -21,4 +21,12 @@
android:showDefault="true"
android:showSilent="true"
/>
<EditTextPreference
android:key="@string/p_fontSize"
android:title="@string/prefs_fontSize_title"
android:summary="@string/prefs_fontSize_desc" />
<EditTextPreference
android:key="@string/p_deadlineTime"
android:title="@string/prefs_deadlineTime_title"
android:summary="@string/prefs_deadlineTime_desc" />
</PreferenceScreen>

@ -28,7 +28,6 @@ import java.util.Map;
import java.util.Set;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.database.Cursor;
@ -40,7 +39,7 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
@ -55,6 +54,7 @@ import android.widget.Spinner;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import com.timsu.astrid.R;
@ -98,7 +98,7 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
// UI components
private EditText name;
private Spinner importance;
private ImportanceControlSet importance;
private TimeDurationControlSet estimatedDuration;
private TimeDurationControlSet elapsedDuration;
private TimeDurationControlSet notification;
@ -184,7 +184,7 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
append(model.getName()));
estimatedDuration.setTimeDuration(model.getEstimatedSeconds());
elapsedDuration.setTimeDuration(model.getElapsedSeconds());
importance.setSelection(model.getImportance().ordinal());
importance.setImportance(model.getImportance());
definiteDueDate.setDate(model.getDefiniteDueDate());
preferredDueDate.setDate(model.getPreferredDueDate());
hiddenUntil.setDate(model.getHiddenUntil());
@ -244,8 +244,7 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
model.setName(name.getText().toString());
model.setEstimatedSeconds(estimatedDuration.getTimeDurationInSeconds());
model.setElapsedSeconds(elapsedDuration.getTimeDurationInSeconds());
model.setImportance(Importance.values()
[importance.getSelectedItemPosition()]);
model.setImportance(importance.getImportance());
model.setDefiniteDueDate(definiteDueDate.getDate());
model.setPreferredDueDate(preferredDueDate.getDate());
model.setHiddenUntil(hiddenUntil.getDate());
@ -326,7 +325,7 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
// populate instance variables
name = (EditText)findViewById(R.id.name);
importance = (Spinner)findViewById(R.id.importance);
importance = new ImportanceControlSet(R.id.importance_container);
tagsContainer = (LinearLayout)findViewById(R.id.tags_container);
estimatedDuration = new TimeDurationControlSet(this,
R.id.estimatedDuration, 0, R.string.hour_minutes_dialog,
@ -351,11 +350,6 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
repeatValue = (Button)findViewById(R.id.repeat_value);
// individual ui component initialization
ImportanceAdapter importanceAdapter = new ImportanceAdapter(this,
android.R.layout.simple_spinner_item,
R.layout.importance_spinner_dropdown,
Importance.values());
importance.setAdapter(importanceAdapter);
ArrayAdapter<String> repeatAdapter = new ArrayAdapter<String>(
this, android.R.layout.simple_spinner_item,
RepeatInterval.getLabels(getResources()));
@ -667,58 +661,6 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
* ========================================== UI component helper classes
* ====================================================================== */
/** Adapter with custom view to display Importance with proper formatting */
private class ImportanceAdapter extends ArrayAdapter<Importance> {
private int textViewResourceId, dropDownResourceId;
private LayoutInflater inflater;
public ImportanceAdapter(Context context, int textViewResourceId,
int dropDownResourceId, Importance[] objects) {
super(context, textViewResourceId, objects);
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.textViewResourceId = textViewResourceId;
this.dropDownResourceId = dropDownResourceId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getView(position, convertView, parent, textViewResourceId, true);
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getView(position, convertView, parent, dropDownResourceId, true);
}
public View getView(int position, View convertView, ViewGroup parent,
int resource, boolean setColors) {
View view;
TextView text;
Resources r = getResources();
if (convertView == null) {
view = inflater.inflate(resource, parent, false);
} else {
view = convertView;
}
try {
text = (TextView) view;
} catch (ClassCastException e) {
Log.e("ArrayAdapter", "You must supply a resource ID for a TextView");
throw new IllegalStateException(
"ArrayAdapter requires the resource ID to be a TextView", e);
}
text.setText(r.getString(getItem(position).getLabelResource()));
if(setColors)
text.setBackgroundColor(r.getColor(getItem(position).getColorResource()));
return view;
}
}
/** Control set dealing with notification flags */
public class NotifyFlagControlSet {
private CheckBox before, during, after;
@ -751,6 +693,54 @@ public class TaskEdit extends TaskModificationTabbedActivity<TaskModelForEdit> {
}
}
/** Control set dealing with importance */
public class ImportanceControlSet {
private List<CompoundButton> buttons = new LinkedList<CompoundButton>();
public ImportanceControlSet(int containerId) {
LinearLayout layout = (LinearLayout)findViewById(containerId);
Resources r = getResources();
for(Importance i : Importance.values()) {
final ToggleButton button = new ToggleButton(TaskEdit.this);
button.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1));
button.setTextColor(r.getColor(i.getColorResource()));
button.setTextOff(r.getString(i.getLabelResource()));
button.setTextOn(r.getString(i.getLabelResource()));
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setImportance((Importance)button.getTag());
}
});
button.setTag(i);
buttons.add(button);
layout.addView(button);
}
}
public void setImportance(Importance i) {
for(CompoundButton b : buttons) {
if(b.getTag() == i) {
b.setTextSize(24);
b.setChecked(true);
} else {
b.setTextSize(16);
b.setChecked(false);
}
}
}
public Importance getImportance() {
for(CompoundButton b : buttons)
if(b.isChecked())
return (Importance)b.getTag();
return Importance.DEFAULT;
}
}
/** Control set dealing with "blocking on" */
public class BlockingOnControlSet {

@ -46,6 +46,7 @@ import com.timsu.astrid.data.tag.TagModelForView;
import com.timsu.astrid.data.task.TaskController;
import com.timsu.astrid.data.task.TaskModelForList;
import com.timsu.astrid.utilities.DateUtilities;
import com.timsu.astrid.utilities.Preferences;
/** Adapter for displaying a list of TaskModelForList entities
*
@ -105,7 +106,8 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
final TextView dueDateView = ((TextView)view.findViewById(R.id.text_dueDate));
final TextView tagsView = ((TextView)view.findViewById(R.id.text_tags));
final CheckBox progress = ((CheckBox)view.findViewById(R.id.cb1));
final ImageView timer = ((ImageView)view.findViewById(R.id.image1));
final ImageView timer = ((ImageView)view.findViewById(R.id.imageLeft));
final ImageView importance = ((ImageView)view.findViewById(R.id.imageRight));
boolean hasProperties = false;
view.setTag(task);
@ -115,8 +117,12 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
if(task.getHiddenUntil() != null && task.getHiddenUntil().after(new Date()))
nameValue = "(" + r.getString(R.string.taskList_hiddenPrefix) + ") " + nameValue;
name.setText(nameValue);
Integer fontSizePreference = Preferences.getTaskListFontSize(getContext());
if(fontSizePreference != null && fontSizePreference > 0)
name.setTextSize(fontSizePreference);
if(task.getTimerStart() != null)
timer.setImageDrawable(r.getDrawable(R.drawable.ic_dialog_time));
importance.setImageDrawable(r.getDrawable(task.getImportance().getIconResource()));
progress.setChecked(task.isTaskCompleted());
// due date / completion date
@ -241,7 +247,7 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
}
private void setTaskProgress(final TaskModelForList task, View view, int progress) {
final ImageView timer = ((ImageView)view.findViewById(R.id.image1));
final ImageView timer = ((ImageView)view.findViewById(R.id.imageLeft));
task.setProgressPercentage(progress);
hooks.getTaskController().saveTask(task);

@ -10,9 +10,8 @@ import android.os.Bundle;
import com.timsu.astrid.R;
import com.timsu.astrid.utilities.Constants;
import com.timsu.astrid.utilities.Notifications;
import com.timsu.astrid.widget.NumberPicker;
import com.timsu.astrid.widget.NumberPickerDialog;
import com.timsu.astrid.widget.NumberPickerDialog.OnNumberPickedListener;
import com.timsu.astrid.widget.NNumberPickerDialog;
import com.timsu.astrid.widget.NNumberPickerDialog.OnNNumberPickedListener;
public class TaskViewNotifier extends TaskView {
@ -80,18 +79,19 @@ public class TaskViewNotifier extends TaskView {
private void snoozeAlert() {
Resources r = getResources();
// ask how long
new NumberPickerDialog(this,
new OnNumberPickedListener() {
@Override
public void onNumberPicked(NumberPicker view, int number) {
new NNumberPickerDialog(this, new OnNNumberPickedListener() {
public void onNumbersPicked(int[] values) {
int snoozeSeconds = values[0] * 3600 + values[1] * 60;
Notifications.createSnoozeAlarm(TaskViewNotifier.this,
model.getTaskIdentifier(), number * 60, flags,
model.getTaskIdentifier(), snoozeSeconds, flags,
repeatInterval);
setResult(Constants.RESULT_GO_HOME);
TaskList.shouldCloseInstance = true;
finish();
}
}, r.getString(R.string.notify_snooze_title), 10, 10, 0, 120).show();
}, r.getString(R.string.notify_snooze_title),
new int[] {0, 0}, new int[] {1, 5}, new int[] {0, 0},
new int[] {99, 59}, new String[] {":", null}).show();
}
}

@ -24,21 +24,23 @@ import com.timsu.astrid.R;
public enum Importance {
// MOST IMPORTANT
LEVEL_1(R.string.importance_1, R.color.importance_1),
LEVEL_2(R.string.importance_2, R.color.importance_2),
LEVEL_3(R.string.importance_3, R.color.importance_3),
LEVEL_4(R.string.importance_4, R.color.importance_4),
LEVEL_1(R.string.importance_1, R.color.importance_1, R.drawable.bullet_red),
LEVEL_2(R.string.importance_2, R.color.importance_2, R.drawable.bullet_orange),
LEVEL_3(R.string.importance_3, R.color.importance_3, R.drawable.bullet_blue),
LEVEL_4(R.string.importance_4, R.color.importance_4, R.drawable.bullet_white),
// LEAST IMPORTANT
;
int label;
int color;
int icon;
public static final Importance DEFAULT = LEVEL_3;
private Importance(int label, int color) {
private Importance(int label, int color, int icon) {
this.label = label;
this.color = color;
this.icon = icon;
}
public int getLabelResource() {
@ -48,4 +50,8 @@ public enum Importance {
public int getColorResource() {
return color;
}
public int getIconResource() {
return icon;
}
}

@ -192,7 +192,7 @@ public abstract class AbstractTaskModel extends AbstractModel {
System.currentTimeMillis()) {
return R.color.task_list_overdue;
} else {
return getImportance().getColorResource();
return R.color.task_list_normal;
}
}

@ -85,6 +85,8 @@ public class TaskModelForList extends AbstractTaskModel {
int secondsLeft = getEstimatedSeconds() - getElapsedSeconds();
if(secondsLeft > 0)
weight += secondsLeft / 120;
else
weight += 3600 / 120; // default if no time set
// looming absolute deadline
if(getDefiniteDueDate() != null) {

@ -18,10 +18,6 @@ public class Preferences {
// default values
private static final boolean DEFAULT_PERSISTENCE_MODE = true;
private static SharedPreferences getPrefs(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
/** Set preference defaults, if unset. called at startup */
public static void setPreferenceDefaults(Context context) {
SharedPreferences prefs = getPrefs(context);
@ -32,6 +28,12 @@ public class Preferences {
editor.putBoolean(r.getString(R.string.p_notif_annoy),
DEFAULT_PERSISTENCE_MODE);
}
if(!prefs.contains(r.getString(R.string.p_fontSize))) {
editor.putString(r.getString(R.string.p_fontSize), "20");
}
if(!prefs.contains(r.getString(R.string.p_deadlineTime))) {
editor.putString(r.getString(R.string.p_deadlineTime), "7");
}
editor.commit();
}
@ -61,28 +63,12 @@ public class Preferences {
/** returns hour at which quiet hours start, or null if not set */
public static Integer getQuietHourStart(Context context) {
Resources r = context.getResources();
String value = getPrefs(context).getString(r.getString(
R.string.p_notif_quietStart), "");
try {
return Integer.parseInt(value);
} catch (Exception e) {
return null;
}
return getIntegerValue(context, R.string.p_notif_quietStart);
}
/** returns hour at which quiet hours start, or null if not set */
public static Integer getQuietHourEnd(Context context) {
Resources r = context.getResources();
String value = getPrefs(context).getString(r.getString(
R.string.p_notif_quietEnd), "");
try {
return Integer.parseInt(value);
} catch (Exception e) {
return null;
}
return getIntegerValue(context, R.string.p_notif_quietEnd);
}
/** Get notification ringtone, or null if not set */
@ -104,4 +90,31 @@ public class Preferences {
return getPrefs(context).getBoolean(r.getString(
R.string.p_notif_annoy), DEFAULT_PERSISTENCE_MODE);
}
/** returns the font size user wants on the front page */
public static Integer getTaskListFontSize(Context context) {
return getIntegerValue(context, R.string.p_fontSize);
}
/** Return # of days from now to set deadlines by default */
public static Integer getDefaultDeadlineDays(Context context) {
return getIntegerValue(context, R.string.p_deadlineTime);
}
// --- helper methods
private static SharedPreferences getPrefs(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
private static Integer getIntegerValue(Context context, int keyResource) {
Resources r = context.getResources();
String value = getPrefs(context).getString(r.getString(keyResource), "");
try {
return Integer.parseInt(value);
} catch (Exception e) {
return null;
}
}
}

@ -33,6 +33,8 @@ import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TimePicker;
import com.timsu.astrid.utilities.Preferences;
public class DateControlSet implements OnTimeSetListener,
OnDateSetListener, View.OnClickListener {
@ -68,7 +70,10 @@ public class DateControlSet implements OnTimeSetListener,
this.date = newDate;
if(newDate == null) {
date = new Date();
date.setTime(date.getTime() + 24*3600*1000);
Integer days = Preferences.getDefaultDeadlineDays(activity);
if(days == null)
days = 1;
date.setTime(date.getTime() + days*24*3600*1000);
date.setMinutes(0);
}

Loading…
Cancel
Save