Home | History | Annotate | Download | only in ui
      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  */
     16 package com.android.messaging.ui;
     17 
     18 import android.content.Context;
     19 import android.content.res.Resources;
     20 import android.graphics.Rect;
     21 import android.net.Uri;
     22 import android.support.annotation.Nullable;
     23 import android.text.TextUtils;
     24 import android.view.LayoutInflater;
     25 import android.view.View;
     26 import android.view.View.OnClickListener;
     27 import android.view.View.OnLongClickListener;
     28 import android.view.ViewGroup;
     29 import android.widget.FrameLayout.LayoutParams;
     30 import android.widget.ImageView;
     31 import android.widget.TextView;
     32 
     33 import com.android.messaging.R;
     34 import com.android.messaging.datamodel.DataModel;
     35 import com.android.messaging.datamodel.data.MessagePartData;
     36 import com.android.messaging.datamodel.data.PendingAttachmentData;
     37 import com.android.messaging.datamodel.data.PersonItemData;
     38 import com.android.messaging.datamodel.data.VCardContactItemData;
     39 import com.android.messaging.datamodel.media.FileImageRequestDescriptor;
     40 import com.android.messaging.datamodel.media.ImageRequest;
     41 import com.android.messaging.datamodel.media.ImageRequestDescriptor;
     42 import com.android.messaging.datamodel.media.UriImageRequestDescriptor;
     43 import com.android.messaging.ui.MultiAttachmentLayout.OnAttachmentClickListener;
     44 import com.android.messaging.ui.PersonItemView.PersonItemViewListener;
     45 import com.android.messaging.util.Assert;
     46 import com.android.messaging.util.ContentType;
     47 import com.android.messaging.util.ImageUtils;
     48 import com.android.messaging.util.UiUtils;
     49 import com.android.messaging.util.UriUtil;
     50 
     51 /**
     52  * A view factory that creates previews for single/multiple attachments.
     53  */
     54 public class AttachmentPreviewFactory {
     55     /** Standalone attachment preview */
     56     public static final int TYPE_SINGLE = 1;
     57 
     58     /** Attachment preview displayed in a multi-attachment layout */
     59     public static final int TYPE_MULTIPLE = 2;
     60 
     61     /** Attachment preview displayed in the attachment chooser grid view */
     62     public static final int TYPE_CHOOSER_GRID = 3;
     63 
     64     public static View createAttachmentPreview(final LayoutInflater layoutInflater,
     65             final MessagePartData attachmentData, final ViewGroup parent,
     66             final int viewType, final boolean startImageRequest,
     67             @Nullable final OnAttachmentClickListener clickListener) {
     68         final String contentType = attachmentData.getContentType();
     69         View attachmentView = null;
     70         if (attachmentData instanceof PendingAttachmentData) {
     71             attachmentView = createPendingAttachmentPreview(layoutInflater, parent,
     72                     (PendingAttachmentData) attachmentData);
     73         } else if (ContentType.isImageType(contentType)) {
     74             attachmentView = createImagePreview(layoutInflater, attachmentData, parent, viewType,
     75                     startImageRequest);
     76         } else if (ContentType.isAudioType(contentType)) {
     77             attachmentView = createAudioPreview(layoutInflater, attachmentData, parent, viewType);
     78         } else if (ContentType.isVideoType(contentType)) {
     79             attachmentView = createVideoPreview(layoutInflater, attachmentData, parent, viewType);
     80         } else if (ContentType.isVCardType(contentType)) {
     81             attachmentView = createVCardPreview(layoutInflater, attachmentData, parent, viewType);
     82         } else {
     83             Assert.fail("unsupported attachment type: " + contentType);
     84             return null;
     85         }
     86 
     87         // Some views have a caption, set the text/visibility if one exists
     88         final TextView captionView = (TextView) attachmentView.findViewById(R.id.caption);
     89         if (captionView != null) {
     90             final String caption = attachmentData.getText();
     91             captionView.setVisibility(TextUtils.isEmpty(caption) ? View.GONE : View.VISIBLE);
     92             captionView.setText(caption);
     93         }
     94 
     95         if (attachmentView != null && clickListener != null) {
     96             attachmentView.setOnClickListener(new OnClickListener() {
     97                     @Override
     98                     public void onClick(final View view) {
     99                         final Rect bounds = UiUtils.getMeasuredBoundsOnScreen(view);
    100                         clickListener.onAttachmentClick(attachmentData, bounds,
    101                                 false /* longPress */);
    102                     }
    103                 });
    104             attachmentView.setOnLongClickListener(new OnLongClickListener() {
    105                     @Override
    106                     public boolean onLongClick(final View view) {
    107                         final Rect bounds = UiUtils.getMeasuredBoundsOnScreen(view);
    108                         return clickListener.onAttachmentClick(attachmentData, bounds,
    109                                 true /* longPress */);
    110                     }
    111                 });
    112         }
    113         return attachmentView;
    114     }
    115 
    116     public static MultiAttachmentLayout createMultiplePreview(final Context context,
    117             final OnAttachmentClickListener listener) {
    118         final MultiAttachmentLayout multiAttachmentLayout =
    119                 new MultiAttachmentLayout(context, null);
    120         final ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
    121                 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    122         multiAttachmentLayout.setLayoutParams(layoutParams);
    123         multiAttachmentLayout.setOnAttachmentClickListener(listener);
    124         return multiAttachmentLayout;
    125     }
    126 
    127     public static ImageRequestDescriptor getImageRequestDescriptorForAttachment(
    128             final MessagePartData attachmentData, final int desiredWidth, final int desiredHeight) {
    129         final Uri uri = attachmentData.getContentUri();
    130         final String contentType = attachmentData.getContentType();
    131         if (ContentType.isImageType(contentType)) {
    132             final String filePath = UriUtil.getFilePathFromUri(uri);
    133             if (filePath != null) {
    134                 return new FileImageRequestDescriptor(filePath, desiredWidth, desiredHeight,
    135                         attachmentData.getWidth(), attachmentData.getHeight(),
    136                         false /* canUseThumbnail */, true /* allowCompression */,
    137                         false /* isStatic */);
    138             } else {
    139                 return new UriImageRequestDescriptor(uri, desiredWidth, desiredHeight,
    140                         attachmentData.getWidth(), attachmentData.getHeight(),
    141                         true /* allowCompression */, false /* isStatic */, false /*cropToCircle*/,
    142                         ImageUtils.DEFAULT_CIRCLE_BACKGROUND_COLOR /* circleBackgroundColor */,
    143                         ImageUtils.DEFAULT_CIRCLE_STROKE_COLOR /* circleStrokeColor */);
    144             }
    145         }
    146         return null;
    147     }
    148 
    149     private static View createImagePreview(final LayoutInflater layoutInflater,
    150             final MessagePartData attachmentData, final ViewGroup parent,
    151             final int viewType, final boolean startImageRequest) {
    152         int layoutId = R.layout.attachment_single_image;
    153         switch (viewType) {
    154             case AttachmentPreviewFactory.TYPE_SINGLE:
    155                 layoutId = R.layout.attachment_single_image;
    156                 break;
    157             case AttachmentPreviewFactory.TYPE_MULTIPLE:
    158                 layoutId = R.layout.attachment_multiple_image;
    159                 break;
    160             case AttachmentPreviewFactory.TYPE_CHOOSER_GRID:
    161                 layoutId = R.layout.attachment_chooser_image;
    162                 break;
    163             default:
    164                 Assert.fail("unsupported attachment view type!");
    165                 break;
    166         }
    167         final View view = layoutInflater.inflate(layoutId, parent, false /* attachToRoot */);
    168         final AsyncImageView imageView = (AsyncImageView) view.findViewById(
    169                 R.id.attachment_image_view);
    170         int maxWidth = imageView.getMaxWidth();
    171         int maxHeight = imageView.getMaxHeight();
    172         if (viewType == TYPE_CHOOSER_GRID) {
    173             final Resources resources = layoutInflater.getContext().getResources();
    174             maxWidth = maxHeight = resources.getDimensionPixelSize(
    175                     R.dimen.attachment_grid_image_cell_size);
    176         }
    177         if (maxWidth <= 0 || maxWidth == Integer.MAX_VALUE) {
    178             maxWidth = ImageRequest.UNSPECIFIED_SIZE;
    179         }
    180         if (maxHeight <= 0 || maxHeight == Integer.MAX_VALUE) {
    181             maxHeight = ImageRequest.UNSPECIFIED_SIZE;
    182         }
    183         if (startImageRequest) {
    184             imageView.setImageResourceId(getImageRequestDescriptorForAttachment(attachmentData,
    185                     maxWidth, maxHeight));
    186         }
    187         imageView.setContentDescription(
    188                 parent.getResources().getString(R.string.message_image_content_description));
    189         return view;
    190     }
    191 
    192     private static View createPendingAttachmentPreview(final LayoutInflater layoutInflater,
    193             final ViewGroup parent, final PendingAttachmentData attachmentData) {
    194         final View pendingItemView = layoutInflater.inflate(R.layout.attachment_pending_item,
    195                 parent, false);
    196         final ImageView imageView = (ImageView)
    197                 pendingItemView.findViewById(R.id.pending_item_view);
    198         final ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
    199         final int defaultSize = layoutInflater.getContext().getResources().getDimensionPixelSize(
    200                 R.dimen.pending_attachment_size);
    201         layoutParams.width = attachmentData.getWidth() == MessagePartData.UNSPECIFIED_SIZE ?
    202                 defaultSize : attachmentData.getWidth();
    203         layoutParams.height = attachmentData.getHeight() == MessagePartData.UNSPECIFIED_SIZE ?
    204                 defaultSize : attachmentData.getHeight();
    205         return pendingItemView;
    206     }
    207 
    208     private static View createVCardPreview(final LayoutInflater layoutInflater,
    209             final MessagePartData attachmentData, final ViewGroup parent,
    210             final int viewType) {
    211         int layoutId = R.layout.attachment_single_vcard;
    212         switch (viewType) {
    213             case AttachmentPreviewFactory.TYPE_SINGLE:
    214                 layoutId = R.layout.attachment_single_vcard;
    215                 break;
    216             case AttachmentPreviewFactory.TYPE_MULTIPLE:
    217                 layoutId = R.layout.attachment_multiple_vcard;
    218                 break;
    219             case AttachmentPreviewFactory.TYPE_CHOOSER_GRID:
    220                 layoutId = R.layout.attachment_chooser_vcard;
    221                 break;
    222             default:
    223                 Assert.fail("unsupported attachment view type!");
    224                 break;
    225         }
    226         final View view = layoutInflater.inflate(layoutId, parent, false /* attachToRoot */);
    227         final PersonItemView vcardPreview = (PersonItemView) view.findViewById(
    228                 R.id.vcard_attachment_view);
    229         vcardPreview.setAvatarOnly(viewType != AttachmentPreviewFactory.TYPE_SINGLE);
    230         vcardPreview.bind(DataModel.get().createVCardContactItemData(layoutInflater.getContext(),
    231                 attachmentData));
    232         vcardPreview.setListener(new PersonItemViewListener() {
    233             @Override
    234             public void onPersonClicked(final PersonItemData data) {
    235                 Assert.isTrue(data instanceof VCardContactItemData);
    236                 final VCardContactItemData vCardData = (VCardContactItemData) data;
    237                 if (vCardData.hasValidVCard()) {
    238                     final Uri vCardUri = vCardData.getVCardUri();
    239                     UIIntents.get().launchVCardDetailActivity(vcardPreview.getContext(), vCardUri);
    240                 }
    241             }
    242 
    243             @Override
    244             public boolean onPersonLongClicked(final PersonItemData data) {
    245                 return false;
    246             }
    247         });
    248         return view;
    249     }
    250 
    251     private static View createAudioPreview(final LayoutInflater layoutInflater,
    252                 final MessagePartData attachmentData, final ViewGroup parent,
    253                 final int viewType) {
    254         int layoutId = R.layout.attachment_single_audio;
    255         switch (viewType) {
    256             case AttachmentPreviewFactory.TYPE_SINGLE:
    257                 layoutId = R.layout.attachment_single_audio;
    258                 break;
    259             case AttachmentPreviewFactory.TYPE_MULTIPLE:
    260                 layoutId = R.layout.attachment_multiple_audio;
    261                 break;
    262             case AttachmentPreviewFactory.TYPE_CHOOSER_GRID:
    263                 layoutId = R.layout.attachment_chooser_audio;
    264                 break;
    265             default:
    266                 Assert.fail("unsupported attachment view type!");
    267                 break;
    268         }
    269         final View view = layoutInflater.inflate(layoutId, parent, false /* attachToRoot */);
    270         final AudioAttachmentView audioView = (AudioAttachmentView)
    271                 view.findViewById(R.id.audio_attachment_view);
    272         audioView.bindMessagePartData(
    273                 attachmentData, false /* incoming */, false /* showAsSelected */);
    274         return view;
    275     }
    276 
    277     private static View createVideoPreview(final LayoutInflater layoutInflater,
    278             final MessagePartData attachmentData, final ViewGroup parent,
    279             final int viewType) {
    280         int layoutId = R.layout.attachment_single_video;
    281         switch (viewType) {
    282             case AttachmentPreviewFactory.TYPE_SINGLE:
    283                 layoutId = R.layout.attachment_single_video;
    284                 break;
    285             case AttachmentPreviewFactory.TYPE_MULTIPLE:
    286                 layoutId = R.layout.attachment_multiple_video;
    287                 break;
    288             case AttachmentPreviewFactory.TYPE_CHOOSER_GRID:
    289                 layoutId = R.layout.attachment_chooser_video;
    290                 break;
    291             default:
    292                 Assert.fail("unsupported attachment view type!");
    293                 break;
    294         }
    295         final VideoThumbnailView videoThumbnail = (VideoThumbnailView) layoutInflater.inflate(
    296                 layoutId, parent, false /* attachToRoot */);
    297         videoThumbnail.setSource(attachmentData, false /* incomingMessage */);
    298         return videoThumbnail;
    299     }
    300 }
    301