• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 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 
17 package android.widget;
18 
19 import android.graphics.Canvas;
20 import android.graphics.ColorFilter;
21 import android.graphics.PixelFormat;
22 import android.graphics.Rect;
23 import android.graphics.drawable.Drawable;
24 
25 /**
26  * This is only used by View for displaying its scroll bars.  It should probably
27  * be moved in to the view package since it is used in that lower-level layer.
28  * For now, we'll hide it so it can be cleaned up later.
29  * {@hide}
30  */
31 public class ScrollBarDrawable extends Drawable {
32     private Drawable mVerticalTrack;
33     private Drawable mHorizontalTrack;
34     private Drawable mVerticalThumb;
35     private Drawable mHorizontalThumb;
36     private int mRange;
37     private int mOffset;
38     private int mExtent;
39     private boolean mVertical;
40     private boolean mChanged;
41     private boolean mRangeChanged;
42     private final Rect mTempBounds = new Rect();
43     private boolean mAlwaysDrawHorizontalTrack;
44     private boolean mAlwaysDrawVerticalTrack;
45 
ScrollBarDrawable()46     public ScrollBarDrawable() {
47     }
48 
49     /**
50      * Indicate whether the horizontal scrollbar track should always be drawn regardless of the
51      * extent. Defaults to false.
52      *
53      * @param alwaysDrawTrack Set to true if the track should always be drawn
54      */
setAlwaysDrawHorizontalTrack(boolean alwaysDrawTrack)55     public void setAlwaysDrawHorizontalTrack(boolean alwaysDrawTrack) {
56         mAlwaysDrawHorizontalTrack = alwaysDrawTrack;
57     }
58 
59     /**
60      * Indicate whether the vertical scrollbar track should always be drawn regardless of the
61      * extent. Defaults to false.
62      *
63      * @param alwaysDrawTrack Set to true if the track should always be drawn
64      */
setAlwaysDrawVerticalTrack(boolean alwaysDrawTrack)65     public void setAlwaysDrawVerticalTrack(boolean alwaysDrawTrack) {
66         mAlwaysDrawVerticalTrack = alwaysDrawTrack;
67     }
68 
69     /**
70      * Indicates whether the vertical scrollbar track should always be drawn regardless of the
71      * extent.
72      */
getAlwaysDrawVerticalTrack()73     public boolean getAlwaysDrawVerticalTrack() {
74         return mAlwaysDrawVerticalTrack;
75     }
76 
77     /**
78      * Indicates whether the horizontal scrollbar track should always be drawn regardless of the
79      * extent.
80      */
getAlwaysDrawHorizontalTrack()81     public boolean getAlwaysDrawHorizontalTrack() {
82         return mAlwaysDrawHorizontalTrack;
83     }
84 
setParameters(int range, int offset, int extent, boolean vertical)85     public void setParameters(int range, int offset, int extent, boolean vertical) {
86         if (mVertical != vertical) {
87             mChanged = true;
88         }
89 
90         if (mRange != range || mOffset != offset || mExtent != extent) {
91             mRangeChanged = true;
92         }
93 
94         mRange = range;
95         mOffset = offset;
96         mExtent = extent;
97         mVertical = vertical;
98     }
99 
100     @Override
draw(Canvas canvas)101     public void draw(Canvas canvas) {
102         final boolean vertical = mVertical;
103         final int extent = mExtent;
104         final int range = mRange;
105 
106         boolean drawTrack = true;
107         boolean drawThumb = true;
108         if (extent <= 0 || range <= extent) {
109             drawTrack = vertical ? mAlwaysDrawVerticalTrack : mAlwaysDrawHorizontalTrack;
110             drawThumb = false;
111         }
112 
113         Rect r = getBounds();
114         if (canvas.quickReject(r.left, r.top, r.right, r.bottom,
115                 Canvas.EdgeType.AA)) {
116             return;
117         }
118         if (drawTrack) {
119             drawTrack(canvas, r, vertical);
120         }
121 
122         if (drawThumb) {
123             int size = vertical ? r.height() : r.width();
124             int thickness = vertical ? r.width() : r.height();
125             int length = Math.round((float) size * extent / range);
126             int offset = Math.round((float) (size - length) * mOffset / (range - extent));
127 
128             // avoid the tiny thumb
129             int minLength = thickness * 2;
130             if (length < minLength) {
131                 length = minLength;
132             }
133             // avoid the too-big thumb
134             if (offset + length > size) {
135                 offset = size - length;
136             }
137 
138             drawThumb(canvas, r, offset, length, vertical);
139         }
140     }
141 
142     @Override
onBoundsChange(Rect bounds)143     protected void onBoundsChange(Rect bounds) {
144         super.onBoundsChange(bounds);
145         mChanged = true;
146     }
147 
drawTrack(Canvas canvas, Rect bounds, boolean vertical)148     protected void drawTrack(Canvas canvas, Rect bounds, boolean vertical) {
149         Drawable track;
150         if (vertical) {
151             track = mVerticalTrack;
152         } else {
153             track = mHorizontalTrack;
154         }
155         if (track != null) {
156             if (mChanged) {
157                 track.setBounds(bounds);
158             }
159             track.draw(canvas);
160         }
161     }
162 
drawThumb(Canvas canvas, Rect bounds, int offset, int length, boolean vertical)163     protected void drawThumb(Canvas canvas, Rect bounds, int offset, int length, boolean vertical) {
164         final Rect thumbRect = mTempBounds;
165         final boolean changed = mRangeChanged || mChanged;
166         if (changed) {
167             if (vertical) {
168                 thumbRect.set(bounds.left,  bounds.top + offset,
169                         bounds.right, bounds.top + offset + length);
170             } else {
171                 thumbRect.set(bounds.left + offset, bounds.top,
172                         bounds.left + offset + length, bounds.bottom);
173             }
174         }
175 
176         if (vertical) {
177             final Drawable thumb = mVerticalThumb;
178             if (changed) thumb.setBounds(thumbRect);
179             thumb.draw(canvas);
180         } else {
181             final Drawable thumb = mHorizontalThumb;
182             if (changed) thumb.setBounds(thumbRect);
183             thumb.draw(canvas);
184         }
185     }
186 
setVerticalThumbDrawable(Drawable thumb)187     public void setVerticalThumbDrawable(Drawable thumb) {
188         if (thumb != null) {
189             mVerticalThumb = thumb;
190         }
191     }
192 
setVerticalTrackDrawable(Drawable track)193     public void setVerticalTrackDrawable(Drawable track) {
194         mVerticalTrack = track;
195     }
196 
setHorizontalThumbDrawable(Drawable thumb)197     public void setHorizontalThumbDrawable(Drawable thumb) {
198         if (thumb != null) {
199             mHorizontalThumb = thumb;
200         }
201     }
202 
setHorizontalTrackDrawable(Drawable track)203     public void setHorizontalTrackDrawable(Drawable track) {
204         mHorizontalTrack = track;
205     }
206 
getSize(boolean vertical)207     public int getSize(boolean vertical) {
208         if (vertical) {
209             return (mVerticalTrack != null ?
210                     mVerticalTrack : mVerticalThumb).getIntrinsicWidth();
211         } else {
212             return (mHorizontalTrack != null ?
213                     mHorizontalTrack : mHorizontalThumb).getIntrinsicHeight();
214         }
215     }
216 
217     @Override
setAlpha(int alpha)218     public void setAlpha(int alpha) {
219         if (mVerticalTrack != null) {
220             mVerticalTrack.setAlpha(alpha);
221         }
222         mVerticalThumb.setAlpha(alpha);
223         if (mHorizontalTrack != null) {
224             mHorizontalTrack.setAlpha(alpha);
225         }
226         mHorizontalThumb.setAlpha(alpha);
227     }
228 
229     @Override
setColorFilter(ColorFilter cf)230     public void setColorFilter(ColorFilter cf) {
231         if (mVerticalTrack != null) {
232             mVerticalTrack.setColorFilter(cf);
233         }
234         mVerticalThumb.setColorFilter(cf);
235         if (mHorizontalTrack != null) {
236             mHorizontalTrack.setColorFilter(cf);
237         }
238         mHorizontalThumb.setColorFilter(cf);
239     }
240 
241     @Override
getOpacity()242     public int getOpacity() {
243         return PixelFormat.TRANSLUCENT;
244     }
245 
246     @Override
toString()247     public String toString() {
248         return "ScrollBarDrawable: range=" + mRange + " offset=" + mOffset +
249                " extent=" + mExtent + (mVertical ? " V" : " H");
250     }
251 }
252 
253 
254