1 /* 2 * Copyright (C) 2012 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 17 package com.android.mail.widget; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.graphics.Bitmap; 22 import android.graphics.BitmapFactory; 23 import android.graphics.Typeface; 24 import android.text.Spannable; 25 import android.text.SpannableStringBuilder; 26 import android.text.style.AbsoluteSizeSpan; 27 import android.text.style.CharacterStyle; 28 import android.text.style.ForegroundColorSpan; 29 import android.text.style.StyleSpan; 30 import android.view.View; 31 import android.widget.RemoteViews; 32 33 import com.android.mail.R; 34 import com.android.mail.providers.Conversation; 35 import com.android.mail.providers.Folder; 36 import com.android.mail.ui.FolderDisplayer; 37 import com.android.mail.utils.FolderUri; 38 39 public class WidgetConversationListItemViewBuilder { 40 // Static colors 41 private static int SUBJECT_TEXT_COLOR_READ; 42 private static int SUBJECT_TEXT_COLOR_UNREAD; 43 private static int SNIPPET_TEXT_COLOR; 44 private static int DATE_TEXT_COLOR_READ; 45 private static int DATE_TEXT_COLOR_UNREAD; 46 47 // Static bitmap 48 private static Bitmap ATTACHMENT; 49 50 private WidgetFolderDisplayer mFolderDisplayer; 51 52 /** 53 * Label Displayer for Widget 54 */ 55 protected static class WidgetFolderDisplayer extends FolderDisplayer { WidgetFolderDisplayer(Context context)56 public WidgetFolderDisplayer(Context context) { 57 super(context); 58 } 59 60 // Maximum number of folders we want to display 61 private static final int MAX_DISPLAYED_FOLDERS_COUNT = 3; 62 63 /* 64 * Load Conversation Labels 65 */ 66 @Override loadConversationFolders(Conversation conv, final FolderUri ignoreFolderUri, final int ignoreFolderType)67 public void loadConversationFolders(Conversation conv, final FolderUri ignoreFolderUri, 68 final int ignoreFolderType) { 69 super.loadConversationFolders(conv, ignoreFolderUri, ignoreFolderType); 70 } 71 getFolderViewId(int position)72 private static int getFolderViewId(int position) { 73 switch (position) { 74 case 0: 75 return R.id.widget_folder_0; 76 case 1: 77 return R.id.widget_folder_1; 78 case 2: 79 return R.id.widget_folder_2; 80 } 81 return 0; 82 } 83 84 /** 85 * Display folders 86 */ displayFolders(RemoteViews remoteViews)87 public void displayFolders(RemoteViews remoteViews) { 88 int displayedFolder = 0; 89 for (Folder folderValues : mFoldersSortedSet) { 90 int viewId = getFolderViewId(displayedFolder); 91 if (viewId == 0) { 92 continue; 93 } 94 remoteViews.setViewVisibility(viewId, View.VISIBLE); 95 int color[] = new int[] 96 {folderValues.getBackgroundColor(mFolderDrawableResources.defaultBgColor)}; 97 Bitmap bitmap = Bitmap.createBitmap(color, 1, 1, Bitmap.Config.RGB_565); 98 remoteViews.setImageViewBitmap(viewId, bitmap); 99 100 if (++displayedFolder == MAX_DISPLAYED_FOLDERS_COUNT) { 101 break; 102 } 103 } 104 105 for (int i = displayedFolder; i < MAX_DISPLAYED_FOLDERS_COUNT; i++) { 106 remoteViews.setViewVisibility(getFolderViewId(i), View.GONE); 107 } 108 } 109 } 110 111 /* 112 * Get font sizes and bitmaps from Resources 113 */ WidgetConversationListItemViewBuilder(Context context)114 public WidgetConversationListItemViewBuilder(Context context) { 115 final Resources res = context.getResources(); 116 117 // Initialize colors 118 SUBJECT_TEXT_COLOR_READ = res.getColor(R.color.subject_text_color_read); 119 SUBJECT_TEXT_COLOR_UNREAD = res.getColor(R.color.subject_text_color_unread); 120 SNIPPET_TEXT_COLOR = res.getColor(R.color.snippet_text_color); 121 DATE_TEXT_COLOR_READ = res.getColor(R.color.date_text_color_read); 122 DATE_TEXT_COLOR_UNREAD = res.getColor(R.color.date_text_color_unread); 123 124 // Initialize Bitmap 125 ATTACHMENT = BitmapFactory.decodeResource(res, R.drawable.ic_attach_file_18dp); 126 } 127 128 /* 129 * Add size, color and style to a given text 130 */ addStyle(CharSequence text, int size, int color)131 private static SpannableStringBuilder addStyle(CharSequence text, int size, int color) { 132 final SpannableStringBuilder builder = new SpannableStringBuilder(text); 133 builder.setSpan( 134 new AbsoluteSizeSpan(size), 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 135 if (color != 0) { 136 builder.setSpan(new ForegroundColorSpan(color), 0, text.length(), 137 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 138 } 139 return builder; 140 } 141 142 /* 143 * Return the full View 144 */ getStyledView(final Context context, final CharSequence date, final Conversation conversation, final FolderUri folderUri, final int ignoreFolderType, final SpannableStringBuilder senders, String subject)145 public RemoteViews getStyledView(final Context context, final CharSequence date, 146 final Conversation conversation, final FolderUri folderUri, final int ignoreFolderType, 147 final SpannableStringBuilder senders, String subject) { 148 149 final boolean isUnread = !conversation.read; 150 final String snippet = conversation.getSnippet(); 151 final boolean hasAttachments = conversation.hasAttachments; 152 final Resources res = context.getResources(); 153 final int dateFontSize = res.getDimensionPixelSize(R.dimen.widget_date_font_size); 154 final int subjectFontSize = res.getDimensionPixelSize(R.dimen.widget_subject_font_size); 155 156 // Add style to date 157 final int dateColor = isUnread ? DATE_TEXT_COLOR_UNREAD : DATE_TEXT_COLOR_READ; 158 final SpannableStringBuilder dateBuilder = addStyle(date, dateFontSize, dateColor); 159 if (isUnread) { 160 dateBuilder.setSpan(new StyleSpan(Typeface.BOLD), 0, date.length(), 161 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 162 } 163 164 subject = Conversation.getSubjectForDisplay(context, null /* badgeText */, subject); 165 final SpannableStringBuilder subjectBuilder = new SpannableStringBuilder(subject); 166 if (isUnread) { 167 subjectBuilder.setSpan(new StyleSpan(Typeface.BOLD), 0, subject.length(), 168 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 169 } 170 final int subjectColor = isUnread ? SUBJECT_TEXT_COLOR_UNREAD : SUBJECT_TEXT_COLOR_READ; 171 final CharacterStyle subjectStyle = new ForegroundColorSpan(subjectColor); 172 subjectBuilder.setSpan(subjectStyle, 0, subjectBuilder.length(), 173 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 174 final CharSequence styledSubject = addStyle(subjectBuilder, subjectFontSize, 0); 175 176 final SpannableStringBuilder snippetBuilder = new SpannableStringBuilder(snippet); 177 snippetBuilder.setSpan(new ForegroundColorSpan(SNIPPET_TEXT_COLOR), 0, 178 snippetBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 179 final CharSequence styledSnippet = addStyle(snippetBuilder, subjectFontSize, 0); 180 181 // Paper clip for attachment 182 Bitmap paperclipBitmap = null; 183 if (hasAttachments) { 184 paperclipBitmap = ATTACHMENT; 185 } 186 187 // Inflate and fill out the remote view 188 final RemoteViews remoteViews = new RemoteViews( 189 context.getPackageName(), R.layout.widget_conversation_list_item); 190 remoteViews.setTextViewText(R.id.widget_senders, senders); 191 remoteViews.setTextViewText(R.id.widget_date, dateBuilder); 192 remoteViews.setTextViewText(R.id.widget_subject, styledSubject); 193 remoteViews.setTextViewText(R.id.widget_snippet, styledSnippet); 194 if (paperclipBitmap != null) { 195 remoteViews.setViewVisibility(R.id.widget_attachment, View.VISIBLE); 196 remoteViews.setImageViewBitmap(R.id.widget_attachment, paperclipBitmap); 197 } else { 198 remoteViews.setViewVisibility(R.id.widget_attachment, View.GONE); 199 } 200 if (isUnread) { 201 remoteViews.setViewVisibility(R.id.widget_unread_background, View.VISIBLE); 202 remoteViews.setViewVisibility(R.id.widget_read_background, View.GONE); 203 } else { 204 remoteViews.setViewVisibility(R.id.widget_unread_background, View.GONE); 205 remoteViews.setViewVisibility(R.id.widget_read_background, View.VISIBLE); 206 } 207 if (context.getResources().getBoolean(R.bool.display_folder_colors_in_widget)) { 208 mFolderDisplayer = new WidgetFolderDisplayer(context); 209 mFolderDisplayer.loadConversationFolders(conversation, folderUri, ignoreFolderType); 210 mFolderDisplayer.displayFolders(remoteViews); 211 } 212 213 return remoteViews; 214 } 215 } 216