1/*
2 * Copyright (C) 2011 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.contacts.list;
17
18import android.content.Context;
19import android.graphics.Rect;
20import android.net.Uri;
21import android.util.AttributeSet;
22import android.util.Log;
23import android.view.View;
24import android.widget.FrameLayout;
25import android.widget.ImageView;
26import android.widget.QuickContactBadge;
27import android.widget.TextView;
28
29import com.android.contacts.ContactPhotoManager;
30import com.android.contacts.ContactsUtils;
31import com.android.contacts.R;
32import com.android.contacts.list.ContactTileAdapter.ContactEntry;
33
34/**
35 * A ContactTile displays a contact's picture and name
36 */
37public abstract class ContactTileView extends FrameLayout {
38    private final static String TAG = ContactTileView.class.getSimpleName();
39
40    private Uri mLookupUri;
41    private ImageView mPhoto;
42    private QuickContactBadge mQuickContact;
43    private TextView mName;
44    private TextView mStatus;
45    private TextView mPhoneLabel;
46    private TextView mPhoneNumber;
47    private ContactPhotoManager mPhotoManager = null;
48    private View mPushState;
49    private View mHorizontalDivider;
50    protected Listener mListener;
51
52    public ContactTileView(Context context, AttributeSet attrs) {
53        super(context, attrs);
54    }
55
56    @Override
57    protected void onFinishInflate() {
58        super.onFinishInflate();
59        mName = (TextView) findViewById(R.id.contact_tile_name);
60
61        mQuickContact = (QuickContactBadge) findViewById(R.id.contact_tile_quick);
62        mPhoto = (ImageView) findViewById(R.id.contact_tile_image);
63        mStatus = (TextView) findViewById(R.id.contact_tile_status);
64        mPhoneLabel = (TextView) findViewById(R.id.contact_tile_phone_type);
65        mPhoneNumber = (TextView) findViewById(R.id.contact_tile_phone_number);
66        mPushState = findViewById(R.id.contact_tile_push_state);
67        mHorizontalDivider = findViewById(R.id.contact_tile_horizontal_divider);
68
69        OnClickListener listener = createClickListener();
70
71        if(mPushState != null) {
72            mPushState.setOnClickListener(listener);
73        } else {
74            setOnClickListener(listener);
75        }
76    }
77
78    protected OnClickListener createClickListener() {
79        return new OnClickListener() {
80            @Override
81            public void onClick(View v) {
82                if (mListener == null) return;
83                mListener.onContactSelected(
84                        getLookupUri(),
85                        ContactsUtils.getTargetRectFromView(mContext, ContactTileView.this));
86            }
87        };
88    }
89
90    public void setPhotoManager(ContactPhotoManager photoManager) {
91        mPhotoManager = photoManager;
92    }
93
94    /**
95     * Populates the data members to be displayed from the
96     * fields in {@link ContactEntry}
97     */
98    public void loadFromContact(ContactEntry entry) {
99
100        if (entry != null) {
101            mName.setText(entry.name);
102            mLookupUri = entry.lookupKey;
103
104            if (mStatus != null) {
105                if (entry.status == null) {
106                    mStatus.setVisibility(View.GONE);
107                } else {
108                    mStatus.setText(entry.status);
109                    mStatus.setCompoundDrawablesWithIntrinsicBounds(entry.presenceIcon,
110                            null, null, null);
111                    mStatus.setVisibility(View.VISIBLE);
112                }
113            }
114
115            if (mPhoneLabel != null) {
116                mPhoneLabel.setText(entry.phoneLabel);
117            }
118
119            if (mPhoneNumber != null) {
120                // TODO: Format number correctly
121                mPhoneNumber.setText(entry.phoneNumber);
122            }
123
124            setVisibility(View.VISIBLE);
125
126            if (mPhotoManager != null) {
127                if (mPhoto != null) {
128                    mPhotoManager.loadPhoto(mPhoto, entry.photoUri, getApproximateImageSize(),
129                            isDarkTheme());
130
131                    if (mQuickContact != null) {
132                        mQuickContact.assignContactUri(mLookupUri);
133                    }
134                } else if (mQuickContact != null) {
135                    mQuickContact.assignContactUri(mLookupUri);
136                    mPhotoManager.loadPhoto(mQuickContact, entry.photoUri,
137                            getApproximateImageSize(), isDarkTheme());
138                }
139            } else {
140                Log.w(TAG, "contactPhotoManager not set");
141            }
142
143            if (mPushState != null) {
144                mPushState.setContentDescription(entry.name);
145            } else if (mQuickContact != null) {
146                mQuickContact.setContentDescription(entry.name);
147            }
148        } else {
149            setVisibility(View.INVISIBLE);
150        }
151    }
152
153    public void setListener(Listener listener) {
154        mListener = listener;
155    }
156
157    public void setHorizontalDividerVisibility(int visibility) {
158        if (mHorizontalDivider != null) mHorizontalDivider.setVisibility(visibility);
159    }
160
161    public Uri getLookupUri() {
162        return mLookupUri;
163    }
164
165    protected QuickContactBadge getQuickContact() {
166        return mQuickContact;
167    }
168
169    /**
170     * Implemented by subclasses to estimate the size of the picture. This can return -1 if only
171     * a thumbnail is shown anyway
172     */
173    protected abstract int getApproximateImageSize();
174
175    protected abstract boolean isDarkTheme();
176
177    public interface Listener {
178        /**
179         * Notification that the contact was selected; no specific action is dictated.
180         */
181        void onContactSelected(Uri contactLookupUri, Rect viewRect);
182        /**
183         * Notification that the specified number is to be called.
184         */
185        void onCallNumberDirectly(String phoneNumber);
186        /**
187         * @return The width of each tile. This doesn't have to be a precise number (e.g. paddings
188         *         can be ignored), but is used to load the correct picture size from the database
189         */
190        int getApproximateTileWidth();
191    }
192}
193