/* * 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 android.view; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; /** * Helper class for drawing round scroll bars on round Wear devices. */ class RoundScrollbarRenderer { // The range of the scrollbar position represented as an angle in degrees. private static final int SCROLLBAR_ANGLE_RANGE = 90; private static final int MAX_SCROLLBAR_ANGLE_SWIPE = 16; private static final int MIN_SCROLLBAR_ANGLE_SWIPE = 6; private static final float WIDTH_PERCENTAGE = 0.02f; private static final int DEFAULT_THUMB_COLOR = 0x4CFFFFFF; private static final int DEFAULT_TRACK_COLOR = 0x26FFFFFF; private final Paint mThumbPaint = new Paint(); private final Paint mTrackPaint = new Paint(); private final RectF mRect = new RectF(); private final View mParent; public RoundScrollbarRenderer(View parent) { // Paints for the round scrollbar. // Set up the thumb paint mThumbPaint.setAntiAlias(true); mThumbPaint.setStrokeCap(Paint.Cap.ROUND); mThumbPaint.setStyle(Paint.Style.STROKE); // Set up the track paint mTrackPaint.setAntiAlias(true); mTrackPaint.setStrokeCap(Paint.Cap.ROUND); mTrackPaint.setStyle(Paint.Style.STROKE); mParent = parent; } public void drawRoundScrollbars(Canvas canvas, float alpha, Rect bounds) { if (alpha == 0) { return; } // Get information about the current scroll state of the parent view. float maxScroll = mParent.computeVerticalScrollRange(); float scrollExtent = mParent.computeVerticalScrollExtent(); if (scrollExtent <= 0 || maxScroll <= scrollExtent) { return; } float currentScroll = Math.max(0, mParent.computeVerticalScrollOffset()); float linearThumbLength = mParent.computeVerticalScrollExtent(); float thumbWidth = mParent.getWidth() * WIDTH_PERCENTAGE; mThumbPaint.setStrokeWidth(thumbWidth); mTrackPaint.setStrokeWidth(thumbWidth); setThumbColor(applyAlpha(DEFAULT_THUMB_COLOR, alpha)); setTrackColor(applyAlpha(DEFAULT_TRACK_COLOR, alpha)); // Normalize the sweep angle for the scroll bar. float sweepAngle = (linearThumbLength / maxScroll) * SCROLLBAR_ANGLE_RANGE; sweepAngle = clamp(sweepAngle, MIN_SCROLLBAR_ANGLE_SWIPE, MAX_SCROLLBAR_ANGLE_SWIPE); // Normalize the start angle so that it falls on the track. float startAngle = (currentScroll * (SCROLLBAR_ANGLE_RANGE - sweepAngle)) / (maxScroll - linearThumbLength) - SCROLLBAR_ANGLE_RANGE / 2; startAngle = clamp(startAngle, -SCROLLBAR_ANGLE_RANGE / 2, SCROLLBAR_ANGLE_RANGE / 2 - sweepAngle); // Draw the track and the scroll bar. mRect.set( bounds.left - thumbWidth / 2, bounds.top, bounds.right - thumbWidth / 2, bounds.bottom); canvas.drawArc(mRect, -SCROLLBAR_ANGLE_RANGE / 2, SCROLLBAR_ANGLE_RANGE, false, mTrackPaint); canvas.drawArc(mRect, startAngle, sweepAngle, false, mThumbPaint); } private static float clamp(float val, float min, float max) { if (val < min) { return min; } else if (val > max) { return max; } else { return val; } } private static int applyAlpha(int color, float alpha) { int alphaByte = (int) (Color.alpha(color) * alpha); return Color.argb(alphaByte, Color.red(color), Color.green(color), Color.blue(color)); } private void setThumbColor(int thumbColor) { if (mThumbPaint.getColor() != thumbColor) { mThumbPaint.setColor(thumbColor); } } private void setTrackColor(int trackColor) { if (mTrackPaint.getColor() != trackColor) { mTrackPaint.setColor(trackColor); } } }