xref: /haiku/src/kits/interface/Slider.cpp (revision 51978af14a173e7fae0563b562be5603bc652aeb)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		Slider.h
23 //	Author:			Marc Flerackers (mflerackers@androme.be)
24 //	Description:	BSlider creates and displays a sliding thumb control.
25 //------------------------------------------------------------------------------
26 
27 // Standard Includes -----------------------------------------------------------
28 #include <stdlib.h>
29 #include <string.h>
30 
31 // System Includes -------------------------------------------------------------
32 #include <Slider.h>
33 #include <Message.h>
34 #include <Window.h>
35 #include <Bitmap.h>
36 #include <Errors.h>
37 
38 // Project Includes ------------------------------------------------------------
39 
40 // Local Includes --------------------------------------------------------------
41 
42 // Local Defines ---------------------------------------------------------------
43 
44 // Globals ---------------------------------------------------------------------
45 rgb_color _long_to_color_(int32 color)
46 {
47 	return *((rgb_color*)&color);
48 }
49 
50 int32 _color_to_long_(rgb_color color)
51 {
52 	return *((int32*)&color);
53 }
54 
55 //------------------------------------------------------------------------------
56 BSlider::BSlider(BRect frame, const char *name, const char *label, BMessage *message,
57 				 int32 minValue, int32 maxValue, thumb_style thumbType,
58 				 uint32 resizingMode, uint32 flags)
59 	:	BControl(frame, name, label, message, resizingMode, flags)
60 {
61 	fModificationMessage = NULL;
62 	fSnoozeAmount = 20000;
63 	fOrientation = B_HORIZONTAL;
64 	fBarThickness = 6.0f;
65 	fMinLimitStr = NULL;
66 	fMaxLimitStr = NULL;
67 	fMinValue = minValue;
68 	fMaxValue = maxValue;
69 
70 	SetValue(0);
71 
72 	fKeyIncrementValue = 1;
73 	fHashMarkCount = 0;
74 	fHashMarks = B_HASH_MARKS_NONE;
75 	fStyle = thumbType;
76 
77 	if (Style() == B_BLOCK_THUMB)
78 		SetBarColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
79 			B_DARKEN_4_TINT));
80 	else
81 		SetBarColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
82 			B_DARKEN_4_TINT));
83 
84 	UseFillColor(false, NULL);
85 
86 	_InitObject();
87 }
88 //------------------------------------------------------------------------------
89 BSlider::BSlider(BRect frame, const char *name, const char *label, BMessage *message,
90 				 int32 minValue, int32 maxValue, orientation posture,
91 				 thumb_style thumbType, uint32 resizingMode, uint32 flags)
92 	:	BControl(frame, name, label, message, resizingMode, flags)
93 {
94 	fModificationMessage = NULL;
95 	fSnoozeAmount = 20000;
96 	fOrientation = posture;
97 	fBarThickness = 6.0f;
98 	fMinLimitStr = NULL;
99 	fMaxLimitStr = NULL;
100 	fMinValue = minValue;
101 	fMaxValue = maxValue;
102 
103 	SetValue(0);
104 
105 	fKeyIncrementValue = 1;
106 	fHashMarkCount = 0;
107 	fHashMarks = B_HASH_MARKS_NONE;
108 	fStyle = thumbType;
109 
110 	if (Style() == B_BLOCK_THUMB)
111 		SetBarColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
112 			B_DARKEN_4_TINT));
113 	else
114 		SetBarColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
115 			B_DARKEN_4_TINT));
116 
117 	UseFillColor(false, NULL);
118 
119 	_InitObject();
120 }
121 //------------------------------------------------------------------------------
122 BSlider::~BSlider()
123 {
124 	if (fOffScreenBits)
125 		delete fOffScreenBits;
126 
127 	if (fModificationMessage)
128 		delete fModificationMessage;
129 
130 	if (fMinLimitStr)
131 		free(fMinLimitStr);
132 
133 	if (fMaxLimitStr)
134 		free(fMaxLimitStr);
135 }
136 //------------------------------------------------------------------------------
137 BSlider::BSlider(BMessage *archive)
138 	:	BControl (archive)
139 {
140 	fModificationMessage = NULL;
141 
142 	if (archive->HasMessage("_mod_msg"))
143 	{
144 		BMessage *message = new BMessage;
145 
146 		archive->FindMessage("_mod_msg", message);
147 
148 		SetModificationMessage(message);
149 	}
150 
151 	if (archive->FindInt32("_sdelay", &fSnoozeAmount) != B_OK)
152 		SetSnoozeAmount(20000);
153 
154 	int32 color;
155 
156 	if(archive->FindInt32("_fcolor", &color) == B_OK)
157 	{
158 		rgb_color fillColor = _long_to_color_(color);
159 		UseFillColor(true, &fillColor);
160 	}
161 	else
162 		UseFillColor(false);
163 
164 	int32 orient;
165 
166 	if(archive->FindInt32("_orient", &orient) == B_OK)
167 		fOrientation = (orientation)orient;
168 	else
169 		fOrientation = B_HORIZONTAL;
170 
171 	fMinLimitStr = NULL;
172 	fMaxLimitStr = NULL;
173 
174 	const char *minlbl = NULL, *maxlbl = NULL;
175 
176 	archive->FindString("_minlbl", &minlbl);
177 	archive->FindString("_maxlbl", &maxlbl);
178 
179 	SetLimitLabels(minlbl, maxlbl);
180 
181 	if (archive->FindInt32("_min", &fMinValue) != B_OK)
182 		fMinValue = 0;
183 
184 	if (archive->FindInt32("_max", &fMaxValue) != B_OK)
185 		fMaxValue = 100;
186 
187 	if (archive->FindInt32("_incrementvalue", &fKeyIncrementValue) != B_OK)
188 		fKeyIncrementValue = 1;
189 
190 	if (archive->FindInt32("_hashcount", &fHashMarkCount) != B_OK)
191 		fHashMarkCount = 11;
192 
193 	int16 hashloc;
194 
195 	if(archive->FindInt16("_hashloc", &hashloc) == B_OK)
196 		fHashMarks = (hash_mark_location)hashloc;
197 	else
198 		fHashMarks = B_HASH_MARKS_NONE;
199 
200 	int16 sstyle;
201 
202 	if(archive->FindInt16("_sstyle", &sstyle) == B_OK)
203 		fStyle = (thumb_style)sstyle;
204 	else
205 		fStyle = B_BLOCK_THUMB;
206 
207 	if(archive->FindInt32("_bcolor", &color) == B_OK)
208 		SetBarColor(_long_to_color_(color));
209 	else
210 	{
211 		if (Style() == B_BLOCK_THUMB)
212 			SetBarColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
213 				B_DARKEN_4_TINT));
214 		else
215 			SetBarColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
216 				B_DARKEN_4_TINT));
217 	}
218 
219 	float bthickness;
220 
221 	if (archive->FindFloat("_bthickness", &bthickness) == B_OK)
222 		fBarThickness = bthickness;
223 	else
224 		fBarThickness = 6.0f;
225 
226 	_InitObject();
227 }
228 //------------------------------------------------------------------------------
229 BArchivable *BSlider::Instantiate(BMessage *archive)
230 {
231 	if (validate_instantiation(archive, "BSlider"))
232 		return new BSlider(archive);
233 	else
234 		return NULL;
235 }
236 //------------------------------------------------------------------------------
237 status_t BSlider::Archive(BMessage *archive, bool deep) const
238 {
239 	BControl::Archive(archive, deep);
240 
241 	if (ModificationMessage())
242 		archive->AddMessage("_mod_msg", ModificationMessage());
243 
244 	archive->AddInt32("_sdelay", fSnoozeAmount);
245 
246 	archive->AddInt32("_bcolor", _color_to_long_(fBarColor));
247 
248 	if (FillColor(NULL))
249 		archive->AddInt32("_fcolor", _color_to_long_(fFillColor));
250 
251 	if (fMinLimitStr)
252 		archive->AddString("_minlbl", fMinLimitStr);
253 
254 	if (fMaxLimitStr)
255 		archive->AddString("_maxlbl", fMaxLimitStr);
256 
257 	archive->AddInt32("_min", fMinValue);
258 	archive->AddInt32("_max", fMaxValue);
259 
260 	archive->AddInt32("_incrementvalue", fKeyIncrementValue);
261 
262 	archive->AddInt32("_hashcount", fHashMarkCount);
263 
264 	archive->AddInt16("_hashloc", fHashMarks);
265 
266 	archive->AddInt16("_sstyle", fStyle);
267 
268 	archive->AddInt32("_orient", fOrientation);
269 
270 	archive->AddFloat("_bthickness", fBarThickness);
271 
272 	return B_OK;
273 }
274 //------------------------------------------------------------------------------
275 status_t BSlider::Perform(perform_code d, void *arg)
276 {
277 	return BControl::Perform(d, arg);
278 }
279 //------------------------------------------------------------------------------
280 void BSlider::WindowActivated(bool state)
281 {
282 	BControl::WindowActivated(state);
283 }
284 //------------------------------------------------------------------------------
285 void BSlider::AttachedToWindow()
286 {
287 	ResizeToPreferred();
288 
289 	fLocation.Set(9.0f, 0.0f);
290 
291 	BRect bounds(Bounds());
292 
293 	if (!fOffScreenView)
294 	{
295 		fOffScreenView = new BView(bounds, "", B_FOLLOW_ALL, B_WILL_DRAW);
296 
297 		BFont font;
298 		GetFont(&font);
299 		fOffScreenView->SetFont(&font);
300 	}
301 
302 	if (!fOffScreenBits)
303 	{
304 		// TODO: should use B_CMAP8
305 		fOffScreenBits = new BBitmap(bounds, B_CMAP8, true, false);
306 
307 		if (fOffScreenBits && fOffScreenView)
308 			fOffScreenBits->AddChild(fOffScreenView);
309 	}
310 	else if (fOffScreenView)
311 		fOffScreenBits->AddChild(fOffScreenView);
312 
313 	SetValue(Value());
314 
315 	if (fOffScreenView && Parent())
316 	{
317 		rgb_color color = Parent()->ViewColor();
318 
319 		fOffScreenBits->Lock();
320 		fOffScreenView->SetViewColor(color);
321 		fOffScreenView->SetLowColor(color);
322 		fOffScreenBits->Unlock();
323 	}
324 
325 	BControl::AttachedToWindow();
326 }
327 //------------------------------------------------------------------------------
328 void BSlider::AllAttached()
329 {
330 	BControl::AllAttached();
331 }
332 //------------------------------------------------------------------------------
333 void BSlider::AllDetached()
334 {
335 	BControl::AllDetached();
336 }
337 //------------------------------------------------------------------------------
338 void BSlider::DetachedFromWindow()
339 {
340 	BControl::DetachedFromWindow();
341 
342 	if (fOffScreenBits)
343 	{
344 		delete fOffScreenBits;
345 		fOffScreenBits = NULL;
346 		fOffScreenView = NULL;
347 	}
348 }
349 //------------------------------------------------------------------------------
350 void BSlider::MessageReceived(BMessage *msg)
351 {
352 	BSlider::MessageReceived(msg);
353 }
354 //------------------------------------------------------------------------------
355 void BSlider::FrameMoved(BPoint new_position)
356 {
357 	BSlider::FrameMoved(new_position);
358 }
359 //------------------------------------------------------------------------------
360 void BSlider::FrameResized(float w,float h)
361 {
362 	BControl::FrameResized(w, h);
363 
364 	BRect bounds(Bounds());
365 
366 	if (bounds.right <= 0.0f || bounds.bottom <= 0.0f)
367 		return;
368 
369 	if (fOffScreenBits)
370 	{
371 		fOffScreenBits->RemoveChild(fOffScreenView);
372 		delete fOffScreenBits;
373 
374 		fOffScreenView->ResizeTo(bounds.Width(), bounds.Height());
375 
376 		fOffScreenBits = new BBitmap(Bounds(), B_CMAP8, true, false);
377 		fOffScreenBits->AddChild(fOffScreenView);
378 	}
379 
380 	SetValue(Value());
381 	// virtual
382 }
383 //------------------------------------------------------------------------------
384 void BSlider::KeyDown(const char *bytes, int32 numBytes)
385 {
386 	if (!IsEnabled() || IsHidden())
387 		return;
388 
389 	switch (bytes[0])
390 	{
391 		case B_LEFT_ARROW:
392 		case B_DOWN_ARROW:
393 		{
394 			SetValue(Value() - KeyIncrementValue());
395 			Invoke();
396 			break;
397 		}
398 		case B_RIGHT_ARROW:
399 		case B_UP_ARROW:
400 		{
401 			SetValue(Value() + KeyIncrementValue());
402 			Invoke();
403 			break;
404 		}
405 		default:
406 			BControl::KeyDown(bytes, numBytes);
407 	}
408 }
409 //------------------------------------------------------------------------------
410 void BSlider::MouseDown(BPoint point)
411 {
412 	if (!IsEnabled())
413 		return;
414 
415 	if (BarFrame().Contains(point) || ThumbFrame().Contains(point))
416 		fInitialLocation = _Location();
417 
418 	BPoint pt;
419 	uint32 buttons;
420 
421 	GetMouse(&pt, &buttons, true);
422 
423 	if (fOrientation == B_HORIZONTAL)
424 	{
425 		if (pt.x < _MinPosition())
426 			pt.x = _MinPosition();
427 		else if (pt.x > _MaxPosition())
428 			pt.x = _MaxPosition();
429 	}
430 	else
431 	{
432 		if (pt.y > _MinPosition())
433 			pt.y = _MinPosition();
434 		else if (pt.y < _MaxPosition())
435 			pt.y = _MaxPosition();
436 	}
437 
438 	SetValue(ValueForPoint(pt));
439 	//virtual
440 	InvokeNotify(ModificationMessage(), B_CONTROL_MODIFIED);
441 
442 	if (Window()->Flags() & B_ASYNCHRONOUS_CONTROLS)
443 	{
444 		SetTracking(true);
445 		SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
446 	}
447 	else
448 	{
449 		BPoint prevPt;
450 		bool update;
451 
452 		while (buttons)
453 		{
454 			prevPt = pt;
455 			update = false;
456 
457 			snooze(SnoozeAmount());
458 			GetMouse(&pt, &buttons, true);
459 
460 			if (fOrientation == B_HORIZONTAL)
461 			{
462 				if (pt.x != prevPt.x)
463 				{
464 					update = true;
465 
466 					if (pt.x < _MinPosition())
467 						pt.x = _MinPosition();
468 					else if (pt.x > _MaxPosition())
469 						pt.x = _MaxPosition();
470 				}
471 			}
472 			else
473 			{
474 				if (pt.y != prevPt.y)
475 				{
476 					update = true;
477 
478 					if (pt.y > _MinPosition())
479 						pt.y = _MinPosition();
480 					else if (pt.y < _MaxPosition())
481 						pt.y = _MaxPosition();
482 				}
483 			}
484 
485 			if (update)
486 			{
487 				SetValue(ValueForPoint(pt));
488 				//virtual
489 				InvokeNotify(ModificationMessage(), B_CONTROL_MODIFIED);
490 			}
491 		}
492 	}
493 
494 	if ((Window()->Flags() & B_ASYNCHRONOUS_CONTROLS) == 0)
495 	{
496 		if (_Location() != fInitialLocation)
497 			Invoke();
498 	}
499 }
500 //------------------------------------------------------------------------------
501 void BSlider::MouseUp(BPoint point)
502 {
503 	if (IsTracking())
504 	{
505 		if (_Location() != fInitialLocation)
506 			Invoke();
507 
508 		SetTracking(false);
509 	}
510 	else
511 		BControl::MouseUp(point);
512 }
513 //------------------------------------------------------------------------------
514 void BSlider::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
515 {
516 	if (IsTracking())
517 	{
518 		BPoint loc = _Location();
519 		bool update = false;
520 
521 		if (fOrientation == B_HORIZONTAL)
522 		{
523 			if (point.x != loc.x)
524 			{
525 				update = true;
526 
527 				if (point.x < _MinPosition())
528 					point.x = _MinPosition();
529 				else if (point.x > _MaxPosition())
530 					point.x = _MaxPosition();
531 			}
532 		}
533 		else
534 		{
535 			if (point.y != loc.y)
536 			{
537 				update = true;
538 
539 				if (point.y < _MinPosition())
540 					point.y = _MinPosition();
541 				else if (point.y > _MaxPosition())
542 					point.y = _MaxPosition();
543 			}
544 		}
545 
546 		if (update)
547 		{
548 			SetValue(ValueForPoint(point));
549 			//virtual
550 		}
551 
552 		if (_Location() != loc)
553 			InvokeNotify(ModificationMessage(), B_CONTROL_MODIFIED);
554 	}
555 	else
556 		BControl::MouseMoved(point, transit, message);
557 }
558 //------------------------------------------------------------------------------
559 void BSlider::Pulse()
560 {
561 	BControl::Pulse();
562 }
563 //------------------------------------------------------------------------------
564 void BSlider::SetLabel(const char *label)
565 {
566 	BControl::SetLabel(label);
567 }
568 //------------------------------------------------------------------------------
569 void BSlider::SetLimitLabels(const char *minLabel, const char *maxLabel)
570 {
571 	if (minLabel)
572 	{
573 		if (fMinLimitStr)
574 			free(fMinLimitStr);
575 		fMinLimitStr = strdup(minLabel);
576 	}
577 
578 	if (maxLabel)
579 	{
580 		if (fMaxLimitStr)
581 			free(fMaxLimitStr);
582 		fMaxLimitStr = strdup(maxLabel);
583 	}
584 
585 	ResizeToPreferred();
586 	Invalidate();
587 }
588 //------------------------------------------------------------------------------
589 const char *BSlider::MinLimitLabel() const
590 {
591 	return fMinLimitStr;
592 }
593 //------------------------------------------------------------------------------
594 const char *BSlider::MaxLimitLabel() const
595 {
596 	return fMaxLimitStr;
597 }
598 //------------------------------------------------------------------------------
599 void BSlider::SetValue(int32 value)
600 {
601 	if (value < fMinValue)
602 		value = fMinValue;
603 	if (value > fMaxValue)
604 		value = fMaxValue;
605 
606 	BPoint loc;
607 	float pos = (float)(value - fMinValue) / (float)(fMaxValue - fMinValue) *
608 		_MaxPosition() - _MinPosition();
609 
610 	if (fOrientation == B_HORIZONTAL)
611 	{
612 		loc.x = ceil(_MinPosition() + pos);
613 		loc.y = 0;
614 	}
615 	else
616 	{
617 		loc.x = 0;
618 		loc.y = floor(_MaxPosition() - pos);
619 	}
620 
621 	_SetLocation(loc);
622 
623 	BControl::SetValue(value);
624 }
625 //------------------------------------------------------------------------------
626 int32 BSlider::ValueForPoint(BPoint location) const
627 {
628 	if (fOrientation == B_HORIZONTAL)
629 		return (int32)((location.x - _MinPosition()) * (fMaxValue - fMinValue) /
630 			(_MaxPosition() - _MinPosition())) + fMinValue;
631 	else
632 		return (int32)((location.y - _MinPosition()) * (fMaxValue - fMinValue) /
633 			(_MaxPosition() - _MinPosition())) + fMinValue;
634 }
635 //------------------------------------------------------------------------------
636 void BSlider::SetPosition(float position)
637 {
638 	if (position <= 0.0f)
639 		BControl::SetValue(fMinValue);
640 	else if (position >= 1.0f)
641 		BControl::SetValue(fMaxValue);
642 	else
643 		BControl::SetValue((int32)(position * (fMaxValue - fMinValue) + fMinValue));
644 }
645 //------------------------------------------------------------------------------
646 float BSlider::Position() const
647 {
648 	return ((float)(Value() - fMinValue) / (float)(fMaxValue - fMinValue));
649 }
650 //------------------------------------------------------------------------------
651 void BSlider::SetEnabled(bool on)
652 {
653 	BControl::SetEnabled(on);
654 }
655 //------------------------------------------------------------------------------
656 void BSlider::GetLimits(int32 *minimum, int32 *maximum)
657 {
658 	*minimum = fMinValue;
659 	*maximum = fMaxValue;
660 }
661 //------------------------------------------------------------------------------
662 void BSlider::Draw(BRect updateRect)
663 {
664 	DrawSlider();
665 }
666 //------------------------------------------------------------------------------
667 void BSlider::DrawSlider()
668 {
669 	if (!fOffScreenBits)
670 		return;
671 
672 	if (fOffScreenBits->Lock())
673 	{
674 		OffscreenView()->SetHighColor(ViewColor());
675 		OffscreenView()->FillRect(Bounds());
676 
677 		DrawBar();
678 		DrawHashMarks();
679 		DrawThumb();
680 		DrawFocusMark();
681 		DrawText();
682 		OffscreenView()->Sync();
683 		DrawBitmap(fOffScreenBits, B_ORIGIN);
684 
685 		fOffScreenBits->Unlock();
686 	}
687 }
688 //------------------------------------------------------------------------------
689 void BSlider::DrawBar()
690 {
691 	BRect frame = BarFrame();
692 	BView *view = OffscreenView();
693 
694 	if (fUseFillColor)
695 	{
696 		if (fOrientation == B_HORIZONTAL)
697 		{
698 			view->SetHighColor(fBarColor);
699 			view->FillRect(BRect((float)floor(frame.left + 1 + Position() *
700 				(frame.Width() - 2)), frame.top, frame.right, frame.bottom));
701 
702 			view->SetHighColor(fFillColor);
703 			view->FillRect(BRect(frame.left, frame.top,
704 				(float)floor(frame.left + 1 + Position() * (frame.Width() - 2)),
705 				frame.bottom));
706 		}
707 		else
708 		{
709 			view->SetHighColor(fBarColor);
710 			view->FillRect(BRect(frame.left, frame.top, frame.right,
711 				(float)floor(frame.bottom - 1 - Position() * (frame.Height() - 2))));
712 
713 			view->SetHighColor(fFillColor);
714 			view->FillRect(BRect(frame.left,
715 				(float)floor(frame.bottom - 1 - Position() *
716 				(frame.Height() - 2)), frame.right, frame.bottom));
717 
718 		}
719 	}
720 	else
721 	{
722 		view->SetHighColor(fBarColor);
723 		view->FillRect(frame);
724 	}
725 
726 	rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR),
727 		lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT),
728 		darken1 = tint_color(no_tint, B_DARKEN_1_TINT),
729 		darken2 = tint_color(no_tint, B_DARKEN_2_TINT),
730 		darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT);
731 
732 	view->SetHighColor(darken1);
733 	view->StrokeLine(BPoint(frame.left, frame.top),
734 		BPoint(frame.left + 1.0f, frame.top));
735 	view->StrokeLine(BPoint(frame.left, frame.bottom),
736 		BPoint(frame.left + 1.0f, frame.bottom));
737 	view->StrokeLine(BPoint(frame.right - 1.0f, frame.top),
738 		BPoint(frame.right, frame.top));
739 
740 	view->SetHighColor(darken2);
741 	view->StrokeLine(BPoint(frame.left + 1.0f, frame.top),
742 		BPoint(frame.right - 1.0f, frame.top));
743 	view->StrokeLine(BPoint(frame.left, frame.bottom - 1.0f),
744 		BPoint(frame.left, frame.top + 1.0f));
745 
746 	view->SetHighColor(lightenmax);
747 	view->StrokeLine(BPoint(frame.left + 1.0f, frame.bottom),
748 		BPoint(frame.right, frame.bottom));
749 	view->StrokeLine(BPoint(frame.right, frame.top + 1.0f));
750 
751 	frame.InsetBy(1.0f, 1.0f);
752 
753 	view->SetHighColor(darkenmax);
754 	view->StrokeLine(BPoint(frame.left, frame.bottom),
755 		BPoint(frame.left, frame.top));
756 	view->StrokeLine(BPoint(frame.right, frame.top));
757 }
758 //------------------------------------------------------------------------------
759 void BSlider::DrawHashMarks()
760 {
761 	BRect frame = HashMarksFrame();
762 	BView *view = OffscreenView();
763 	rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR),
764 		lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT),
765 		darken2 = tint_color(no_tint, B_DARKEN_2_TINT);
766 
767 	float pos = _MinPosition();
768 	float factor = (_MaxPosition() - pos) / (fHashMarkCount - 1);
769 
770 	if (fHashMarks & B_HASH_MARKS_TOP)
771 	{
772 		if (fOrientation == B_HORIZONTAL)
773 		{
774 			for (int32 i = 0; i < fHashMarkCount; i++)
775 			{
776 				view->SetHighColor(darken2);
777 				view->StrokeLine(BPoint(pos, frame.top),
778 					BPoint(pos, frame.top + 5));
779 				view->SetHighColor(lightenmax);
780 				view->StrokeLine(BPoint(pos + 1, frame.top),
781 					BPoint(pos + 1, frame.top + 5));
782 
783 				pos += factor;
784 			}
785 		}
786 		else
787 		{
788 			for (int32 i = 0; i < fHashMarkCount; i++)
789 			{
790 				view->SetHighColor(darken2);
791 				view->StrokeLine(BPoint(frame.left, pos),
792 					BPoint(frame.left + 5, pos));
793 				view->SetHighColor(lightenmax);
794 				view->StrokeLine(BPoint(frame.left, pos + 1),
795 					BPoint(frame.left + 5, pos + 1));
796 
797 				pos += factor;
798 			}
799 		}
800 	}
801 
802 	pos = _MinPosition();
803 
804 	if (fHashMarks & B_HASH_MARKS_BOTTOM)
805 	{
806 		if (fOrientation == B_HORIZONTAL)
807 		{
808 			for (int32 i = 0; i < fHashMarkCount; i++)
809 			{
810 				view->SetHighColor(darken2);
811 				view->StrokeLine(BPoint(pos, frame.bottom - 5),
812 					BPoint(pos, frame.bottom));
813 				view->SetHighColor(lightenmax);
814 				view->StrokeLine(BPoint(pos + 1, frame.bottom - 5),
815 					BPoint(pos + 1, frame.bottom));
816 
817 				pos += factor;
818 			}
819 		}
820 		else
821 		{
822 			for (int32 i = 0; i < fHashMarkCount; i++)
823 			{
824 				view->SetHighColor(darken2);
825 				view->StrokeLine(BPoint(frame.right - 5, pos),
826 					BPoint(frame.right, pos));
827 				view->SetHighColor(lightenmax);
828 				view->StrokeLine(BPoint(frame.right - 5, pos + 1),
829 					BPoint(frame.right, pos + 1));
830 
831 				pos += factor;
832 			}
833 		}
834 	}
835 }
836 //------------------------------------------------------------------------------
837 void BSlider::DrawThumb()
838 {
839 	if (Style() == B_BLOCK_THUMB)
840 		_DrawBlockThumb();
841 	else
842 		_DrawTriangleThumb();
843 }
844 //------------------------------------------------------------------------------
845 void BSlider::DrawFocusMark()
846 {
847 	if (!IsFocus())
848 		return;
849 
850 	OffscreenView()->SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
851 
852 	BRect frame = ThumbFrame();
853 
854 	if (fStyle == B_BLOCK_THUMB)
855 	{
856 		frame.left += 2.0f;
857 		frame.top += 2.0f;
858 		frame.right -= 3.0f;
859 		frame.bottom -= 3.0f;
860 		OffscreenView()->StrokeRect(frame);
861 	}
862 	else
863 	{
864 		if (fOrientation == B_HORIZONTAL)
865 			OffscreenView()->StrokeLine(BPoint(frame.left, frame.bottom + 3.0f),
866 				BPoint(frame.right, frame.bottom + 3.0f));
867 		else
868 			OffscreenView()->StrokeLine(BPoint(frame.left - 2.0f, frame.top),
869 				BPoint(frame.left - 2.0f, frame.bottom));
870 	}
871 
872 }
873 //------------------------------------------------------------------------------
874 void BSlider::DrawText()
875 {
876 	BRect bounds(Bounds());
877 	BView *view = OffscreenView();
878 
879 	view->SetHighColor(0, 0, 0);
880 
881 	font_height fheight;
882 
883 	GetFontHeight(&fheight);
884 
885 	if (Orientation() == B_HORIZONTAL)
886 	{
887 		if (Label())
888 			view->DrawString(Label(), BPoint(2.0f, (float)ceil(fheight.ascent)));
889 
890 		if (fMinLimitStr)
891 			view->DrawString(fMinLimitStr, BPoint(2.0f, bounds.bottom - 4.0f));
892 
893 		if (fMaxLimitStr)
894 			view->DrawString(fMaxLimitStr, BPoint(bounds.right -
895 				StringWidth(fMaxLimitStr) - 2.0f, bounds.bottom - 4.0f));
896 	}
897 	else
898 	{
899 		float ascent = (float)ceil(fheight.ascent);
900 
901 		if (Label())
902 			view->DrawString(Label(), BPoint(bounds.Width() / 2.0f -
903 				StringWidth(Label()) / 2.0f, ascent));
904 
905 		if (fMaxLimitStr)
906 			view->DrawString(fMaxLimitStr, BPoint(bounds.Width() / 2.0f -
907 				StringWidth(fMaxLimitStr) / 2.0f, ascent +
908 				(Label() ? (float)ceil(ascent + fheight.descent + 2.0f) : 0.0f)));
909 
910 		if (fMinLimitStr)
911 			view->DrawString(fMinLimitStr, BPoint(bounds.Width() / 2.0f -
912 				StringWidth(fMinLimitStr) / 2.0f,
913 				bounds.bottom - 2.0f));
914 	}
915 }
916 //------------------------------------------------------------------------------
917 char *BSlider::UpdateText() const
918 {
919 	return NULL;
920 }
921 //------------------------------------------------------------------------------
922 BRect BSlider::BarFrame() const
923 {
924 	BRect frame(Bounds());
925 	font_height fheight;
926 
927 	GetFontHeight(&fheight);
928 
929 	float textHeight = (float)ceil(fheight.ascent + fheight.descent);
930 
931 	if (fStyle == B_BLOCK_THUMB)
932 	{
933 		if (Orientation() == B_HORIZONTAL)
934 		{
935 			frame.left = 8.0f;
936 			frame.top = 6.0f + (Label() ? textHeight + 4.0f : 0.0f);
937 			frame.right -= 8.0f;
938 			frame.bottom = frame.bottom - 6.0f -
939 				(fMinLimitStr || fMaxLimitStr ? textHeight + 4.0f : 0.0f);
940 		}
941 		else
942 		{
943 			frame.left = frame.Width() / 2.0f - 3;
944 			frame.top = 12.0f + (Label() ? textHeight : 0.0f) +
945 				(fMaxLimitStr ? textHeight : 0.0f);
946 			frame.right = frame.left + 6;
947 			frame.bottom = frame.bottom - 8.0f -
948 				(fMinLimitStr ? textHeight + 4 : 0.0f);
949 		}
950 	}
951 	else
952 	{
953 		if (Orientation() == B_HORIZONTAL)
954 		{
955 			frame.left = 7.0f;
956 			frame.top = 6.0f + (Label() ? textHeight + 4.0f : 0.0f);
957 			frame.right -= 7.0f;
958 			frame.bottom = frame.bottom - 6.0f -
959 				(fMinLimitStr || fMaxLimitStr ? textHeight + 4.0f : 0.0f);
960 		}
961 		else
962 		{
963 			frame.left = frame.Width() / 2.0f - 3;
964 			frame.top = 11.0f + (Label() ? textHeight : 0.0f) +
965 				(fMaxLimitStr ? textHeight : 0.0f);
966 			frame.right = frame.left + 6;
967 			frame.bottom = frame.bottom - 7.0f -
968 				(fMinLimitStr ? textHeight + 4 : 0.0f);
969 		}
970 	}
971 
972 	return frame;
973 }
974 //------------------------------------------------------------------------------
975 BRect BSlider::HashMarksFrame() const
976 {
977 	BRect frame(BarFrame());
978 
979 	if (fOrientation == B_HORIZONTAL)
980 	{
981 		frame.top -= 6.0f;
982 		frame.bottom += 6.0f;
983 	}
984 	else
985 	{
986 		frame.left -= 6.0f;
987 		frame.right += 6.0f;
988 	}
989 
990 	return frame;
991 }
992 //------------------------------------------------------------------------------
993 BRect BSlider::ThumbFrame() const
994 {
995 	BRect frame = Bounds();
996 	font_height fheight;
997 
998 	GetFontHeight(&fheight);
999 
1000 	float textHeight = (float)ceil(fheight.ascent + fheight.descent);
1001 
1002 	if (fStyle == B_BLOCK_THUMB)
1003 	{
1004 		if (Orientation() == B_HORIZONTAL)
1005 		{
1006 			frame.left = (float)floor(Position() * (_MaxPosition() - _MinPosition()) +
1007 				_MinPosition()) - 8.0f;
1008 			frame.top = 2.0f + (Label() ? textHeight + 4.0f : 0.0f);
1009 			frame.right = frame.left + 17.0f;
1010 			frame.bottom = frame.bottom - 3.0f -
1011 				(MinLimitLabel() || MaxLimitLabel() ? textHeight + 4.0f : 0.0f);
1012 		}
1013 		else
1014 		{
1015 			frame.left = frame.Width() / 2.0f - 7;
1016 			frame.top = (float)floor(Position() * (_MaxPosition() - _MinPosition()) +
1017 				_MinPosition()) - 8.0f;
1018 			frame.right = frame.left + 13;
1019 			frame.bottom = frame.top + 17;
1020 		}
1021 	}
1022 	else
1023 	{
1024 		if (Orientation() == B_HORIZONTAL)
1025 		{
1026 			frame.left = (float)floor(Position() * (_MaxPosition() - _MinPosition()) +
1027 				_MinPosition()) - 6;
1028 			frame.top = 9.0f + (Label() ? textHeight + 4.0f : 0.0f);
1029 			frame.right = frame.left + 12.0f;
1030 			frame.bottom = frame.bottom - 3.0f -
1031 				(MinLimitLabel() || MaxLimitLabel() ? textHeight + 4.0f : 0.0f);
1032 		}
1033 		else
1034 		{
1035 			frame.left = frame.Width() / 2.0f - 6;
1036 			frame.top = (float)floor(Position() * (_MaxPosition() - _MinPosition())) +
1037 				_MinPosition() - 6.0f;
1038 			frame.right = frame.left + 7;
1039 			frame.bottom = frame.top + 12;
1040 		}
1041 	}
1042 
1043 	return frame;
1044 }
1045 //------------------------------------------------------------------------------
1046 void BSlider::SetFlags(uint32 flags)
1047 {
1048 	BControl::SetFlags(flags);
1049 }
1050 //------------------------------------------------------------------------------
1051 void BSlider::SetResizingMode(uint32 mode)
1052 {
1053 	BControl::SetResizingMode(mode);
1054 }
1055 //------------------------------------------------------------------------------
1056 void BSlider::GetPreferredSize(float *width, float *height)
1057 {
1058 	font_height fheight;
1059 
1060 	GetFontHeight(&fheight);
1061 
1062 	if (Orientation() == B_HORIZONTAL)
1063 	{
1064 		*width = (Frame().Width() < 32.0f) ? 32.0f : Frame().Width();
1065 		*height = 18.0f;
1066 
1067 		if (Label())
1068 			*height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f;
1069 
1070 		if (MinLimitLabel() || MaxLimitLabel())
1071 			*height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f;
1072 	}
1073 	else // B_VERTICAL
1074 	{
1075 		*width = (Frame().Width() < 18.0f) ? 18.0f : Frame().Width();
1076 		*height = 32.0f;
1077 
1078 		if (Label())
1079 			*height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f;
1080 
1081 		if (MaxLimitLabel())
1082 			*height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f;
1083 
1084 		if (MinLimitLabel())
1085 			*height += (float)ceil(fheight.ascent + fheight.descent) + 4.0f;
1086 
1087 		if (Label() && (MaxLimitLabel()))
1088 			*height -= 4.0f;
1089 
1090 		*height = (Frame().Height() < *height) ? *height : Frame().Height();
1091 	}
1092 }
1093 //------------------------------------------------------------------------------
1094 void BSlider::ResizeToPreferred()
1095 {
1096 	BControl::ResizeToPreferred();
1097 }
1098 //------------------------------------------------------------------------------
1099 status_t BSlider::Invoke(BMessage *msg)
1100 {
1101 	return BControl::Invoke(msg);
1102 }
1103 //------------------------------------------------------------------------------
1104 BHandler *BSlider::ResolveSpecifier(BMessage *message, int32 index,
1105 									BMessage *specifier, int32 command,
1106 									const char *property)
1107 {
1108 	return BControl::ResolveSpecifier(message, index, specifier, command,
1109 		property);
1110 }
1111 //------------------------------------------------------------------------------
1112 status_t BSlider::GetSupportedSuites(BMessage *message)
1113 {
1114 	return BControl::GetSupportedSuites(message);
1115 }
1116 //------------------------------------------------------------------------------
1117 void BSlider::SetModificationMessage(BMessage *message)
1118 {
1119 	if (fModificationMessage)
1120 		delete fModificationMessage;
1121 
1122 	fModificationMessage = message;
1123 }
1124 //------------------------------------------------------------------------------
1125 BMessage *BSlider::ModificationMessage() const
1126 {
1127 	return fModificationMessage;
1128 }
1129 //------------------------------------------------------------------------------
1130 void BSlider::SetSnoozeAmount(int32 snooze_time)
1131 {
1132 	if (snooze_time < 5000)
1133 		snooze_time = 5000;
1134 	if (snooze_time > 1000000)
1135 		snooze_time = 1000000;
1136 
1137 	fSnoozeAmount = snooze_time;
1138 }
1139 //------------------------------------------------------------------------------
1140 int32 BSlider::SnoozeAmount() const
1141 {
1142 	return fSnoozeAmount;
1143 }
1144 //------------------------------------------------------------------------------
1145 void BSlider::SetKeyIncrementValue(int32 increment_value)
1146 {
1147 	fKeyIncrementValue = increment_value;
1148 }
1149 //------------------------------------------------------------------------------
1150 int32 BSlider::KeyIncrementValue() const
1151 {
1152 	return fKeyIncrementValue;
1153 }
1154 //------------------------------------------------------------------------------
1155 void BSlider::SetHashMarkCount(int32 hash_mark_count)
1156 {
1157 	fHashMarkCount = hash_mark_count;
1158 	Invalidate();
1159 }
1160 //------------------------------------------------------------------------------
1161 int32 BSlider::HashMarkCount() const
1162 {
1163 	return fHashMarkCount;
1164 }
1165 //------------------------------------------------------------------------------
1166 void BSlider::SetHashMarks(hash_mark_location where)
1167 {
1168 	fHashMarks = where;
1169 	Invalidate();
1170 }
1171 //------------------------------------------------------------------------------
1172 hash_mark_location BSlider::HashMarks() const
1173 {
1174 	return fHashMarks;
1175 }
1176 //------------------------------------------------------------------------------
1177 void BSlider::SetStyle(thumb_style style)
1178 {
1179 	fStyle = style;
1180 }
1181 //------------------------------------------------------------------------------
1182 thumb_style BSlider::Style() const
1183 {
1184 	return fStyle;
1185 }
1186 //------------------------------------------------------------------------------
1187 void BSlider::SetBarColor(rgb_color bar_color)
1188 {
1189 	fBarColor = bar_color;
1190 }
1191 //------------------------------------------------------------------------------
1192 rgb_color BSlider::BarColor() const
1193 {
1194 	return fBarColor;
1195 }
1196 //------------------------------------------------------------------------------
1197 void BSlider::UseFillColor(bool use_fill, const rgb_color *bar_color)
1198 {
1199 	fUseFillColor = use_fill;
1200 
1201 	if (use_fill && bar_color)
1202 		fFillColor = *bar_color;
1203 }
1204 //------------------------------------------------------------------------------
1205 bool BSlider::FillColor(rgb_color *bar_color) const
1206 {
1207 	if (bar_color && fUseFillColor)
1208 		*bar_color = fFillColor;
1209 
1210 	return fUseFillColor;
1211 }
1212 //------------------------------------------------------------------------------
1213 BView *BSlider::OffscreenView() const
1214 {
1215 	return fOffScreenView;
1216 }
1217 //------------------------------------------------------------------------------
1218 orientation BSlider::Orientation() const
1219 {
1220 	return fOrientation;
1221 }
1222 //------------------------------------------------------------------------------
1223 void BSlider::SetOrientation(orientation posture)
1224 {
1225 	fOrientation = posture;
1226 }
1227 //------------------------------------------------------------------------------
1228 float BSlider::BarThickness() const
1229 {
1230 	return fBarThickness;
1231 }
1232 //------------------------------------------------------------------------------
1233 void BSlider::SetBarThickness(float thickness)
1234 {
1235 	fBarThickness = thickness;
1236 }
1237 //------------------------------------------------------------------------------
1238 void BSlider::SetFont(const BFont *font, uint32 properties)
1239 {
1240 	BControl::SetFont(font, properties);
1241 
1242 	if (fOffScreenView && fOffScreenBits)
1243 	{
1244 		if (fOffScreenBits->Lock())
1245 		{
1246 			fOffScreenView->SetFont(font, properties);
1247 			fOffScreenBits->Unlock();
1248 		}
1249 	}
1250 }
1251 //------------------------------------------------------------------------------
1252 void BSlider::SetLimits(int32 minimum, int32 maximum)
1253 {
1254 	// TODO: Redraw
1255 	fMinValue = minimum;
1256 	fMaxValue = maximum;
1257 }
1258 //------------------------------------------------------------------------------
1259 void BSlider::_DrawBlockThumb()
1260 {
1261 	BRect frame = ThumbFrame();
1262 	BView *view = OffscreenView();
1263 
1264 	rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR),
1265 		lighten2 = tint_color(no_tint, B_LIGHTEN_2_TINT),
1266 		darken2 = tint_color(no_tint, B_DARKEN_2_TINT),
1267 		darken3 = tint_color(no_tint, B_DARKEN_3_TINT),
1268 		darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT);
1269 
1270 	// Outline
1271 	view->SetHighColor(darken3);
1272 	view->StrokeLine(BPoint(frame.left, frame.bottom - 2.0f),
1273 		BPoint(frame.left, frame.top + 1.0f));
1274 	view->StrokeLine(BPoint(frame.left + 1.0f, frame.top),
1275 		BPoint(frame.right - 2.0f, frame.top));
1276 	view->StrokeLine(BPoint(frame.right, frame.top + 2.0f),
1277 		BPoint(frame.right, frame.bottom - 1.0f));
1278 	view->StrokeLine(BPoint(frame.left + 2.0f, frame.bottom),
1279 		BPoint(frame.right - 1.0f, frame.bottom));
1280 
1281 	// First bevel
1282 	frame.InsetBy(1.0f, 1.0f);
1283 
1284 	view->SetHighColor(lighten2);
1285 	view->FillRect(frame);
1286 
1287 	view->SetHighColor(darkenmax);
1288 	view->StrokeLine(BPoint(frame.left, frame.bottom),
1289 		BPoint(frame.right - 1.0f, frame.bottom));
1290 	view->StrokeLine(BPoint(frame.right, frame.bottom - 1),
1291 		BPoint(frame.right, frame.top));
1292 
1293 	frame.InsetBy(1.0f, 1.0f);
1294 
1295 	// Second bevel and center dots
1296 	view->SetHighColor(darken2);
1297 	view->StrokeLine(BPoint(frame.left, frame.bottom),
1298 		BPoint(frame.right, frame.bottom));
1299 	view->StrokeLine(BPoint(frame.right, frame.top));
1300 
1301 	if (Orientation() == B_HORIZONTAL)
1302 	{
1303 		view->StrokeLine(BPoint(frame.left + 6.0f, frame.top + 2.0f),
1304 			BPoint(frame.left + 6.0f, frame.top + 2.0f));
1305 		view->StrokeLine(BPoint(frame.left + 6.0f, frame.top + 4.0f),
1306 			BPoint(frame.left + 6.0f, frame.top + 4.0f));
1307 		view->StrokeLine(BPoint(frame.left + 6.0f, frame.top + 6.0f),
1308 			BPoint(frame.left + 6.0f, frame.top + 6.0f));
1309 	}
1310 	else
1311 	{
1312 		view->StrokeLine(BPoint(frame.left + 2.0f, frame.top + 6.0f),
1313 			BPoint(frame.left + 2.0f, frame.top + 6.0f));
1314 		view->StrokeLine(BPoint(frame.left + 4.0f, frame.top + 6.0f),
1315 			BPoint(frame.left + 4.0f, frame.top + 6.0f));
1316 		view->StrokeLine(BPoint(frame.left + 6.0f, frame.top + 6.0f),
1317 			BPoint(frame.left + 6.0f, frame.top + 6.0f));
1318 	}
1319 
1320 	view->StrokeLine(BPoint(frame.right + 1.0f, frame.bottom + 1.0f),
1321 		BPoint(frame.right + 1.0f, frame.bottom + 1.0f));
1322 
1323 	frame.InsetBy(1.0f, 1.0f);
1324 
1325 	// Third bevel
1326 	view->SetHighColor(no_tint);
1327 	view->StrokeLine(BPoint(frame.left, frame.bottom),
1328 		BPoint(frame.right, frame.bottom));
1329 	view->StrokeLine(BPoint(frame.right, frame.top));
1330 }
1331 //------------------------------------------------------------------------------
1332 void BSlider::_DrawTriangleThumb()
1333 {
1334 	BRect frame = ThumbFrame();
1335 	BView *view = OffscreenView();
1336 
1337 	rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR),
1338 		lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT),
1339 //		lighten2 = tint_color(no_tint, B_LIGHTEN_2_TINT),
1340 //		lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT),
1341 //		darken1 = tint_color(no_tint, B_DARKEN_1_TINT),
1342 		darken2 = tint_color(no_tint, B_DARKEN_2_TINT),
1343 //		darken3 = tint_color(no_tint, B_DARKEN_3_TINT),
1344 		darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT);
1345 
1346 	if (Orientation() == B_HORIZONTAL)
1347 	{
1348 		view->SetHighColor(lighten1);
1349 		view->FillTriangle(BPoint(frame.left, frame.bottom - 1.0f),
1350 			BPoint(frame.left + 6.0f, frame.top),
1351 			BPoint(frame.right, frame.bottom - 1.0f));
1352 
1353 		view->SetHighColor(darkenmax);
1354 		view->StrokeLine(BPoint(frame.right, frame.bottom + 1),
1355 			BPoint(frame.left, frame.bottom + 1));
1356 		view->StrokeLine(BPoint(frame.right, frame.bottom),
1357 			BPoint(frame.left + 6.0f, frame.top));
1358 
1359 		view->SetHighColor(darken2);
1360 		view->StrokeLine(BPoint(frame.right - 1, frame.bottom),
1361 			BPoint(frame.left, frame.bottom));
1362 		view->StrokeLine(BPoint(frame.left, frame.bottom),
1363 			BPoint(frame.left + 5.0f, frame.top + 1));
1364 
1365 		view->SetHighColor(no_tint);
1366 		view->StrokeLine(BPoint(frame.right - 2, frame.bottom - 1.0f),
1367 			BPoint(frame.left + 3.0f, frame.bottom - 1.0f));
1368 		view->StrokeLine(BPoint(frame.right - 3, frame.bottom - 2.0f),
1369 			BPoint(frame.left + 6.0f, frame.top + 1));
1370 	}
1371 	else
1372 	{
1373 		view->SetHighColor(lighten1);
1374 		view->FillTriangle(BPoint(frame.left + 1.0f, frame.top),
1375 			BPoint(frame.left + 7.0f, frame.top + 6.0f),
1376 			BPoint(frame.left + 1.0f, frame.bottom));
1377 
1378 		view->SetHighColor(darkenmax);
1379 		view->StrokeLine(BPoint(frame.left, frame.top + 1),
1380 			BPoint(frame.left, frame.bottom));
1381 		view->StrokeLine(BPoint(frame.left + 1.0f, frame.bottom),
1382 			BPoint(frame.left + 7.0f, frame.top + 6.0f));
1383 
1384 		view->SetHighColor(darken2);
1385 		view->StrokeLine(BPoint(frame.left, frame.top),
1386 			BPoint(frame.left, frame.bottom - 1));
1387 		view->StrokeLine(BPoint(frame.left + 1.0f, frame.top),
1388 			BPoint(frame.left + 6.0f, frame.top + 5.0f));
1389 
1390 		view->SetHighColor(no_tint);
1391 		view->StrokeLine(BPoint(frame.left + 1.0f, frame.top + 2.0f),
1392 			BPoint(frame.left + 1.0f, frame.bottom - 1.0f));
1393 		view->StrokeLine(BPoint(frame.left + 2.0f, frame.bottom - 2.0f),
1394 			BPoint(frame.left + 6.0f, frame.top + 6.0f));
1395 	}
1396 }
1397 //------------------------------------------------------------------------------
1398 BPoint BSlider::_Location() const
1399 {
1400 	return fLocation;
1401 }
1402 //------------------------------------------------------------------------------
1403 void BSlider::_SetLocation(BPoint p)
1404 {
1405 	fLocation = p;
1406 }
1407 //------------------------------------------------------------------------------
1408 float BSlider::_MinPosition() const
1409 {
1410 	if (fOrientation == B_HORIZONTAL)
1411 		return BarFrame().left + 1.0f;
1412 	else
1413 		return BarFrame().bottom - 1.0f;
1414 }
1415 //------------------------------------------------------------------------------
1416 float BSlider::_MaxPosition() const
1417 {
1418 	if (fOrientation == B_HORIZONTAL)
1419 		return BarFrame().right - 1.0f;
1420 	else
1421 		return BarFrame().top + 1.0f;
1422 }
1423 //------------------------------------------------------------------------------
1424 extern "C"
1425 void _ReservedSlider4__7BSlider(BSlider *slider, int32 minimum, int32 maximum)
1426 {
1427 	slider->SetLimits(minimum, maximum);
1428 }
1429 //------------------------------------------------------------------------------
1430 void BSlider::_ReservedSlider5() {}
1431 void BSlider::_ReservedSlider6() {}
1432 void BSlider::_ReservedSlider7() {}
1433 void BSlider::_ReservedSlider8() {}
1434 void BSlider::_ReservedSlider9() {}
1435 void BSlider::_ReservedSlider10() {}
1436 void BSlider::_ReservedSlider11() {}
1437 void BSlider::_ReservedSlider12() {}
1438 //------------------------------------------------------------------------------
1439 BSlider &BSlider::operator=(const BSlider &)
1440 {
1441 	return *this;
1442 }
1443 //------------------------------------------------------------------------------
1444 void BSlider::_InitObject()
1445 {
1446 	fLocation.x = 0;
1447 	fLocation.y = 0;
1448 	fInitialLocation.x = 0;
1449 	fInitialLocation.y = 0;
1450 
1451 	fOffScreenBits = NULL;
1452 	fOffScreenView = NULL;
1453 }
1454 //------------------------------------------------------------------------------
1455 
1456 
1457 
1458 
1459 
1460 
1461 
1462 
1463 
1464 
1465 
1466 
1467 
1468 
1469 
1470 
1471 
1472 
1473 
1474 
1475 
1476 
1477 
1478 
1479 
1480 
1481 
1482