• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.dialer.voicemail.settings;
18 
19 import android.content.Context;
20 import android.graphics.Canvas;
21 import android.graphics.Color;
22 import android.graphics.Paint;
23 import android.graphics.Rect;
24 import android.graphics.RectF;
25 import android.graphics.drawable.Drawable;
26 import android.graphics.drawable.LayerDrawable;
27 import android.support.v4.content.ContextCompat;
28 import android.util.AttributeSet;
29 import android.widget.Button;
30 import com.android.dialer.voicemail.settings.RecordVoicemailGreetingActivity.ButtonState;
31 
32 /** Custom Button View for Dialer voicemail greeting recording */
33 public class RecordButton extends Button {
34 
35   private final float trackWidth = getResources().getDimensionPixelSize(R.dimen.track_width);
36   private final int centerIconRadius =
37       getResources().getDimensionPixelSize(R.dimen.center_icon_radius);
38   private final int secondaryTrackAlpha = 64;
39 
40   private float mainTrackFraction;
41   private float secondaryTrackFraction;
42 
43   private Rect centerIconRect;
44   private RectF bodyRect;
45 
46   private Drawable readyDrawable;
47   private Drawable recordingDrawable;
48   private Drawable recordedDrawable;
49   private Drawable playingDrawable;
50   private Drawable currentCenterDrawable;
51 
52   private Paint mainTrackPaint;
53   private Paint secondaryTrackPaint;
54 
RecordButton(Context context)55   public RecordButton(Context context) {
56     super(context);
57     init();
58   }
59 
RecordButton(Context context, AttributeSet attrs)60   public RecordButton(Context context, AttributeSet attrs) {
61     super(context, attrs);
62     init();
63   }
64 
RecordButton(Context context, AttributeSet attrs, int defStyle)65   public RecordButton(Context context, AttributeSet attrs, int defStyle) {
66     super(context, attrs, defStyle);
67     init();
68   }
69 
70   /**
71    * Updates bounds for main and secondary tracks and the size of the center Drawable based on View
72    * resizing
73    */
74   @Override
onSizeChanged(int width, int height, int oldWidth, int oldHeight)75   protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
76     // Canvas.drawArc() method draws from center of stroke, so the trackWidth must be accounted for
77     float viewRadius = Math.min(width, height) / 2f - trackWidth;
78     float centerX = width / 2f;
79     float centerY = viewRadius + trackWidth / 2f;
80 
81     bodyRect =
82         new RectF(
83             centerX - viewRadius, centerY - viewRadius, centerX + viewRadius, centerY + viewRadius);
84 
85     centerIconRect =
86         new Rect(
87             (int) centerX - centerIconRadius,
88             (int) centerY - centerIconRadius,
89             (int) centerX + centerIconRadius,
90             (int) centerY + centerIconRadius);
91   }
92 
init()93   private void init() {
94     readyDrawable = ContextCompat.getDrawable(getContext(), R.drawable.start_recording_drawable);
95     recordingDrawable = ContextCompat.getDrawable(getContext(), R.drawable.stop_recording_drawable);
96     recordedDrawable = ContextCompat.getDrawable(getContext(), R.drawable.start_playback_drawable);
97     playingDrawable = ContextCompat.getDrawable(getContext(), R.drawable.stop_playback_drawable);
98 
99     fixQuantumIconTint(Color.WHITE);
100 
101     mainTrackPaint = getBasePaint(R.color.dialer_call_green);
102     secondaryTrackPaint = getBasePaint(R.color.dialer_call_green);
103     secondaryTrackPaint.setAlpha(secondaryTrackAlpha);
104 
105     setState(RecordVoicemailGreetingActivity.RECORD_GREETING_INIT);
106   }
107 
fixQuantumIconTint(int color)108   private void fixQuantumIconTint(int color) {
109     Drawable playArrow = ((LayerDrawable) recordedDrawable).findDrawableByLayerId(R.id.play_icon);
110     playArrow.mutate().setTint(color);
111     ((LayerDrawable) recordedDrawable).setDrawableByLayerId(R.id.play_icon, playArrow);
112 
113     Drawable micIcon = ((LayerDrawable) readyDrawable).findDrawableByLayerId(R.id.record_icon);
114     micIcon.mutate().setTint(color);
115     ((LayerDrawable) readyDrawable).setDrawableByLayerId(R.id.record_icon, micIcon);
116   }
117 
118   /** Returns Paint with base attributes for drawing the main and secondary tracks */
getBasePaint(int id)119   private Paint getBasePaint(int id) {
120     Paint paint = new Paint();
121     paint.setAntiAlias(true);
122     paint.setStrokeWidth(trackWidth);
123     paint.setStrokeCap(Paint.Cap.ROUND);
124     paint.setStyle(Paint.Style.STROKE);
125     paint.setColor(ContextCompat.getColor(getContext(), id));
126     return paint;
127   }
128 
129   /** Sets the fraction value of progress tracks, this will trigger a redraw of the button. */
setTracks(float mainTrackFraction, float secondaryTrackFraction)130   public void setTracks(float mainTrackFraction, float secondaryTrackFraction) {
131     this.mainTrackFraction = mainTrackFraction;
132     this.secondaryTrackFraction = secondaryTrackFraction;
133     invalidate();
134   }
135 
136   /**
137    * Sets internal state of RecordButton. This will also trigger UI refresh of the button to reflect
138    * the new state.
139    */
setState(@uttonState int state)140   public void setState(@ButtonState int state) {
141     switch (state) {
142       case RecordVoicemailGreetingActivity.RECORD_GREETING_INIT:
143         mainTrackPaint = getBasePaint(R.color.dialer_call_green);
144         secondaryTrackPaint = getBasePaint(R.color.dialer_call_green);
145         secondaryTrackPaint.setAlpha(secondaryTrackAlpha);
146         currentCenterDrawable = readyDrawable;
147         break;
148       case RecordVoicemailGreetingActivity.RECORD_GREETING_PLAYING_BACK:
149         mainTrackPaint = getBasePaint(R.color.google_blue_500);
150         secondaryTrackPaint = getBasePaint(R.color.google_blue_50);
151         currentCenterDrawable = playingDrawable;
152         break;
153       case RecordVoicemailGreetingActivity.RECORD_GREETING_RECORDED:
154         mainTrackPaint = getBasePaint(R.color.google_blue_500);
155         secondaryTrackPaint = getBasePaint(R.color.google_blue_50);
156         currentCenterDrawable = recordedDrawable;
157         break;
158       case RecordVoicemailGreetingActivity.RECORD_GREETING_RECORDING:
159         mainTrackPaint = getBasePaint(R.color.dialer_red);
160         secondaryTrackPaint = getBasePaint(R.color.dialer_red);
161         secondaryTrackPaint.setAlpha(secondaryTrackAlpha);
162         currentCenterDrawable = recordingDrawable;
163         break;
164       default:
165         throw new RuntimeException("Invalid button state");
166     }
167     refreshDrawableState();
168     invalidate();
169   }
170 
171   /**
172    * Handles drawing the main and secondary track arcs and the center Drawable image based on track
173    * fractions and the Button's current state
174    */
175   @Override
onDraw(Canvas canvas)176   protected void onDraw(Canvas canvas) {
177     super.onDraw(canvas);
178 
179     canvas.drawArc(bodyRect, -90, secondaryTrackFraction * 360, false, secondaryTrackPaint);
180     canvas.drawArc(bodyRect, -90, mainTrackFraction * 360, false, mainTrackPaint);
181 
182     // TODO(marquelle) - Add pulse
183 
184     currentCenterDrawable.setBounds(centerIconRect);
185     currentCenterDrawable.draw(canvas);
186   }
187 }
188