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