CaretDrawable.java revision 016eaeea99e163f0b5385cf660297e6c21ff21e5
1/* 2 * Copyright (C) 2016 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 */ 16package com.android.launcher3.pageindicators; 17 18import android.content.Context; 19import android.content.res.Resources; 20import android.graphics.Canvas; 21import android.graphics.ColorFilter; 22import android.graphics.Paint; 23import android.graphics.Path; 24import android.graphics.PixelFormat; 25 26import com.android.launcher3.R; 27 28import android.graphics.drawable.Drawable; 29 30public class CaretDrawable extends Drawable { 31 public static final float PROGRESS_CARET_POINTING_UP = -1f; 32 public static final float PROGRESS_CARET_POINTING_DOWN = 1f; 33 public static final float PROGRESS_CARET_NEUTRAL = 0; 34 35 private float mCaretProgress = PROGRESS_CARET_NEUTRAL; 36 37 private Paint mShadowPaint = new Paint(); 38 private Paint mCaretPaint = new Paint(); 39 private Path mPath = new Path(); 40 private final int mCaretSizePx; 41 42 public CaretDrawable(Context context) { 43 final Resources res = context.getResources(); 44 45 final int strokeWidth = res.getDimensionPixelSize(R.dimen.all_apps_caret_stroke_width); 46 final int shadowSpread = res.getDimensionPixelSize(R.dimen.all_apps_caret_shadow_spread); 47 48 mCaretPaint.setColor(res.getColor(R.color.all_apps_caret_color)); 49 mCaretPaint.setAntiAlias(true); 50 mCaretPaint.setStrokeWidth(strokeWidth); 51 mCaretPaint.setStyle(Paint.Style.STROKE); 52 mCaretPaint.setStrokeCap(Paint.Cap.SQUARE); 53 mCaretPaint.setStrokeJoin(Paint.Join.MITER); 54 55 mShadowPaint.setColor(res.getColor(R.color.all_apps_caret_shadow_color)); 56 mShadowPaint.setAntiAlias(true); 57 mShadowPaint.setStrokeWidth(strokeWidth + (shadowSpread * 2)); 58 mShadowPaint.setStyle(Paint.Style.STROKE); 59 mShadowPaint.setStrokeCap(Paint.Cap.ROUND); 60 mShadowPaint.setStrokeJoin(Paint.Join.ROUND); 61 62 mCaretSizePx = res.getDimensionPixelSize(R.dimen.all_apps_caret_size); 63 } 64 65 @Override 66 public int getIntrinsicHeight() { 67 return mCaretSizePx; 68 } 69 70 @Override 71 public int getIntrinsicWidth() { 72 return mCaretSizePx; 73 } 74 75 @Override 76 public void draw(Canvas canvas) { 77 // Assumes caret paint is more important than shadow paint 78 if (Float.compare(mCaretPaint.getAlpha(), 0f) == 0) { 79 return; 80 } 81 82 // Assumes shadow stroke width is larger 83 final float width = getBounds().width() - mShadowPaint.getStrokeWidth(); 84 final float height = getBounds().height() - mShadowPaint.getStrokeWidth(); 85 final float left = getBounds().left + (mShadowPaint.getStrokeWidth() / 2); 86 final float top = getBounds().top + (mShadowPaint.getStrokeWidth() / 2); 87 88 // When the bounds are square, this will result in a caret with a right angle 89 final float verticalInset = (height / 4); 90 final float caretHeight = (height - (verticalInset * 2)); 91 92 mPath.reset(); 93 mPath.moveTo(left, top + caretHeight * (1 - getNormalizedCaretProgress())); 94 mPath.lineTo(left + (width / 2), top + caretHeight * getNormalizedCaretProgress()); 95 mPath.lineTo(left + width, top + caretHeight * (1 - getNormalizedCaretProgress())); 96 97 canvas.drawPath(mPath, mShadowPaint); 98 canvas.drawPath(mPath, mCaretPaint); 99 } 100 101 /** 102 * Sets the caret progress 103 * 104 * @param progress The progress ({@value #PROGRESS_CARET_POINTING_UP} for pointing up, 105 * {@value #PROGRESS_CARET_POINTING_DOWN} for pointing down, {@value #PROGRESS_CARET_NEUTRAL} 106 * for neutral) 107 */ 108 public void setCaretProgress(float progress) { 109 mCaretProgress = progress; 110 invalidateSelf(); 111 } 112 113 /** 114 * Returns the caret progress 115 * 116 * @return The progress 117 */ 118 public float getCaretProgress() { 119 return mCaretProgress; 120 } 121 122 /** 123 * Returns the caret progress normalized to [0..1] 124 * 125 * @return The normalized progress 126 */ 127 public float getNormalizedCaretProgress() { 128 return (mCaretProgress - PROGRESS_CARET_POINTING_UP) / 129 (PROGRESS_CARET_POINTING_DOWN - PROGRESS_CARET_POINTING_UP); 130 } 131 132 @Override 133 public int getOpacity() { 134 return PixelFormat.TRANSLUCENT; 135 } 136 137 @Override 138 public void setAlpha(int alpha) { 139 mCaretPaint.setAlpha(alpha); 140 mShadowPaint.setAlpha(alpha); 141 invalidateSelf(); 142 } 143 144 @Override 145 public void setColorFilter(ColorFilter cf) { 146 // no-op 147 } 148} 149