1 /* 2 * Copyright (C) 2021 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.keyguard; 17 18 import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_BUTTON; 19 import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.ColorId.NUM_PAD_KEY; 20 21 import android.content.Context; 22 import android.content.res.ColorStateList; 23 import android.content.res.Configuration; 24 import android.graphics.drawable.Drawable; 25 import android.graphics.drawable.GradientDrawable; 26 import android.graphics.drawable.VectorDrawable; 27 import android.util.AttributeSet; 28 import android.view.MotionEvent; 29 30 import androidx.annotation.Nullable; 31 32 import com.android.settingslib.Utils; 33 import com.android.systemui.R; 34 35 /** 36 * Similar to the {@link NumPadKey}, but displays an image. 37 */ 38 public class NumPadButton extends AlphaOptimizedImageButton implements NumPadAnimationListener { 39 40 @Nullable 41 private NumPadAnimator mAnimator; 42 private int mOrientation; 43 private int mStyleAttr; 44 private boolean mIsTransparentMode; 45 NumPadButton(Context context, AttributeSet attrs)46 public NumPadButton(Context context, AttributeSet attrs) { 47 super(context, attrs); 48 mStyleAttr = attrs.getStyleAttribute(); 49 setupAnimator(); 50 } 51 52 @Override onConfigurationChanged(Configuration newConfig)53 protected void onConfigurationChanged(Configuration newConfig) { 54 mOrientation = newConfig.orientation; 55 } 56 57 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)58 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 59 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 60 61 // Set width/height to the same value to ensure a smooth circle for the bg, but shrink 62 // the height to match the old pin bouncer. 63 // This is only used for PIN/PUK; the main PIN pad now uses ConstraintLayout, which will 64 // force our width/height to conform to the ratio in the layout. 65 int width = getMeasuredWidth(); 66 67 boolean shortenHeight = mAnimator == null 68 || mOrientation == Configuration.ORIENTATION_LANDSCAPE; 69 int height = shortenHeight ? (int) (width * .66f) : width; 70 71 setMeasuredDimension(getMeasuredWidth(), height); 72 } 73 74 @Override onLayout(boolean changed, int l, int t, int r, int b)75 protected void onLayout(boolean changed, int l, int t, int r, int b) { 76 super.onLayout(changed, l, t, r, b); 77 int width = r - l; 78 int height = b - t; 79 if (mAnimator != null) mAnimator.onLayout(width, height); 80 } 81 82 @Override onTouchEvent(MotionEvent event)83 public boolean onTouchEvent(MotionEvent event) { 84 switch(event.getActionMasked()) { 85 case MotionEvent.ACTION_DOWN: 86 if (mAnimator != null) mAnimator.expand(); 87 break; 88 case MotionEvent.ACTION_UP: 89 case MotionEvent.ACTION_CANCEL: 90 if (mAnimator != null) mAnimator.contract(); 91 break; 92 } 93 return super.onTouchEvent(event); 94 } 95 96 /** 97 * Reload colors from resources. 98 **/ reloadColors()99 public void reloadColors() { 100 if (mAnimator != null) mAnimator.reloadColors(getContext()); 101 102 int textColorResId = mIsTransparentMode ? NUM_PAD_KEY : NUM_PAD_BUTTON; 103 int imageColor = Utils.getColorAttrDefaultColor(getContext(), textColorResId); 104 ((VectorDrawable) getDrawable()).setTintList(ColorStateList.valueOf(imageColor)); 105 } 106 107 @Override setProgress(float progress)108 public void setProgress(float progress) { 109 if (mAnimator != null) { 110 mAnimator.setProgress(progress); 111 } 112 } 113 114 /** 115 * Set whether button is transparent mode. 116 * 117 * @param isTransparentMode 118 */ setTransparentMode(boolean isTransparentMode)119 public void setTransparentMode(boolean isTransparentMode) { 120 if (mIsTransparentMode == isTransparentMode) { 121 return; 122 } 123 124 mIsTransparentMode = isTransparentMode; 125 126 if (isTransparentMode) { 127 setBackgroundColor(getResources().getColor(android.R.color.transparent)); 128 } else { 129 setBackground(getContext().getDrawable(R.drawable.num_pad_key_background)); 130 } 131 setupAnimator(); 132 reloadColors(); 133 requestLayout(); 134 } 135 136 /** 137 * Set up the animator for the NumPadButton. 138 */ setupAnimator()139 private void setupAnimator() { 140 Drawable background = getBackground(); 141 if (background instanceof GradientDrawable) { 142 mAnimator = new NumPadAnimator(getContext(), background.mutate(), 143 mStyleAttr, getDrawable()); 144 } else { 145 mAnimator = null; 146 } 147 } 148 } 149