1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.messaging.ui.mediapicker;
17
18import android.content.Context;
19import android.database.Cursor;
20import android.graphics.Rect;
21import android.util.AttributeSet;
22import android.view.MotionEvent;
23import android.view.TouchDelegate;
24import android.view.View;
25import android.widget.CheckBox;
26import android.widget.FrameLayout;
27import android.widget.ImageView.ScaleType;
28
29import com.android.messaging.R;
30import com.android.messaging.datamodel.DataModel;
31import com.android.messaging.datamodel.data.GalleryGridItemData;
32import com.android.messaging.ui.AsyncImageView;
33import com.android.messaging.ui.ConversationDrawables;
34import com.google.common.annotations.VisibleForTesting;
35
36import java.util.concurrent.TimeUnit;
37
38/**
39 * Shows an item in the gallery picker grid view. Hosts an FileImageView with a checkbox.
40 */
41public class GalleryGridItemView extends FrameLayout {
42    /**
43     * Implemented by the owner of this GalleryGridItemView instance to communicate on media
44     * picking and selection events.
45     */
46    public interface HostInterface {
47        void onItemClicked(View view, GalleryGridItemData data, boolean longClick);
48        boolean isItemSelected(GalleryGridItemData data);
49        boolean isMultiSelectEnabled();
50    }
51
52    @VisibleForTesting
53    GalleryGridItemData mData;
54    private AsyncImageView mImageView;
55    private CheckBox mCheckBox;
56    private HostInterface mHostInterface;
57    private final OnClickListener mOnClickListener = new OnClickListener() {
58        @Override
59        public void onClick(final View v) {
60            mHostInterface.onItemClicked(GalleryGridItemView.this, mData, false /*longClick*/);
61        }
62    };
63
64    public GalleryGridItemView(final Context context, final AttributeSet attrs) {
65        super(context, attrs);
66        mData = DataModel.get().createGalleryGridItemData();
67    }
68
69    @Override
70    protected void onFinishInflate() {
71        super.onFinishInflate();
72        mImageView = (AsyncImageView) findViewById(R.id.image);
73        mCheckBox = (CheckBox) findViewById(R.id.checkbox);
74        mCheckBox.setOnClickListener(mOnClickListener);
75        setOnClickListener(mOnClickListener);
76        final OnLongClickListener longClickListener = new OnLongClickListener() {
77            @Override
78            public boolean onLongClick(final View v) {
79                mHostInterface.onItemClicked(v, mData, true /* longClick */);
80                return true;
81            }
82        };
83        setOnLongClickListener(longClickListener);
84        mCheckBox.setOnLongClickListener(longClickListener);
85        addOnLayoutChangeListener(new OnLayoutChangeListener() {
86            @Override
87            public void onLayoutChange(View v, int left, int top, int right, int bottom,
88                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
89                // Enlarge the clickable region for the checkbox to fill the entire view.
90                final Rect region = new Rect(0, 0, getWidth(), getHeight());
91                setTouchDelegate(new TouchDelegate(region, mCheckBox) {
92                    @Override
93                    public boolean onTouchEvent(MotionEvent event) {
94                        switch (event.getAction()) {
95                            case MotionEvent.ACTION_DOWN:
96                                setPressed(true);
97                                break;
98                            case MotionEvent.ACTION_UP:
99                            case MotionEvent.ACTION_CANCEL:
100                                setPressed(false);
101                                break;
102                        }
103                        return super.onTouchEvent(event);
104                    }
105                });
106            }
107        });
108    }
109
110    @Override
111    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
112        // The grid view auto-fit the columns, so we want to let the height match the width
113        // to make the image square.
114        super.onMeasure(widthMeasureSpec, widthMeasureSpec);
115    }
116
117    public void bind(final Cursor cursor, final HostInterface hostInterface) {
118        final int desiredSize = getResources()
119                .getDimensionPixelSize(R.dimen.gallery_image_cell_size);
120        mData.bind(cursor, desiredSize, desiredSize);
121        mHostInterface = hostInterface;
122        updateViewState();
123    }
124
125    private void updateViewState() {
126        updateImageView();
127        if (mHostInterface.isMultiSelectEnabled() && !mData.isDocumentPickerItem()) {
128            mCheckBox.setVisibility(VISIBLE);
129            mCheckBox.setClickable(true);
130            mCheckBox.setChecked(mHostInterface.isItemSelected(mData));
131        } else {
132            mCheckBox.setVisibility(GONE);
133            mCheckBox.setClickable(false);
134        }
135    }
136
137    private void updateImageView() {
138        if (mData.isDocumentPickerItem()) {
139            mImageView.setScaleType(ScaleType.CENTER);
140            setBackgroundColor(ConversationDrawables.get().getConversationThemeColor());
141            mImageView.setImageResourceId(null);
142            mImageView.setImageResource(R.drawable.ic_photo_library_light);
143            mImageView.setContentDescription(getResources().getString(
144                    R.string.pick_image_from_document_library_content_description));
145        } else {
146            mImageView.setScaleType(ScaleType.CENTER_CROP);
147            setBackgroundColor(getResources().getColor(R.color.gallery_image_default_background));
148            mImageView.setImageResourceId(mData.getImageRequestDescriptor());
149            final long dateSeconds = mData.getDateSeconds();
150            final boolean isValidDate = (dateSeconds > 0);
151            final int templateId = isValidDate ?
152                    R.string.mediapicker_gallery_image_item_description :
153                    R.string.mediapicker_gallery_image_item_description_no_date;
154            String contentDescription = String.format(getResources().getString(templateId),
155                    dateSeconds * TimeUnit.SECONDS.toMillis(1));
156            mImageView.setContentDescription(contentDescription);
157        }
158    }
159}
160