| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.photo_picker; | 5 package org.chromium.chrome.browser.photo_picker; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.content.res.Resources; | 8 import android.content.res.Resources; |
| 9 import android.graphics.Bitmap; | 9 import android.graphics.Bitmap; |
| 10 import android.graphics.PorterDuff; | 10 import android.graphics.PorterDuff; |
| 11 import android.graphics.drawable.Drawable; | 11 import android.graphics.drawable.Drawable; |
| 12 import android.support.annotation.IntDef; |
| 12 import android.support.annotation.Nullable; | 13 import android.support.annotation.Nullable; |
| 13 import android.support.graphics.drawable.VectorDrawableCompat; | 14 import android.support.graphics.drawable.VectorDrawableCompat; |
| 14 import android.util.AttributeSet; | 15 import android.util.AttributeSet; |
| 15 import android.view.View; | 16 import android.view.View; |
| 16 import android.view.ViewGroup; | 17 import android.view.ViewGroup; |
| 17 import android.view.animation.Animation; | 18 import android.view.animation.Animation; |
| 18 import android.view.animation.ScaleAnimation; | 19 import android.view.animation.ScaleAnimation; |
| 19 import android.widget.ImageView; | 20 import android.widget.ImageView; |
| 20 import android.widget.TextView; | 21 import android.widget.TextView; |
| 21 | 22 |
| 22 import org.chromium.base.ApiCompatibilityUtils; | 23 import org.chromium.base.ApiCompatibilityUtils; |
| 24 import org.chromium.base.VisibleForTesting; |
| 23 import org.chromium.chrome.R; | 25 import org.chromium.chrome.R; |
| 24 import org.chromium.chrome.browser.widget.selection.SelectableItemView; | 26 import org.chromium.chrome.browser.widget.selection.SelectableItemView; |
| 25 import org.chromium.chrome.browser.widget.selection.SelectionDelegate; | 27 import org.chromium.chrome.browser.widget.selection.SelectionDelegate; |
| 26 | 28 |
| 29 import java.lang.annotation.Retention; |
| 30 import java.lang.annotation.RetentionPolicy; |
| 27 import java.util.List; | 31 import java.util.List; |
| 28 | 32 |
| 29 /** | 33 /** |
| 30 * A container class for a view showing a photo in the Photo Picker. | 34 * A container class for a view showing a photo in the Photo Picker. |
| 31 */ | 35 */ |
| 32 public class PickerBitmapView extends SelectableItemView<PickerBitmap> { | 36 public class PickerBitmapView extends SelectableItemView<PickerBitmap> { |
| 33 // The length of the image selection animation (in ms). | 37 // The length of the image selection animation (in ms). |
| 34 private static final int ANIMATION_DURATION = 100; | 38 private static final int ANIMATION_DURATION = 100; |
| 35 | 39 |
| 36 // The length of the fade in animation (in ms). | 40 // The length of the fade in animation (in ms). |
| 37 private static final int IMAGE_FADE_IN_DURATION = 200; | 41 private static final int IMAGE_FADE_IN_DURATION = 200; |
| 38 | 42 |
| 43 // The possible stages of loading an image. |
| 44 @IntDef({PENDING, LOADING, LOADED}) |
| 45 @Retention(RetentionPolicy.SOURCE) |
| 46 public @interface LoadingStage {} |
| 47 public static final int PENDING = 0; |
| 48 public static final int LOADING = 1; |
| 49 public static final int LOADED = 2; |
| 50 |
| 39 // Our context. | 51 // Our context. |
| 40 private Context mContext; | 52 private Context mContext; |
| 41 | 53 |
| 42 // Our parent category. | 54 // Our parent category. |
| 43 private PickerCategoryView mCategoryView; | 55 private PickerCategoryView mCategoryView; |
| 44 | 56 |
| 45 // Our selection delegate. | 57 // Our selection delegate. |
| 46 private SelectionDelegate<PickerBitmap> mSelectionDelegate; | 58 private SelectionDelegate<PickerBitmap> mSelectionDelegate; |
| 47 | 59 |
| 48 // The request details (meta-data) for the bitmap shown. | 60 // The request details (meta-data) for the bitmap shown. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 63 | 75 |
| 64 // The camera/gallery special tile (with icon as drawable). | 76 // The camera/gallery special tile (with icon as drawable). |
| 65 private View mSpecialTile; | 77 private View mSpecialTile; |
| 66 | 78 |
| 67 // The camera/gallery icon. | 79 // The camera/gallery icon. |
| 68 public ImageView mSpecialTileIcon; | 80 public ImageView mSpecialTileIcon; |
| 69 | 81 |
| 70 // The label under the special tile. | 82 // The label under the special tile. |
| 71 public TextView mSpecialTileLabel; | 83 public TextView mSpecialTileLabel; |
| 72 | 84 |
| 73 // Whether the image has been loaded already. | 85 // The loading stage for this tile. |
| 74 private boolean mImageLoaded; | 86 @LoadingStage |
| 87 private int mLoadingStage = PENDING; |
| 75 | 88 |
| 76 // The amount to use for the border. | 89 // The amount to use for the border. |
| 77 private int mBorder; | 90 private int mBorder; |
| 78 | 91 |
| 79 /** | 92 /** |
| 80 * Constructor for inflating from XML. | 93 * Constructor for inflating from XML. |
| 81 */ | 94 */ |
| 82 public PickerBitmapView(Context context, AttributeSet attrs) { | 95 public PickerBitmapView(Context context, AttributeSet attrs) { |
| 83 super(context, attrs); | 96 super(context, attrs); |
| 84 mContext = context; | 97 mContext = context; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 * @param placeholder Whether the image given is a placeholder or the actual
image. | 212 * @param placeholder Whether the image given is a placeholder or the actual
image. |
| 200 */ | 213 */ |
| 201 public void initialize( | 214 public void initialize( |
| 202 PickerBitmap bitmapDetails, @Nullable Bitmap thumbnail, boolean plac
eholder) { | 215 PickerBitmap bitmapDetails, @Nullable Bitmap thumbnail, boolean plac
eholder) { |
| 203 resetTile(); | 216 resetTile(); |
| 204 | 217 |
| 205 mBitmapDetails = bitmapDetails; | 218 mBitmapDetails = bitmapDetails; |
| 206 setItem(bitmapDetails); | 219 setItem(bitmapDetails); |
| 207 if (isCameraTile() || isGalleryTile()) { | 220 if (isCameraTile() || isGalleryTile()) { |
| 208 initializeSpecialTile(mBitmapDetails); | 221 initializeSpecialTile(mBitmapDetails); |
| 209 mImageLoaded = true; | 222 mLoadingStage = LOADED; |
| 210 } else { | 223 } else { |
| 211 setThumbnailBitmap(thumbnail); | 224 setThumbnailBitmap(thumbnail); |
| 212 mImageLoaded = !placeholder; | 225 mLoadingStage = placeholder ? LOADING : LOADED; |
| 213 } | 226 } |
| 214 | 227 |
| 215 updateSelectionState(); | 228 updateSelectionState(); |
| 216 } | 229 } |
| 217 | 230 |
| 218 /** | 231 /** |
| 219 * Initialization for the special tiles (camera/gallery icon). | 232 * Initialization for the special tiles (camera/gallery icon). |
| 220 * @param bitmapDetails The details about the bitmap represented by this Pic
kerBitmapView. | 233 * @param bitmapDetails The details about the bitmap represented by this Pic
kerBitmapView. |
| 221 */ | 234 */ |
| 222 public void initializeSpecialTile(PickerBitmap bitmapDetails) { | 235 public void initializeSpecialTile(PickerBitmap bitmapDetails) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 252 mIconView.setImageBitmap(thumbnail); | 265 mIconView.setImageBitmap(thumbnail); |
| 253 | 266 |
| 254 // If the tile has been selected before the bitmap has loaded, make sure
it shows up with | 267 // If the tile has been selected before the bitmap has loaded, make sure
it shows up with |
| 255 // a selection border on load. | 268 // a selection border on load. |
| 256 if (super.isChecked()) { | 269 if (super.isChecked()) { |
| 257 mIconView.getLayoutParams().height = imageSizeWithBorders(); | 270 mIconView.getLayoutParams().height = imageSizeWithBorders(); |
| 258 mIconView.getLayoutParams().width = imageSizeWithBorders(); | 271 mIconView.getLayoutParams().width = imageSizeWithBorders(); |
| 259 addPaddingToParent(mIconView, mBorder); | 272 addPaddingToParent(mIconView, mBorder); |
| 260 } | 273 } |
| 261 | 274 |
| 262 boolean noImageWasLoaded = !mImageLoaded; | 275 boolean noImageWasLoaded = mLoadingStage != LOADED; |
| 263 mImageLoaded = true; | 276 mLoadingStage = LOADED; |
| 264 updateSelectionState(); | 277 updateSelectionState(); |
| 265 | 278 |
| 266 return noImageWasLoaded; | 279 return noImageWasLoaded; |
| 267 } | 280 } |
| 268 | 281 |
| 269 /** Returns the size of the image plus the pre-determined border on each sid
e. */ | 282 /** Returns the size of the image plus the pre-determined border on each sid
e. */ |
| 270 private int imageSizeWithBorders() { | 283 private int imageSizeWithBorders() { |
| 271 return mCategoryView.getImageSize() - 2 * mBorder; | 284 return mCategoryView.getImageSize() - 2 * mBorder; |
| 272 } | 285 } |
| 273 | 286 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 Drawable drawable = mSpecialTileIcon.getDrawable(); | 344 Drawable drawable = mSpecialTileIcon.getDrawable(); |
| 332 int color = ApiCompatibilityUtils.getColor(resources, fgColorId); | 345 int color = ApiCompatibilityUtils.getColor(resources, fgColorId); |
| 333 drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); | 346 drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); |
| 334 mSpecialTileIcon.invalidate(); | 347 mSpecialTileIcon.invalidate(); |
| 335 } | 348 } |
| 336 | 349 |
| 337 setBackgroundColor(ApiCompatibilityUtils.getColor(resources, bgColorId))
; | 350 setBackgroundColor(ApiCompatibilityUtils.getColor(resources, bgColorId))
; |
| 338 | 351 |
| 339 // The visibility of the unselected image is a little more complex becau
se we don't want | 352 // The visibility of the unselected image is a little more complex becau
se we don't want |
| 340 // to show it when nothing is selected and also not on a blank canvas. | 353 // to show it when nothing is selected and also not on a blank canvas. |
| 354 boolean imageLoaded = mLoadingStage == LOADED; |
| 341 mSelectedView.setVisibility(!special && checked ? View.VISIBLE : View.GO
NE); | 355 mSelectedView.setVisibility(!special && checked ? View.VISIBLE : View.GO
NE); |
| 342 mUnselectedView.setVisibility( | 356 mUnselectedView.setVisibility( |
| 343 !special && !checked && anySelection && mImageLoaded ? View.VISI
BLE : View.GONE); | 357 !special && !checked && anySelection && imageLoaded ? View.VISIB
LE : View.GONE); |
| 344 mScrim.setVisibility( | 358 mScrim.setVisibility( |
| 345 !special && !checked && anySelection && mImageLoaded ? View.VISI
BLE : View.GONE); | 359 !special && !checked && anySelection && imageLoaded ? View.VISIB
LE : View.GONE); |
| 346 } | 360 } |
| 347 | 361 |
| 348 private boolean isGalleryTile() { | 362 private boolean isGalleryTile() { |
| 349 return mBitmapDetails.type() == PickerBitmap.GALLERY; | 363 return mBitmapDetails.type() == PickerBitmap.GALLERY; |
| 350 } | 364 } |
| 351 | 365 |
| 352 private boolean isCameraTile() { | 366 private boolean isCameraTile() { |
| 353 return mBitmapDetails.type() == PickerBitmap.CAMERA; | 367 return mBitmapDetails.type() == PickerBitmap.CAMERA; |
| 354 } | 368 } |
| 355 | 369 |
| 356 private boolean isPictureTile() { | 370 private boolean isPictureTile() { |
| 357 return mBitmapDetails.type() == PickerBitmap.PICTURE; | 371 return mBitmapDetails.type() == PickerBitmap.PICTURE; |
| 358 } | 372 } |
| 373 |
| 374 @VisibleForTesting |
| 375 public boolean getImageLoadingForTesting() { |
| 376 return mLoadingStage == LOADING; |
| 377 } |
| 359 } | 378 } |
| OLD | NEW |