xref: /haiku/src/apps/soundrecorder/TrackSlider.cpp (revision 9ecf9d1c1d4888d341a6eac72112c72d1ae3a4cb)
1 /*
2  * Copyright 2005, Jérôme Duval. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Inspired by SoundCapture from Be newsletter (Media Kit Basics: Consumers and Producers)
6  */
7 
8 #include <stdio.h>
9 #include <string.h>
10 #include <Screen.h>
11 
12 #include "TrackSlider.h"
13 #include "icon_button.h"
14 
15 TrackSlider::TrackSlider(BRect rect, const char *title, BMessage *msg, uint32 resizeFlags)
16 	: BControl(rect, "slider", NULL, msg, resizeFlags, B_WILL_DRAW | B_FRAME_EVENTS),
17 	fLeftTime(0), fRightTime(1000000), fMainTime(0), fTotalTime(1000000),
18 	fLeftTracking(false), fRightTracking(false), fMainTracking(false)
19 {
20 	fFont.SetSize(8.0);
21 	fFont.SetFlags(B_DISABLE_ANTIALIASING);
22 
23 	int32 numFamilies = count_font_families();
24 	for (int32 i = 0; i < numFamilies; i++ ) {
25 		font_family family;
26 		uint32 flags;
27 		if ((get_font_family(i, &family, &flags) == B_OK)
28 			&& (strcmp(family, "Baskerville") == 0)) {
29 			fFont.SetFamilyAndFace(family, B_REGULAR_FACE);
30 			break;
31 		}
32 	}
33 
34 }
35 
36 
37 TrackSlider::~TrackSlider()
38 {
39 	delete fBitmap;
40 }
41 
42 
43 void
44 TrackSlider::AttachedToWindow()
45 {
46 	BControl::AttachedToWindow();
47 	SetViewColor(B_TRANSPARENT_COLOR);
48 	InitBitmap();
49 	RenderBitmap();
50 }
51 
52 
53 void
54 TrackSlider::InitBitmap()
55 {
56 	if (fBitmapView) {
57 		fBitmap->RemoveChild(fBitmapView);
58 		delete fBitmapView;
59 	}
60 	if (fBitmap)
61 		delete fBitmap;
62 
63 	BRect rect = Bounds();
64 
65 	fBitmap = new BBitmap(rect, BScreen().ColorSpace(), true);
66 
67 	fBitmapView = new SliderOffscreenView(rect.OffsetToSelf(B_ORIGIN), "bitmapView");
68 	fBitmap->AddChild(fBitmapView);
69 
70 	fBitmapView->fRight = Bounds().right - kLeftRightTrackSliderWidth;
71 	if (fTotalTime == 0) {
72 		fBitmapView->fLeftX = 14;
73 		fBitmapView->fRightX = fBitmapView->fRight;
74 		fBitmapView->fPositionX = 15;
75 	} else {
76 		fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime);
77 		fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime);
78 		fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime);
79 	}
80 }
81 
82 #define SLIDER_BASE 10
83 
84 void
85 TrackSlider::RenderBitmap()
86 {
87 	/* rendering */
88 	if (fBitmap->Lock()) {
89 		fBitmapView->DrawX();
90 		fBitmap->Unlock();
91 	}
92 }
93 
94 
95 void
96 TrackSlider::Draw(BRect updateRect)
97 {
98 	DrawBitmapAsync(fBitmap, BPoint(0,0));
99 
100 	DrawCounter(fMainTime, fBitmapView->fPositionX, fMainTracking);
101 	if (fLeftTracking)
102 		DrawCounter(fLeftTime, fBitmapView->fLeftX, fLeftTracking);
103 	else if (fRightTracking)
104 		DrawCounter(fRightTime, fBitmapView->fRightX, fRightTracking);
105 
106 	DrawMarker(fBitmapView->fPositionX);
107 
108 	Sync();
109 }
110 
111 
112 void
113 TrackSlider::DrawCounter(bigtime_t timestamp, float position, bool isTracking)
114 {
115 	// timecounter
116 
117 	rgb_color gray = {128,128,128};
118 	rgb_color blue = {0,0,140};
119 	rgb_color blue2 = {146,146,214};
120 	rgb_color white = {255,255,255};
121 
122 	char string[12];
123 	TimeToString(timestamp, string);
124 	int32 halfwidth = ((int32)fFont.StringWidth(string)) / 2;
125 
126 	float counterX = position;
127 	if (counterX < 39)
128 		counterX = 39;
129 	if (counterX > fBitmapView->fRight - 23)
130 		counterX = fBitmapView->fRight - 23;
131 
132 	BeginLineArray(4);
133 	if (!isTracking) {
134 		AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE+1), BPoint(counterX+halfwidth+3,SLIDER_BASE+1), gray);
135 		AddLine(BPoint(counterX+halfwidth+4,SLIDER_BASE+1), BPoint(counterX+halfwidth+4,SLIDER_BASE-8), gray);
136 		AddLine(BPoint(counterX-halfwidth-4,SLIDER_BASE+1), BPoint(counterX-halfwidth-4,SLIDER_BASE-9), white);
137 		AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE-9), BPoint(counterX+halfwidth+4,SLIDER_BASE-9), white);
138 		SetHighColor(216,216,216);
139 	} else {
140 		AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE+1), BPoint(counterX+halfwidth+3,SLIDER_BASE+1), blue);
141 		AddLine(BPoint(counterX+halfwidth+4,SLIDER_BASE+1), BPoint(counterX+halfwidth+4,SLIDER_BASE-9), blue2);
142 		AddLine(BPoint(counterX-halfwidth-4,SLIDER_BASE+1), BPoint(counterX-halfwidth-4,SLIDER_BASE-9), blue2);
143 		AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE-9), BPoint(counterX+halfwidth+3,SLIDER_BASE-9), blue2);
144 		SetHighColor(48,48,241);
145 	}
146 	EndLineArray();
147 	FillRect(BRect(counterX-halfwidth-3,SLIDER_BASE-8,counterX+halfwidth+3,SLIDER_BASE));
148 
149 	SetDrawingMode(B_OP_COPY);
150 	if (isTracking)
151 		SetHighColor(255,255,255);
152 	else
153 		SetHighColor(0,0,0);
154 	SetLowColor(ViewColor());
155 
156 	SetFont(&fFont);
157 	DrawString(string, BPoint(counterX-halfwidth, SLIDER_BASE-1));
158 
159 }
160 
161 
162 void
163 TrackSlider::DrawMarker(float position)
164 {
165 	rgb_color black = {0,0,0};
166 	rgb_color rose = {255,152,152};
167 	rgb_color red = {255,0,0};
168 	rgb_color bordeau = {178,0,0};
169 	rgb_color white = {255,255,255};
170 
171 	BeginLineArray(30);
172 	AddLine(BPoint(position,SLIDER_BASE+7), BPoint(position-4,SLIDER_BASE+3), black);
173 	AddLine(BPoint(position-4,SLIDER_BASE+3), BPoint(position-4,SLIDER_BASE+1), black);
174 	AddLine(BPoint(position-4,SLIDER_BASE+1), BPoint(position+4,SLIDER_BASE+1), black);
175 	AddLine(BPoint(position+4,SLIDER_BASE+1), BPoint(position+4,SLIDER_BASE+3), black);
176 	AddLine(BPoint(position+4,SLIDER_BASE+3), BPoint(position,SLIDER_BASE+7), black);
177 
178 
179 	AddLine(BPoint(position-3,SLIDER_BASE+2), BPoint(position+3,SLIDER_BASE+2), rose);
180 	AddLine(BPoint(position-3,SLIDER_BASE+3), BPoint(position-1,SLIDER_BASE+5), rose);
181 
182 	AddLine(BPoint(position-2,SLIDER_BASE+3), BPoint(position+2,SLIDER_BASE+3), red);
183 	AddLine(BPoint(position-1,SLIDER_BASE+4), BPoint(position+1,SLIDER_BASE+4), red);
184 	AddLine(BPoint(position,SLIDER_BASE+5), BPoint(position,SLIDER_BASE+5), red);
185 
186 	AddLine(BPoint(position,SLIDER_BASE+6), BPoint(position+3,SLIDER_BASE+3), bordeau);
187 
188 	AddLine(BPoint(position,SLIDER_BASE+12), BPoint(position-4,SLIDER_BASE+16), black);
189 	AddLine(BPoint(position-4,SLIDER_BASE+16), BPoint(position-4,SLIDER_BASE+17), black);
190 	AddLine(BPoint(position-4,SLIDER_BASE+17), BPoint(position+4,SLIDER_BASE+17), black);
191 	AddLine(BPoint(position+4,SLIDER_BASE+17), BPoint(position+4,SLIDER_BASE+16), black);
192 	AddLine(BPoint(position+4,SLIDER_BASE+16), BPoint(position,SLIDER_BASE+12), black);
193 	AddLine(BPoint(position-4,SLIDER_BASE+18), BPoint(position+4,SLIDER_BASE+18), white);
194 
195 	AddLine(BPoint(position-3,SLIDER_BASE+16), BPoint(position,SLIDER_BASE+13), rose);
196 
197 	AddLine(BPoint(position-2,SLIDER_BASE+16), BPoint(position+2,SLIDER_BASE+16), red);
198 	AddLine(BPoint(position-1,SLIDER_BASE+15), BPoint(position+1,SLIDER_BASE+15), red);
199 	AddLine(BPoint(position,SLIDER_BASE+14), BPoint(position,SLIDER_BASE+14), red);
200 
201 	AddLine(BPoint(position+1,SLIDER_BASE+14), BPoint(position+3,SLIDER_BASE+16), bordeau);
202 
203 	EndLineArray();
204 }
205 
206 
207 void
208 TrackSlider::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
209 {
210 	if (!IsTracking())
211 		return;
212 
213 	uint32 mouseButtons;
214 	BPoint where;
215 	GetMouse(&where, &mouseButtons, true);
216 
217 	// button not pressed, exit
218 	if (! (mouseButtons & B_PRIMARY_MOUSE_BUTTON)) {
219 		Invoke();
220 		SetTracking(false);
221 	}
222 
223 	UpdatePosition(point);
224 }
225 
226 
227 void
228 TrackSlider::MouseDown(BPoint point)
229 {
230 	if (!Bounds().InsetBySelf(2,2).Contains(point))
231 		return;
232 
233 	UpdatePosition(point);
234 	SetTracking(true);
235 	SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY | B_LOCK_WINDOW_FOCUS);
236 }
237 
238 
239 void
240 TrackSlider::MouseUp(BPoint point)
241 {
242 	if (!IsTracking())
243 		return;
244 	if (Bounds().InsetBySelf(2,2).Contains(point)) {
245 		UpdatePosition(point);
246 	}
247 
248 	fLeftTracking = fRightTracking = fMainTracking = false;
249 
250 	Invoke();
251 	SetTracking(false);
252 	Draw(Bounds());
253 	Flush();
254 }
255 
256 
257 void
258 TrackSlider::UpdatePosition(BPoint point)
259 {
260 	BRect leftRect(fBitmapView->fLeftX-9, SLIDER_BASE+3, fBitmapView->fLeftX, SLIDER_BASE+16);
261 	BRect rightRect(fBitmapView->fRightX, SLIDER_BASE+3, fBitmapView->fRightX+9, SLIDER_BASE+16);
262 
263 	if (!(fRightTracking || fMainTracking) && (fLeftTracking || ((point.x < fBitmapView->fPositionX-4) && leftRect.Contains(point)))) {
264 		if (!IsTracking())
265 			fBitmapView->fLastX = point.x - fBitmapView->fLeftX;
266 		fBitmapView->fLeftX = MIN(MAX(point.x - fBitmapView->fLastX, 15), fBitmapView->fRight);
267 		fLeftTime = (bigtime_t)(MAX(MIN((fBitmapView->fLeftX - 15) / (fBitmapView->fRight - 14),1), 0) * fTotalTime);
268 		fLeftTracking = true;
269 
270 		BMessage msg = *Message();
271 		msg.AddInt64("left", fLeftTime);
272 
273 		if (fBitmapView->fPositionX < fBitmapView->fLeftX) {
274 			fBitmapView->fPositionX = fBitmapView->fLeftX + 1;
275 			fMainTime = fLeftTime;
276 			msg.AddInt64("main", fMainTime);
277 			if (fBitmapView->fRightX < fBitmapView->fPositionX) {
278 				fBitmapView->fRightX = fBitmapView->fPositionX;
279 				fRightTime = fMainTime;
280 				msg.AddInt64("right", fRightTime);
281 			}
282 		}
283 
284 		Invoke(&msg);
285 		RenderBitmap();
286 
287 		//printf("fLeftPos : %Ld\n", fLeftTime);
288 	} else if (!fMainTracking && (fRightTracking || ((point.x > fBitmapView->fPositionX+4) && rightRect.Contains(point)))) {
289 		if (!IsTracking())
290 			fBitmapView->fLastX = point.x - fBitmapView->fRightX;
291 		fBitmapView->fRightX = MIN(MAX(point.x - fBitmapView->fLastX, 15), fBitmapView->fRight);
292 		fRightTime = (bigtime_t)(MAX(MIN((fBitmapView->fRightX - 15) / (fBitmapView->fRight - 14),1), 0) * fTotalTime);
293 		fRightTracking = true;
294 
295 		BMessage msg = *Message();
296 		msg.AddInt64("right", fRightTime);
297 
298 		if (fBitmapView->fPositionX > fBitmapView->fRightX) {
299 			fBitmapView->fPositionX = fBitmapView->fRightX;
300 			fMainTime = fRightTime;
301 			msg.AddInt64("main", fMainTime);
302 			if (fBitmapView->fLeftX > fBitmapView->fPositionX) {
303 				fBitmapView->fLeftX = fBitmapView->fPositionX - 1;
304 				fLeftTime = fMainTime;
305 				msg.AddInt64("left", fLeftTime);
306 			}
307 		}
308 
309 		Invoke(&msg);
310 		RenderBitmap();
311 
312 		//printf("fRightPos : %Ld\n", fRightTime);
313 	} else {
314 		fBitmapView->fPositionX = MIN(MAX(point.x, 15), fBitmapView->fRight);
315 		fMainTime = (bigtime_t)(MAX(MIN((fBitmapView->fPositionX - 15) / (fBitmapView->fRight - 14),1), 0) * fTotalTime);
316 		fMainTracking = true;
317 
318 		BMessage msg = *Message();
319 		msg.AddInt64("main", fMainTime);
320 
321 		if (fBitmapView->fRightX < fBitmapView->fPositionX) {
322 			fBitmapView->fRightX = fBitmapView->fPositionX;
323 			fRightTime = fMainTime;
324 			msg.AddInt64("right", fRightTime);
325 			RenderBitmap();
326 		} else if (fBitmapView->fLeftX > fBitmapView->fPositionX) {
327 			fBitmapView->fLeftX = fBitmapView->fPositionX - 1;
328 			fLeftTime = fMainTime;
329 			msg.AddInt64("left", fLeftTime);
330 			RenderBitmap();
331 		}
332 
333 		Invoke(&msg);
334 		//printf("fPosition : %Ld\n", fMainTime);
335 	}
336 	Draw(Bounds());
337 	Flush();
338 }
339 
340 
341 void
342 TrackSlider::TimeToString(bigtime_t timestamp, char *string)
343 {
344 	uint32 hours = timestamp / 3600000000LL;
345 	timestamp -= hours * 3600000000LL;
346 	uint32 minutes = timestamp / 60000000LL;
347 	timestamp -= minutes * 60000000LL;
348 	uint32 seconds = timestamp / 1000000LL;
349 	timestamp -= seconds * 1000000LL;
350 	uint32 centiseconds = timestamp / 10000LL;
351 	sprintf(string, "%02ld:%02ld:%02ld:%02ld", hours, minutes, seconds, centiseconds);
352 
353 }
354 
355 
356 void
357 TrackSlider::SetMainTime(bigtime_t timestamp, bool reset)
358 {
359 	fMainTime = timestamp;
360 	fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime);
361 	if (reset) {
362 		fRightTime = fTotalTime;
363 		fLeftTime = 0;
364 		fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime);
365 		fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime);
366 	}
367 	Invalidate();
368 }
369 
370 void
371 TrackSlider::SetTotalTime(bigtime_t timestamp, bool reset)
372 {
373 	fTotalTime = timestamp;
374 	if (reset) {
375 		fMainTime = 0;
376 		fRightTime = fTotalTime;
377 		fLeftTime = 0;
378 	}
379 	fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime);
380 	fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime);
381 	fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime);
382 	Invalidate();
383 }
384 
385 
386 void
387 TrackSlider::ResetMainTime()
388 {
389 	fMainTime = fLeftTime;
390 	fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime);
391 	Invalidate();
392 }
393 
394 
395 void
396 TrackSlider::FrameResized(float width, float height)
397 {
398 	fBitmapView->fRight = Bounds().right - kLeftRightTrackSliderWidth;
399 	fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14) * ((double)fMainTime / fTotalTime);
400 	InitBitmap();
401 	fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15) * ((double)fLeftTime / fTotalTime);
402 	fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16) * ((double)fRightTime / fTotalTime);
403 	RenderBitmap();
404 	Invalidate();
405 }
406 
407 
408 SliderOffscreenView::SliderOffscreenView(BRect frame, char *name)
409 	: BView(frame, name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW),
410 	leftBitmap(BRect(BPoint(0,0), kLeftRightTrackSliderSize), B_CMAP8),
411 	rightBitmap(BRect(BPoint(0,0), kLeftRightTrackSliderSize), B_CMAP8),
412 	leftThumbBitmap(BRect(0, 0, kLeftRightThumbWidth - 1, kLeftRightThumbHeight - 1), B_CMAP8),
413 	rightThumbBitmap(BRect(0, 0, kLeftRightThumbWidth - 1, kLeftRightThumbHeight - 1), B_CMAP8)
414 {
415 	leftBitmap.SetBits(kLeftTrackSliderBits, kLeftRightTrackSliderWidth * kLeftRightTrackSliderHeight, 0, B_CMAP8);
416 	rightBitmap.SetBits(kRightTrackSliderBits, kLeftRightTrackSliderWidth * kLeftRightTrackSliderHeight, 0, B_CMAP8);
417 	leftThumbBitmap.SetBits(kLeftThumbBits, kLeftRightThumbWidth * kLeftRightThumbHeight, 0, B_CMAP8);
418 	rightThumbBitmap.SetBits(kRightThumbBits, kLeftRightThumbWidth * kLeftRightThumbHeight, 0, B_CMAP8);
419 }
420 
421 
422 SliderOffscreenView::~SliderOffscreenView()
423 {
424 
425 }
426 
427 
428 void
429 SliderOffscreenView::DrawX()
430 {
431 	SetHighColor(216,216,216);
432 	FillRect(Bounds());
433 
434 	SetHighColor(189,186,189);
435 	StrokeLine(BPoint(11,SLIDER_BASE+1), BPoint(fRight,SLIDER_BASE+1));
436 	SetHighColor(0,0,0);
437 	StrokeLine(BPoint(11,SLIDER_BASE+2), BPoint(fRight,SLIDER_BASE+2));
438 	SetHighColor(255,255,255);
439 	StrokeLine(BPoint(11,SLIDER_BASE+17), BPoint(fRight,SLIDER_BASE+17));
440 	SetHighColor(231,227,231);
441 	StrokeLine(BPoint(11,SLIDER_BASE+18), BPoint(fRight,SLIDER_BASE+18));
442 
443 	SetDrawingMode(B_OP_OVER);
444 	SetLowColor(HighColor());
445 
446 	BPoint leftPoint(5,SLIDER_BASE+1);
447 	DrawBitmapAsync(&leftBitmap, BRect(BPoint(0,0), kLeftRightTrackSliderSize - BPoint(5,0)),
448 		BRect(leftPoint, leftPoint+kLeftRightTrackSliderSize-BPoint(5,0)));
449 	BPoint rightPoint(fRight + 1,SLIDER_BASE+1);
450 	DrawBitmapAsync(&rightBitmap, BRect(BPoint(5,0), kLeftRightTrackSliderSize),
451 		BRect(rightPoint, rightPoint+kLeftRightTrackSliderSize-BPoint(5,0)));
452 
453 	SetHighColor(153,153,153);
454 	FillRect(BRect(11,SLIDER_BASE+3,fLeftX-9,SLIDER_BASE+16));
455 	FillRect(BRect(fRightX+9,SLIDER_BASE+3,fRight,SLIDER_BASE+16));
456 	if (fLeftX>19) {
457 		StrokeLine(BPoint(fLeftX-9,SLIDER_BASE+3),BPoint(fLeftX-6,SLIDER_BASE+3));
458 		StrokeLine(BPoint(fLeftX-9,SLIDER_BASE+4),BPoint(fLeftX-7,SLIDER_BASE+4));
459 		StrokeLine(BPoint(fLeftX-9,SLIDER_BASE+5),BPoint(fLeftX-8,SLIDER_BASE+5));
460 		StrokeLine(BPoint(fLeftX-9,SLIDER_BASE+16),BPoint(fLeftX-6,SLIDER_BASE+16));
461 		StrokeLine(BPoint(fLeftX-9,SLIDER_BASE+15),BPoint(fLeftX-7,SLIDER_BASE+15));
462 		StrokeLine(BPoint(fLeftX-9,SLIDER_BASE+14),BPoint(fLeftX-8,SLIDER_BASE+14));
463 	}
464 	if (fRightX < fRight - 5) {
465 		StrokeLine(BPoint(fRightX+5,SLIDER_BASE+3),BPoint(fRightX+8,SLIDER_BASE+3));
466 		StrokeLine(BPoint(fRightX+7,SLIDER_BASE+4),BPoint(fRightX+8,SLIDER_BASE+4));
467 		StrokeLine(BPoint(fRightX+8,SLIDER_BASE+5),BPoint(fRightX+8,SLIDER_BASE+6));
468 		StrokeLine(BPoint(fRightX+8,SLIDER_BASE+13),BPoint(fRightX+8,SLIDER_BASE+14));
469 		StrokeLine(BPoint(fRightX+5,SLIDER_BASE+16),BPoint(fRightX+8,SLIDER_BASE+16));
470 		StrokeLine(BPoint(fRightX+7,SLIDER_BASE+15),BPoint(fRightX+8,SLIDER_BASE+15));
471 	}
472 	SetHighColor(144,186,136);
473 	FillRect(BRect(fLeftX+1,SLIDER_BASE+3,fRightX,SLIDER_BASE+4));
474 	FillRect(BRect(fLeftX+1,SLIDER_BASE+5,fLeftX+2,SLIDER_BASE+16));
475 	SetHighColor(171,221,161);
476 	FillRect(BRect(fLeftX+3,SLIDER_BASE+5,fRightX,SLIDER_BASE+16));
477 
478 	int i = 17;
479 	int j = 18;
480 	SetHighColor(128,128,128);
481 	for (; i<fLeftX-9; i+=6) {
482 		StrokeLine(BPoint(i,SLIDER_BASE+7), BPoint(i,SLIDER_BASE+13));
483 	}
484 	SetHighColor(179,179,179);
485 	for (; j<fLeftX-9; j+=6) {
486 		StrokeLine(BPoint(j,SLIDER_BASE+7), BPoint(j,SLIDER_BASE+13));
487 	}
488 
489 	while (i<=fLeftX)
490 		i+=6;
491 	while (j<=fLeftX)
492 		j+=6;
493 
494 	SetHighColor(144,186,136);
495 	for (; i<=fRightX; i+=6) {
496 		StrokeLine(BPoint(i,SLIDER_BASE+7), BPoint(i,SLIDER_BASE+13));
497 	}
498 	SetHighColor(189,244,178);
499 	for (; j<=fRightX; j+=6) {
500 		StrokeLine(BPoint(j,SLIDER_BASE+7), BPoint(j,SLIDER_BASE+13));
501 	}
502 
503 	while (i<=fRightX+9)
504 		i+=6;
505 	while (j<=fRightX+9)
506 		j+=6;
507 
508 	SetHighColor(128,128,128);
509 	for (; i<=fRight + 1; i+=6) {
510 		StrokeLine(BPoint(i,SLIDER_BASE+7), BPoint(i,SLIDER_BASE+13));
511 	}
512 	SetHighColor(179,179,179);
513 	for (; j<=fRight + 1; j+=6) {
514 		StrokeLine(BPoint(j,SLIDER_BASE+7), BPoint(j,SLIDER_BASE+13));
515 	}
516 
517 	SetLowColor(HighColor());
518 
519 	BPoint leftThumbPoint(fLeftX-8,SLIDER_BASE+3);
520 	DrawBitmapAsync(&leftThumbBitmap, BRect(BPoint(0,0), kLeftRightThumbSize - BPoint(7,0)),
521 		BRect(leftThumbPoint, leftThumbPoint+kLeftRightThumbSize-BPoint(7,0)));
522 
523 	BPoint rightThumbPoint(fRightX,SLIDER_BASE+3);
524 	DrawBitmapAsync(&rightThumbBitmap, BRect(BPoint(6,0), kLeftRightThumbSize),
525 		BRect(rightThumbPoint, rightThumbPoint+kLeftRightThumbSize-BPoint(6,0)));
526 
527 	Sync();
528 }
529