1b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska/* 2b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * Copyright (C) 2016 The Android Open Source Project 3b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * 4b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * Licensed under the Apache License, Version 2.0 (the "License"); 5b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * you may not use this file except in compliance with the License. 6b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * You may obtain a copy of the License at 7b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * 8b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * http://www.apache.org/licenses/LICENSE-2.0 9b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * 10b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * Unless required by applicable law or agreed to in writing, software 11b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * distributed under the License is distributed on an "AS IS" BASIS, 12b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * See the License for the specific language governing permissions and 14b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * limitations under the License. 15b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska */ 16b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 17b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurskapackage android.view; 18b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 19b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurskaimport android.graphics.Canvas; 20b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurskaimport android.graphics.Color; 21b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurskaimport android.graphics.Paint; 228cc883de9ee40ca6943f64805bb0c063487514b6Aga Madurskaimport android.graphics.Rect; 2367e2ae86396c6d0f989285275cbf908dee5e71f7Aurimas Liutikasimport android.graphics.RectF; 24b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 25b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska/** 26b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska * Helper class for drawing round scroll bars on round Wear devices. 27b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska */ 28b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurskaclass RoundScrollbarRenderer { 29b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska // The range of the scrollbar position represented as an angle in degrees. 30b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private static final int SCROLLBAR_ANGLE_RANGE = 90; 31b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private static final int MAX_SCROLLBAR_ANGLE_SWIPE = 16; 32b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private static final int MIN_SCROLLBAR_ANGLE_SWIPE = 6; 33b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private static final float WIDTH_PERCENTAGE = 0.02f; 3451772647350eef283bc7cffceecd09ecfd393769Aga Madurska private static final int DEFAULT_THUMB_COLOR = 0x4CFFFFFF; 3551772647350eef283bc7cffceecd09ecfd393769Aga Madurska private static final int DEFAULT_TRACK_COLOR = 0x26FFFFFF; 36b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 37b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private final Paint mThumbPaint = new Paint(); 38b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private final Paint mTrackPaint = new Paint(); 39b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private final RectF mRect = new RectF(); 40b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private final View mParent; 41b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 42b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska public RoundScrollbarRenderer(View parent) { 43b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska // Paints for the round scrollbar. 44b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska // Set up the thumb paint 45b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mThumbPaint.setAntiAlias(true); 46b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mThumbPaint.setStrokeCap(Paint.Cap.ROUND); 47b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mThumbPaint.setStyle(Paint.Style.STROKE); 48b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 49b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska // Set up the track paint 50b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mTrackPaint.setAntiAlias(true); 51b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mTrackPaint.setStrokeCap(Paint.Cap.ROUND); 52b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mTrackPaint.setStyle(Paint.Style.STROKE); 53b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 54b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mParent = parent; 55b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 56b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 578cc883de9ee40ca6943f64805bb0c063487514b6Aga Madurska public void drawRoundScrollbars(Canvas canvas, float alpha, Rect bounds) { 58b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska if (alpha == 0) { 59b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska return; 60b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 61b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska // Get information about the current scroll state of the parent view. 62b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska float maxScroll = mParent.computeVerticalScrollRange(); 63b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska float scrollExtent = mParent.computeVerticalScrollExtent(); 64b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska if (scrollExtent <= 0 || maxScroll <= scrollExtent) { 65b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska return; 66b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 67b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska float currentScroll = Math.max(0, mParent.computeVerticalScrollOffset()); 68b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska float linearThumbLength = mParent.computeVerticalScrollExtent(); 69b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska float thumbWidth = mParent.getWidth() * WIDTH_PERCENTAGE; 70b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mThumbPaint.setStrokeWidth(thumbWidth); 71b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mTrackPaint.setStrokeWidth(thumbWidth); 72b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 73b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska setThumbColor(applyAlpha(DEFAULT_THUMB_COLOR, alpha)); 74b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska setTrackColor(applyAlpha(DEFAULT_TRACK_COLOR, alpha)); 75b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 76b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska // Normalize the sweep angle for the scroll bar. 77b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska float sweepAngle = (linearThumbLength / maxScroll) * SCROLLBAR_ANGLE_RANGE; 78b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska sweepAngle = clamp(sweepAngle, MIN_SCROLLBAR_ANGLE_SWIPE, MAX_SCROLLBAR_ANGLE_SWIPE); 79b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska // Normalize the start angle so that it falls on the track. 80b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska float startAngle = (currentScroll * (SCROLLBAR_ANGLE_RANGE - sweepAngle)) 81b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska / (maxScroll - linearThumbLength) - SCROLLBAR_ANGLE_RANGE / 2; 82b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska startAngle = clamp(startAngle, -SCROLLBAR_ANGLE_RANGE / 2, 83b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska SCROLLBAR_ANGLE_RANGE / 2 - sweepAngle); 84b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 85b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska // Draw the track and the scroll bar. 86b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mRect.set( 878cc883de9ee40ca6943f64805bb0c063487514b6Aga Madurska bounds.left - thumbWidth / 2, 888cc883de9ee40ca6943f64805bb0c063487514b6Aga Madurska bounds.top, 898cc883de9ee40ca6943f64805bb0c063487514b6Aga Madurska bounds.right - thumbWidth / 2, 908cc883de9ee40ca6943f64805bb0c063487514b6Aga Madurska bounds.bottom); 918cc883de9ee40ca6943f64805bb0c063487514b6Aga Madurska 92b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska canvas.drawArc(mRect, -SCROLLBAR_ANGLE_RANGE / 2, SCROLLBAR_ANGLE_RANGE, false, 93b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mTrackPaint); 94b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska canvas.drawArc(mRect, startAngle, sweepAngle, false, mThumbPaint); 95b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 96b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 97b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private static float clamp(float val, float min, float max) { 98b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska if (val < min) { 99b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska return min; 100b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } else if (val > max) { 101b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska return max; 102b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } else { 103b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska return val; 104b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 105b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 106b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 107b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private static int applyAlpha(int color, float alpha) { 108b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska int alphaByte = (int) (Color.alpha(color) * alpha); 109b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska return Color.argb(alphaByte, Color.red(color), Color.green(color), Color.blue(color)); 110b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 111b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 112b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private void setThumbColor(int thumbColor) { 113b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska if (mThumbPaint.getColor() != thumbColor) { 114b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mThumbPaint.setColor(thumbColor); 115b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 116b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 117b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska 118b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska private void setTrackColor(int trackColor) { 119b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska if (mTrackPaint.getColor() != trackColor) { 120b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska mTrackPaint.setColor(trackColor); 121b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 122b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska } 123b19d0f9800ea4db15f4812db9ddf12839fd8efcdAga Madurska} 124