1 /*
2 
3  * Copyright (C) 2011 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package com.android.dialer.list;
18 
19 import android.content.ClipData;
20 import android.content.Context;
21 import android.text.TextUtils;
22 import android.util.AttributeSet;
23 import android.view.View;
24 import android.widget.ImageView;
25 
26 import com.android.contacts.common.ContactPhotoManager;
27 import com.android.contacts.common.MoreContactUtils;
28 import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
29 import com.android.contacts.common.list.ContactEntry;
30 import com.android.contacts.common.list.ContactTileView;
31 import com.android.dialer.R;
32 
33 /**
34  * A light version of the {@link com.android.contacts.common.list.ContactTileView} that is used in
35  * Dialtacts for frequently called contacts. Slightly different behavior from superclass when you
36  * tap it, you want to call the frequently-called number for the contact, even if that is not the
37  * default number for that contact. This abstract class is the super class to both the row and tile
38  * view.
39  */
40 public abstract class PhoneFavoriteTileView extends ContactTileView {
41 
42     private static final String TAG = PhoneFavoriteTileView.class.getSimpleName();
43     private static final boolean DEBUG = false;
44 
45     // These parameters instruct the photo manager to display the default image/letter at 70% of
46     // its normal size, and vertically offset upwards 12% towards the top of the letter tile, to
47     // make room for the contact name and number label at the bottom of the image.
48     private static final float DEFAULT_IMAGE_LETTER_OFFSET = -0.12f;
49     private static final float DEFAULT_IMAGE_LETTER_SCALE = 0.70f;
50 
51     /** View that contains the transparent shadow that is overlaid on top of the contact image. */
52     private View mShadowOverlay;
53 
54     /** Users' most frequent phone number. */
55     private String mPhoneNumberString;
56 
57     // Dummy clip data object that is attached to drag shadows so that text views
58     // don't crash with an NPE if the drag shadow is released in their bounds
59     private static final ClipData EMPTY_CLIP_DATA = ClipData.newPlainText("", "");
60 
61     // Constant to pass to the drag event so that the drag action only happens when a phone favorite
62     // tile is long pressed.
63     static final String DRAG_PHONE_FAVORITE_TILE = "PHONE_FAVORITE_TILE";
64 
PhoneFavoriteTileView(Context context, AttributeSet attrs)65     public PhoneFavoriteTileView(Context context, AttributeSet attrs) {
66         super(context, attrs);
67     }
68 
69     @Override
onFinishInflate()70     protected void onFinishInflate() {
71         super.onFinishInflate();
72         mShadowOverlay = findViewById(R.id.shadow_overlay);
73 
74         setOnLongClickListener(new OnLongClickListener() {
75             @Override
76             public boolean onLongClick(View v) {
77                 final PhoneFavoriteTileView view = (PhoneFavoriteTileView) v;
78                 // NOTE The drag shadow is handled in the ListView.
79                 view.startDrag(EMPTY_CLIP_DATA, new View.DragShadowBuilder(),
80                         DRAG_PHONE_FAVORITE_TILE, 0);
81                 return true;
82             }
83         });
84     }
85 
86     @Override
loadFromContact(ContactEntry entry)87     public void loadFromContact(ContactEntry entry) {
88         super.loadFromContact(entry);
89         // Set phone number to null in case we're reusing the view.
90         mPhoneNumberString = null;
91         if (entry != null) {
92             // Grab the phone-number to call directly. See {@link onClick()}.
93             mPhoneNumberString = entry.phoneNumber;
94 
95             // If this is a blank entry, don't show anything.
96             // TODO krelease: Just hide the view for now. For this to truly look like an empty row
97             // the entire ContactTileRow needs to be hidden.
98             if (entry == ContactEntry.BLANK_ENTRY) {
99                 setVisibility(View.INVISIBLE);
100             } else {
101                 final ImageView starIcon = (ImageView) findViewById(R.id.contact_star_icon);
102                 starIcon.setVisibility(entry.isFavorite ? View.VISIBLE : View.GONE);
103                 setVisibility(View.VISIBLE);
104             }
105         }
106     }
107 
108     @Override
isDarkTheme()109     protected boolean isDarkTheme() {
110         return false;
111     }
112 
113     @Override
createClickListener()114     protected OnClickListener createClickListener() {
115         return new OnClickListener() {
116             @Override
117             public void onClick(View v) {
118                 if (mListener == null) {
119                     return;
120                 }
121                 if (TextUtils.isEmpty(mPhoneNumberString)) {
122                     // Copy "superclass" implementation
123                     mListener.onContactSelected(getLookupUri(), MoreContactUtils
124                             .getTargetRectFromView(PhoneFavoriteTileView.this));
125                 } else {
126                     // When you tap a frequently-called contact, you want to
127                     // call them at the number that you usually talk to them
128                     // at (i.e. the one displayed in the UI), regardless of
129                     // whether that's their default number.
130                     mListener.onCallNumberDirectly(mPhoneNumberString);
131                 }
132             }
133         };
134     }
135 
136     @Override
137     protected DefaultImageRequest getDefaultImageRequest(String displayName, String lookupKey) {
138         return new DefaultImageRequest(displayName, lookupKey, ContactPhotoManager.TYPE_DEFAULT,
139                 DEFAULT_IMAGE_LETTER_SCALE, DEFAULT_IMAGE_LETTER_OFFSET, false);
140     }
141 
142     @Override
143     protected void configureViewForImage(boolean isDefaultImage) {
144         // Hide the shadow overlay if the image is a default image (i.e. colored letter tile)
145         if (mShadowOverlay != null) {
146             mShadowOverlay.setVisibility(isDefaultImage ? View.GONE : View.VISIBLE);
147         }
148     }
149 
150     @Override
151     protected boolean isContactPhotoCircular() {
152         // Unlike Contacts' tiles, the Dialer's favorites tiles are square.
153         return false;
154     }
155 }
156