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 |