blob: 9886bc37bc0b2820197014bb411a90ba62e668a1 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.widget;
18
19import android.graphics.Canvas;
20import android.graphics.ColorFilter;
21import android.graphics.PixelFormat;
22import android.graphics.Rect;
23import 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 */
31public 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
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 */
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 */
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 */
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 */
81 public boolean getAlwaysDrawHorizontalTrack() {
82 return mAlwaysDrawHorizontalTrack;
83 }
84
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
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();
Romain Guy8fb95422010-08-17 18:38:51 -0700114 if (canvas.quickReject(r.left, r.top, r.right, r.bottom, Canvas.EdgeType.AA)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115 return;
116 }
117 if (drawTrack) {
118 drawTrack(canvas, r, vertical);
119 }
120
121 if (drawThumb) {
122 int size = vertical ? r.height() : r.width();
123 int thickness = vertical ? r.width() : r.height();
124 int length = Math.round((float) size * extent / range);
125 int offset = Math.round((float) (size - length) * mOffset / (range - extent));
126
127 // avoid the tiny thumb
128 int minLength = thickness * 2;
129 if (length < minLength) {
130 length = minLength;
131 }
132 // avoid the too-big thumb
133 if (offset + length > size) {
134 offset = size - length;
135 }
136
137 drawThumb(canvas, r, offset, length, vertical);
138 }
139 }
140
141 @Override
142 protected void onBoundsChange(Rect bounds) {
143 super.onBoundsChange(bounds);
144 mChanged = true;
145 }
146
147 protected void drawTrack(Canvas canvas, Rect bounds, boolean vertical) {
148 Drawable track;
149 if (vertical) {
150 track = mVerticalTrack;
151 } else {
152 track = mHorizontalTrack;
153 }
154 if (track != null) {
155 if (mChanged) {
156 track.setBounds(bounds);
157 }
158 track.draw(canvas);
159 }
160 }
161
162 protected void drawThumb(Canvas canvas, Rect bounds, int offset, int length, boolean vertical) {
163 final Rect thumbRect = mTempBounds;
164 final boolean changed = mRangeChanged || mChanged;
165 if (changed) {
166 if (vertical) {
167 thumbRect.set(bounds.left, bounds.top + offset,
168 bounds.right, bounds.top + offset + length);
169 } else {
170 thumbRect.set(bounds.left + offset, bounds.top,
171 bounds.left + offset + length, bounds.bottom);
172 }
173 }
174
175 if (vertical) {
176 final Drawable thumb = mVerticalThumb;
177 if (changed) thumb.setBounds(thumbRect);
178 thumb.draw(canvas);
179 } else {
180 final Drawable thumb = mHorizontalThumb;
181 if (changed) thumb.setBounds(thumbRect);
182 thumb.draw(canvas);
183 }
184 }
185
186 public void setVerticalThumbDrawable(Drawable thumb) {
187 if (thumb != null) {
188 mVerticalThumb = thumb;
189 }
190 }
191
192 public void setVerticalTrackDrawable(Drawable track) {
193 mVerticalTrack = track;
194 }
195
196 public void setHorizontalThumbDrawable(Drawable thumb) {
197 if (thumb != null) {
198 mHorizontalThumb = thumb;
199 }
200 }
201
202 public void setHorizontalTrackDrawable(Drawable track) {
203 mHorizontalTrack = track;
204 }
205
206 public int getSize(boolean vertical) {
207 if (vertical) {
208 return (mVerticalTrack != null ?
209 mVerticalTrack : mVerticalThumb).getIntrinsicWidth();
210 } else {
211 return (mHorizontalTrack != null ?
212 mHorizontalTrack : mHorizontalThumb).getIntrinsicHeight();
213 }
214 }
215
216 @Override
217 public void setAlpha(int alpha) {
218 if (mVerticalTrack != null) {
219 mVerticalTrack.setAlpha(alpha);
220 }
221 mVerticalThumb.setAlpha(alpha);
222 if (mHorizontalTrack != null) {
223 mHorizontalTrack.setAlpha(alpha);
224 }
225 mHorizontalThumb.setAlpha(alpha);
226 }
227
228 @Override
Chet Haaseb1af7f32013-03-08 14:02:04 -0800229 public int getAlpha() {
230 // All elements should have same alpha, just return one of them
231 return mVerticalThumb.getAlpha();
232 }
233
234 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 public void setColorFilter(ColorFilter cf) {
236 if (mVerticalTrack != null) {
237 mVerticalTrack.setColorFilter(cf);
238 }
239 mVerticalThumb.setColorFilter(cf);
240 if (mHorizontalTrack != null) {
241 mHorizontalTrack.setColorFilter(cf);
242 }
243 mHorizontalThumb.setColorFilter(cf);
244 }
245
246 @Override
247 public int getOpacity() {
248 return PixelFormat.TRANSLUCENT;
249 }
250
251 @Override
252 public String toString() {
253 return "ScrollBarDrawable: range=" + mRange + " offset=" + mOffset +
254 " extent=" + mExtent + (mVertical ? " V" : " H");
255 }
256}
257
258