19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19f6d87ec193f17e8dad82c9994ba7a58e975d364bAlan Viveretteimport android.annotation.NonNull; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.ColorFilter; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikasimport com.android.internal.widget.ScrollBarUtils; 2799441c5d7da45c10b729185852be97cbb0bdc8d5Aurimas Liutikas 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 29029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * This is only used by View for displaying its scroll bars. It should probably 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be moved in to the view package since it is used in that lower-level layer. 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For now, we'll hide it so it can be cleaned up later. 32029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 35029d039ea5df180218288f955f96f66d57b74bc3Alan Viverettepublic class ScrollBarDrawable extends Drawable implements Drawable.Callback { 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mVerticalTrack; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mHorizontalTrack; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mVerticalThumb; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Drawable mHorizontalThumb; 40029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mRange; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mOffset; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mExtent; 44029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mVertical; 46029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette private boolean mBoundsChanged; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mRangeChanged; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAlwaysDrawHorizontalTrack; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAlwaysDrawVerticalTrack; 50f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette private boolean mMutated; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 52029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette private int mAlpha = 255; 53029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette private boolean mHasSetAlpha; 54029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 55029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette private ColorFilter mColorFilter; 56029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette private boolean mHasSetColorFilter; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 59029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * Indicate whether the horizontal scrollbar track should always be drawn 60029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * regardless of the extent. Defaults to false. 61029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * 62029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * @param alwaysDrawTrack Whether the track should always be drawn 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 64029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * @see #getAlwaysDrawHorizontalTrack() 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlwaysDrawHorizontalTrack(boolean alwaysDrawTrack) { 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlwaysDrawHorizontalTrack = alwaysDrawTrack; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 71029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * Indicate whether the vertical scrollbar track should always be drawn 72029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * regardless of the extent. Defaults to false. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 74029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * @param alwaysDrawTrack Whether the track should always be drawn 75029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * 76029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * @see #getAlwaysDrawVerticalTrack() 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlwaysDrawVerticalTrack(boolean alwaysDrawTrack) { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAlwaysDrawVerticalTrack = alwaysDrawTrack; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 83029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * @return whether the vertical scrollbar track should always be drawn 84029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * regardless of the extent. 85029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * 86029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * @see #setAlwaysDrawVerticalTrack(boolean) 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getAlwaysDrawVerticalTrack() { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAlwaysDrawVerticalTrack; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 93029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * @return whether the horizontal scrollbar track should always be drawn 94029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * regardless of the extent. 95029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * 96029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette * @see #setAlwaysDrawHorizontalTrack(boolean) 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean getAlwaysDrawHorizontalTrack() { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAlwaysDrawHorizontalTrack; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setParameters(int range, int offset, int extent, boolean vertical) { 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVertical != vertical) { 104029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mVertical = vertical; 105029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 106029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mBoundsChanged = true; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRange != range || mOffset != offset || mExtent != extent) { 110029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mRange = range; 111029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mOffset = offset; 112029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mExtent = extent; 113029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRangeChanged = true; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void draw(Canvas canvas) { 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean vertical = mVertical; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int extent = mExtent; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int range = mRange; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean drawTrack = true; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean drawThumb = true; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extent <= 0 || range <= extent) { 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project drawTrack = vertical ? mAlwaysDrawVerticalTrack : mAlwaysDrawHorizontalTrack; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project drawThumb = false; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 131029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette final Rect r = getBounds(); 1328fb954263dd2f918ad339045cc6d82e346515599Romain Guy if (canvas.quickReject(r.left, r.top, r.right, r.bottom, Canvas.EdgeType.AA)) { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 135029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (drawTrack) { 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project drawTrack(canvas, r, vertical); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (drawThumb) { 141d85bc5074dc1211fdb1c6799d9321af54ac5a32fKeisuke Kuroyanagi final int scrollBarLength = vertical ? r.height() : r.width(); 142029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette final int thickness = vertical ? r.width() : r.height(); 143d85bc5074dc1211fdb1c6799d9321af54ac5a32fKeisuke Kuroyanagi final int thumbLength = 144d85bc5074dc1211fdb1c6799d9321af54ac5a32fKeisuke Kuroyanagi ScrollBarUtils.getThumbLength(scrollBarLength, thickness, extent, range); 145d85bc5074dc1211fdb1c6799d9321af54ac5a32fKeisuke Kuroyanagi final int thumbOffset = 146d85bc5074dc1211fdb1c6799d9321af54ac5a32fKeisuke Kuroyanagi ScrollBarUtils.getThumbOffset(scrollBarLength, thumbLength, extent, range, 147d85bc5074dc1211fdb1c6799d9321af54ac5a32fKeisuke Kuroyanagi mOffset); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 149d85bc5074dc1211fdb1c6799d9321af54ac5a32fKeisuke Kuroyanagi drawThumb(canvas, r, thumbOffset, thumbLength, vertical); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onBoundsChange(Rect bounds) { 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onBoundsChange(bounds); 156029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mBoundsChanged = true; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 159029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette @Override 160029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette public boolean isStateful() { 161029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette return (mVerticalTrack != null && mVerticalTrack.isStateful()) 162029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette || (mVerticalThumb != null && mVerticalThumb.isStateful()) 163029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette || (mHorizontalTrack != null && mHorizontalTrack.isStateful()) 164029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette || (mHorizontalThumb != null && mHorizontalThumb.isStateful()) 165029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette || super.isStateful(); 166029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 167029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 168029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette @Override 169029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette protected boolean onStateChange(int[] state) { 170029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette boolean changed = super.onStateChange(state); 171029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mVerticalTrack != null) { 172029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette changed |= mVerticalTrack.setState(state); 173029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 174029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mVerticalThumb != null) { 175029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette changed |= mVerticalThumb.setState(state); 176029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 177029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mHorizontalTrack != null) { 178029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette changed |= mHorizontalTrack.setState(state); 179029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 180029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mHorizontalThumb != null) { 181029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette changed |= mHorizontalThumb.setState(state); 182029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 183029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette return changed; 184029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 185029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 186029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette private void drawTrack(Canvas canvas, Rect bounds, boolean vertical) { 187029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette final Drawable track; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vertical) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project track = mVerticalTrack; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project track = mHorizontalTrack; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 193029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (track != null) { 195029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mBoundsChanged) { 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project track.setBounds(bounds); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project track.draw(canvas); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 202029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette private void drawThumb(Canvas canvas, Rect bounds, int offset, int length, boolean vertical) { 203029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette final boolean changed = mRangeChanged || mBoundsChanged; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vertical) { 2056c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase if (mVerticalThumb != null) { 2066c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase final Drawable thumb = mVerticalThumb; 207029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (changed) { 208029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette thumb.setBounds(bounds.left, bounds.top + offset, 209029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette bounds.right, bounds.top + offset + length); 210029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 211029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 2126c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase thumb.draw(canvas); 2136c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase } 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2156c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase if (mHorizontalThumb != null) { 2166c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase final Drawable thumb = mHorizontalThumb; 217029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (changed) { 218029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette thumb.setBounds(bounds.left + offset, bounds.top, 219029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette bounds.left + offset + length, bounds.bottom); 220029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 221029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 2226c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase thumb.draw(canvas); 2236c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setVerticalThumbDrawable(Drawable thumb) { 228029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mVerticalThumb != null) { 229029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mVerticalThumb.setCallback(null); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 231029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 232029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette propagateCurrentState(thumb); 233029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mVerticalThumb = thumb; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setVerticalTrackDrawable(Drawable track) { 237029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mVerticalTrack != null) { 238029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mVerticalTrack.setCallback(null); 23903748a5707fe3d1f071226ea3caf571abdc0d25dAlan Viverette } 240029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 241029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette propagateCurrentState(track); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVerticalTrack = track; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setHorizontalThumbDrawable(Drawable thumb) { 246029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mHorizontalThumb != null) { 247029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mHorizontalThumb.setCallback(null); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 249029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 250029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette propagateCurrentState(thumb); 251029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mHorizontalThumb = thumb; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setHorizontalTrackDrawable(Drawable track) { 255029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mHorizontalTrack != null) { 256029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mHorizontalTrack.setCallback(null); 25703748a5707fe3d1f071226ea3caf571abdc0d25dAlan Viverette } 258029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 259029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette propagateCurrentState(track); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalTrack = track; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 263029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette private void propagateCurrentState(Drawable d) { 264029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (d != null) { 265f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette if (mMutated) { 266b989c5561ea10e623d73e7bb89b37ac38ccdd908Alan Viverette d.mutate(); 267b989c5561ea10e623d73e7bb89b37ac38ccdd908Alan Viverette } 268b989c5561ea10e623d73e7bb89b37ac38ccdd908Alan Viverette 269029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette d.setState(getState()); 270029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette d.setCallback(this); 271029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 272029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mHasSetAlpha) { 273029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette d.setAlpha(mAlpha); 274029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 275029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 276029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette if (mHasSetColorFilter) { 277029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette d.setColorFilter(mColorFilter); 278029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 279029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 280029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 281029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSize(boolean vertical) { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vertical) { 2846c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase return mVerticalTrack != null ? mVerticalTrack.getIntrinsicWidth() : 2856c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase mVerticalThumb != null ? mVerticalThumb.getIntrinsicWidth() : 0; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2876c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase return mHorizontalTrack != null ? mHorizontalTrack.getIntrinsicHeight() : 2886c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase mHorizontalThumb != null ? mHorizontalThumb.getIntrinsicHeight() : 0; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 293f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette public ScrollBarDrawable mutate() { 294f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette if (!mMutated && super.mutate() == this) { 295f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette if (mVerticalTrack != null) { 296f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette mVerticalTrack.mutate(); 297f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette } 298f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette if (mVerticalThumb != null) { 299f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette mVerticalThumb.mutate(); 300f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette } 301f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette if (mHorizontalTrack != null) { 302f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette mHorizontalTrack.mutate(); 303f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette } 304f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette if (mHorizontalThumb != null) { 305f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette mHorizontalThumb.mutate(); 306f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette } 307f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette mMutated = true; 308f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette } 309f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette return this; 310f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette } 311f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette 312f8512ce08174426dfbba96e8108e5a64332f1e71Alan Viverette @Override 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAlpha(int alpha) { 314029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mAlpha = alpha; 315029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mHasSetAlpha = true; 316029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVerticalTrack != null) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVerticalTrack.setAlpha(alpha); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3206c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase if (mVerticalThumb != null) { 3216c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase mVerticalThumb.setAlpha(alpha); 3226c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHorizontalTrack != null) { 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalTrack.setAlpha(alpha); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3266c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase if (mHorizontalThumb != null) { 3276c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase mHorizontalThumb.setAlpha(alpha); 3286c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 332b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase public int getAlpha() { 333029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette return mAlpha; 334b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase } 335b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase 336b1af7f3d4be6cd6bc6e1e805f22c209e19bf928fChet Haase @Override 337bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik public void setColorFilter(ColorFilter colorFilter) { 338bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik mColorFilter = colorFilter; 339029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette mHasSetColorFilter = true; 340029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mVerticalTrack != null) { 342bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik mVerticalTrack.setColorFilter(colorFilter); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3446c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase if (mVerticalThumb != null) { 345bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik mVerticalThumb.setColorFilter(colorFilter); 3466c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase } 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHorizontalTrack != null) { 348bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik mHorizontalTrack.setColorFilter(colorFilter); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3506c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase if (mHorizontalThumb != null) { 351bd3bfc5285dcacff0a69fecf3baeeeb90d887a58Chris Craik mHorizontalThumb.setColorFilter(colorFilter); 3526c8fef7fb866d244486a962dd82f4a6f26505f16Chet Haase } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 356029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette public ColorFilter getColorFilter() { 357029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette return mColorFilter; 358029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 359029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 360029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette @Override 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getOpacity() { 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return PixelFormat.TRANSLUCENT; 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 366f6d87ec193f17e8dad82c9994ba7a58e975d364bAlan Viverette public void invalidateDrawable(@NonNull Drawable who) { 367029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette invalidateSelf(); 368029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 369029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 370029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette @Override 371f6d87ec193f17e8dad82c9994ba7a58e975d364bAlan Viverette public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { 372029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette scheduleSelf(what, when); 373029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 374029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 375029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette @Override 376f6d87ec193f17e8dad82c9994ba7a58e975d364bAlan Viverette public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { 377029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette unscheduleSelf(what); 378029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette } 379029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette 380029d039ea5df180218288f955f96f66d57b74bc3Alan Viverette @Override 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "ScrollBarDrawable: range=" + mRange + " offset=" + mOffset + 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " extent=" + mExtent + (mVertical ? " V" : " H"); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 388