/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher3.pageindicators; import android.content.Context; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PixelFormat; import com.android.launcher3.R; import android.graphics.drawable.Drawable; public class CaretDrawable extends Drawable { public static final float PROGRESS_CARET_POINTING_UP = -1f; public static final float PROGRESS_CARET_POINTING_DOWN = 1f; public static final float PROGRESS_CARET_NEUTRAL = 0; private float mCaretProgress = PROGRESS_CARET_NEUTRAL; private Paint mShadowPaint = new Paint(); private Paint mCaretPaint = new Paint(); private Path mPath = new Path(); private final int mCaretSizePx; public CaretDrawable(Context context) { final Resources res = context.getResources(); final int strokeWidth = res.getDimensionPixelSize(R.dimen.all_apps_caret_stroke_width); final int shadowSpread = res.getDimensionPixelSize(R.dimen.all_apps_caret_shadow_spread); mCaretPaint.setColor(res.getColor(R.color.all_apps_caret_color)); mCaretPaint.setAntiAlias(true); mCaretPaint.setStrokeWidth(strokeWidth); mCaretPaint.setStyle(Paint.Style.STROKE); mCaretPaint.setStrokeCap(Paint.Cap.SQUARE); mCaretPaint.setStrokeJoin(Paint.Join.MITER); mShadowPaint.setColor(res.getColor(R.color.all_apps_caret_shadow_color)); mShadowPaint.setAntiAlias(true); mShadowPaint.setStrokeWidth(strokeWidth + (shadowSpread * 2)); mShadowPaint.setStyle(Paint.Style.STROKE); mShadowPaint.setStrokeCap(Paint.Cap.ROUND); mShadowPaint.setStrokeJoin(Paint.Join.ROUND); mCaretSizePx = res.getDimensionPixelSize(R.dimen.all_apps_caret_size); } @Override public int getIntrinsicHeight() { return mCaretSizePx; } @Override public int getIntrinsicWidth() { return mCaretSizePx; } @Override public void draw(Canvas canvas) { // Assumes caret paint is more important than shadow paint if (Float.compare(mCaretPaint.getAlpha(), 0f) == 0) { return; } // Assumes shadow stroke width is larger final float width = getBounds().width() - mShadowPaint.getStrokeWidth(); final float height = getBounds().height() - mShadowPaint.getStrokeWidth(); final float left = getBounds().left + (mShadowPaint.getStrokeWidth() / 2); final float top = getBounds().top + (mShadowPaint.getStrokeWidth() / 2); // When the bounds are square, this will result in a caret with a right angle final float verticalInset = (height / 4); final float caretHeight = (height - (verticalInset * 2)); mPath.reset(); mPath.moveTo(left, top + caretHeight * (1 - getNormalizedCaretProgress())); mPath.lineTo(left + (width / 2), top + caretHeight * getNormalizedCaretProgress()); mPath.lineTo(left + width, top + caretHeight * (1 - getNormalizedCaretProgress())); canvas.drawPath(mPath, mShadowPaint); canvas.drawPath(mPath, mCaretPaint); } /** * Sets the caret progress * * @param progress The progress ({@value #PROGRESS_CARET_POINTING_UP} for pointing up, * {@value #PROGRESS_CARET_POINTING_DOWN} for pointing down, {@value #PROGRESS_CARET_NEUTRAL} * for neutral) */ public void setCaretProgress(float progress) { mCaretProgress = progress; invalidateSelf(); } /** * Returns the caret progress * * @return The progress */ public float getCaretProgress() { return mCaretProgress; } /** * Returns the caret progress normalized to [0..1] * * @return The normalized progress */ public float getNormalizedCaretProgress() { return (mCaretProgress - PROGRESS_CARET_POINTING_UP) / (PROGRESS_CARET_POINTING_DOWN - PROGRESS_CARET_POINTING_UP); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } @Override public void setAlpha(int alpha) { mCaretPaint.setAlpha(alpha); mShadowPaint.setAlpha(alpha); invalidateSelf(); } @Override public void setColorFilter(ColorFilter cf) { // no-op } }