From 2182bb81b038eb144f7ae9b464a68f0ee65f8df8 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Thu, 11 Jun 2015 11:40:46 -0500 Subject: [PATCH] Material navigation drawer --- src/main/AndroidManifest.xml | 5 +- .../activity/FilterShortcutActivity.java | 15 +- .../astrid/activity/ShortcutActivity.java | 22 +- .../todoroo/astrid/adapter/FilterAdapter.java | 225 ++++++++++-------- .../java/com/todoroo/astrid/api/Filter.java | 13 +- .../todoroo/astrid/api/FilterListItem.java | 32 ++- .../astrid/api/FilterWithCustomIntent.java | 8 - .../todoroo/astrid/api/FilterWithUpdate.java | 93 -------- .../astrid/core/BuiltInFilterExposer.java | 10 +- .../todoroo/astrid/tags/TagFilterExposer.java | 8 +- .../astrid/widget/WidgetConfigActivity.java | 13 +- .../org/tasks/filters/FilterProvider.java | 20 +- .../tasks/filters/NavigationDrawerAction.java | 85 +++++++ .../filters/NavigationDrawerSeparator.java | 11 + .../filters/NavigationDrawerSubheader.java | 15 ++ .../tasks/ui/NavigationDrawerFragment.java | 64 +++-- src/main/res/layout/filter_adapter_row.xml | 32 ++- .../res/layout/filter_adapter_separator.xml | 15 ++ .../res/layout/filter_adapter_subheader.xml | 26 ++ .../res/layout/filter_shortcut_activity.xml | 39 +++ .../res/layout/fragment_navigation_drawer.xml | 55 +---- .../res/layout/widget_config_activity.xml | 7 +- src/main/res/values-land/dimens.xml | 4 + src/main/res/values-sw360dp/dimens.xml | 4 + src/main/res/values-sw384dp/dimens.xml | 4 + src/main/res/values-sw600dp/dimens.xml | 4 + src/main/res/values-v21/fonts.xml | 4 + src/main/res/values-w820dp/dimens.xml | 7 - src/main/res/values/dimens.xml | 3 +- src/main/res/values/fonts.xml | 4 + src/main/res/values/strings.xml | 2 + src/main/res/values/styles.xml | 12 +- 32 files changed, 490 insertions(+), 371 deletions(-) delete mode 100644 src/main/java/com/todoroo/astrid/api/FilterWithUpdate.java create mode 100644 src/main/java/org/tasks/filters/NavigationDrawerAction.java create mode 100644 src/main/java/org/tasks/filters/NavigationDrawerSeparator.java create mode 100644 src/main/java/org/tasks/filters/NavigationDrawerSubheader.java create mode 100644 src/main/res/layout/filter_adapter_separator.xml create mode 100644 src/main/res/layout/filter_adapter_subheader.xml create mode 100644 src/main/res/layout/filter_shortcut_activity.xml create mode 100644 src/main/res/values-land/dimens.xml create mode 100644 src/main/res/values-sw360dp/dimens.xml create mode 100644 src/main/res/values-sw384dp/dimens.xml create mode 100644 src/main/res/values-sw600dp/dimens.xml create mode 100644 src/main/res/values-v21/fonts.xml delete mode 100644 src/main/res/values-w820dp/dimens.xml create mode 100644 src/main/res/values/fonts.xml diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 20490ad5d..43e5245d6 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -142,6 +142,7 @@ @@ -197,7 +198,9 @@ android:theme="@style/Tasks" /> - + diff --git a/src/main/java/com/todoroo/astrid/activity/FilterShortcutActivity.java b/src/main/java/com/todoroo/astrid/activity/FilterShortcutActivity.java index 855894484..33bc80e79 100644 --- a/src/main/java/com/todoroo/astrid/activity/FilterShortcutActivity.java +++ b/src/main/java/com/todoroo/astrid/activity/FilterShortcutActivity.java @@ -16,6 +16,7 @@ import android.widget.ListView; import com.todoroo.andlib.utility.DialogUtilities; import com.todoroo.astrid.adapter.FilterAdapter; import com.todoroo.astrid.api.Filter; +import com.todoroo.astrid.api.FilterListItem; import org.tasks.R; import org.tasks.filters.FilterCounter; @@ -39,18 +40,12 @@ public class FilterShortcutActivity extends InjectingListActivity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - preferences.applyTheme(); - - // Set the result to CANCELED unless a filter is selected. - setResult(RESULT_CANCELED); - + preferences.applyLightStatusBarColor(); // Set the view layout resource to use. - setContentView(R.layout.widget_config_activity); + setContentView(R.layout.filter_shortcut_activity); // set up ui - adapter = new FilterAdapter(filterProvider, filterCounter, this, getListView(), - R.layout.filter_adapter_row, true); - adapter.filterStyle = R.style.TextAppearance_FLA_Filter_Widget; + adapter = new FilterAdapter(filterProvider, filterCounter, this, getListView(), false); setListAdapter(adapter); Button button = (Button)findViewById(R.id.ok); @@ -81,7 +76,7 @@ public class FilterShortcutActivity extends InjectingListActivity { @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); - Filter item = adapter.getItem(position); + FilterListItem item = adapter.getItem(position); adapter.setSelection(item); } diff --git a/src/main/java/com/todoroo/astrid/activity/ShortcutActivity.java b/src/main/java/com/todoroo/astrid/activity/ShortcutActivity.java index 68325e8e5..2cb6c4e46 100644 --- a/src/main/java/com/todoroo/astrid/activity/ShortcutActivity.java +++ b/src/main/java/com/todoroo/astrid/activity/ShortcutActivity.java @@ -16,7 +16,6 @@ import com.todoroo.andlib.sql.QueryTemplate; import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.FilterWithCustomIntent; -import com.todoroo.astrid.api.FilterWithUpdate; import com.todoroo.astrid.data.Task; import org.tasks.R; @@ -54,9 +53,6 @@ public class ShortcutActivity extends Activity { /** token for passing a ComponentNameto launch */ public static final String TOKEN_CUSTOM_CLASS = "class"; //$NON-NLS-1$ - /** token for passing a image url*/ - public static final String TOKEN_IMAGE_URL = "imageUrl"; //$NON-NLS-1$ TODO: Remove this - /** List of the above constants for searching */ private static final String[] CUSTOM_EXTRAS = { TOKEN_SINGLE_TASK, @@ -64,8 +60,7 @@ public class ShortcutActivity extends Activity { TOKEN_FILTER_SQL, TOKEN_FILTER_VALUES, TOKEN_FILTER_VALUES_ITEM, - TOKEN_CUSTOM_CLASS, - TOKEN_IMAGE_URL + TOKEN_CUSTOM_CLASS }; // --- implementation @@ -128,14 +123,7 @@ public class ShortcutActivity extends Activity { Filter filter; if (extras.containsKey(TOKEN_CUSTOM_CLASS)) { - if (extras.containsKey(TOKEN_IMAGE_URL)) { - filter = new FilterWithUpdate(title, title, sql, values); - ((FilterWithUpdate) filter).imageUrl = extras.getString(TOKEN_IMAGE_URL); - } - else { - filter = new FilterWithCustomIntent(title, title, sql, values); - } - + filter = new FilterWithCustomIntent(title, title, sql, values); Bundle customExtras = new Bundle(); Set keys = extras.keySet(); for (String key : keys) { @@ -172,12 +160,6 @@ public class ShortcutActivity extends Activity { shortcutIntent.putExtras(customFilter.customExtras); } shortcutIntent.putExtra(TOKEN_CUSTOM_CLASS, customFilter.customTaskList.flattenToString()); - if (filter instanceof FilterWithUpdate) { - FilterWithUpdate filterWithUpdate = (FilterWithUpdate) filter; - if (filterWithUpdate.imageUrl != null) { - shortcutIntent.putExtra(TOKEN_IMAGE_URL, filterWithUpdate.imageUrl); - } - } } shortcutIntent.setAction(Intent.ACTION_VIEW); diff --git a/src/main/java/com/todoroo/astrid/adapter/FilterAdapter.java b/src/main/java/com/todoroo/astrid/adapter/FilterAdapter.java index 709e3bc95..711f41b61 100644 --- a/src/main/java/com/todoroo/astrid/adapter/FilterAdapter.java +++ b/src/main/java/com/todoroo/astrid/adapter/FilterAdapter.java @@ -10,12 +10,11 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.graphics.Color; -import android.util.DisplayMetrics; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; +import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; @@ -24,59 +23,47 @@ import com.todoroo.astrid.activity.TaskListFragment; import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.FilterListItem; -import com.todoroo.astrid.api.FilterWithUpdate; import org.tasks.R; import org.tasks.filters.FilterCounter; import org.tasks.filters.FilterProvider; +import org.tasks.filters.NavigationDrawerAction; +import org.tasks.filters.NavigationDrawerSubheader; +import org.tasks.filters.NavigationDrawerSeparator; +import org.tasks.preferences.BasicPreferences; -import static org.tasks.preferences.ResourceResolver.getData; +import java.util.List; -public class FilterAdapter extends ArrayAdapter { +import static org.tasks.preferences.ResourceResolver.getData; +import static org.tasks.preferences.ResourceResolver.getResource; - // --- style constants +public class FilterAdapter extends ArrayAdapter { - public int filterStyle = R.style.TextAppearance_FLA_Filter; + private static final int VIEW_TYPE_COUNT = FilterListItem.Type.values().length; // --- instance variables + public static final int REQUEST_SETTINGS = 10123; + private final FilterProvider filterProvider; private final FilterCounter filterCounter; - - /** parent activity */ private final Activity activity; - - /** owner listview */ - private ListView listView; - - /** display metrics for scaling icons */ - private final DisplayMetrics metrics = new DisplayMetrics(); - + private final ListView listView; + private boolean navigationDrawer; private final FilterListUpdateReceiver filterListUpdateReceiver = new FilterListUpdateReceiver(); - /** row layout to inflate */ - private final int layout; - /** layout inflater */ private final LayoutInflater inflater; - /** whether to skip Filters that launch intents instead of being real filters */ - private final boolean skipIntentFilters; - - public FilterAdapter(FilterProvider filterProvider, FilterCounter filterCounter, Activity activity, ListView listView, - int rowLayout, boolean skipIntentFilters) { + public FilterAdapter(FilterProvider filterProvider, FilterCounter filterCounter, Activity activity, ListView listView, boolean navigationDrawer) { super(activity, 0); this.filterProvider = filterProvider; this.filterCounter = filterCounter; this.activity = activity; this.listView = listView; - this.layout = rowLayout; - this.skipIntentFilters = skipIntentFilters; - - inflater = (LayoutInflater) activity.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); + this.navigationDrawer = navigationDrawer; - activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); + inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override @@ -85,11 +72,16 @@ public class FilterAdapter extends ArrayAdapter { } @Override - public void add(Filter item) { + public void add(FilterListItem item) { + if (getPosition(item) >= 0) { + return; + } + super.add(item); // load sizes - filterCounter.registerFilter(item); - notifyDataSetChanged(); + if (item instanceof Filter) { + filterCounter.registerFilter((Filter) item); + } } @Override @@ -102,24 +94,6 @@ public class FilterAdapter extends ArrayAdapter { }); } - private void addOrLookup(Filter filter) { - int index = getPosition(filter); - if (index >= 0) { - Filter existing = getItem(index); - transferImageReferences(filter, existing); - return; - } - add(filter); - } - - // Helper function: if a filter was created from serialized extras, it may not - // have the same image data we can get from the in-app broadcast - private void transferImageReferences(Filter from, Filter to) { - if (from instanceof FilterWithUpdate && to instanceof FilterWithUpdate) { - ((FilterWithUpdate) to).imageUrl = ((FilterWithUpdate) from).imageUrl; - } - } - public void refreshFilterCount() { filterCounter.refreshFilterCounts(new Runnable() { @Override @@ -129,20 +103,28 @@ public class FilterAdapter extends ArrayAdapter { }); } - public void setListView(ListView listView) { - this.listView = listView; - } - /** * Create or reuse a view */ - private View newView(View convertView, ViewGroup parent) { + private View newView(View convertView, ViewGroup parent, FilterListItem.Type viewType) { if(convertView == null) { - convertView = inflater.inflate(layout, parent, false); ViewHolder viewHolder = new ViewHolder(); + switch(viewType) { + case ITEM: + convertView = inflater.inflate(R.layout.filter_adapter_row, parent, false); + viewHolder.name = (TextView)convertView.findViewById(R.id.name); + viewHolder.icon = (ImageView) convertView.findViewById(R.id.icon); + viewHolder.size = (TextView)convertView.findViewById(R.id.size); + break; + case SEPARATOR: + convertView = inflater.inflate(R.layout.filter_adapter_separator, parent, false); + break; + case SUBHEADER: + convertView = inflater.inflate(R.layout.filter_adapter_subheader, parent, false); + viewHolder.name = (TextView) convertView.findViewById(R.id.subheader_text); + break; + } viewHolder.view = convertView; - viewHolder.name = (TextView)convertView.findViewById(R.id.name); - viewHolder.size = (TextView)convertView.findViewById(R.id.size); convertView.setTag(viewHolder); } return convertView; @@ -151,31 +133,57 @@ public class FilterAdapter extends ArrayAdapter { public static class ViewHolder { public FilterListItem item; public TextView name; + public ImageView icon; public TextView size; public View view; } - @Override public View getView(int position, View convertView, ViewGroup parent) { - convertView = newView(convertView, parent); + FilterListItem item = getItem(position); + + convertView = newView(convertView, parent, item.getItemType()); ViewHolder viewHolder = (ViewHolder) convertView.getTag(); viewHolder.item = getItem(position); - populateView(viewHolder); - - Filter selected = null; - if (activity instanceof AstridActivity) { - TaskListFragment tlf = ((AstridActivity) activity).getTaskListFragment(); - selected = tlf.getFilter(); - } - - if (selected != null && selected.equals(viewHolder.item)) { - convertView.setBackgroundColor(getData(activity, R.attr.drawer_background_selected)); + switch(item.getItemType()) { + case ITEM: + populateItem(viewHolder); + + Filter selected = null; + if (activity instanceof AstridActivity) { + TaskListFragment tlf = ((AstridActivity) activity).getTaskListFragment(); + selected = tlf.getFilter(); + } + + if (selected != null && selected.equals(viewHolder.item)) { + convertView.setBackgroundColor(getData(activity, R.attr.drawer_background_selected)); + } + break; + case SUBHEADER: + populateHeader(viewHolder); + break; + case SEPARATOR: + break; } return convertView; } + @Override + public int getViewTypeCount() { + return VIEW_TYPE_COUNT; + } + + @Override + public boolean isEnabled(int position) { + return getItem(position).getItemType() == FilterListItem.Type.ITEM; + } + + @Override + public int getItemViewType(int position) { + return getItem(position).getItemType().ordinal(); + } + @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { return getView(position, convertView, parent); @@ -215,16 +223,39 @@ public class FilterAdapter extends ArrayAdapter { } } - public void getLists() { - for (FilterListItem filter : filterProvider.getFilters()) { - if(skipIntentFilters && !(filter instanceof Filter)) { - continue; - } + public void addSubMenu(final int titleResource, List filters) { + if (filters.size() > 0) { + add(new NavigationDrawerSubheader(activity.getResources().getString(titleResource))); + } - if (filter instanceof Filter){ - addOrLookup((Filter) filter); - } + for (FilterListItem filterListItem : filters) { + add(filterListItem); + } + } + + public void populateList() { + clear(); + + add(filterProvider.getMyTasksFilter()); + + addSubMenu(R.string.filters, filterProvider.getFilters()); + + addSubMenu(R.string.tags, filterProvider.getTags()); + + addSubMenu(R.string.gtasks_GPr_header, filterProvider.getGoogleTaskFilters()); + + if (navigationDrawer) { + add(new NavigationDrawerSeparator()); + + add(new NavigationDrawerAction( + activity.getResources().getString(R.string.TLA_menu_settings), + getResource(activity, R.attr.ic_action_settings), + new Intent(activity, BasicPreferences.class), + REQUEST_SETTINGS)); } + + notifyDataSetChanged(); + filterCounter.refreshFilterCounts(new Runnable() { @Override public void run() { @@ -238,7 +269,8 @@ public class FilterAdapter extends ArrayAdapter { */ public void registerRecevier() { activity.registerReceiver(filterListUpdateReceiver, new IntentFilter(AstridApiConstants.BROADCAST_EVENT_REFRESH)); - getLists(); + + populateList(); refreshFilterCount(); } @@ -254,45 +286,40 @@ public class FilterAdapter extends ArrayAdapter { * ================================================================ views * ====================================================================== */ - private void populateView(ViewHolder viewHolder) { + private void populateItem(ViewHolder viewHolder) { FilterListItem filter = viewHolder.item; if(filter == null) { return; } viewHolder.view.setBackgroundResource(0); - viewHolder.name.setTextAppearance(activity, filterStyle); - viewHolder.name.setShadowLayer(0, 0, 0, 0); + int icon = filter.icon; + viewHolder.icon.setImageResource(icon); + viewHolder.icon.setVisibility(icon == 0 ? View.INVISIBLE : View.VISIBLE); String title = filter.listingTitle; if(!title.equals(viewHolder.name.getText())) { viewHolder.name.setText(title); } - int countInt; + int countInt = 0; if(filterCounter.containsKey(filter)) { - viewHolder.size.setVisibility(View.VISIBLE); countInt = filterCounter.get(filter); viewHolder.size.setText(Integer.toString(countInt)); - } else { - viewHolder.size.setVisibility(View.GONE); - countInt = -1; } + viewHolder.size.setVisibility(countInt > 0 ? View.VISIBLE : View.GONE); - if(countInt == 0) { - viewHolder.size.setVisibility(View.GONE); + if (selection == viewHolder.item) { + viewHolder.view.setBackgroundColor(getData(activity, R.attr.drawer_background_selected)); } + } - viewHolder.name.getLayoutParams().height = (int) (58 * metrics.density); - - if (filter.color != 0) { - viewHolder.name.setTextColor(filter.color); + private void populateHeader(ViewHolder viewHolder) { + FilterListItem filter = viewHolder.item; + if (filter == null) { + return; } - // selection - if(selection == viewHolder.item) { - // TODO: convert to color - viewHolder.view.setBackgroundColor(Color.rgb(128, 230, 0)); - } + viewHolder.name.setText(filter.listingTitle); } } diff --git a/src/main/java/com/todoroo/astrid/api/Filter.java b/src/main/java/com/todoroo/astrid/api/Filter.java index 4f2175466..e2875f642 100644 --- a/src/main/java/com/todoroo/astrid/api/Filter.java +++ b/src/main/java/com/todoroo/astrid/api/Filter.java @@ -130,14 +130,6 @@ public class Filter extends FilterListItem { // --- parcelable - /** - * {@inheritDoc} - */ - @Override - public int describeContents() { - return 0; - } - @Override public int hashCode() { final int prime = 31; @@ -177,6 +169,11 @@ public class Filter extends FilterListItem { return true; } + @Override + public Type getItemType() { + return Type.ITEM; + } + /** * {@inheritDoc} */ diff --git a/src/main/java/com/todoroo/astrid/api/FilterListItem.java b/src/main/java/com/todoroo/astrid/api/FilterListItem.java index 16230dc6f..e6e3e1877 100644 --- a/src/main/java/com/todoroo/astrid/api/FilterListItem.java +++ b/src/main/java/com/todoroo/astrid/api/FilterListItem.java @@ -17,15 +17,30 @@ import android.os.Parcelable; */ abstract public class FilterListItem implements Parcelable { + public enum Type { + ITEM(0), + SUBHEADER(1), + SEPARATOR(2); + + private int viewType; + + Type(int viewType) { + this.viewType = viewType; + } + + public int getViewType() { + return viewType; + } + } + + public abstract Type getItemType(); + /** * Title of this item displayed on the Filters page */ public String listingTitle = null; - /** - * Text Color. 0 => default color - */ - public int color = 0; + public int icon = 0; /** * Context Menu labels. The context menu will be displayed when users @@ -40,6 +55,11 @@ abstract public class FilterListItem implements Parcelable { */ public Intent contextMenuIntents[] = new Intent[0]; + @Override + public int describeContents() { + return 0; + } + // --- parcelable helpers /** @@ -48,7 +68,7 @@ abstract public class FilterListItem implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(listingTitle); - dest.writeInt(color); + dest.writeInt(icon); // write array lengths before arrays dest.writeStringArray(contextMenuLabels); @@ -60,7 +80,7 @@ abstract public class FilterListItem implements Parcelable { */ public void readFromParcel(Parcel source) { listingTitle = source.readString(); - color = source.readInt(); + icon = source.readInt(); contextMenuLabels = source.createStringArray(); contextMenuIntents = source.createTypedArray(Intent.CREATOR); diff --git a/src/main/java/com/todoroo/astrid/api/FilterWithCustomIntent.java b/src/main/java/com/todoroo/astrid/api/FilterWithCustomIntent.java index bd2a24681..6fb90e607 100644 --- a/src/main/java/com/todoroo/astrid/api/FilterWithCustomIntent.java +++ b/src/main/java/com/todoroo/astrid/api/FilterWithCustomIntent.java @@ -58,14 +58,6 @@ public class FilterWithCustomIntent extends Filter { // --- parcelable - /** - * {@inheritDoc} - */ - @Override - public int describeContents() { - return 0; - } - /** * {@inheritDoc} */ diff --git a/src/main/java/com/todoroo/astrid/api/FilterWithUpdate.java b/src/main/java/com/todoroo/astrid/api/FilterWithUpdate.java deleted file mode 100644 index 4f7034589..000000000 --- a/src/main/java/com/todoroo/astrid/api/FilterWithUpdate.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (c) 2012 Todoroo Inc - * - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.astrid.api; - - -import android.content.ContentValues; -import android.os.Parcel; -import android.os.Parcelable; - -import com.todoroo.andlib.sql.QueryTemplate; - -public class FilterWithUpdate extends FilterWithCustomIntent { - - /** - * Update image URL - */ - public String imageUrl = null; - - /** - * Update message text - */ - public String updateText = null; - - protected FilterWithUpdate() { - super(); - } - - public FilterWithUpdate(String listingTitle, String title, - QueryTemplate sqlQuery, ContentValues valuesForNewTasks) { - super(listingTitle, title, sqlQuery, valuesForNewTasks); - } - - public FilterWithUpdate(String listingTitle, String title, - String sqlQuery, ContentValues valuesForNewTasks) { - super(listingTitle, title, sqlQuery, valuesForNewTasks); - } - - // --- parcelable - - /** - * {@inheritDoc} - */ - @Override - public int describeContents() { - return 0; - } - - /** - * {@inheritDoc} - */ - @Override - public void writeToParcel(Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeString(imageUrl); - dest.writeString(updateText); - } - - @Override - public void readFromParcel(Parcel source) { - super.readFromParcel(source); - imageUrl = source.readString(); - updateText = source.readString(); - } - - /** - * Parcelable Creator Object - */ - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - - /** - * {@inheritDoc} - */ - @Override - public FilterWithUpdate createFromParcel(Parcel source) { - FilterWithUpdate item = new FilterWithUpdate(); - item.readFromParcel(source); - return item; - } - - /** - * {@inheritDoc} - */ - @Override - public FilterWithUpdate[] newArray(int size) { - return new FilterWithUpdate[size]; - } - - }; - -} diff --git a/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.java b/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.java index ceb615368..2dfc423de 100644 --- a/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.java +++ b/src/main/java/com/todoroo/astrid/core/BuiltInFilterExposer.java @@ -15,7 +15,6 @@ import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.sql.QueryTemplate; import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.astrid.api.Filter; -import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.PermaSql; import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; @@ -50,12 +49,15 @@ public final class BuiltInFilterExposer { this.preferences = preferences; } - public List getFilters() { + public Filter getMyTasksFilter() { + return getMyTasksFilter(context.getResources()); + } + + public List getFilters() { Resources r = context.getResources(); // core filters - List filters = new ArrayList<>(3); + List filters = new ArrayList<>(); - filters.add(getMyTasksFilter(r)); if (preferences.getBoolean(R.string.p_show_today_filter, true)) { filters.add(getTodayFilter(r)); } diff --git a/src/main/java/com/todoroo/astrid/tags/TagFilterExposer.java b/src/main/java/com/todoroo/astrid/tags/TagFilterExposer.java index f9bb54f1c..e83d16bf5 100644 --- a/src/main/java/com/todoroo/astrid/tags/TagFilterExposer.java +++ b/src/main/java/com/todoroo/astrid/tags/TagFilterExposer.java @@ -19,9 +19,7 @@ import com.todoroo.andlib.sql.Join; import com.todoroo.andlib.sql.QueryTemplate; import com.todoroo.astrid.actfm.TagViewFragment; import com.todoroo.astrid.api.Filter; -import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.FilterWithCustomIntent; -import com.todoroo.astrid.api.FilterWithUpdate; import com.todoroo.astrid.dao.TaskDao.TaskCriteria; import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.TagData; @@ -54,8 +52,8 @@ public class TagFilterExposer { this.tagService = tagService; } - public List getFilters() { - ArrayList list = new ArrayList<>(); + public List getFilters() { + ArrayList list = new ArrayList<>(); list.addAll(filterFromTags(tagService.getTagList())); @@ -75,7 +73,7 @@ public class TagFilterExposer { contentValues.put(TaskToTagMetadata.TAG_NAME.name, tag.getName()); contentValues.put(TaskToTagMetadata.TAG_UUID.name, tag.getUuid()); - FilterWithUpdate filter = new FilterWithUpdate(tag.getName(), + FilterWithCustomIntent filter = new FilterWithCustomIntent(tag.getName(), title, tagTemplate, contentValues); diff --git a/src/main/java/com/todoroo/astrid/widget/WidgetConfigActivity.java b/src/main/java/com/todoroo/astrid/widget/WidgetConfigActivity.java index 1c705f5b2..1e261fc94 100644 --- a/src/main/java/com/todoroo/astrid/widget/WidgetConfigActivity.java +++ b/src/main/java/com/todoroo/astrid/widget/WidgetConfigActivity.java @@ -71,11 +71,7 @@ public class WidgetConfigActivity extends InjectingListActivity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - - // Set the result to CANCELED. This will cause the widget host to cancel - // out of the widget placement if they press the back button. - setResult(RESULT_CANCELED); - + preferences.applyLightStatusBarColor(); // Set the view layout resource to use. setContentView(R.layout.widget_config_activity); @@ -99,9 +95,7 @@ public class WidgetConfigActivity extends InjectingListActivity { } // set up ui - adapter = new FilterAdapter(filterProvider, filterCounter, this, getListView(), - R.layout.filter_adapter_row, true); - adapter.filterStyle = R.style.TextAppearance_FLA_Filter_Widget; + adapter = new FilterAdapter(filterProvider, filterCounter, this, getListView(), false); setListAdapter(adapter); Button button = (Button) findViewById(R.id.ok); @@ -129,11 +123,10 @@ public class WidgetConfigActivity extends InjectingListActivity { }); } - @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); - Filter item = adapter.getItem(position); + FilterListItem item = adapter.getItem(position); adapter.setSelection(item); } diff --git a/src/main/java/org/tasks/filters/FilterProvider.java b/src/main/java/org/tasks/filters/FilterProvider.java index 7d6823976..1d9cd65a0 100644 --- a/src/main/java/org/tasks/filters/FilterProvider.java +++ b/src/main/java/org/tasks/filters/FilterProvider.java @@ -1,6 +1,6 @@ package org.tasks.filters; -import com.todoroo.astrid.api.FilterListItem; +import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.core.BuiltInFilterExposer; import com.todoroo.astrid.core.CustomFilterExposer; import com.todoroo.astrid.gtasks.GtasksFilterExposer; @@ -31,13 +31,23 @@ public class FilterProvider { this.gtasksFilterExposer = gtasksFilterExposer; } - public List getFilters() { - return new ArrayList() {{ + public Filter getMyTasksFilter() { + return builtInFilterExposer.getMyTasksFilter(); + } + + public List getFilters() { + return new ArrayList() {{ addAll(builtInFilterExposer.getFilters()); addAll(timerFilterExposer.getFilters()); addAll(customFilterExposer.getFilters()); - addAll(tagFilterExposer.getFilters()); - addAll(gtasksFilterExposer.getFilters()); }}; } + + public List getTags() { + return tagFilterExposer.getFilters(); + } + + public List getGoogleTaskFilters() { + return gtasksFilterExposer.getFilters(); + } } diff --git a/src/main/java/org/tasks/filters/NavigationDrawerAction.java b/src/main/java/org/tasks/filters/NavigationDrawerAction.java new file mode 100644 index 000000000..0386a4d45 --- /dev/null +++ b/src/main/java/org/tasks/filters/NavigationDrawerAction.java @@ -0,0 +1,85 @@ +package org.tasks.filters; + +import android.content.Intent; +import android.os.Parcel; +import android.os.Parcelable; + +import com.todoroo.astrid.api.FilterListItem; + +public class NavigationDrawerAction extends FilterListItem { + + public Intent intent; + public int requestCode; + + private NavigationDrawerAction() { + + } + + public NavigationDrawerAction(String listingTitle, int icon, Intent intent, int requestCode) { + this.listingTitle = listingTitle; + this.icon = icon; + this.intent = intent; + this.requestCode = requestCode; + } + + @Override + public Type getItemType() { + return Type.ITEM; + } + + /** + * {@inheritDoc} + */ + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeParcelable(intent, 0); + dest.writeInt(requestCode); + } + + @Override + public void readFromParcel(Parcel source) { + super.readFromParcel(source); + intent = source.readParcelable(Intent.class.getClassLoader()); + requestCode = source.readInt(); + } + + /** + * Parcelable Creator Object + */ + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + + /** + * {@inheritDoc} + */ + @Override + public NavigationDrawerAction createFromParcel(Parcel source) { + NavigationDrawerAction item = new NavigationDrawerAction(); + item.readFromParcel(source); + return item; + } + + /** + * {@inheritDoc} + */ + @Override + public NavigationDrawerAction[] newArray(int size) { + return new NavigationDrawerAction[size]; + } + }; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + NavigationDrawerAction that = (NavigationDrawerAction) o; + + return requestCode == that.requestCode; + } + + @Override + public int hashCode() { + return requestCode; + } +} diff --git a/src/main/java/org/tasks/filters/NavigationDrawerSeparator.java b/src/main/java/org/tasks/filters/NavigationDrawerSeparator.java new file mode 100644 index 000000000..93fd1ee30 --- /dev/null +++ b/src/main/java/org/tasks/filters/NavigationDrawerSeparator.java @@ -0,0 +1,11 @@ +package org.tasks.filters; + +import com.todoroo.astrid.api.FilterListItem; + +public class NavigationDrawerSeparator extends FilterListItem { + + @Override + public Type getItemType() { + return Type.SEPARATOR; + } +} diff --git a/src/main/java/org/tasks/filters/NavigationDrawerSubheader.java b/src/main/java/org/tasks/filters/NavigationDrawerSubheader.java new file mode 100644 index 000000000..88804bb7a --- /dev/null +++ b/src/main/java/org/tasks/filters/NavigationDrawerSubheader.java @@ -0,0 +1,15 @@ +package org.tasks.filters; + +import com.todoroo.astrid.api.FilterListItem; + +public class NavigationDrawerSubheader extends FilterListItem { + + public NavigationDrawerSubheader(String listingTitle) { + this.listingTitle = listingTitle; + } + + @Override + public Type getItemType() { + return Type.SUBHEADER; + } +} diff --git a/src/main/java/org/tasks/ui/NavigationDrawerFragment.java b/src/main/java/org/tasks/ui/NavigationDrawerFragment.java index 760c94e42..5336b11f1 100644 --- a/src/main/java/org/tasks/ui/NavigationDrawerFragment.java +++ b/src/main/java/org/tasks/ui/NavigationDrawerFragment.java @@ -41,11 +41,11 @@ import org.slf4j.LoggerFactory; import org.tasks.R; import org.tasks.filters.FilterCounter; import org.tasks.filters.FilterProvider; +import org.tasks.filters.NavigationDrawerAction; import org.tasks.injection.ForApplication; import org.tasks.injection.InjectingFragment; import org.tasks.location.GeofenceService; import org.tasks.preferences.AppearancePreferences; -import org.tasks.preferences.BasicPreferences; import org.tasks.preferences.Preferences; import javax.inject.Inject; @@ -63,7 +63,6 @@ public class NavigationDrawerFragment extends InjectingFragment { private static final int CONTEXT_MENU_SHORTCUT = R.string.FLA_context_shortcut; private static final int CONTEXT_MENU_INTENT = Menu.FIRST + 4; - public static final int ACTIVITY_SETTINGS = 1; public static final int REQUEST_CUSTOM_INTENT = 10; public static final int REQUEST_NEW_LIST = 4; @@ -108,7 +107,7 @@ public class NavigationDrawerFragment extends InjectingFragment { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == ACTIVITY_SETTINGS && resultCode == Activity.RESULT_OK && data != null) { + if (requestCode == FilterAdapter.REQUEST_SETTINGS && resultCode == Activity.RESULT_OK && data != null) { if (data.getBooleanExtra(ReminderPreferences.TOGGLE_GEOFENCES, false)) { if (preferences.geofencesEnabled()) { geofenceService.setupGeofences(); @@ -131,8 +130,7 @@ public class NavigationDrawerFragment extends InjectingFragment { } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false); if (atLeastLollipop()) { ((ScrimInsetsFrameLayout) layout.findViewById(R.id.scrim_layout)).setOnInsetsCallback(new ScrimInsetsFrameLayout.OnInsetsCallback() { @@ -149,19 +147,12 @@ public class NavigationDrawerFragment extends InjectingFragment { selectItem(position); } }); - layout.findViewById(R.id.settings_row).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - closeMenu(); - startActivityForResult(new Intent(getActivity(), BasicPreferences.class), ACTIVITY_SETTINGS); - } - }); mDrawerListView.setItemChecked(mCurrentSelectedPosition, true); return layout; } private void setUpList() { - adapter.setListView(mDrawerListView); + adapter = new FilterAdapter(filterProvider, filterCounter, getActivity(), mDrawerListView, true); mDrawerListView.setAdapter(adapter); registerForContextMenu(mDrawerListView); } @@ -198,14 +189,19 @@ public class NavigationDrawerFragment extends InjectingFragment { } private void selectItem(int position) { - Filter item = adapter.getItem(position); - mCurrentSelectedPosition = position; - if (mDrawerListView != null) { - mDrawerListView.setItemChecked(position, true); - } closeMenu(); - if (mCallbacks != null) { - mCallbacks.onFilterItemClicked(item); + FilterListItem item = adapter.getItem(position); + if (item instanceof Filter) { + mCurrentSelectedPosition = position; + if (mDrawerListView != null) { + mDrawerListView.setItemChecked(position, true); + } + if (mCallbacks != null) { + mCallbacks.onFilterItemClicked(item); + } + } else if (item instanceof NavigationDrawerAction) { + NavigationDrawerAction action = (NavigationDrawerAction) item; + startActivityForResult(action.intent, action.requestCode); } } @@ -213,7 +209,6 @@ public class NavigationDrawerFragment extends InjectingFragment { public void onAttach(Activity activity) { super.onAttach(activity); mCallbacks = (OnFilterItemClickedListener) activity; - adapter = new FilterAdapter(filterProvider, filterCounter, getActivity(), null, R.layout.filter_adapter_row, false); } @Override @@ -359,29 +354,30 @@ public class NavigationDrawerFragment extends InjectingFragment { } public void refresh() { - adapter.clear(); - adapter.getLists(); + adapter.populateList(); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; - Filter item = adapter.getItem(info.position); + FilterListItem item = adapter.getItem(info.position); - MenuItem menuItem = menu.add(0, CONTEXT_MENU_SHORTCUT, 0, R.string.FLA_context_shortcut); - menuItem.setIntent(ShortcutActivity.createIntent(context, item)); + if (item instanceof Filter) { + MenuItem menuItem = menu.add(0, CONTEXT_MENU_SHORTCUT, 0, R.string.FLA_context_shortcut); + menuItem.setIntent(ShortcutActivity.createIntent(context, (Filter) item)); - for(int i = 0; i < item.contextMenuLabels.length; i++) { - if(item.contextMenuIntents.length <= i) { - break; + for (int i = 0; i < item.contextMenuLabels.length; i++) { + if (item.contextMenuIntents.length <= i) { + break; + } + menuItem = menu.add(0, CONTEXT_MENU_INTENT, 0, item.contextMenuLabels[i]); + menuItem.setIntent(item.contextMenuIntents[i]); } - menuItem = menu.add(0, CONTEXT_MENU_INTENT, 0, item.contextMenuLabels[i]); - menuItem.setIntent(item.contextMenuIntents[i]); - } - if(menu.size() > 0) { - menu.setHeaderTitle(item.listingTitle); + if (menu.size() > 0) { + menu.setHeaderTitle(item.listingTitle); + } } } diff --git a/src/main/res/layout/filter_adapter_row.xml b/src/main/res/layout/filter_adapter_row.xml index 3f49f81cc..1bb0d6bc6 100644 --- a/src/main/res/layout/filter_adapter_row.xml +++ b/src/main/res/layout/filter_adapter_row.xml @@ -8,15 +8,33 @@ are defined in FilterAdapter.java --> - + + + - + + + + + diff --git a/src/main/res/layout/filter_adapter_subheader.xml b/src/main/res/layout/filter_adapter_subheader.xml new file mode 100644 index 000000000..cefbc73f9 --- /dev/null +++ b/src/main/res/layout/filter_adapter_subheader.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/res/layout/filter_shortcut_activity.xml b/src/main/res/layout/filter_shortcut_activity.xml new file mode 100644 index 000000000..af48ee8aa --- /dev/null +++ b/src/main/res/layout/filter_shortcut_activity.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + +