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