mobile/android/base/home/TopSitesGridItemView.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 package org.mozilla.gecko.home;
     8 import org.mozilla.gecko.favicons.Favicons;
     9 import org.mozilla.gecko.R;
    11 import android.content.Context;
    12 import android.graphics.Bitmap;
    13 import android.text.TextUtils;
    14 import android.util.AttributeSet;
    15 import android.view.LayoutInflater;
    16 import android.widget.ImageView;
    17 import android.widget.ImageView.ScaleType;
    18 import android.widget.RelativeLayout;
    19 import android.widget.TextView;
    21 /**
    22  * A view that displays the thumbnail and the title/url for a top/pinned site.
    23  * If the title/url is longer than the width of the view, they are faded out.
    24  * If there is no valid url, a default string is shown at 50% opacity.
    25  * This is denoted by the empty state.
    26  */
    27 public class TopSitesGridItemView extends RelativeLayout {
    28     private static final String LOGTAG = "GeckoTopSitesGridItemView";
    30     // Empty state, to denote there is no valid url.
    31     private static final int[] STATE_EMPTY = { android.R.attr.state_empty };
    33     private static final ScaleType SCALE_TYPE_FAVICON   = ScaleType.CENTER;
    34     private static final ScaleType SCALE_TYPE_RESOURCE  = ScaleType.CENTER;
    35     private static final ScaleType SCALE_TYPE_THUMBNAIL = ScaleType.CENTER_CROP;
    37     // Child views.
    38     private final TextView mTitleView;
    39     private final ImageView mThumbnailView;
    41     // Data backing this view.
    42     private String mTitle;
    43     private String mUrl;
    44     private String mFaviconURL;
    46     private boolean mThumbnailSet;
    48     // Pinned state.
    49     private boolean mIsPinned = false;
    51     // Dirty state.
    52     private boolean mIsDirty = false;
    54     // Empty state.
    55     private boolean mIsEmpty = true;
    56     private int mLoadId = Favicons.NOT_LOADING;
    58     public TopSitesGridItemView(Context context) {
    59         this(context, null);
    60     }
    62     public TopSitesGridItemView(Context context, AttributeSet attrs) {
    63         this(context, attrs, R.attr.topSitesGridItemViewStyle);
    64     }
    66     public TopSitesGridItemView(Context context, AttributeSet attrs, int defStyle) {
    67         super(context, attrs, defStyle);
    69         LayoutInflater.from(context).inflate(R.layout.top_sites_grid_item_view, this);
    71         mTitleView = (TextView) findViewById(R.id.title);
    72         mThumbnailView = (ImageView) findViewById(R.id.thumbnail);
    73     }
    75     /**
    76      * {@inheritDoc}
    77      */
    78     @Override
    79     public int[] onCreateDrawableState(int extraSpace) {
    80         final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
    82         if (mIsEmpty) {
    83             mergeDrawableStates(drawableState, STATE_EMPTY);
    84         }
    86         return drawableState;
    87     }
    89     /**
    90      * @return The title shown by this view.
    91      */
    92     public String getTitle() {
    93         return (!TextUtils.isEmpty(mTitle) ? mTitle : mUrl);
    94     }
    96     /**
    97      * @return The url shown by this view.
    98      */
    99     public String getUrl() {
   100         return mUrl;
   101     }
   103     /**
   104      * @return true, if this view is pinned, false otherwise.
   105      */
   106     public boolean isPinned() {
   107         return mIsPinned;
   108     }
   110     /**
   111      * @return true, if this view has no content to show.
   112      */
   113     public boolean isEmpty() {
   114         return mIsEmpty;
   115     }
   117     /**
   118      * @param title The title for this view.
   119      */
   120     public void setTitle(String title) {
   121         if (mTitle != null && mTitle.equals(title)) {
   122             return;
   123         }
   125         mTitle = title;
   126         updateTitleView();
   127     }
   129     /**
   130      * @param url The url for this view.
   131      */
   132     public void setUrl(String url) {
   133         if (mUrl != null && mUrl.equals(url)) {
   134             return;
   135         }
   137         mUrl = url;
   138         updateTitleView();
   139     }
   141     /**
   142      * @param pinned The pinned state of this view.
   143      */
   144     public void setPinned(boolean pinned) {
   145         mIsPinned = pinned;
   146         mTitleView.setCompoundDrawablesWithIntrinsicBounds(pinned ? R.drawable.pin : 0, 0, 0, 0);
   147     }
   149     public void blankOut() {
   150         mUrl = "";
   151         mTitle = "";
   152         mIsPinned = false;
   153         updateTitleView();
   154         mTitleView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
   155         setLoadId(Favicons.NOT_LOADING);
   156         displayThumbnail(R.drawable.top_site_add);
   157     }
   159     public void markAsDirty() {
   160         mIsDirty = true;
   161     }
   163     /**
   164      * Updates the title, URL, and pinned state of this view.
   165      *
   166      * Also resets our loadId to NOT_LOADING.
   167      *
   168      * Returns true if any fields changed.
   169      */
   170     public boolean updateState(final String title, final String url, final boolean pinned, final Bitmap thumbnail) {
   171         boolean changed = false;
   172         if (mUrl == null || !mUrl.equals(url)) {
   173             mUrl = url;
   174             changed = true;
   175         }
   177         if (mTitle == null || !mTitle.equals(title)) {
   178             mTitle = title;
   179             changed = true;
   180         }
   182         if (thumbnail != null) {
   183             displayThumbnail(thumbnail);
   184         } else if (changed) {
   185             // Because we'll have a new favicon or thumbnail arriving shortly, and
   186             // we need to not reject it because we already had a thumbnail.
   187             mThumbnailSet = false;
   188         }
   190         if (changed) {
   191             updateTitleView();
   192             setLoadId(Favicons.NOT_LOADING);
   193         }
   195         if (mIsPinned != pinned) {
   196             mIsPinned = pinned;
   197             mTitleView.setCompoundDrawablesWithIntrinsicBounds(pinned ? R.drawable.pin : 0, 0, 0, 0);
   198             changed = true;
   199         }
   201         // The dirty state forces the state update to return true
   202         // so that the adapter loads favicons once the thumbnails
   203         // are loaded in TopSitesPanel/TopSitesGridAdapter.
   204         changed = (changed || mIsDirty);
   205         mIsDirty = false;
   207         return changed;
   208     }
   210     /**
   211      * Display the thumbnail from a resource.
   212      *
   213      * @param resId Resource ID of the drawable to show.
   214      */
   215     public void displayThumbnail(int resId) {
   216         mThumbnailView.setScaleType(SCALE_TYPE_RESOURCE);
   217         mThumbnailView.setImageResource(resId);
   218         mThumbnailView.setBackgroundColor(0x0);
   219         mThumbnailSet = false;
   220     }
   222     /**
   223      * Display the thumbnail from a bitmap.
   224      *
   225      * @param thumbnail The bitmap to show as thumbnail.
   226      */
   227     public void displayThumbnail(Bitmap thumbnail) {
   228         if (thumbnail == null) {
   229             // Show a favicon based view instead.
   230             displayThumbnail(R.drawable.favicon);
   231             return;
   232         }
   233         mThumbnailSet = true;
   234         Favicons.cancelFaviconLoad(mLoadId);
   236         mThumbnailView.setScaleType(SCALE_TYPE_THUMBNAIL);
   237         mThumbnailView.setImageBitmap(thumbnail);
   238         mThumbnailView.setBackgroundDrawable(null);
   239     }
   241     public void displayFavicon(Bitmap favicon, String faviconURL, int expectedLoadId) {
   242         if (mLoadId != Favicons.NOT_LOADING &&
   243             mLoadId != expectedLoadId) {
   244             // View recycled.
   245             return;
   246         }
   248         // Yes, there's a chance of a race here.
   249         displayFavicon(favicon, faviconURL);
   250     }
   252     /**
   253      * Display the thumbnail from a favicon.
   254      *
   255      * @param favicon The favicon to show as thumbnail.
   256      */
   257     public void displayFavicon(Bitmap favicon, String faviconURL) {
   258         if (mThumbnailSet) {
   259             // Already showing a thumbnail; do nothing.
   260             return;
   261         }
   263         if (favicon == null) {
   264             // Should show default favicon.
   265             displayThumbnail(R.drawable.favicon);
   266             return;
   267         }
   269         if (faviconURL != null) {
   270             mFaviconURL = faviconURL;
   271         }
   273         mThumbnailView.setScaleType(SCALE_TYPE_FAVICON);
   274         mThumbnailView.setImageBitmap(favicon);
   276         if (mFaviconURL != null) {
   277             mThumbnailView.setBackgroundColor(Favicons.getFaviconColor(mFaviconURL));
   278         }
   279     }
   281     /**
   282      * Update the title shown by this view. If both title and url
   283      * are empty, mark the state as STATE_EMPTY and show a default text.
   284      */
   285     private void updateTitleView() {
   286         String title = getTitle();
   287         if (!TextUtils.isEmpty(title)) {
   288             mTitleView.setText(title);
   289             mIsEmpty = false;
   290         } else {
   291             mTitleView.setText(R.string.home_top_sites_add);
   292             mIsEmpty = true;
   293         }
   295         // Refresh for state change.
   296         refreshDrawableState();
   297     }
   299     public void setLoadId(int aLoadId) {
   300         Favicons.cancelFaviconLoad(mLoadId);
   301         mLoadId = aLoadId;
   302     }
   303 }

mercurial