OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package org.chromium.chrome.browser.photo_picker; | |
6 | |
7 import android.content.Context; | |
8 import android.content.res.Resources; | |
9 import android.graphics.Bitmap; | |
10 import android.graphics.BitmapFactory; | |
11 import android.graphics.Color; | |
12 import android.graphics.PorterDuff; | |
13 import android.graphics.drawable.BitmapDrawable; | |
14 import android.graphics.drawable.Drawable; | |
15 import android.support.annotation.Nullable; | |
16 import android.support.v4.content.ContextCompat; | |
17 import android.util.AttributeSet; | |
18 import android.view.View; | |
19 import android.view.ViewGroup; | |
20 import android.widget.ImageView; | |
21 import android.widget.TextView; | |
22 | |
23 import org.chromium.base.ApiCompatibilityUtils; | |
24 import org.chromium.chrome.R; | |
25 import org.chromium.chrome.browser.widget.selection.SelectableItemView; | |
26 import org.chromium.chrome.browser.widget.selection.SelectionDelegate; | |
27 | |
28 import java.util.List; | |
29 | |
30 /** | |
31 * A container class for a view showing a photo in the photo picker. | |
32 */ | |
33 public class PickerBitmapView extends SelectableItemView<PickerBitmap> { | |
34 // Our context. | |
35 private Context mContext; | |
36 | |
37 // Our parent category. | |
38 private PickerCategoryView mCategoryView; | |
39 | |
40 // Our selection delegate. | |
41 private SelectionDelegate<PickerBitmap> mSelectionDelegate; | |
42 | |
43 // The request details (meta-data) for the bitmap shown. | |
44 private PickerBitmap mRequest; | |
45 | |
46 // The image view containing the bitmap. | |
47 private ImageView mIconView; | |
48 | |
49 // The view behind the image, representing the selection border. | |
50 private View mBorderView; | |
51 | |
52 // The camera/gallery special tile (with icon as drawable). | |
53 private TextView mSpecialTile; | |
54 | |
55 // Whether the image has been loaded already. | |
56 private boolean mImageLoaded; | |
57 | |
58 /** | |
59 * Constructor for inflating from XML. | |
60 */ | |
61 public PickerBitmapView(Context context, AttributeSet attrs) { | |
62 super(context, attrs); | |
63 mContext = context; | |
64 } | |
65 | |
66 @Override | |
67 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
68 super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
69 | |
70 if (mCategoryView == null) return; | |
71 | |
72 int width = mCategoryView.getImageSize(); | |
73 int height = mCategoryView.getImageSize(); | |
74 setMeasuredDimension(width, height); | |
75 } | |
76 | |
77 @Override | |
78 protected void onFinishInflate() { | |
79 super.onFinishInflate(); | |
80 mIconView = (ImageView) findViewById(R.id.bitmap_view); | |
81 mBorderView = findViewById(R.id.border); | |
82 mSpecialTile = (TextView) findViewById(R.id.special_tile); | |
83 } | |
84 | |
85 @Override | |
86 public void onClick() { | |
87 // TODO(finnur): Remove the null checks here and below. | |
88 if (mRequest != null && mRequest.type() == PickerBitmap.TileTypes.GALLER Y) { | |
89 mCategoryView.showGallery(); | |
90 return; | |
91 } else if (mRequest != null && mRequest.type() == PickerBitmap.TileTypes .CAMERA) { | |
92 mCategoryView.showCamera(); | |
93 return; | |
94 } | |
95 | |
96 mSelectionDelegate.toggleSelectionForItem(mRequest); | |
Theresa
2017/03/31 18:05:56
I think this could be simplified to calling super.
Finnur
2017/04/03 17:30:29
Yup. Seems to work fine that way.
| |
97 setChecked(!super.isChecked()); | |
98 } | |
99 | |
100 @Override | |
101 public void setChecked(boolean checked) { | |
102 if (mRequest != null && mRequest.type() != PickerBitmap.TileTypes.PICTUR E) { | |
103 return; | |
104 } | |
105 | |
106 super.setChecked(checked); | |
107 updateSelectionState(); | |
108 } | |
109 | |
110 @Override | |
111 public void onSelectionStateChange(List<PickerBitmap> selectedItems) { | |
112 boolean selected = selectedItems.contains(mRequest); | |
113 | |
114 if (mRequest != null && mRequest.type() != PickerBitmap.TileTypes.PICTUR E) { | |
115 if (selected) mSelectionDelegate.toggleSelectionForItem(mRequest); | |
116 updateSelectionState(); | |
Theresa
2017/03/31 18:05:56
Instead of unselecting the camera/gallery here, co
Finnur
2017/04/03 17:30:29
Done (much better).
| |
117 return; | |
118 } | |
119 | |
120 boolean checked = super.isChecked(); | |
121 | |
122 if (!mCategoryView.isMultiSelect() && !selected && checked) { | |
123 super.toggle(); | |
Theresa
2017/03/31 18:05:56
I'm confused about how the item could be !selected
Finnur
2017/04/03 17:30:29
I don't remember why this is needed anymore and si
| |
124 } | |
125 | |
126 updateSelectionState(); | |
127 } | |
128 | |
129 /** | |
130 * Pre-initializes the PickerBitmapView. | |
131 * @param categoryView The category view showing the images. | |
132 */ | |
133 public void preInitialize(PickerCategoryView categoryView) { | |
134 mCategoryView = categoryView; | |
135 mSelectionDelegate = mCategoryView.getSelectionDelegate(); | |
136 super.setSelectionDelegate(mSelectionDelegate); | |
137 } | |
138 | |
139 /** | |
140 * Completes the initialization of the PickerBitmapView. Must be called befo re the image can | |
141 * respond to click events. | |
142 * @param request The request represented by this PickerBitmapView. | |
143 * @param thumbnail The Bitmap to use for the thumbnail (or null). | |
144 * @param placeholder Whether the image given is a placeholder or the actual image. | |
145 */ | |
146 public void initialize(PickerBitmap request, @Nullable Bitmap thumbnail, boo lean placeholder) { | |
147 resetTile(); | |
148 | |
149 mRequest = request; | |
150 setItem(request); | |
151 setThumbnailBitmap(thumbnail); | |
152 mImageLoaded = !placeholder; | |
153 | |
154 updateSelectionState(); | |
155 | |
156 setOnClickListener(this); | |
Theresa
2017/03/31 18:05:56
The superclass already calls setOnClickListener()
Finnur
2017/04/03 17:30:29
Removed.
| |
157 } | |
158 | |
159 /** | |
160 * Initialization for the special tiles (camera/gallery icon). | |
161 */ | |
162 public void initializeSpecialTile() { | |
163 int size = mCategoryView.getImageSize(); | |
Theresa
2017/03/31 18:05:56
You shouldn't need to programatically construct a
Finnur
2017/04/03 17:30:29
I don't have much experience with how the drawable
Theresa
2017/04/04 15:48:32
Something completely different :).
Currently you'
Finnur
2017/04/04 18:05:36
I've introduced the vector format to this, so the
Theresa
2017/04/04 18:40:45
Vector drawables cannot be used directly in XML -
Finnur
2017/04/05 15:14:39
Understood. I've done it the way you suggested. Th
| |
164 Bitmap tile = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); | |
165 tile.eraseColor(Color.argb(0, 0, 0, 0)); | |
166 | |
167 int iconBitmapId, labelStringId; | |
168 if (mRequest != null && mRequest.type() == PickerBitmap.TileTypes.CAMERA ) { | |
169 iconBitmapId = R.drawable.ic_photo_camera; | |
170 labelStringId = R.string.file_picker_camera; | |
171 } else { | |
172 iconBitmapId = R.drawable.ic_collections_black_24dp; | |
173 labelStringId = R.string.file_picker_browse; | |
174 } | |
175 | |
176 Resources resources = mContext.getResources(); | |
177 mSpecialTile.setText(labelStringId); | |
178 Bitmap icon = BitmapFactory.decodeResource(resources, iconBitmapId); | |
179 float pixels = resources.getDimensionPixelOffset(R.dimen.file_picker_spe cial_icon_size); | |
180 BitmapDrawable drawable = new BitmapDrawable( | |
181 resources, Bitmap.createScaledBitmap(icon, (int) pixels, (int) p ixels, true)); | |
182 ApiCompatibilityUtils.setCompoundDrawablesRelativeWithIntrinsicBounds( | |
183 mSpecialTile, null, drawable, null, null); | |
184 | |
185 initialize(mRequest, tile, false); | |
186 | |
187 mSpecialTile.setVisibility(View.VISIBLE); | |
188 } | |
189 | |
190 /** | |
191 * Sets a thumbnail bitmap for the current view. | |
192 * @param thumbnail The Bitmap to use for the icon ImageView. | |
193 * @return True if no image was loaded before (e.g. not even a low-res image ). | |
194 */ | |
195 public boolean setThumbnailBitmap(Bitmap thumbnail) { | |
196 mIconView.setImageBitmap(thumbnail); | |
197 | |
198 boolean noImageWasLoaded = !mImageLoaded; | |
199 mImageLoaded = true; | |
200 updateSelectionState(); | |
201 | |
202 return noImageWasLoaded; | |
203 } | |
204 | |
205 /** | |
206 * Resets the view to its starting state, which is necessary when the view i s about to be | |
207 * re-used. | |
208 */ | |
209 private void resetTile() { | |
210 mSpecialTile.setVisibility(View.GONE); | |
211 } | |
212 | |
213 /** | |
214 * Adds padding to the parent of the |view|. | |
215 * @param view The child view of the view to receive the padding. | |
216 * @param padding The amount of padding to use (in pixels). | |
217 */ | |
218 private static void addPaddingToParent(View view, int padding) { | |
Theresa
2017/03/31 18:05:56
Is anything calling this anymore?
Finnur
2017/04/03 17:30:29
Nope! Removed.
| |
219 ViewGroup layout = (ViewGroup) view.getParent(); | |
220 layout.setPadding(padding, padding, padding, padding); | |
221 layout.requestLayout(); | |
222 } | |
223 | |
224 /** | |
225 * Updates the selection controls for this view. | |
226 */ | |
227 private void updateSelectionState() { | |
228 boolean special = mRequest != null && mRequest.type() != PickerBitmap.Ti leTypes.PICTURE; | |
229 boolean checked = super.isChecked(); | |
230 boolean anySelection = | |
231 mSelectionDelegate != null && mSelectionDelegate.isSelectionEnab led(); | |
232 boolean multiSelect = mCategoryView.isMultiSelect(); | |
233 int bgColorId, fgColorId; | |
234 if (!special) { | |
235 bgColorId = R.color.file_picker_tile_bg_color; | |
236 fgColorId = R.color.file_picker_special_tile_color; | |
237 } else if (!anySelection || !multiSelect) { | |
238 bgColorId = R.color.file_picker_special_tile_bg_color; | |
239 fgColorId = R.color.file_picker_special_tile_color; | |
240 } else { | |
241 bgColorId = R.color.file_picker_special_tile_disabled_bg_color; | |
Theresa
2017/03/31 18:05:56
If multi-select is allowed, won't this set the set
Finnur
2017/04/03 17:30:29
Yes, I don't know why that condition is there.
| |
242 fgColorId = R.color.file_picker_special_tile_disabled_color; | |
243 } | |
244 | |
245 mBorderView.setBackgroundColor(ContextCompat.getColor(mContext, bgColorI d)); | |
Theresa
2017/03/31 18:05:56
Typically we use ApiCompatibilityUtils#getColor()
Finnur
2017/04/03 17:30:29
Done.
| |
246 mSpecialTile.setTextColor(ContextCompat.getColor(mContext, fgColorId)); | |
247 Drawable[] drawables = mSpecialTile.getCompoundDrawables(); | |
248 // The textview only has a top compound drawable (2nd element). | |
249 if (drawables[1] != null) { | |
250 int color = ContextCompat.getColor(mContext, fgColorId); | |
251 drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN); | |
252 } | |
253 } | |
254 } | |
OLD | NEW |