From 766efc96ab032834f2e161ad6e570475491c1d9b Mon Sep 17 00:00:00 2001 From: Josh Dover Date: Tue, 4 Mar 2014 15:15:44 -0800 Subject: [PATCH] Bug 975055 - Show previous filter for back row item. r=lucasr --- .../android/base/home/PanelBackItemView.java | 30 +++++++ mobile/android/base/home/PanelGridView.java | 7 ++ mobile/android/base/home/PanelLayout.java | 49 ++++++++++- mobile/android/base/home/PanelListView.java | 7 ++ .../android/base/home/PanelViewAdapter.java | 82 ++++++++++++++++++- .../base/home/PanelViewUrlHandler.java | 20 +++++ mobile/android/base/moz.build | 1 + .../base/resources/layout/panel_back_item.xml | 19 +++++ 8 files changed, 210 insertions(+), 5 deletions(-) create mode 100644 mobile/android/base/home/PanelBackItemView.java create mode 100644 mobile/android/base/resources/layout/panel_back_item.xml diff --git a/mobile/android/base/home/PanelBackItemView.java b/mobile/android/base/home/PanelBackItemView.java new file mode 100644 index 00000000000..52c747e9b47 --- /dev/null +++ b/mobile/android/base/home/PanelBackItemView.java @@ -0,0 +1,30 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.gecko.home; + +import org.mozilla.gecko.R; + +import android.content.Context; +import android.view.LayoutInflater; +import android.widget.LinearLayout; +import android.widget.TextView; + +class PanelBackItemView extends LinearLayout { + private final TextView title; + + public PanelBackItemView(Context context) { + super(context); + + LayoutInflater.from(context).inflate(R.layout.panel_back_item, this); + setOrientation(HORIZONTAL); + + title = (TextView) findViewById(R.id.title); + } + + public void updateFromFilter(String filter) { + title.setText(filter); + } +} diff --git a/mobile/android/base/home/PanelGridView.java b/mobile/android/base/home/PanelGridView.java index 7b1f89f353d..4f5f03401f4 100644 --- a/mobile/android/base/home/PanelGridView.java +++ b/mobile/android/base/home/PanelGridView.java @@ -13,6 +13,7 @@ import org.mozilla.gecko.home.HomeConfig.ItemHandler; import org.mozilla.gecko.home.HomeConfig.ViewConfig; import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; import org.mozilla.gecko.home.PanelLayout.DatasetBacked; +import org.mozilla.gecko.home.PanelLayout.FilterManager; import org.mozilla.gecko.home.PanelLayout.PanelView; import android.content.Context; @@ -57,6 +58,12 @@ public class PanelGridView extends GridView mUrlHandler.setOnUrlOpenListener(listener); } + @Override + public void setFilterManager(FilterManager filterManager) { + mAdapter.setFilterManager(filterManager); + mUrlHandler.setFilterManager(filterManager); + } + private class PanelGridItemClickListener implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { diff --git a/mobile/android/base/home/PanelLayout.java b/mobile/android/base/home/PanelLayout.java index ce3640d4402..f79f32e1714 100644 --- a/mobile/android/base/home/PanelLayout.java +++ b/mobile/android/base/home/PanelLayout.java @@ -20,7 +20,6 @@ import android.view.KeyEvent; import android.view.View; import android.widget.FrameLayout; -import java.util.Deque; import java.util.EnumSet; import java.util.LinkedList; import java.util.Map; @@ -74,6 +73,7 @@ abstract class PanelLayout extends FrameLayout { */ public interface DatasetBacked { public void setDataset(Cursor cursor); + public void setFilterManager(FilterManager manager); } /** @@ -143,6 +143,12 @@ abstract class PanelLayout extends FrameLayout { public void setOnUrlOpenListener(OnUrlOpenListener listener); } + public interface FilterManager { + public String getPreviousFilter(); + public boolean canGoBack(); + public void goBack(); + } + public PanelLayout(Context context, PanelConfig panelConfig, DatasetHandler datasetHandler, OnUrlOpenListener urlOpenListener) { super(context); mViewStateMap = new WeakHashMap(); @@ -217,6 +223,11 @@ abstract class PanelLayout extends FrameLayout { ((PanelView) view).setOnUrlOpenListener(new PanelUrlOpenListener(state)); view.setOnKeyListener(new PanelKeyListener(state)); + if (view instanceof DatasetBacked) { + DatasetBacked datasetBacked = (DatasetBacked) view; + datasetBacked.setFilterManager(new PanelFilterManager(state)); + } + return view; } @@ -268,7 +279,7 @@ abstract class PanelLayout extends FrameLayout { */ protected static class ViewState { private final ViewConfig mViewConfig; - private Deque mFilterStack; + private LinkedList mFilterStack; public ViewState(ViewConfig viewConfig) { mViewConfig = viewConfig; @@ -289,6 +300,17 @@ abstract class PanelLayout extends FrameLayout { } } + /** + * Get the previous filter that this view was displaying, or null if none. + */ + public String getPreviousFilter() { + if (!canPopFilter()) { + return null; + } + + return mFilterStack.get(1); + } + /** * Adds a filter to the history stack for this view. */ @@ -383,4 +405,27 @@ abstract class PanelLayout extends FrameLayout { return false; } } + + private class PanelFilterManager implements FilterManager { + private final ViewState mViewState; + + public PanelFilterManager(ViewState viewState) { + mViewState = viewState; + } + + @Override + public String getPreviousFilter() { + return mViewState.getPreviousFilter(); + } + + @Override + public boolean canGoBack() { + return mViewState.canPopFilter(); + } + + @Override + public void goBack() { + popFilterOnView(mViewState); + } + } } diff --git a/mobile/android/base/home/PanelListView.java b/mobile/android/base/home/PanelListView.java index 50c32c98d5b..68f91f26803 100644 --- a/mobile/android/base/home/PanelListView.java +++ b/mobile/android/base/home/PanelListView.java @@ -12,6 +12,7 @@ import org.mozilla.gecko.home.HomeConfig.ItemHandler; import org.mozilla.gecko.home.HomeConfig.ViewConfig; import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; import org.mozilla.gecko.home.PanelLayout.DatasetBacked; +import org.mozilla.gecko.home.PanelLayout.FilterManager; import org.mozilla.gecko.home.PanelLayout.PanelView; import android.content.Context; @@ -53,6 +54,12 @@ public class PanelListView extends HomeListView mUrlHandler.setOnUrlOpenListener(listener); } + @Override + public void setFilterManager(FilterManager filterManager) { + mAdapter.setFilterManager(filterManager); + mUrlHandler.setFilterManager(filterManager); + } + private class PanelListItemClickListener implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { diff --git a/mobile/android/base/home/PanelViewAdapter.java b/mobile/android/base/home/PanelViewAdapter.java index c513e4a4200..d310de853d0 100644 --- a/mobile/android/base/home/PanelViewAdapter.java +++ b/mobile/android/base/home/PanelViewAdapter.java @@ -6,6 +6,9 @@ package org.mozilla.gecko.home; import org.mozilla.gecko.home.HomeConfig.ItemType; +import org.mozilla.gecko.home.PanelLayout.FilterManager; + +import org.mozilla.gecko.R; import android.content.Context; import android.database.Cursor; @@ -14,8 +17,12 @@ import android.view.View; import android.view.ViewGroup; class PanelViewAdapter extends CursorAdapter { + private static final int VIEW_TYPE_ITEM = 0; + private static final int VIEW_TYPE_BACK = 1; + private final Context mContext; private final ItemType mItemType; + private FilterManager mFilterManager; public PanelViewAdapter(Context context, ItemType itemType) { super(context, null, 0); @@ -23,14 +30,83 @@ class PanelViewAdapter extends CursorAdapter { mItemType = itemType; } + public void setFilterManager(FilterManager manager) { + mFilterManager = manager; + } + @Override - public void bindView(View view, Context context, Cursor cursor) { + public final int getViewTypeCount() { + return 2; + } + + @Override + public int getCount() { + return super.getCount() + (isShowingBack() ? 1 : 0); + } + + @Override + public int getItemViewType(int position) { + if (isShowingBack() && position == 0) { + return VIEW_TYPE_BACK; + } else { + return VIEW_TYPE_ITEM; + } + } + + @Override + public final View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = newView(parent.getContext(), position, parent); + } + + bindView(convertView, position); + return convertView; + } + + private View newView(Context context, int position, ViewGroup parent) { + if (getItemViewType(position) == VIEW_TYPE_BACK) { + return new PanelBackItemView(context); + } else { + return PanelItemView.create(context, mItemType); + } + } + + private void bindView(View view, int position) { + if (isShowingBack()) { + if (position == 0) { + final PanelBackItemView item = (PanelBackItemView) view; + item.updateFromFilter(mFilterManager.getPreviousFilter()); + return; + } + + position--; + } + + final Cursor cursor = getCursor(position); final PanelItemView item = (PanelItemView) view; item.updateFromCursor(cursor); } + private boolean isShowingBack() { + return (mFilterManager != null ? mFilterManager.canGoBack() : false); + } + + private final Cursor getCursor(int position) { + final Cursor cursor = getCursor(); + if (cursor == null || !cursor.moveToPosition(position)) { + throw new IllegalStateException("Couldn't move cursor to position " + position); + } + + return cursor; + } + @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - return PanelItemView.create(mContext, mItemType); + public final void bindView(View view, Context context, Cursor cursor) { + // Do nothing. + } + + @Override + public final View newView(Context context, Cursor cursor, ViewGroup parent) { + return null; } } diff --git a/mobile/android/base/home/PanelViewUrlHandler.java b/mobile/android/base/home/PanelViewUrlHandler.java index a2669de51e3..c7f64383363 100644 --- a/mobile/android/base/home/PanelViewUrlHandler.java +++ b/mobile/android/base/home/PanelViewUrlHandler.java @@ -9,6 +9,7 @@ import org.mozilla.gecko.db.BrowserContract.HomeItems; import org.mozilla.gecko.home.HomeConfig.ItemHandler; import org.mozilla.gecko.home.HomeConfig.ViewConfig; import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; +import org.mozilla.gecko.home.PanelLayout.FilterManager; import android.database.Cursor; @@ -17,6 +18,7 @@ import java.util.EnumSet; class PanelViewUrlHandler { private final ViewConfig mViewConfig; private OnUrlOpenListener mUrlOpenListener; + private FilterManager mFilterManager; public PanelViewUrlHandler(ViewConfig viewConfig) { mViewConfig = viewConfig; @@ -26,7 +28,25 @@ class PanelViewUrlHandler { mUrlOpenListener = listener; } + public void setFilterManager(FilterManager manager) { + mFilterManager = manager; + } + + /** + * If item at this position is a back item, perform the go back action via the + * {@code FilterManager}. Otherwise, prepare the url to be opened by the + * {@code OnUrlOpenListener}. + */ public void openUrlAtPosition(Cursor cursor, int position) { + if (mFilterManager != null && mFilterManager.canGoBack()) { + if (position == 0) { + mFilterManager.goBack(); + return; + } + + position--; + } + if (cursor == null || !cursor.moveToPosition(position)) { throw new IllegalStateException("Couldn't move cursor to position " + position); } diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build index 395f63e7446..2191e1f231f 100644 --- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -246,6 +246,7 @@ gbjar.sources += [ 'home/LastTabsPanel.java', 'home/MostRecentPanel.java', 'home/MultiTypeCursorAdapter.java', + 'home/PanelBackItemView.java', 'home/PanelGridView.java', 'home/PanelItemView.java', 'home/PanelLayout.java', diff --git a/mobile/android/base/resources/layout/panel_back_item.xml b/mobile/android/base/resources/layout/panel_back_item.xml new file mode 100644 index 00000000000..0c6d50bfcd5 --- /dev/null +++ b/mobile/android/base/resources/layout/panel_back_item.xml @@ -0,0 +1,19 @@ + + + + + + + +