1 /*
2  * Copyright (C) 2015 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 package com.android.messaging.ui;
17 
18 import android.content.Context;
19 import android.content.res.Resources;
20 import android.graphics.drawable.Drawable;
21 
22 import com.android.messaging.Factory;
23 import com.android.messaging.R;
24 import com.android.messaging.util.ImageUtils;
25 
26 /**
27  * A singleton cache that holds tinted drawable resources for displaying messages, such as
28  * message bubbles, audio attachments etc.
29  */
30 public class ConversationDrawables {
31     private static ConversationDrawables sInstance;
32 
33     // Cache the color filtered bubble drawables so that we don't need to create a
34     // new one for each ConversationMessageView.
35     private Drawable mIncomingBubbleDrawable;
36     private Drawable mOutgoingBubbleDrawable;
37     private Drawable mIncomingErrorBubbleDrawable;
38     private Drawable mIncomingBubbleNoArrowDrawable;
39     private Drawable mOutgoingBubbleNoArrowDrawable;
40     private Drawable mAudioPlayButtonDrawable;
41     private Drawable mAudioPauseButtonDrawable;
42     private Drawable mIncomingAudioProgressBackgroundDrawable;
43     private Drawable mOutgoingAudioProgressBackgroundDrawable;
44     private Drawable mAudioProgressForegroundDrawable;
45     private Drawable mFastScrollThumbDrawable;
46     private Drawable mFastScrollThumbPressedDrawable;
47     private Drawable mFastScrollPreviewDrawableLeft;
48     private Drawable mFastScrollPreviewDrawableRight;
49     private final Context mContext;
50     private int mOutgoingBubbleColor;
51     private int mIncomingErrorBubbleColor;
52     private int mIncomingAudioButtonColor;
53     private int mSelectedBubbleColor;
54     private int mThemeColor;
55 
get()56     public static ConversationDrawables get() {
57         if (sInstance == null) {
58             sInstance = new ConversationDrawables(Factory.get().getApplicationContext());
59         }
60         return sInstance;
61     }
62 
ConversationDrawables(final Context context)63     private ConversationDrawables(final Context context) {
64         mContext = context;
65         // Pre-create all the drawables.
66         updateDrawables();
67     }
68 
getConversationThemeColor()69     public int getConversationThemeColor() {
70         return mThemeColor;
71     }
72 
updateDrawables()73     public void updateDrawables() {
74         final Resources resources = mContext.getResources();
75 
76         mIncomingBubbleDrawable = resources.getDrawable(R.drawable.msg_bubble_incoming);
77         mIncomingBubbleNoArrowDrawable =
78                 resources.getDrawable(R.drawable.message_bubble_incoming_no_arrow);
79         mIncomingErrorBubbleDrawable = resources.getDrawable(R.drawable.msg_bubble_error);
80         mOutgoingBubbleDrawable =  resources.getDrawable(R.drawable.msg_bubble_outgoing);
81         mOutgoingBubbleNoArrowDrawable =
82                 resources.getDrawable(R.drawable.message_bubble_outgoing_no_arrow);
83         mAudioPlayButtonDrawable = resources.getDrawable(R.drawable.ic_audio_play);
84         mAudioPauseButtonDrawable = resources.getDrawable(R.drawable.ic_audio_pause);
85         mIncomingAudioProgressBackgroundDrawable =
86                 resources.getDrawable(R.drawable.audio_progress_bar_background_incoming);
87         mOutgoingAudioProgressBackgroundDrawable =
88                 resources.getDrawable(R.drawable.audio_progress_bar_background_outgoing);
89         mAudioProgressForegroundDrawable =
90                 resources.getDrawable(R.drawable.audio_progress_bar_progress);
91         mFastScrollThumbDrawable = resources.getDrawable(R.drawable.fastscroll_thumb);
92         mFastScrollThumbPressedDrawable =
93                 resources.getDrawable(R.drawable.fastscroll_thumb_pressed);
94         mFastScrollPreviewDrawableLeft =
95                 resources.getDrawable(R.drawable.fastscroll_preview_left);
96         mFastScrollPreviewDrawableRight =
97                 resources.getDrawable(R.drawable.fastscroll_preview_right);
98         mOutgoingBubbleColor = resources.getColor(R.color.message_bubble_color_outgoing);
99         mIncomingErrorBubbleColor =
100                 resources.getColor(R.color.message_error_bubble_color_incoming);
101         mIncomingAudioButtonColor =
102                 resources.getColor(R.color.message_audio_button_color_incoming);
103         mSelectedBubbleColor = resources.getColor(R.color.message_bubble_color_selected);
104         mThemeColor = resources.getColor(R.color.primary_color);
105     }
106 
getBubbleDrawable(final boolean selected, final boolean incoming, final boolean needArrow, final boolean isError)107     public Drawable getBubbleDrawable(final boolean selected, final boolean incoming,
108             final boolean needArrow, final boolean isError) {
109         final Drawable protoDrawable;
110         if (needArrow) {
111             if (incoming) {
112                 protoDrawable = isError && !selected ?
113                         mIncomingErrorBubbleDrawable : mIncomingBubbleDrawable;
114             } else {
115                 protoDrawable = mOutgoingBubbleDrawable;
116             }
117         } else if (incoming) {
118             protoDrawable = mIncomingBubbleNoArrowDrawable;
119         } else {
120             protoDrawable = mOutgoingBubbleNoArrowDrawable;
121         }
122 
123         int color;
124         if (selected) {
125             color = mSelectedBubbleColor;
126         } else if (incoming) {
127             if (isError) {
128                 color = mIncomingErrorBubbleColor;
129             } else {
130                 color = mThemeColor;
131             }
132         } else {
133             color = mOutgoingBubbleColor;
134         }
135 
136         return ImageUtils.getTintedDrawable(mContext, protoDrawable, color);
137     }
138 
getAudioButtonColor(final boolean incoming)139     private int getAudioButtonColor(final boolean incoming) {
140         return incoming ? mIncomingAudioButtonColor : mThemeColor;
141     }
142 
getPlayButtonDrawable(final boolean incoming)143     public Drawable getPlayButtonDrawable(final boolean incoming) {
144         return ImageUtils.getTintedDrawable(
145                 mContext, mAudioPlayButtonDrawable, getAudioButtonColor(incoming));
146     }
147 
getPauseButtonDrawable(final boolean incoming)148     public Drawable getPauseButtonDrawable(final boolean incoming) {
149         return ImageUtils.getTintedDrawable(
150                 mContext, mAudioPauseButtonDrawable, getAudioButtonColor(incoming));
151     }
152 
getAudioProgressDrawable(final boolean incoming)153     public Drawable getAudioProgressDrawable(final boolean incoming) {
154         return ImageUtils.getTintedDrawable(
155                 mContext, mAudioProgressForegroundDrawable, getAudioButtonColor(incoming));
156     }
157 
getAudioProgressBackgroundDrawable(final boolean incoming)158     public Drawable getAudioProgressBackgroundDrawable(final boolean incoming) {
159         return incoming ? mIncomingAudioProgressBackgroundDrawable :
160             mOutgoingAudioProgressBackgroundDrawable;
161     }
162 
getFastScrollThumbDrawable(final boolean pressed)163     public Drawable getFastScrollThumbDrawable(final boolean pressed) {
164         if (pressed) {
165             return ImageUtils.getTintedDrawable(mContext, mFastScrollThumbPressedDrawable,
166                     mThemeColor);
167         } else {
168             return mFastScrollThumbDrawable;
169         }
170     }
171 
getFastScrollPreviewDrawable(boolean positionRight)172     public Drawable getFastScrollPreviewDrawable(boolean positionRight) {
173         Drawable protoDrawable = positionRight ? mFastScrollPreviewDrawableRight :
174             mFastScrollPreviewDrawableLeft;
175         return ImageUtils.getTintedDrawable(mContext, protoDrawable, mThemeColor);
176     }
177 }
178