Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java

Issue 2758313002: Implement the new Photo picker, part two. (Closed)
Patch Set: Trim changelist Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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.app.Activity;
8 import android.content.Context;
9 import android.graphics.Bitmap;
10 import android.graphics.Canvas;
11 import android.graphics.Paint;
12 import android.graphics.PorterDuff;
13 import android.graphics.PorterDuffColorFilter;
14 import android.support.v7.widget.GridLayoutManager;
15 import android.support.v7.widget.RecyclerView;
16 import android.support.v7.widget.Toolbar.OnMenuItemClickListener;
17 import android.util.AttributeSet;
18 import android.view.LayoutInflater;
19 import android.view.MenuItem;
20 import android.view.View;
21 import android.widget.RelativeLayout;
22
23 import org.chromium.chrome.R;
24 import org.chromium.chrome.browser.widget.selection.SelectableListLayout;
25 import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
26 import org.chromium.ui.PhotoPickerListener;
27
28 import java.util.ArrayList;
29 import java.util.List;
30
31 /**
32 * A class for keeping track of common data associated with showing photos in
33 * the photo picker, for example the RecyclerView and the bitmap caches.
34 */
35 public class PickerCategoryView extends RelativeLayout implements OnMenuItemClic kListener {
36 private static final int KILOBYTE = 1024;
37
38 // The dialog that owns us.
39 private PhotoPickerDialog mDialog;
40
41 // The view containing the recycler view and the toolbar, etc.
42 private SelectableListLayout<PickerBitmap> mSelectableListLayout;
43
44 // Our context.
45 private Context mContext;
46
47 // The list of images on disk, sorted by last-modified first.
48 private List<PickerBitmap> mPickerBitmaps;
49
50 // True if multi-selection is allowed in the picker.
51 private boolean mMultiSelectionAllowed;
52
53 // The callback to notify the listener of decisions reached in the picker.
54 private PhotoPickerListener mListener;
55
56 // The recycler view showing the images.
57 private RecyclerView mRecyclerView;
58
59 // The picker adapter for the RecyclerView.
60 private PickerAdapter mPickerAdapter;
61
62 // The selection delegate keeping track of which images are selected.
63 private SelectionDelegate<PickerBitmap> mSelectionDelegate;
64
65 /**
66 * The number of columns to show. Note: mColumns and mPadding (see below) sh ould both be even
67 * numbers or both odd, not a mix (the column padding will not be of uniform thickness if they
68 * are a mix).
69 */
70 private int mColumns;
71
72 // The padding between columns. See also comment for mColumns.
73 private int mPadding;
74
75 // The size of the bitmaps (equal length for width and height).
76 private int mImageSize;
77
78 public PickerCategoryView(Context context) {
79 super(context);
80 init(context);
81 }
82
83 public PickerCategoryView(Context context, AttributeSet attrs) {
84 super(context, attrs);
85 init(context);
86 }
87
88 public PickerCategoryView(Context context, AttributeSet attrs, int defStyle) {
89 super(context, attrs, defStyle);
90 init(context);
91 }
92
93 /**
94 * A helper function for initializing the PickerCategoryView.
95 * @param context The context to use.
96 */
97 @SuppressWarnings("unchecked") // mSelectableListLayout
98 private void init(Context context) {
99 mContext = context;
100
101 mSelectionDelegate = new SelectionDelegate<PickerBitmap>();
102
103 View root = LayoutInflater.from(context).inflate(R.layout.photo_picker_d ialog, this);
104 mSelectableListLayout =
105 (SelectableListLayout<PickerBitmap>) root.findViewById(R.id.sele ctable_list);
106
107 mPickerAdapter = new PickerAdapter(this);
108 mRecyclerView = mSelectableListLayout.initializeRecyclerView(mPickerAdap ter);
109 mSelectableListLayout.initializeToolbar(R.layout.photo_picker_toolbar, m SelectionDelegate,
110 R.string.menu_history, null, R.id.file_picker_normal_menu_group,
111 R.id.file_picker_selection_mode_menu_group, R.color.default_prim ary_color, false,
112 this);
113
114 View view = ((Activity) context).getWindow().getDecorView();
Theresa 2017/03/31 18:05:56 getDecorView() contains all of the window decorati
Finnur 2017/04/03 17:30:30 We only care about the width here.
Theresa 2017/04/04 15:48:32 Sometimes the width contains the window decoration
Finnur 2017/04/04 18:05:36 Done.
115 int width = view.getWidth() - view.getPaddingLeft() - view.getPaddingRig ht();
116
117 calculateGridMetrics(width);
118
119 RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(mConte xt, mColumns);
120 mRecyclerView.setHasFixedSize(true);
121 mRecyclerView.setLayoutManager(mLayoutManager);
122 // TODO(finnur): Implement grid spacing.
123 // TODO(finnur): Implement caching.
124 // TODO(finnur): Remove this once the decoder service is in place.
125 prepareBitmaps();
126 }
127
128 /**
129 * Sets the starting state for the PickerCategoryView object.
130 * @param dialog The dialog showing us.
131 * @param listener The listener who should be notified of actions.
132 * @param multiSelection Whether to allow the user to select more than one i mage.
133 */
134 public void setStartingState(
Theresa 2017/03/31 18:05:56 The values set in this don't appear to change so #
Finnur 2017/04/03 17:30:30 Yeah, I struggled with this as well. All I can thi
Theresa 2017/04/04 15:48:32 What about something like postConstruction() for t
Finnur 2017/04/04 18:05:36 Sounds reasonable.
135 PhotoPickerDialog dialog, PhotoPickerListener listener, boolean mult iSelection) {
Theresa 2017/03/31 18:05:56 Please rename this parameter to match mMultiSelect
Finnur 2017/04/03 17:30:30 Done.
136 // TODO(finnur): Change selection delegate to support single-selection.
137
138 mDialog = dialog;
139 mMultiSelectionAllowed = multiSelection;
140 mListener = listener;
141 }
142
143 // OnMenuItemClickListener:
144
145 @Override
146 public boolean onMenuItemClick(MenuItem item) {
147 if (item.getItemId() == R.id.close_menu_id
148 || item.getItemId() == R.id.selection_mode_done_menu_id) {
149 tryNotifyPhotoSet();
150 mDialog.dismiss();
151 return true;
152 }
153 return false;
154 }
155
156 // Simple accessors:
157
158 public int getImageSize() {
159 return mImageSize;
160 }
161 public SelectionDelegate<PickerBitmap> getSelectionDelegate() {
Theresa 2017/03/31 18:05:56 nit: add a blank space above this method and the o
Finnur 2017/04/03 17:30:30 Done.
162 return mSelectionDelegate;
163 }
164 public List<PickerBitmap> getPickerBitmaps() {
165 return mPickerBitmaps;
166 }
167 public boolean isMultiSelect() {
Theresa 2017/03/31 18:05:56 Please rename this method as well.
Finnur 2017/04/03 17:30:30 Done.
168 return mMultiSelectionAllowed;
169 }
170
171 /**
172 * Notifies the caller that the user selected to launch the gallery.
173 */
174 public void showGallery() {
175 mListener.onPickerUserAction(PhotoPickerListener.Action.LAUNCH_GALLERY, null);
176 }
177
178 /**
179 * Notifies the caller that the user selected to launch the camera intent.
180 */
181 public void showCamera() {
182 mListener.onPickerUserAction(PhotoPickerListener.Action.LAUNCH_CAMERA, n ull);
183 }
184
185 /**
186 * Applies a color filter to a bitmap.
187 * @param original The bitmap to color.
188 * @param color The color to apply.
189 * @return A colored bitmap.
190 */
191 private Bitmap colorBitmap(Bitmap original, int color) {
Theresa 2017/03/31 18:05:56 It looks like this is no longer used.
Finnur 2017/04/03 17:30:30 Correct.
192 Bitmap mutable = original.copy(Bitmap.Config.ARGB_8888, true);
193 Canvas canvas = new Canvas(mutable);
194 Paint paint = new Paint();
195 paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SR C_IN));
196 canvas.drawBitmap(mutable, 0.f, 0.f, paint);
197 return mutable;
198 }
199
200 /**
201 * Calculates image size and how many columns can fit on-screen.
202 * @param width The total width of the boundary to show the images in.
203 */
204 private void calculateGridMetrics(int width) {
205 int minSize =
206 mContext.getResources().getDimensionPixelSize(R.dimen.file_picke r_tile_min_size);
207 mPadding = mContext.getResources().getDimensionPixelSize(R.dimen.file_pi cker_tile_gap);
208 mColumns = Math.max(1, (width - mPadding) / (minSize + mPadding));
209 mImageSize = (width - mPadding * (mColumns + 1)) / (mColumns);
210
211 // Make sure columns and padding are either both even or both odd.
212 if (((mColumns % 2) == 0) != ((mPadding % 2) == 0)) {
213 mPadding++;
214 }
215 }
216
217 /**
218 * Prepares bitmaps for loading.
219 */
220 private void prepareBitmaps() {
221 // TODO(finnur): Use worker thread to fetch bitmaps instead of hard-codi ng.
222 mPickerBitmaps = new ArrayList<>();
223 mPickerBitmaps.add(0, new PickerBitmap("", 0, PickerBitmap.TileTypes.GAL LERY));
224 mPickerBitmaps.add(0, new PickerBitmap("", 0, PickerBitmap.TileTypes.CAM ERA));
225 mPickerBitmaps.add(new PickerBitmap("foo/bar1.jpg", 1, PickerBitmap.Tile Types.PICTURE));
226 mPickerBitmaps.add(new PickerBitmap("foo/bar2.jpg", 2, PickerBitmap.Tile Types.PICTURE));
227 mPickerBitmaps.add(new PickerBitmap("foo/bar3.jpg", 3, PickerBitmap.Tile Types.PICTURE));
228 mPickerBitmaps.add(new PickerBitmap("foo/bar4.jpg", 4, PickerBitmap.Tile Types.PICTURE));
229 mPickerAdapter.notifyDataSetChanged();
230 }
231
232 /**
233 * Tries to notify any listeners that one or more photos have been selected.
Theresa 2017/03/31 18:05:56 When would it not successfully notify the listener
Finnur 2017/04/03 17:30:30 Yes, in an old revision this could actually result
234 */
235 private void tryNotifyPhotoSet() {
236 List<PickerBitmap> selectedFiles = mSelectionDelegate.getSelectedItems() ;
237 String[] photos = new String[selectedFiles.size()];
238 int i = 0;
239 for (PickerBitmap bitmap : selectedFiles) {
240 photos[i++] = bitmap.getFilePath();
241 }
242
243 mListener.onPickerUserAction(PhotoPickerListener.Action.PHOTOS_SELECTED, photos);
244 }
245 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698