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 */
17package com.android.dialer.list;
18
19import android.content.ClipData;
20import android.content.Context;
21import android.text.TextUtils;
22import android.util.AttributeSet;
23import android.view.View;
24import android.widget.ImageView;
25
26import com.android.contacts.common.ContactPhotoManager;
27import com.android.contacts.common.MoreContactUtils;
28import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
29import com.android.contacts.common.list.ContactEntry;
30import com.android.contacts.common.list.ContactTileView;
31import 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 */
40public 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
65    public PhoneFavoriteTileView(Context context, AttributeSet attrs) {
66        super(context, attrs);
67    }
68
69    @Override
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
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
109    protected boolean isDarkTheme() {
110        return false;
111    }
112
113    @Override
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