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