xref: /haiku/src/apps/mediaplayer/interface/SeekSlider.cpp (revision 8e9973a09d9258802f9bd0142e1c4c877dfd9688)
10fc56ed5SStephan Aßmus /*
29282400fSStephan Aßmus  * Copyright © 2006-2008 Stephan Aßmus <superstippi@gmx.de>
39282400fSStephan Aßmus  * All rights reserved. Distributed under the terms of the MIT License.
40fc56ed5SStephan Aßmus  */
50fc56ed5SStephan Aßmus 
60fc56ed5SStephan Aßmus // NOTE: Based on my code in the BeOS interface for the VLC media player
79282400fSStephan Aßmus // that I did during the VLC 0.4.3 - 0.4.6 times. Code not written by me
80fc56ed5SStephan Aßmus // removed. -Stephan Aßmus
90fc56ed5SStephan Aßmus 
100fc56ed5SStephan Aßmus #include "SeekSlider.h"
110fc56ed5SStephan Aßmus 
120fc56ed5SStephan Aßmus #include <stdio.h>
130fc56ed5SStephan Aßmus #include <string.h>
140fc56ed5SStephan Aßmus 
150fc56ed5SStephan Aßmus #include "DrawingTidbits.h"
160fc56ed5SStephan Aßmus 
170fc56ed5SStephan Aßmus 
180fc56ed5SStephan Aßmus #define SEEK_SLIDER_KNOB_WIDTH 8.0
190fc56ed5SStephan Aßmus 
200fc56ed5SStephan Aßmus const rgb_color kSeekGreen = (rgb_color){ 171, 221, 161, 255 };
210fc56ed5SStephan Aßmus const rgb_color kSeekGreenShadow = (rgb_color){ 144, 186, 136, 255 };
220fc56ed5SStephan Aßmus const rgb_color kSeekRed = (rgb_color){ 255, 0, 0, 255 };
230fc56ed5SStephan Aßmus const rgb_color kSeekRedLight = (rgb_color){ 255, 152, 152, 255 };
240fc56ed5SStephan Aßmus const rgb_color kSeekRedShadow = (rgb_color){ 178, 0, 0, 255 };
250fc56ed5SStephan Aßmus 
260fc56ed5SStephan Aßmus const char* kDisabledSeekMessage = "Drop files to play";
270fc56ed5SStephan Aßmus 
280fc56ed5SStephan Aßmus 
290fc56ed5SStephan Aßmus SeekSlider::SeekSlider(BRect frame, const char* name, BMessage* message,
300fc56ed5SStephan Aßmus 					   int32 minValue, int32 maxValue)
31e663610eSStephan Aßmus 	:
32e663610eSStephan Aßmus 	BControl(frame, name, NULL, message, B_FOLLOW_LEFT | B_FOLLOW_TOP,
33e663610eSStephan Aßmus 		   B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_FRAME_EVENTS),
34e663610eSStephan Aßmus 	fTracking(false),
35e663610eSStephan Aßmus 	fLastTrackTime(0),
36e663610eSStephan Aßmus 	fKnobPos(_KnobPosFor(Bounds(), Value())),
37e663610eSStephan Aßmus 	fMinValue(minValue),
38e663610eSStephan Aßmus 	fMaxValue(maxValue),
39e663610eSStephan Aßmus 
40e663610eSStephan Aßmus 	fDisabledString(kDisabledSeekMessage)
410fc56ed5SStephan Aßmus {
420fc56ed5SStephan Aßmus 	BFont font(be_plain_font);
430fc56ed5SStephan Aßmus 	font.SetSize(9.0);
440fc56ed5SStephan Aßmus 	SetFont(&font);
450fc56ed5SStephan Aßmus }
460fc56ed5SStephan Aßmus 
470fc56ed5SStephan Aßmus 
480fc56ed5SStephan Aßmus SeekSlider::~SeekSlider()
490fc56ed5SStephan Aßmus {
500fc56ed5SStephan Aßmus }
510fc56ed5SStephan Aßmus 
520fc56ed5SStephan Aßmus 
530fc56ed5SStephan Aßmus void
540fc56ed5SStephan Aßmus SeekSlider::AttachedToWindow()
550fc56ed5SStephan Aßmus {
560fc56ed5SStephan Aßmus 	BControl::AttachedToWindow();
570fc56ed5SStephan Aßmus 	SetViewColor(B_TRANSPARENT_32_BIT);
580fc56ed5SStephan Aßmus }
590fc56ed5SStephan Aßmus 
600fc56ed5SStephan Aßmus 
610fc56ed5SStephan Aßmus void
620fc56ed5SStephan Aßmus SeekSlider::SetValue(int32 value)
630fc56ed5SStephan Aßmus {
640fc56ed5SStephan Aßmus 	if (value == Value())
650fc56ed5SStephan Aßmus 		return;
660fc56ed5SStephan Aßmus 
670fc56ed5SStephan Aßmus #if __HAIKU__
680fc56ed5SStephan Aßmus 	BControl::SetValueNoUpdate(value);
690fc56ed5SStephan Aßmus #else
700fc56ed5SStephan Aßmus 	BControl::SetValue(value);
710fc56ed5SStephan Aßmus 		// this will Invalidate() the whole view
720fc56ed5SStephan Aßmus #endif
730fc56ed5SStephan Aßmus 	Invoke();
740fc56ed5SStephan Aßmus 
750fc56ed5SStephan Aßmus 	_SetKnobPosition(_KnobPosFor(Bounds(), Value()));
760fc56ed5SStephan Aßmus 
770fc56ed5SStephan Aßmus 	fLastTrackTime = system_time();
780fc56ed5SStephan Aßmus }
790fc56ed5SStephan Aßmus 
800fc56ed5SStephan Aßmus 
810fc56ed5SStephan Aßmus void
820fc56ed5SStephan Aßmus SeekSlider::Draw(BRect updateRect)
830fc56ed5SStephan Aßmus {
840fc56ed5SStephan Aßmus 	BRect r(Bounds());
850fc56ed5SStephan Aßmus 
860fc56ed5SStephan Aßmus 	// draw both sides (the original from Be doesn't seem
870fc56ed5SStephan Aßmus 	// to make a difference for enabled/disabled state)
880fc56ed5SStephan Aßmus //	DrawBitmapAsync(fLeftSideBits, r.LeftTop());
890fc56ed5SStephan Aßmus //	DrawBitmapAsync(fRightSideBits, BPoint(sliderEnd + 1.0, r.top));
900fc56ed5SStephan Aßmus 	// colors for the slider area between the two bitmaps
910fc56ed5SStephan Aßmus 	rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
920fc56ed5SStephan Aßmus 	rgb_color shadow = tint_color(background, B_DARKEN_2_TINT);
930fc56ed5SStephan Aßmus 	rgb_color softShadow = tint_color(background, B_DARKEN_1_TINT);
940fc56ed5SStephan Aßmus 	rgb_color darkShadow = tint_color(background, B_DARKEN_4_TINT);
950fc56ed5SStephan Aßmus 	rgb_color midShadow = tint_color(background, B_DARKEN_3_TINT);
960fc56ed5SStephan Aßmus 	rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
970fc56ed5SStephan Aßmus 	rgb_color softLight = tint_color(background, B_LIGHTEN_1_TINT);
980fc56ed5SStephan Aßmus 	rgb_color green = kSeekGreen;
990fc56ed5SStephan Aßmus 	rgb_color greenShadow = kSeekGreenShadow;
1000fc56ed5SStephan Aßmus 	rgb_color black = kBlack;
1010fc56ed5SStephan Aßmus 	rgb_color dotGrey = midShadow;
1020fc56ed5SStephan Aßmus 	rgb_color dotGreen = greenShadow;
1030fc56ed5SStephan Aßmus 	// draw frame
1049282400fSStephan Aßmus 	_StrokeFrame(r, softShadow, softShadow, light, light);
1050fc56ed5SStephan Aßmus 	r.InsetBy(1.0, 1.0);
1069282400fSStephan Aßmus 	_StrokeFrame(r, black, black, softShadow, softShadow);
1070fc56ed5SStephan Aßmus 	if (IsEnabled()) {
1080fc56ed5SStephan Aßmus 		// *** enabled look ***
1090fc56ed5SStephan Aßmus 		r.InsetBy(1.0, 1.0);
1100fc56ed5SStephan Aßmus 		// inner shadow
1110fc56ed5SStephan Aßmus 		_StrokeFrame(r, greenShadow, greenShadow, green, green);
1120fc56ed5SStephan Aßmus 		r.top++;
1130fc56ed5SStephan Aßmus 		r.left++;
1140fc56ed5SStephan Aßmus 		_StrokeFrame(r, greenShadow, greenShadow, green, green);
1150fc56ed5SStephan Aßmus 		// inside area
1160fc56ed5SStephan Aßmus 		r.InsetBy(1.0, 1.0);
1170fc56ed5SStephan Aßmus 		SetHighColor(green);
1180fc56ed5SStephan Aßmus 		FillRect(r);
1190fc56ed5SStephan Aßmus 		// dots
1200fc56ed5SStephan Aßmus 		int32 dotCount = (int32)(r.Width() / 6.0);
1210fc56ed5SStephan Aßmus 		BPoint dotPos;
1220fc56ed5SStephan Aßmus 		dotPos.y = r.top + 2.0;
1230fc56ed5SStephan Aßmus 		SetHighColor(dotGreen);
1240fc56ed5SStephan Aßmus 
1250fc56ed5SStephan Aßmus 		float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
1260fc56ed5SStephan Aßmus 		float sliderStart = (r.left + knobWidth2);
1270fc56ed5SStephan Aßmus 
1280fc56ed5SStephan Aßmus 		for (int32 i = 0; i < dotCount; i++) {
1290fc56ed5SStephan Aßmus 			dotPos.x = sliderStart + i * 6.0;
1300fc56ed5SStephan Aßmus 			StrokeLine(dotPos, BPoint(dotPos.x, dotPos.y + 6.0));
1310fc56ed5SStephan Aßmus 		}
1320fc56ed5SStephan Aßmus 		// slider handle
1330fc56ed5SStephan Aßmus 		r.top -= 4.0;
1340fc56ed5SStephan Aßmus 		r.bottom += 3.0;
1350fc56ed5SStephan Aßmus 		r.left = fKnobPos - knobWidth2;
1360fc56ed5SStephan Aßmus 		r.right = fKnobPos + knobWidth2;
1370fc56ed5SStephan Aßmus 		// black outline
1380fc56ed5SStephan Aßmus 		float handleBottomSize = 2.0;
1390fc56ed5SStephan Aßmus 		float handleArrowSize = 6.0;
1400fc56ed5SStephan Aßmus 		BeginLineArray(10);
1410fc56ed5SStephan Aßmus 			// upper handle
1420fc56ed5SStephan Aßmus 			AddLine(BPoint(r.left, r.top + handleBottomSize),
1430fc56ed5SStephan Aßmus 					BPoint(r.left, r.top), black);
1440fc56ed5SStephan Aßmus 			AddLine(BPoint(r.left + 1.0, r.top),
1450fc56ed5SStephan Aßmus 					BPoint(r.right, r.top), black);
1460fc56ed5SStephan Aßmus 			AddLine(BPoint(r.right, r.top + 1.0),
1470fc56ed5SStephan Aßmus 					BPoint(r.right, r.top + handleBottomSize), black);
1480fc56ed5SStephan Aßmus 			AddLine(BPoint(r.right - 1.0, r.top + handleBottomSize + 1.0),
1490fc56ed5SStephan Aßmus 					BPoint(fKnobPos, r.top + handleArrowSize), black);
1500fc56ed5SStephan Aßmus 			AddLine(BPoint(fKnobPos - 1.0, r.top + handleArrowSize - 1.0),
1510fc56ed5SStephan Aßmus 					BPoint(r.left + 1.0, r.top + handleBottomSize + 1.0), black);
1520fc56ed5SStephan Aßmus 			// lower handle
1530fc56ed5SStephan Aßmus 			AddLine(BPoint(r.left, r.bottom),
1540fc56ed5SStephan Aßmus 					BPoint(r.left, r.bottom - handleBottomSize), black);
1550fc56ed5SStephan Aßmus 			AddLine(BPoint(r.left + 1.0, r.bottom - handleBottomSize - 1.0),
1560fc56ed5SStephan Aßmus 					BPoint(fKnobPos, r.bottom - handleArrowSize), black);
1570fc56ed5SStephan Aßmus 			AddLine(BPoint(fKnobPos + 1.0, r.bottom - handleArrowSize + 1.0),
1580fc56ed5SStephan Aßmus 					BPoint(r.right, r.bottom - handleBottomSize), black);
1590fc56ed5SStephan Aßmus 			AddLine(BPoint(r.right, r.bottom - handleBottomSize + 1.0),
1600fc56ed5SStephan Aßmus 					BPoint(r.right, r.bottom), black);
1610fc56ed5SStephan Aßmus 			AddLine(BPoint(r.right - 1.0, r.bottom),
1620fc56ed5SStephan Aßmus 					BPoint(r.left + 1.0, r.bottom), black);
1630fc56ed5SStephan Aßmus 		EndLineArray();
1640fc56ed5SStephan Aßmus 		// inner red light and shadow lines
1650fc56ed5SStephan Aßmus 		r.InsetBy(1.0, 1.0);
1660fc56ed5SStephan Aßmus 		handleBottomSize--;
1670fc56ed5SStephan Aßmus 		handleArrowSize -= 2.0;
1680fc56ed5SStephan Aßmus 		BeginLineArray(10);
1690fc56ed5SStephan Aßmus 			// upper handle
1700fc56ed5SStephan Aßmus 			AddLine(BPoint(r.left, r.top + handleBottomSize),
1710fc56ed5SStephan Aßmus 					BPoint(r.left, r.top), kSeekRedLight);
1720fc56ed5SStephan Aßmus 			AddLine(BPoint(r.left + 1.0, r.top),
1730fc56ed5SStephan Aßmus 					BPoint(r.right, r.top), kSeekRedLight);
1740fc56ed5SStephan Aßmus 			AddLine(BPoint(r.right, r.top + 1.0),
1750fc56ed5SStephan Aßmus 					BPoint(r.right, r.top + handleBottomSize), kSeekRedShadow);
1760fc56ed5SStephan Aßmus 			AddLine(BPoint(r.right - 1.0, r.top + handleBottomSize + 1.0),
1770fc56ed5SStephan Aßmus 					BPoint(fKnobPos, r.top + handleArrowSize), kSeekRedShadow);
1780fc56ed5SStephan Aßmus 			AddLine(BPoint(fKnobPos - 1.0, r.top + handleArrowSize - 1.0),
1790fc56ed5SStephan Aßmus 					BPoint(r.left + 1.0, r.top + handleBottomSize + 1.0), kSeekRedLight);
1800fc56ed5SStephan Aßmus 			// lower handle
1810fc56ed5SStephan Aßmus 			AddLine(BPoint(r.left, r.bottom),
1820fc56ed5SStephan Aßmus 					BPoint(r.left, r.bottom - handleBottomSize), kSeekRedLight);
1830fc56ed5SStephan Aßmus 			AddLine(BPoint(r.left + 1.0, r.bottom - handleBottomSize - 1.0),
1840fc56ed5SStephan Aßmus 					BPoint(fKnobPos, r.bottom - handleArrowSize), kSeekRedLight);
1850fc56ed5SStephan Aßmus 			AddLine(BPoint(fKnobPos + 1.0, r.bottom - handleArrowSize + 1.0),
1860fc56ed5SStephan Aßmus 					BPoint(r.right, r.bottom - handleBottomSize), kSeekRedShadow);
1870fc56ed5SStephan Aßmus 			AddLine(BPoint(r.right, r.bottom - handleBottomSize + 1.0),
1880fc56ed5SStephan Aßmus 					BPoint(r.right, r.bottom), kSeekRedShadow);
1890fc56ed5SStephan Aßmus 			AddLine(BPoint(r.right - 1.0, r.bottom),
1900fc56ed5SStephan Aßmus 					BPoint(r.left + 1.0, r.bottom), kSeekRedShadow);
1910fc56ed5SStephan Aßmus 		EndLineArray();
1920fc56ed5SStephan Aßmus 		// fill rest of handles with red
1930fc56ed5SStephan Aßmus 		SetHighColor(kSeekRed);
1940fc56ed5SStephan Aßmus 		r.InsetBy(1.0, 1.0);
1950fc56ed5SStephan Aßmus 		handleArrowSize -= 2.0;
1960fc56ed5SStephan Aßmus 		BPoint arrow[3];
1970fc56ed5SStephan Aßmus 		// upper handle arrow
1980fc56ed5SStephan Aßmus 		arrow[0].x = r.left;
1990fc56ed5SStephan Aßmus 		arrow[0].y = r.top;
2000fc56ed5SStephan Aßmus 		arrow[1].x = r.right;
2010fc56ed5SStephan Aßmus 		arrow[1].y = r.top;
2020fc56ed5SStephan Aßmus 		arrow[2].x = fKnobPos;
2030fc56ed5SStephan Aßmus 		arrow[2].y = r.top + handleArrowSize;
2040fc56ed5SStephan Aßmus 		FillPolygon(arrow, 3);
2050fc56ed5SStephan Aßmus 		// lower handle arrow
2060fc56ed5SStephan Aßmus 		arrow[0].x = r.left;
2070fc56ed5SStephan Aßmus 		arrow[0].y = r.bottom;
2080fc56ed5SStephan Aßmus 		arrow[1].x = r.right;
2090fc56ed5SStephan Aßmus 		arrow[1].y = r.bottom;
2100fc56ed5SStephan Aßmus 		arrow[2].x = fKnobPos;
2110fc56ed5SStephan Aßmus 		arrow[2].y = r.bottom - handleArrowSize;
2120fc56ed5SStephan Aßmus 		FillPolygon(arrow, 3);
2130fc56ed5SStephan Aßmus 	} else {
2140fc56ed5SStephan Aßmus 		// *** disabled look ***
2150fc56ed5SStephan Aßmus 		r.InsetBy(1.0, 1.0);
2160fc56ed5SStephan Aßmus 		_StrokeFrame(r, darkShadow, darkShadow, darkShadow, darkShadow);
2170fc56ed5SStephan Aßmus 		r.InsetBy(1.0, 1.0);
2180fc56ed5SStephan Aßmus 		_StrokeFrame(r, darkShadow, darkShadow, darkShadow, darkShadow);
2190fc56ed5SStephan Aßmus 		r.InsetBy(1.0, 1.0);
2200fc56ed5SStephan Aßmus 		SetHighColor(darkShadow);
2210fc56ed5SStephan Aßmus 		SetLowColor(shadow);
2220fc56ed5SStephan Aßmus 		// stripes
223e663610eSStephan Aßmus 		float width = floorf(StringWidth(fDisabledString.String()));
2240fc56ed5SStephan Aßmus 		float textPos = r.left + r.Width() / 2.0 - width / 2.0;
2250fc56ed5SStephan Aßmus 		pattern stripes = { { 0xc7, 0x8f, 0x1f, 0x3e, 0x7c, 0xf8, 0xf1, 0xe3 } };
2260fc56ed5SStephan Aßmus 		BRect stripesRect(r);
2270fc56ed5SStephan Aßmus 		stripesRect.right = textPos - 5.0;
2280fc56ed5SStephan Aßmus 		FillRect(stripesRect, stripes);
2290fc56ed5SStephan Aßmus 		stripesRect.left = textPos + width + 3.0;
2300fc56ed5SStephan Aßmus 		stripesRect.right = r.right;
2310fc56ed5SStephan Aßmus 		FillRect(stripesRect, stripes);
2320fc56ed5SStephan Aßmus 		// info text
2330fc56ed5SStephan Aßmus 		r.left = textPos - 4.0;
2340fc56ed5SStephan Aßmus 		r.right = textPos + width + 2.0;
2350fc56ed5SStephan Aßmus 		FillRect(r);
2360fc56ed5SStephan Aßmus 		SetHighColor(shadow);
2370fc56ed5SStephan Aßmus 		SetLowColor(darkShadow);
2380fc56ed5SStephan Aßmus 		font_height fh;
2390fc56ed5SStephan Aßmus 		GetFontHeight(&fh);
240e663610eSStephan Aßmus 		DrawString(fDisabledString.String(),
241e663610eSStephan Aßmus 			BPoint(textPos, r.top + ceilf(fh.ascent) - 1.0));
2420fc56ed5SStephan Aßmus 	}
2430fc56ed5SStephan Aßmus }
2440fc56ed5SStephan Aßmus 
2450fc56ed5SStephan Aßmus 
2460fc56ed5SStephan Aßmus void
2470fc56ed5SStephan Aßmus SeekSlider::MouseDown(BPoint where)
2480fc56ed5SStephan Aßmus {
2490fc56ed5SStephan Aßmus 	if (IsEnabled() && Bounds().Contains(where)) {
2500fc56ed5SStephan Aßmus 		SetValue(_ValueFor(where.x));
2510fc56ed5SStephan Aßmus 		fTracking = true;
2520fc56ed5SStephan Aßmus 		SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
2530fc56ed5SStephan Aßmus 	}
2540fc56ed5SStephan Aßmus }
2550fc56ed5SStephan Aßmus 
2560fc56ed5SStephan Aßmus 
2570fc56ed5SStephan Aßmus void
2580fc56ed5SStephan Aßmus SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
2590fc56ed5SStephan Aßmus {
2600fc56ed5SStephan Aßmus 	if (fTracking) {
2610fc56ed5SStephan Aßmus 		SetValue(_ValueFor(where.x));
2620fc56ed5SStephan Aßmus 	}
2630fc56ed5SStephan Aßmus }
2640fc56ed5SStephan Aßmus 
2650fc56ed5SStephan Aßmus 
2660fc56ed5SStephan Aßmus void
2670fc56ed5SStephan Aßmus SeekSlider::MouseUp(BPoint where)
2680fc56ed5SStephan Aßmus {
2690fc56ed5SStephan Aßmus 	if (fTracking) {
2700fc56ed5SStephan Aßmus 		fTracking = false;
2710fc56ed5SStephan Aßmus 	}
2720fc56ed5SStephan Aßmus }
2730fc56ed5SStephan Aßmus 
2740fc56ed5SStephan Aßmus 
2750fc56ed5SStephan Aßmus 
2760fc56ed5SStephan Aßmus void
2770fc56ed5SStephan Aßmus SeekSlider::ResizeToPreferred()
2780fc56ed5SStephan Aßmus {
279e663610eSStephan Aßmus 	float width = 15.0 + StringWidth(fDisabledString.String()) + 15.0;
2800fc56ed5SStephan Aßmus 	ResizeTo(width, 17.0);
2810fc56ed5SStephan Aßmus }
2820fc56ed5SStephan Aßmus 
2830fc56ed5SStephan Aßmus 
2840fc56ed5SStephan Aßmus void
2859282400fSStephan Aßmus SeekSlider::FrameResized(float width, float height)
2869282400fSStephan Aßmus {
2879282400fSStephan Aßmus 	_SetKnobPosition(_KnobPosFor(Bounds(), Value()));
2889282400fSStephan Aßmus }
2899282400fSStephan Aßmus 
2909282400fSStephan Aßmus 
2919282400fSStephan Aßmus void
2920fc56ed5SStephan Aßmus SeekSlider::SetPosition(float position)
2930fc56ed5SStephan Aßmus {
2940fc56ed5SStephan Aßmus 	int32 value = fMinValue + (int32)floorf((fMaxValue - fMinValue) * position + 0.5);
2950fc56ed5SStephan Aßmus 	if (value != Value()) {
2960fc56ed5SStephan Aßmus 		BControl::SetValue(value);
2970fc56ed5SStephan Aßmus 		_SetKnobPosition(_KnobPosFor(Bounds(), Value()));
2980fc56ed5SStephan Aßmus 	}
2990fc56ed5SStephan Aßmus }
3000fc56ed5SStephan Aßmus 
3010fc56ed5SStephan Aßmus 
302*8e9973a0SStephan Aßmus float
303*8e9973a0SStephan Aßmus SeekSlider::Position() const
304*8e9973a0SStephan Aßmus {
305*8e9973a0SStephan Aßmus 	int32 range = fMaxValue - fMinValue;
306*8e9973a0SStephan Aßmus 	if (range == 0)
307*8e9973a0SStephan Aßmus 		return 0;
308*8e9973a0SStephan Aßmus 	return (float)(Value() - fMinValue) / range;
309*8e9973a0SStephan Aßmus }
310*8e9973a0SStephan Aßmus 
311*8e9973a0SStephan Aßmus 
3120fc56ed5SStephan Aßmus bool
3130fc56ed5SStephan Aßmus SeekSlider::IsTracking() const
3140fc56ed5SStephan Aßmus {
3150fc56ed5SStephan Aßmus 	if (fTracking)
3160fc56ed5SStephan Aßmus 		return true;
3170fc56ed5SStephan Aßmus 	return system_time() - fLastTrackTime < 250000;
3180fc56ed5SStephan Aßmus }
3190fc56ed5SStephan Aßmus 
3200fc56ed5SStephan Aßmus 
321e663610eSStephan Aßmus void
322e663610eSStephan Aßmus SeekSlider::SetDisabledString(const char* string)
323e663610eSStephan Aßmus {
324e663610eSStephan Aßmus 	if (string == NULL)
325e663610eSStephan Aßmus 		string = kDisabledSeekMessage;
326e663610eSStephan Aßmus 
327e663610eSStephan Aßmus 	if (fDisabledString == string)
328e663610eSStephan Aßmus 		return;
329e663610eSStephan Aßmus 
330e663610eSStephan Aßmus 	fDisabledString = string;
331e663610eSStephan Aßmus 
332e663610eSStephan Aßmus 	if (!IsEnabled())
333e663610eSStephan Aßmus 		Invalidate();
334e663610eSStephan Aßmus }
335e663610eSStephan Aßmus 
336e663610eSStephan Aßmus 
3370fc56ed5SStephan Aßmus // #pragma mark -
3380fc56ed5SStephan Aßmus 
3390fc56ed5SStephan Aßmus 
3400fc56ed5SStephan Aßmus int32
3410fc56ed5SStephan Aßmus SeekSlider::_ValueFor(float xPos) const
3420fc56ed5SStephan Aßmus {
3430fc56ed5SStephan Aßmus 	BRect r(Bounds());
3440fc56ed5SStephan Aßmus 	float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
3450fc56ed5SStephan Aßmus 	float sliderStart = (r.left + knobWidth2);
3460fc56ed5SStephan Aßmus 	float sliderEnd = (r.right - knobWidth2);
3470fc56ed5SStephan Aßmus 	int32 value =  fMinValue + (int32)(((xPos - sliderStart) * (fMaxValue - fMinValue))
3480fc56ed5SStephan Aßmus 				  / (sliderEnd - sliderStart - 1.0));
3490fc56ed5SStephan Aßmus 	if (value < fMinValue)
3500fc56ed5SStephan Aßmus 		value = fMinValue;
3510fc56ed5SStephan Aßmus 	if (value > fMaxValue)
3520fc56ed5SStephan Aßmus 		value = fMaxValue;
3530fc56ed5SStephan Aßmus 	return value;
3540fc56ed5SStephan Aßmus }
3550fc56ed5SStephan Aßmus 
3560fc56ed5SStephan Aßmus 
3570fc56ed5SStephan Aßmus int32
3580fc56ed5SStephan Aßmus SeekSlider::_KnobPosFor(BRect r, int32 value) const
3590fc56ed5SStephan Aßmus {
3600fc56ed5SStephan Aßmus 	float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
3610fc56ed5SStephan Aßmus 	r.left += knobWidth2;
3620fc56ed5SStephan Aßmus 	r.right -= knobWidth2;
3630fc56ed5SStephan Aßmus 	float knobPos = r.left
3640fc56ed5SStephan Aßmus 					+ floorf((r.right - r.left - 1.0) * (Value() - fMinValue)
3650fc56ed5SStephan Aßmus 					/ (fMaxValue - fMinValue) + 0.5);
3660fc56ed5SStephan Aßmus 	return (int32)knobPos;
3670fc56ed5SStephan Aßmus }
3680fc56ed5SStephan Aßmus 
3690fc56ed5SStephan Aßmus 
3700fc56ed5SStephan Aßmus void
3710fc56ed5SStephan Aßmus SeekSlider::_StrokeFrame(BRect r, rgb_color left, rgb_color top,
3720fc56ed5SStephan Aßmus 						 rgb_color right, rgb_color bottom)
3730fc56ed5SStephan Aßmus {
3740fc56ed5SStephan Aßmus 	BeginLineArray(4);
3750fc56ed5SStephan Aßmus 		AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), left);
3760fc56ed5SStephan Aßmus 		AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), top);
3770fc56ed5SStephan Aßmus 		AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), right);
3780fc56ed5SStephan Aßmus 		AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), bottom);
3790fc56ed5SStephan Aßmus 	EndLineArray();
3800fc56ed5SStephan Aßmus }
3810fc56ed5SStephan Aßmus 
3820fc56ed5SStephan Aßmus 
3830fc56ed5SStephan Aßmus void
3840fc56ed5SStephan Aßmus SeekSlider::_SetKnobPosition(int32 knobPos)
3850fc56ed5SStephan Aßmus {
3860fc56ed5SStephan Aßmus 	if (fKnobPos == knobPos)
3870fc56ed5SStephan Aßmus 		return;
3880fc56ed5SStephan Aßmus 
3890fc56ed5SStephan Aßmus 	float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
3900fc56ed5SStephan Aßmus 	BRect oldKnob(Bounds());
3910fc56ed5SStephan Aßmus 	BRect newKnob(oldKnob);
3920fc56ed5SStephan Aßmus 	oldKnob.left = fKnobPos - knobWidth2;
3930fc56ed5SStephan Aßmus 	oldKnob.right = fKnobPos + knobWidth2;
3940fc56ed5SStephan Aßmus 
3950fc56ed5SStephan Aßmus 	fKnobPos = knobPos;
3960fc56ed5SStephan Aßmus 
3970fc56ed5SStephan Aßmus 	newKnob.left = fKnobPos - knobWidth2;
3980fc56ed5SStephan Aßmus 	newKnob.right = fKnobPos + knobWidth2;
399a2ce0594SStephan Aßmus 	Invalidate((oldKnob | newKnob).InsetBySelf(-1, 0));
4000fc56ed5SStephan Aßmus }
4010fc56ed5SStephan Aßmus 
402