18b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo/*
28b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * Copyright (C) 2011 The Android Open Source Project
38b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo *
48b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * Licensed under the Apache License, Version 2.0 (the "License");
58b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * you may not use this file except in compliance with the License.
68b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * You may obtain a copy of the License at
78b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo *
88b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo *      http://www.apache.org/licenses/LICENSE-2.0
98b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo *
108b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * Unless required by applicable law or agreed to in writing, software
118b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * distributed under the License is distributed on an "AS IS" BASIS,
128b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * See the License for the specific language governing permissions and
148b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * limitations under the License.
158b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo */
168b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
178b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
188b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalopackage com.android.email.activity;
198b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
208b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.content.Context;
218b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.content.res.Resources;
228b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.graphics.Typeface;
238b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.text.TextPaint;
248b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.util.SparseArray;
258b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.view.LayoutInflater;
268b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.view.View;
278b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.view.View.MeasureSpec;
288b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.view.ViewGroup;
298b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.view.ViewParent;
308b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komaloimport android.widget.TextView;
318b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
32383279a1c5e0cba982645a5ed06e06534d12159eBen Komaloimport com.android.email.R;
33383279a1c5e0cba982645a5ed06e06534d12159eBen Komalo
348b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo/**
358b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * Represents the coordinates of elements inside a CanvasConversationHeaderView
368b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * (eg, checkmark, star, subject, sender, labels, etc.) It will inflate a view,
378b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * and record the coordinates of each element after layout. This will allows us
388b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * to easily improve performance by creating custom view while still defining
398b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo * layout in XML files.
408b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo */
418b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalopublic class MessageListItemCoordinates {
428b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Modes.
438b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    public static final int WIDE_MODE = 0;
448b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    public static final int NORMAL_MODE = 1;
458b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
468b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Static threshold.
478b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    private static int MINIMUM_WIDTH_WIDE_MODE = -1;
488b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    private static int[] SUBJECT_LENGTHS;
498b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
508b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Checkmark.
518b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int checkmarkX;
528b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int checkmarkY;
538b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int checkmarkWidthIncludingMargins;
548b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
55e2f6f18396f27d2fee1149d6a3896721297bf7f3Jorge Lugo    // Reply and forward state.
56e2f6f18396f27d2fee1149d6a3896721297bf7f3Jorge Lugo    int stateX;
57e2f6f18396f27d2fee1149d6a3896721297bf7f3Jorge Lugo    int stateY;
58e2f6f18396f27d2fee1149d6a3896721297bf7f3Jorge Lugo
598b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Star.
608b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int starX;
618b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int starY;
628b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
638b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Senders.
648b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int sendersX;
658b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int sendersY;
668b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int sendersWidth;
678b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int sendersLineCount;
688b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int sendersFontSize;
698b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int sendersAscent;
708b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
718b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Subject.
728b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int subjectX;
738b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int subjectY;
748b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int subjectWidth;
758b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int subjectLineCount;
768b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int subjectFontSize;
778b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int subjectAscent;
788b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
798b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Color chip.
808b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int chipX;
818b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int chipY;
828b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int chipWidth;
838b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int chipHeight;
848b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
858b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Date.
868b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int dateXEnd;
878b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int dateY;
888b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int dateFontSize;
898b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int dateAscent;
908b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
918b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Paperclip.
928b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    int paperclipY;
938b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
948b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Cache to save Coordinates based on view width.
958b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    private static SparseArray<MessageListItemCoordinates> mCache =
968b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            new SparseArray<MessageListItemCoordinates>();
978b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
988b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    private static TextPaint sPaint = new TextPaint();
998b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
1008b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    static {
1018b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        sPaint.setTypeface(Typeface.DEFAULT);
1028b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        sPaint.setAntiAlias(true);
1038b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
1048b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
1058b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    // Not directly instantiable.
1068b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    private MessageListItemCoordinates() {}
1078b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
1088b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
1098b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns the mode of the header view (Wide/Normal/Narrow) given the its
1108b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * measured width.
1118b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
1128b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    public static int getMode(Context context, int width) {
1138b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        Resources res = context.getResources();
114383279a1c5e0cba982645a5ed06e06534d12159eBen Komalo        if (MINIMUM_WIDTH_WIDE_MODE <= 0) {
1158b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            MINIMUM_WIDTH_WIDE_MODE = res.getDimensionPixelSize(R.dimen.minimum_width_wide_mode);
1168b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        }
1178b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
1188b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        // Choose the correct mode based on view width.
119383279a1c5e0cba982645a5ed06e06534d12159eBen Komalo        int mode = NORMAL_MODE;
1208b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        if (width > MINIMUM_WIDTH_WIDE_MODE) {
1218b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            mode = WIDE_MODE;
1228b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        }
1238b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        return mode;
1248b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
1258b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
126e4202e782c91075c09cd5c348517a90620622a7fMindy Pereira    public static boolean isMultiPane(Context context) {
127e4202e782c91075c09cd5c348517a90620622a7fMindy Pereira        return UiUtilities.useTwoPane(context);
128e4202e782c91075c09cd5c348517a90620622a7fMindy Pereira    }
129e4202e782c91075c09cd5c348517a90620622a7fMindy Pereira
1308b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
1318b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns the layout id to be inflated in this mode.
1328b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
1338b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    private static int getLayoutId(int mode) {
1348b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        switch (mode) {
1358b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            case WIDE_MODE:
1368b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo                return R.layout.message_list_item_wide;
1378b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            case NORMAL_MODE:
1388b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo                return R.layout.message_list_item_normal;
1398b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            default:
1408b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo                throw new IllegalArgumentException("Unknown conversation header view mode " + mode);
1418b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        }
1428b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
1438b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
1448b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
1458b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns a value array multiplied by the specified density.
1468b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
1478b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    public static int[] getDensityDependentArray(int[] values, float density) {
1488b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        int result[] = new int[values.length];
1498b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        for (int i = 0; i < values.length; ++i) {
1508b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            result[i] = (int) (values[i] * density);
1518b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        }
1528b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        return result;
1538b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
1548b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
1558b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
1568b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns the height of the view in this mode.
1578b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
1588b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    public static int getHeight(Context context, int mode) {
1592ae341bfa1e8e05528946f070470ddad14b91355Ben Komalo        return context.getResources().getDimensionPixelSize(
1602ae341bfa1e8e05528946f070470ddad14b91355Ben Komalo                (mode == WIDE_MODE)
1612ae341bfa1e8e05528946f070470ddad14b91355Ben Komalo                        ? R.dimen.message_list_item_height_wide
1622ae341bfa1e8e05528946f070470ddad14b91355Ben Komalo                        : R.dimen.message_list_item_height_normal);
1638b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
1648b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
1658b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
1668b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns the x coordinates of a view by tracing up its hierarchy.
1678b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
1688b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    private static int getX(View view) {
1698b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        int x = 0;
1708b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        while (view != null) {
1718b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            x += (int) view.getX();
1728b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            ViewParent parent = view.getParent();
1738b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            view = parent != null ? (View) parent : null;
1748b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        }
1758b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        return x;
1768b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
1778b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
1788b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
1798b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns the y coordinates of a view by tracing up its hierarchy.
1808b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
1818b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    private static int getY(View view) {
1828b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        int y = 0;
1838b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        while (view != null) {
1848b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            y += (int) view.getY();
1858b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            ViewParent parent = view.getParent();
1868b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            view = parent != null ? (View) parent : null;
1878b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        }
1888b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        return y;
1898b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
1908b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
1918b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
1928b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns the width of a view.
1938b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     *
1948b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * @param includeMargins whether or not to include margins when calculating
1958b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     *            width.
1968b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
1978b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    public static int getWidth(View view, boolean includeMargins) {
1988b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
1998b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        return view.getWidth() + (includeMargins ? params.leftMargin + params.rightMargin : 0);
2008b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
2018b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
2028b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
2038b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns the height of a view.
2048b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     *
2058b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * @param includeMargins whether or not to include margins when calculating
2068b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     *            height.
2078b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
2088b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    public static int getHeight(View view, boolean includeMargins) {
2098b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
2108b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        return view.getHeight() + (includeMargins ? params.topMargin + params.bottomMargin : 0);
2118b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
2128b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
2138b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
2148b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns the number of lines of this text view.
2158b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
2168b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    private static int getLineCount(TextView textView) {
2178b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        return textView.getHeight() / textView.getLineHeight();
2188b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
2198b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
2208b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
2218b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns the length (maximum of characters) of subject in this mode.
2228b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
2238b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    public static int getSubjectLength(Context context, int mode) {
2248b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        Resources res = context.getResources();
2258b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        if (SUBJECT_LENGTHS == null) {
2268b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            SUBJECT_LENGTHS = res.getIntArray(R.array.subject_lengths);
2278b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        }
2288b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        return SUBJECT_LENGTHS[mode];
2298b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
2308b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
2318b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    /**
23228e496daef8be15def1de3787845a22bed0c8b79Ben Komalo     * Reset the caches associated with the coordinate layouts.
23328e496daef8be15def1de3787845a22bed0c8b79Ben Komalo     */
23428e496daef8be15def1de3787845a22bed0c8b79Ben Komalo    static void resetCaches() {
23528e496daef8be15def1de3787845a22bed0c8b79Ben Komalo        mCache.clear();
23628e496daef8be15def1de3787845a22bed0c8b79Ben Komalo    }
23728e496daef8be15def1de3787845a22bed0c8b79Ben Komalo
23828e496daef8be15def1de3787845a22bed0c8b79Ben Komalo    /**
2398b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * Returns coordinates for elements inside a conversation header view given
2408b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     * the view width.
2418b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo     */
2428b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    public static MessageListItemCoordinates forWidth(Context context, int width) {
2438b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        MessageListItemCoordinates coordinates = mCache.get(width);
2448b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        if (coordinates == null) {
2458b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates = new MessageListItemCoordinates();
2468b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            mCache.put(width, coordinates);
2478b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            // TODO: make the field computation done inside of the constructor and mark fields final
2488b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
2498b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            // Layout the appropriate view.
2508b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            int mode = getMode(context, width);
2518b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            int height = getHeight(context, mode);
2528b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            View view = LayoutInflater.from(context).inflate(getLayoutId(mode), null);
2538b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
2548b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
2558b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            view.measure(widthSpec, heightSpec);
2568b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            view.layout(0, 0, width, height);
2578b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
2588b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            // Records coordinates.
2598b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            View checkmark = view.findViewById(R.id.checkmark);
2608b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.checkmarkX = getX(checkmark);
2618b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.checkmarkY = getY(checkmark);
2628b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.checkmarkWidthIncludingMargins = getWidth(checkmark, true);
2638b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
2648b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            View star = view.findViewById(R.id.star);
2658b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.starX = getX(star);
2668b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.starY = getY(star);
2678b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
268e2f6f18396f27d2fee1149d6a3896721297bf7f3Jorge Lugo            View state = view.findViewById(R.id.reply_state);
269e2f6f18396f27d2fee1149d6a3896721297bf7f3Jorge Lugo            coordinates.stateX = getX(state);
270e2f6f18396f27d2fee1149d6a3896721297bf7f3Jorge Lugo            coordinates.stateY = getY(state);
271e2f6f18396f27d2fee1149d6a3896721297bf7f3Jorge Lugo
2728b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            TextView senders = (TextView) view.findViewById(R.id.senders);
2738b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.sendersX = getX(senders);
2748b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.sendersY = getY(senders);
2758b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.sendersWidth = getWidth(senders, false);
2768b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.sendersLineCount = getLineCount(senders);
2778b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.sendersFontSize = (int) senders.getTextSize();
278383279a1c5e0cba982645a5ed06e06534d12159eBen Komalo            coordinates.sendersAscent = Math.round(senders.getPaint().ascent());
2798b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
2808b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            TextView subject = (TextView) view.findViewById(R.id.subject);
2818b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.subjectX = getX(subject);
2828b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.subjectY = getY(subject);
2838b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.subjectWidth = getWidth(subject, false);
2848b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.subjectLineCount = getLineCount(subject);
2858b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.subjectFontSize = (int) subject.getTextSize();
286383279a1c5e0cba982645a5ed06e06534d12159eBen Komalo            coordinates.subjectAscent = Math.round(subject.getPaint().ascent());
2878b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
2888b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            View chip = view.findViewById(R.id.color_chip);
2898b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.chipX = getX(chip);
2908b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.chipY = getY(chip);
2918b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.chipWidth = getWidth(chip, false);
2928b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.chipHeight = getHeight(chip, false);
2938b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
2948b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            TextView date = (TextView) view.findViewById(R.id.date);
2958b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.dateXEnd = getX(date) + date.getWidth();
2968b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.dateY = getY(date);
2978b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.dateFontSize = (int) date.getTextSize();
298383279a1c5e0cba982645a5ed06e06534d12159eBen Komalo            coordinates.dateAscent = Math.round(date.getPaint().ascent());
2998b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo
3008b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            // The x-value is computed relative to the date.
3018b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            View paperclip = view.findViewById(R.id.paperclip);
3028b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo            coordinates.paperclipY = getY(paperclip);
3038b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        }
3048b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo        return coordinates;
3058b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo    }
3068b2109f047d8b50edbb677a822f6ee34df8d17b8Ben Komalo}
307