Bug 826075 - Show an indicator on pinned sites. r=mfinkle, r=sriram, a=bajaj
authorWes Johnston <wjohnston@mozilla.com>
Wed, 09 Jan 2013 14:07:32 -0800
changeset 127285 82551fd7085bc08e588a30f279a143e9bc24a814
parent 127284 a585490ca84c39e438f7f1ad2d7f9f6b6fb4e6ed
child 127286 9d9abb80b40c05497589f8fb278ab0b759b11082
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle, sriram, bajaj
bugs826075
milestone20.0a2
Bug 826075 - Show an indicator on pinned sites. r=mfinkle, r=sriram, a=bajaj
mobile/android/base/AboutHomeContent.java
mobile/android/base/db/BrowserDB.java
mobile/android/base/resources/layout/abouthome_topsite_item.xml
mobile/android/base/resources/values/colors.xml
mobile/android/base/resources/values/dimens.xml
mobile/android/base/resources/values/styles.xml
--- a/mobile/android/base/AboutHomeContent.java
+++ b/mobile/android/base/AboutHomeContent.java
@@ -30,16 +30,18 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.PathShape;
 import android.graphics.Path;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
@@ -118,16 +120,17 @@ public class AboutHomeContent extends Sc
     protected AboutHomeSection mAddons;
     protected AboutHomeSection mLastTabs;
     protected AboutHomeSection mRemoteTabs;
 
     private View.OnClickListener mRemoteTabClickListener;
 
     private static Rect sIconBounds;
     private static TextAppearanceSpan sSubTitleSpan;
+    private static Drawable sPinDrawable = null;
 
     public interface UriLoadCallback {
         public void callback(String uriSpec);
     }
 
     public interface VoidCallback {
         public void callback();
     }
@@ -844,17 +847,46 @@ public class AboutHomeContent extends Sc
         public int getSelectedPosition() {
             return mSelected;
         }
     }
 
     private class TopSitesViewHolder {
         public TextView titleView = null;
         public ImageView thumbnailView = null;
+        public ImageView pinnedView = null;
         public String url = null;
+
+        public TopSitesViewHolder(View v) {
+            titleView = (TextView) v.findViewById(R.id.title);
+            thumbnailView = (ImageView) v.findViewById(R.id.thumbnail);
+            pinnedView = (ImageView) v.findViewById(R.id.pinned);
+        }
+
+        private Drawable getPinDrawable() {
+            if (sPinDrawable == null) {
+                int size = mContext.getResources().getDimensionPixelSize(R.dimen.abouthome_topsite_pinsize);
+
+                // Draw a little triangle in the upper right corner
+                Path path = new Path();
+                path.moveTo(0, 0);
+                path.lineTo(size, 0);
+                path.lineTo(size, size);
+                path.close();
+
+                sPinDrawable = new ShapeDrawable(new PathShape(path, size, size));
+                Paint p = ((ShapeDrawable) sPinDrawable).getPaint();
+                p.setColor(mContext.getResources().getColor(R.color.abouthome_topsite_pin));
+            }
+            return sPinDrawable;
+        }
+
+        public void setPinned(boolean aPinned) {
+            pinnedView.setBackgroundDrawable(aPinned ? getPinDrawable() : null);
+        }
     }
 
     public class TopSitesCursorAdapter extends SimpleCursorAdapter {
         public TopSitesCursorAdapter(Context context, int layout, Cursor c,
                                      String[] from, int[] to) {
             super(context, layout, c, from, to);
         }
 
@@ -865,52 +897,54 @@ public class AboutHomeContent extends Sc
 
         @Override
         protected void onContentChanged () {
             // Don't do anything. We don't want to regenerate every time
             // our history database is updated.
             return;
         }
 
-        private View buildView(String url, String title, View convertView) {
+        private View buildView(String url, String title, boolean pinned, View convertView) {
             TopSitesViewHolder viewHolder;
             if (convertView == null) {
                 convertView = mInflater.inflate(R.layout.abouthome_topsite_item, null);
 
-                viewHolder = new TopSitesViewHolder();
-                viewHolder.titleView = (TextView) convertView.findViewById(R.id.title);
-                viewHolder.thumbnailView = (ImageView) convertView.findViewById(R.id.thumbnail);
+                viewHolder = new TopSitesViewHolder(convertView);
                 convertView.setTag(viewHolder);
             } else {
                 viewHolder = (TopSitesViewHolder) convertView.getTag();
             }
 
             viewHolder.titleView.setVisibility(TextUtils.isEmpty(title) ? View.INVISIBLE : View.VISIBLE);
             viewHolder.titleView.setText(title);
             viewHolder.url = url;
+            viewHolder.setPinned(pinned);
 
             // Force the view to fit inside this slot in the grid
             convertView.setLayoutParams(new AbsListView.LayoutParams(mTopSitesGrid.getColumnWidth(),
                         Math.round(mTopSitesGrid.getColumnWidth()*ThumbnailHelper.THUMBNAIL_ASPECT_RATIO)));
 
             return convertView;
         }
 
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             String url = "";
             String title = "";
+            boolean pinned = false;
 
             Cursor c = getCursor();
             c.moveToPosition(position);
             if (!c.isAfterLast()) {
                 url = c.getString(c.getColumnIndex(URLColumns.URL));
                 title = c.getString(c.getColumnIndex(URLColumns.TITLE));
+                pinned = ((TopSitesCursorWrapper)c).isPinned();
             }
-            return buildView(url, title, convertView);
+
+            return buildView(url, title, pinned, convertView);
         }
     }
 
     private void clearThumbnail(TopSitesViewHolder holder) {
         holder.titleView.setText("");
         holder.url = "";
         holder.thumbnailView.setImageResource(R.drawable.abouthome_thumbnail_bg);
         holder.thumbnailView.setScaleType(ImageView.ScaleType.FIT_CENTER);
@@ -919,16 +953,17 @@ public class AboutHomeContent extends Sc
     public void unpinAllSites() {
         final ContentResolver resolver = mActivity.getContentResolver();
 
         // Clear the view quickly to make things appear responsive
         for (int i = 0; i < mTopSitesGrid.getChildCount(); i++) {
             View v = mTopSitesGrid.getChildAt(i);
             TopSitesViewHolder holder = (TopSitesViewHolder) v.getTag();
             clearThumbnail(holder);
+            holder.setPinned(false);
         }
 
         (new GeckoAsyncTask<Void, Void, Void>(GeckoApp.mAppContext, GeckoAppShell.getHandler()) {
             @Override
             public Void doInBackground(Void... params) {
                 ContentResolver resolver = mActivity.getContentResolver();
                 BrowserDB.unpinAllSites(resolver);
                 return null;
@@ -940,16 +975,17 @@ public class AboutHomeContent extends Sc
             }
         }).execute();
     }
 
     public void unpinSite() {
         final int position = mTopSitesGrid.getSelectedPosition();
         View v = mTopSitesGrid.getChildAt(position);
         TopSitesViewHolder holder = (TopSitesViewHolder) v.getTag();
+        holder.setPinned(false);
 
         // Quickly update the view so that there isn't as much lag between the request and response
         clearThumbnail(holder);
         (new GeckoAsyncTask<Void, Void, Void>(GeckoApp.mAppContext, GeckoAppShell.getHandler()) {
             @Override
             public Void doInBackground(Void... params) {
                 ContentResolver resolver = mActivity.getContentResolver();
                 BrowserDB.unpinSite(resolver, position);
@@ -965,16 +1001,18 @@ public class AboutHomeContent extends Sc
 
     public void pinSite() {
         final int position = mTopSitesGrid.getSelectedPosition();
         View v = mTopSitesGrid.getChildAt(position);
 
         TopSitesViewHolder holder = (TopSitesViewHolder) v.getTag();
         final String url = holder.url;
         final String title = holder.titleView.getText().toString();
+        holder.setPinned(true);
+
         // update the database on a background thread
         (new GeckoAsyncTask<Void, Void, Void>(GeckoApp.mAppContext, GeckoAppShell.getHandler()) {
             @Override
             public Void doInBackground(Void... params) {
                 final ContentResolver resolver = mActivity.getContentResolver();
                 BrowserDB.pinSite(resolver, url, (title == null || TextUtils.isEmpty(title) ? url : title), position);
                 return null;
             }
--- a/mobile/android/base/db/BrowserDB.java
+++ b/mobile/android/base/db/BrowserDB.java
@@ -325,16 +325,20 @@ public class BrowserDB {
 
         public PinnedSite getPinnedSite(int position) {
             if (!hasPinnedSites()) {
                 return null;
             }
             return mPinnedSites.get(position);
         }
 
+        public boolean isPinned() {
+            return mPinnedSites.get(mIndex) != null;
+        }
+
         private int getPinnedBefore(int position) {
             int numFound = 0;
             if (!hasPinnedSites()) {
                 return numFound;
             }
 
             for (int i = 0; i < position; i++) {
                 if (mPinnedSites.get(i) != null) {
--- a/mobile/android/base/resources/layout/abouthome_topsite_item.xml
+++ b/mobile/android/base/resources/layout/abouthome_topsite_item.xml
@@ -8,9 +8,12 @@
 
     <ImageView
           android:id="@+id/thumbnail"
           style="@style/AboutHome.Thumbnail.Image"/>
 
     <TextView android:id="@+id/title"
               style="@style/AboutHome.Thumbnail.Label"/>
 
+    <ImageView android:id="@+id/pinned"
+               style="@style/AboutHome.Thumbnail.Pinned"/>
+
 </RelativeLayout>
--- a/mobile/android/base/resources/values/colors.xml
+++ b/mobile/android/base/resources/values/colors.xml
@@ -14,10 +14,11 @@
   <color name="identity_identified">#B7D46A</color>
   <color name="url_bar_text_highlight">#FFFF9500</color>
   <color name="url_bar_text_highlight_pb">#FFD06BFF</color>
   <color name="suggestion_primary">#dddddd</color>
   <color name="suggestion_pressed">#bbbbbb</color>
   <color name="tab_indicator_unselected">@android:color/transparent</color>
   <color name="tab_indicator_unselected_focused">#34FF9500</color>
   <color name="abouthome_topsite_shadow">#1000</color>
+  <color name="abouthome_topsite_pin">#55000000</color>
 </resources>
 
--- a/mobile/android/base/resources/values/dimens.xml
+++ b/mobile/android/base/resources/values/dimens.xml
@@ -6,16 +6,17 @@
 <resources>
 
     <dimen name="abouthome_addon_icon_size">32dp</dimen>
     <dimen name="abouthome_content_top_sites_item_height">110dp</dimen>
     <dimen name="abouthome_gutter_small">0dp</dimen>
     <dimen name="abouthome_gutter_large">0dp</dimen>
     <dimen name="abouthome_icon_crop">-14dp</dimen>
     <dimen name="abouthome_icon_radius">2dp</dimen>
+    <dimen name="abouthome_topsite_pinsize">20dp</dimen>
     <dimen name="abouthome_topsite_shadow_offset">2dp</dimen>
     <dimen name="autocomplete_min_width">200dp</dimen>
     <dimen name="autocomplete_row_height">32dp</dimen>
     <dimen name="awesomebar_header_row_height">20dp</dimen>
     <dimen name="awesomebar_row_height">48dp</dimen>
     <dimen name="awesomebar_row_favicon_size_small">16dp</dimen>
     <dimen name="awesomebar_row_favicon_size_large">32dp</dimen>
     <dimen name="awesomebar_row_favicon_bg">32dp</dimen>
--- a/mobile/android/base/resources/values/styles.xml
+++ b/mobile/android/base/resources/values/styles.xml
@@ -236,16 +236,25 @@
       <item name="android:gravity">center</item>
       <item name="android:listSelector">@drawable/action_bar_button</item>
       <item name="android:paddingTop">0dip</item>
       <item name="android:paddingBottom">0dip</item>
       <item name="android:paddingLeft">0dip</item>
       <item name="android:paddingRight">0dip</item>
     </style>
 
+    <style name="AboutHome.Thumbnail.Pinned">
+      <item name="android:layout_width">@dimen/abouthome_topsite_pinsize</item>
+      <item name="android:layout_height">@dimen/abouthome_topsite_pinsize</item>
+      <item name="android:layout_alignTop">@id/thumbnail</item>
+      <item name="android:layout_alignRight">@id/thumbnail</item>
+      <item name="android:minWidth">30dip</item>
+      <item name="android:minHeight">30dip</item>
+    </style>
+
     <style name="AboutHome.Thumbnail.Image">
       <item name="android:layout_width">fill_parent</item>
       <item name="android:layout_height">fill_parent</item>
       <item name="android:layout_centerHorizontal">true</item>
       <item name="android:layout_alignParentTop">true</item>
       <item name="android:src">@drawable/abouthome_thumbnail_bg</item>
       <item name="android:background">#5FFF</item>
       <item name="android:paddingTop">0dip</item>