| Index: chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b4151f27bcb592e6ddb8005a09d1304d1274742d
|
| --- /dev/null
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerCategoryView.java
|
| @@ -0,0 +1,229 @@
|
| +// Copyright 2017 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +package org.chromium.chrome.browser.photo_picker;
|
| +
|
| +import android.app.Activity;
|
| +import android.content.Context;
|
| +import android.graphics.Rect;
|
| +import android.support.v7.widget.GridLayoutManager;
|
| +import android.support.v7.widget.RecyclerView;
|
| +import android.support.v7.widget.Toolbar.OnMenuItemClickListener;
|
| +import android.util.AttributeSet;
|
| +import android.view.LayoutInflater;
|
| +import android.view.MenuItem;
|
| +import android.view.View;
|
| +import android.widget.RelativeLayout;
|
| +
|
| +import org.chromium.chrome.R;
|
| +import org.chromium.chrome.browser.widget.selection.SelectableListLayout;
|
| +import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
|
| +import org.chromium.ui.PhotoPickerListener;
|
| +
|
| +import java.util.ArrayList;
|
| +import java.util.List;
|
| +
|
| +/**
|
| + * A class for keeping track of common data associated with showing photos in
|
| + * the photo picker, for example the RecyclerView and the bitmap caches.
|
| + */
|
| +public class PickerCategoryView extends RelativeLayout implements OnMenuItemClickListener {
|
| + // The dialog that owns us.
|
| + private PhotoPickerDialog mDialog;
|
| +
|
| + // The view containing the RecyclerView and the toolbar, etc.
|
| + private SelectableListLayout<PickerBitmap> mSelectableListLayout;
|
| +
|
| + // Our context.
|
| + private Context mContext;
|
| +
|
| + // The list of images on disk, sorted by last-modified first.
|
| + private List<PickerBitmap> mPickerBitmaps;
|
| +
|
| + // True if multi-selection is allowed in the picker.
|
| + private boolean mMultiSelectionAllowed;
|
| +
|
| + // The callback to notify the listener of decisions reached in the picker.
|
| + private PhotoPickerListener mListener;
|
| +
|
| + // The RecyclerView showing the images.
|
| + private RecyclerView mRecyclerView;
|
| +
|
| + // The {@link PickerAdapter} for the RecyclerView.
|
| + private PickerAdapter mPickerAdapter;
|
| +
|
| + // The {@link SelectionDelegate} keeping track of which images are selected.
|
| + private SelectionDelegate<PickerBitmap> mSelectionDelegate;
|
| +
|
| + /**
|
| + * The number of columns to show. Note: mColumns and mPadding (see below) should both be even
|
| + * numbers or both odd, not a mix (the column padding will not be of uniform thickness if they
|
| + * are a mix).
|
| + */
|
| + private int mColumns;
|
| +
|
| + // The padding between columns. See also comment for mColumns.
|
| + private int mPadding;
|
| +
|
| + // The size of the bitmaps (equal length for width and height).
|
| + private int mImageSize;
|
| +
|
| + public PickerCategoryView(Context context) {
|
| + super(context);
|
| + postConstruction(context);
|
| + }
|
| +
|
| + public PickerCategoryView(Context context, AttributeSet attrs) {
|
| + super(context, attrs);
|
| + postConstruction(context);
|
| + }
|
| +
|
| + public PickerCategoryView(Context context, AttributeSet attrs, int defStyle) {
|
| + super(context, attrs, defStyle);
|
| + postConstruction(context);
|
| + }
|
| +
|
| + /**
|
| + * A helper function for initializing the PickerCategoryView.
|
| + * @param context The context to use.
|
| + */
|
| + @SuppressWarnings("unchecked") // mSelectableListLayout
|
| + private void postConstruction(Context context) {
|
| + mContext = context;
|
| +
|
| + mSelectionDelegate = new SelectionDelegate<PickerBitmap>();
|
| +
|
| + View root = LayoutInflater.from(context).inflate(R.layout.photo_picker_dialog, this);
|
| + mSelectableListLayout =
|
| + (SelectableListLayout<PickerBitmap>) root.findViewById(R.id.selectable_list);
|
| +
|
| + mPickerAdapter = new PickerAdapter(this);
|
| + mRecyclerView = mSelectableListLayout.initializeRecyclerView(mPickerAdapter);
|
| + mSelectableListLayout.initializeToolbar(R.layout.photo_picker_toolbar, mSelectionDelegate,
|
| + R.string.photo_picker_select_images, null, R.id.photo_picker_normal_menu_group,
|
| + R.id.photo_picker_selection_mode_menu_group, R.color.default_primary_color, false,
|
| + this);
|
| +
|
| + Rect appRect = new Rect();
|
| + ((Activity) context).getWindow().getDecorView().getWindowVisibleDisplayFrame(appRect);
|
| + calculateGridMetrics(appRect.width());
|
| +
|
| + RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(mContext, mColumns);
|
| + mRecyclerView.setHasFixedSize(true);
|
| + mRecyclerView.setLayoutManager(mLayoutManager);
|
| + // TODO(finnur): Implement grid spacing.
|
| + // TODO(finnur): Implement caching.
|
| + // TODO(finnur): Remove this once the decoder service is in place.
|
| + prepareBitmaps();
|
| + }
|
| +
|
| + /**
|
| + * Initializes the PickerCategoryView object.
|
| + * @param dialog The dialog showing us.
|
| + * @param listener The listener who should be notified of actions.
|
| + * @param multiSelectionAllowed Whether to allow the user to select more than one image.
|
| + */
|
| + public void initialize(
|
| + PhotoPickerDialog dialog, PhotoPickerListener listener, boolean multiSelectionAllowed) {
|
| + // TODO(finnur): Change selection delegate to support single-selection.
|
| +
|
| + mDialog = dialog;
|
| + mMultiSelectionAllowed = multiSelectionAllowed;
|
| + mListener = listener;
|
| + }
|
| +
|
| + // OnMenuItemClickListener:
|
| +
|
| + @Override
|
| + public boolean onMenuItemClick(MenuItem item) {
|
| + if (item.getItemId() == R.id.close_menu_id) {
|
| + mListener.onPickerUserAction(PhotoPickerListener.Action.CANCEL, null);
|
| + mDialog.dismiss();
|
| + return true;
|
| + } else if (item.getItemId() == R.id.selection_mode_done_menu_id) {
|
| + notifyPhotosSelected();
|
| + mDialog.dismiss();
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + // Simple accessors:
|
| +
|
| + public int getImageSize() {
|
| + return mImageSize;
|
| + }
|
| +
|
| + public SelectionDelegate<PickerBitmap> getSelectionDelegate() {
|
| + return mSelectionDelegate;
|
| + }
|
| +
|
| + public List<PickerBitmap> getPickerBitmaps() {
|
| + return mPickerBitmaps;
|
| + }
|
| +
|
| + public boolean isMultiSelectAllowed() {
|
| + return mMultiSelectionAllowed;
|
| + }
|
| +
|
| + /**
|
| + * Notifies the listener that the user selected to launch the gallery.
|
| + */
|
| + public void showGallery() {
|
| + mListener.onPickerUserAction(PhotoPickerListener.Action.LAUNCH_GALLERY, null);
|
| + }
|
| +
|
| + /**
|
| + * Notifies the listener that the user selected to launch the camera intent.
|
| + */
|
| + public void showCamera() {
|
| + mListener.onPickerUserAction(PhotoPickerListener.Action.LAUNCH_CAMERA, null);
|
| + }
|
| +
|
| + /**
|
| + * Calculates image size and how many columns can fit on-screen.
|
| + * @param width The total width of the boundary to show the images in.
|
| + */
|
| + private void calculateGridMetrics(int width) {
|
| + int minSize =
|
| + mContext.getResources().getDimensionPixelSize(R.dimen.photo_picker_tile_min_size);
|
| + mPadding = mContext.getResources().getDimensionPixelSize(R.dimen.photo_picker_tile_gap);
|
| + mColumns = Math.max(1, (width - mPadding) / (minSize + mPadding));
|
| + mImageSize = (width - mPadding * (mColumns + 1)) / (mColumns);
|
| +
|
| + // Make sure columns and padding are either both even or both odd.
|
| + if (((mColumns % 2) == 0) != ((mPadding % 2) == 0)) {
|
| + mPadding++;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Prepares bitmaps for loading.
|
| + */
|
| + private void prepareBitmaps() {
|
| + // TODO(finnur): Use worker thread to fetch bitmaps instead of hard-coding.
|
| + mPickerBitmaps = new ArrayList<>();
|
| + mPickerBitmaps.add(0, new PickerBitmap("", 0, PickerBitmap.GALLERY));
|
| + mPickerBitmaps.add(0, new PickerBitmap("", 0, PickerBitmap.CAMERA));
|
| + mPickerBitmaps.add(new PickerBitmap("foo/bar1.jpg", 1, PickerBitmap.PICTURE));
|
| + mPickerBitmaps.add(new PickerBitmap("foo/bar2.jpg", 2, PickerBitmap.PICTURE));
|
| + mPickerBitmaps.add(new PickerBitmap("foo/bar3.jpg", 3, PickerBitmap.PICTURE));
|
| + mPickerBitmaps.add(new PickerBitmap("foo/bar4.jpg", 4, PickerBitmap.PICTURE));
|
| + mPickerAdapter.notifyDataSetChanged();
|
| + }
|
| +
|
| + /**
|
| + * Notifies any listeners that one or more photos have been selected.
|
| + */
|
| + private void notifyPhotosSelected() {
|
| + List<PickerBitmap> selectedFiles = mSelectionDelegate.getSelectedItems();
|
| + String[] photos = new String[selectedFiles.size()];
|
| + int i = 0;
|
| + for (PickerBitmap bitmap : selectedFiles) {
|
| + photos[i++] = bitmap.getFilePath();
|
| + }
|
| +
|
| + mListener.onPickerUserAction(PhotoPickerListener.Action.PHOTOS_SELECTED, photos);
|
| + }
|
| +}
|
|
|