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[] {folderValues.getBackgroundColor(mDefaultBgColor)}; 96 Bitmap bitmap = Bitmap.createBitmap(color, 1, 1, Bitmap.Config.RGB_565); 97 remoteViews.setImageViewBitmap(viewId, bitmap); 98 99 if (++displayedFolder == MAX_DISPLAYED_FOLDERS_COUNT) { 100 break; 101 } 102 } 103 104 for (int i = displayedFolder; i < MAX_DISPLAYED_FOLDERS_COUNT; i++) { 105 remoteViews.setViewVisibility(getFolderViewId(i), View.GONE); 106 } 107 } 108 } 109 110 /* 111 * Get font sizes and bitmaps from Resources 112 */ WidgetConversationListItemViewBuilder(Context context)113 public WidgetConversationListItemViewBuilder(Context context) { 114 final Resources res = context.getResources(); 115 116 // Initialize colors 117 SUBJECT_TEXT_COLOR_READ = res.getColor(R.color.subject_text_color_read); 118 SUBJECT_TEXT_COLOR_UNREAD = res.getColor(R.color.subject_text_color_unread); 119 SNIPPET_TEXT_COLOR = res.getColor(R.color.snippet_text_color); 120 DATE_TEXT_COLOR_READ = res.getColor(R.color.date_text_color_read); 121 DATE_TEXT_COLOR_UNREAD = res.getColor(R.color.date_text_color_unread); 122 123 // Initialize Bitmap 124 ATTACHMENT = BitmapFactory.decodeResource(res, R.drawable.ic_attach_file_20dp); 125 } 126 127 /* 128 * Add size, color and style to a given text 129 */ addStyle(CharSequence text, int size, int color)130 private static CharSequence addStyle(CharSequence text, int size, int color) { 131 SpannableStringBuilder builder = new SpannableStringBuilder(text); 132 builder.setSpan( 133 new AbsoluteSizeSpan(size), 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 134 if (color != 0) { 135 builder.setSpan(new ForegroundColorSpan(color), 0, text.length(), 136 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 137 } 138 return builder; 139 } 140 141 /* 142 * Return the full View 143 */ getStyledView(final Context context, final CharSequence date, final Conversation conversation, final FolderUri folderUri, final int ignoreFolderType, final SpannableStringBuilder senders, String subject)144 public RemoteViews getStyledView(final Context context, final CharSequence date, 145 final Conversation conversation, final FolderUri folderUri, final int ignoreFolderType, 146 final SpannableStringBuilder senders, String subject) { 147 148 final boolean isUnread = !conversation.read; 149 final String snippet = conversation.getSnippet(); 150 final boolean hasAttachments = conversation.hasAttachments; 151 final Resources res = context.getResources(); 152 final int dateFontSize = res.getDimensionPixelSize(R.dimen.widget_date_font_size); 153 final int subjectFontSize = res.getDimensionPixelSize(R.dimen.widget_subject_font_size); 154 155 // Add style to date 156 final int dateColor = isUnread ? DATE_TEXT_COLOR_UNREAD : DATE_TEXT_COLOR_READ; 157 final CharSequence styledDate = addStyle(date, dateFontSize, dateColor); 158 159 subject = Conversation.getSubjectForDisplay(context, null /* badgeText */, subject); 160 final SpannableStringBuilder subjectBuilder = new SpannableStringBuilder(subject); 161 if (isUnread) { 162 subjectBuilder.setSpan(new StyleSpan(Typeface.BOLD), 0, subject.length(), 163 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 164 } 165 final CharacterStyle subjectStyle = new ForegroundColorSpan( 166 isUnread ? SUBJECT_TEXT_COLOR_UNREAD : SUBJECT_TEXT_COLOR_READ); 167 subjectBuilder.setSpan(subjectStyle, 0, subjectBuilder.length(), 168 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 169 final CharSequence styledSubject = addStyle(subjectBuilder, subjectFontSize, 0); 170 171 final SpannableStringBuilder snippetBuilder = new SpannableStringBuilder(snippet); 172 snippetBuilder.setSpan(new ForegroundColorSpan(SNIPPET_TEXT_COLOR), 0, 173 snippetBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 174 final CharSequence styledSnippet = addStyle(snippetBuilder, subjectFontSize, 0); 175 176 // Paper clip for attachment 177 Bitmap paperclipBitmap = null; 178 if (hasAttachments) { 179 paperclipBitmap = ATTACHMENT; 180 } 181 182 // Inflate and fill out the remote view 183 final RemoteViews remoteViews = new RemoteViews( 184 context.getPackageName(), R.layout.widget_conversation_list_item); 185 remoteViews.setTextViewText(R.id.widget_senders, senders); 186 remoteViews.setTextViewText(R.id.widget_date, styledDate); 187 remoteViews.setTextViewText(R.id.widget_subject, styledSubject); 188 remoteViews.setTextViewText(R.id.widget_snippet, styledSnippet); 189 if (paperclipBitmap != null) { 190 remoteViews.setViewVisibility(R.id.widget_attachment, View.VISIBLE); 191 remoteViews.setImageViewBitmap(R.id.widget_attachment, paperclipBitmap); 192 } else { 193 remoteViews.setViewVisibility(R.id.widget_attachment, View.GONE); 194 } 195 if (isUnread) { 196 remoteViews.setViewVisibility(R.id.widget_unread_background, View.VISIBLE); 197 remoteViews.setViewVisibility(R.id.widget_read_background, View.GONE); 198 } else { 199 remoteViews.setViewVisibility(R.id.widget_unread_background, View.GONE); 200 remoteViews.setViewVisibility(R.id.widget_read_background, View.VISIBLE); 201 } 202 if (context.getResources().getBoolean(R.bool.display_folder_colors_in_widget)) { 203 mFolderDisplayer = new WidgetFolderDisplayer(context); 204 mFolderDisplayer.loadConversationFolders(conversation, folderUri, ignoreFolderType); 205 mFolderDisplayer.displayFolders(remoteViews); 206 } 207 208 return remoteViews; 209 } 210 } 211