CaretDrawable.java revision c06af333cbcebb183d13d004cccf5c9d69a70af0
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; 25import android.graphics.drawable.Drawable; 26 27import com.android.launcher3.R; 28import com.android.launcher3.util.Themes; 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(Themes.getAttrColor(context, android.R.attr.textColorPrimary)); 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.default_shadow_color_no_alpha)); 56 mShadowPaint.setAlpha(Themes.getAlpha(context, android.R.attr.spotShadowAlpha)); 57 mShadowPaint.setAntiAlias(true); 58 mShadowPaint.setStrokeWidth(strokeWidth + (shadowSpread * 2)); 59 mShadowPaint.setStyle(Paint.Style.STROKE); 60 mShadowPaint.setStrokeCap(Paint.Cap.ROUND); 61 mShadowPaint.setStrokeJoin(Paint.Join.ROUND); 62 63 mCaretSizePx = res.getDimensionPixelSize(R.dimen.all_apps_caret_size); 64 } 65 66 @Override 67 public int getIntrinsicHeight() { 68 return mCaretSizePx; 69 } 70 71 @Override 72 public int getIntrinsicWidth() { 73 return mCaretSizePx; 74 } 75 76 @Override 77 public void draw(Canvas canvas) { 78 // Assumes caret paint is more important than shadow paint 79 if (Float.compare(mCaretPaint.getAlpha(), 0f) == 0) { 80 return; 81 } 82 83 // Assumes shadow stroke width is larger 84 final float width = getBounds().width() - mShadowPaint.getStrokeWidth(); 85 final float height = getBounds().height() - mShadowPaint.getStrokeWidth(); 86 final float left = getBounds().left + (mShadowPaint.getStrokeWidth() / 2); 87 final float top = getBounds().top + (mShadowPaint.getStrokeWidth() / 2); 88 89 // When the bounds are square, this will result in a caret with a right angle 90 final float verticalInset = (height / 4); 91 final float caretHeight = (height - (verticalInset * 2)); 92 93 mPath.reset(); 94 mPath.moveTo(left, top + caretHeight * (1 - getNormalizedCaretProgress())); 95 mPath.lineTo(left + (width / 2), top + caretHeight * getNormalizedCaretProgress()); 96 mPath.lineTo(left + width, top + caretHeight * (1 - getNormalizedCaretProgress())); 97 98 canvas.drawPath(mPath, mShadowPaint); 99 canvas.drawPath(mPath, mCaretPaint); 100 } 101 102 /** 103 * Sets the caret progress 104 * 105 * @param progress The progress ({@value #PROGRESS_CARET_POINTING_UP} for pointing up, 106 * {@value #PROGRESS_CARET_POINTING_DOWN} for pointing down, {@value #PROGRESS_CARET_NEUTRAL} 107 * for neutral) 108 */ 109 public void setCaretProgress(float progress) { 110 mCaretProgress = progress; 111 invalidateSelf(); 112 } 113 114 /** 115 * Returns the caret progress 116 * 117 * @return The progress 118 */ 119 public float getCaretProgress() { 120 return mCaretProgress; 121 } 122 123 /** 124 * Returns the caret progress normalized to [0..1] 125 * 126 * @return The normalized progress 127 */ 128 public float getNormalizedCaretProgress() { 129 return (mCaretProgress - PROGRESS_CARET_POINTING_UP) / 130 (PROGRESS_CARET_POINTING_DOWN - PROGRESS_CARET_POINTING_UP); 131 } 132 133 @Override 134 public int getOpacity() { 135 return PixelFormat.TRANSLUCENT; 136 } 137 138 @Override 139 public void setAlpha(int alpha) { 140 mCaretPaint.setAlpha(alpha); 141 mShadowPaint.setAlpha(alpha); 142 invalidateSelf(); 143 } 144 145 @Override 146 public void setColorFilter(ColorFilter cf) { 147 // no-op 148 } 149} 150