xref: /haiku/src/apps/mediaplayer/interface/SeekSlider.cpp (revision 341ea11eb304738c351755be9d15ab232e4a037a)
10fc56ed5SStephan Aßmus /*
2b000c602SStephan Aßmus  * Copyright 2006-2010 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 
70fc56ed5SStephan Aßmus #include "SeekSlider.h"
80fc56ed5SStephan Aßmus 
90fc56ed5SStephan Aßmus #include <stdio.h>
100fc56ed5SStephan Aßmus #include <string.h>
110fc56ed5SStephan Aßmus 
12b000c602SStephan Aßmus #include <ControlLook.h>
13b000c602SStephan Aßmus #include <Region.h>
14b000c602SStephan Aßmus #include <Shape.h>
15b000c602SStephan Aßmus 
160fc56ed5SStephan Aßmus 
17b000c602SStephan Aßmus const rgb_color kThumbRed = (rgb_color){ 255, 52, 52, 255 };
180fc56ed5SStephan Aßmus 
190fc56ed5SStephan Aßmus const char* kDisabledSeekMessage = "Drop files to play";
200fc56ed5SStephan Aßmus 
210fc56ed5SStephan Aßmus 
22b000c602SStephan Aßmus SeekSlider::SeekSlider(const char* name, BMessage* message, int32 minValue,
23b000c602SStephan Aßmus 		int32 maxValue)
24e663610eSStephan Aßmus 	:
25b000c602SStephan Aßmus 	BSlider(name, NULL, NULL, minValue, maxValue, B_HORIZONTAL,
26b000c602SStephan Aßmus 		B_TRIANGLE_THUMB),
27e663610eSStephan Aßmus 	fTracking(false),
28e663610eSStephan Aßmus 	fLastTrackTime(0),
29*341ea11eSStephan Aßmus 	fDisabledString(kDisabledSeekMessage),
30*341ea11eSStephan Aßmus 	fScale(0.0f)
310fc56ed5SStephan Aßmus {
320fc56ed5SStephan Aßmus 	BFont font(be_plain_font);
330fc56ed5SStephan Aßmus 	font.SetSize(9.0);
340fc56ed5SStephan Aßmus 	SetFont(&font);
35*341ea11eSStephan Aßmus 	SetSymbolScale(1.0);
36b000c602SStephan Aßmus 	rgb_color fillColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
37b000c602SStephan Aßmus 		B_DARKEN_3_TINT);
38b000c602SStephan Aßmus 	UseFillColor(true, &fillColor);
39b000c602SStephan Aßmus 	SetModificationMessage(message);
400fc56ed5SStephan Aßmus }
410fc56ed5SStephan Aßmus 
420fc56ed5SStephan Aßmus 
430fc56ed5SStephan Aßmus SeekSlider::~SeekSlider()
440fc56ed5SStephan Aßmus {
450fc56ed5SStephan Aßmus }
460fc56ed5SStephan Aßmus 
470fc56ed5SStephan Aßmus 
48b000c602SStephan Aßmus status_t
49b000c602SStephan Aßmus SeekSlider::Invoke(BMessage* message)
500fc56ed5SStephan Aßmus {
51b000c602SStephan Aßmus 	fLastTrackTime = system_time();
52b000c602SStephan Aßmus 	return BSlider::Invoke(message);
530fc56ed5SStephan Aßmus }
540fc56ed5SStephan Aßmus 
550fc56ed5SStephan Aßmus 
56*341ea11eSStephan Aßmus BRect
57*341ea11eSStephan Aßmus SeekSlider::ThumbFrame() const
58*341ea11eSStephan Aßmus {
59*341ea11eSStephan Aßmus 	BRect frame = BSlider::ThumbFrame();
60*341ea11eSStephan Aßmus 
61*341ea11eSStephan Aßmus 	float center = (frame.left + frame.right) / 2.0f;
62*341ea11eSStephan Aßmus 	float height = ceilf(frame.Height() * fScale);
63*341ea11eSStephan Aßmus 	float width = ceilf(frame.Width() * fScale);
64*341ea11eSStephan Aßmus 
65*341ea11eSStephan Aßmus 	frame.left = floorf(center - width / 2) + 1;
66*341ea11eSStephan Aßmus 	frame.right = frame.left + width;
67*341ea11eSStephan Aßmus 	frame.bottom = frame.top + height;
68*341ea11eSStephan Aßmus 
69*341ea11eSStephan Aßmus 	return frame;
70*341ea11eSStephan Aßmus }
71*341ea11eSStephan Aßmus 
72*341ea11eSStephan Aßmus 
730fc56ed5SStephan Aßmus void
74b000c602SStephan Aßmus SeekSlider::DrawBar()
750fc56ed5SStephan Aßmus {
76b000c602SStephan Aßmus 	BSlider::DrawBar();
77b000c602SStephan Aßmus 	if (IsEnabled())
780fc56ed5SStephan Aßmus 		return;
790fc56ed5SStephan Aßmus 
80b000c602SStephan Aßmus 	BRect r(BarFrame());
81b000c602SStephan Aßmus 	font_height fh;
82b000c602SStephan Aßmus 	GetFontHeight(&fh);
83b000c602SStephan Aßmus 	float width = ceilf(StringWidth(fDisabledString.String()));
84b000c602SStephan Aßmus 	BPoint textPos;
85b000c602SStephan Aßmus 	textPos.x = r.left + (r.Width() - width) / 2.0;
86b000c602SStephan Aßmus 	textPos.y = (r.top + r.bottom - ceilf(fh.ascent + fh.descent)) / 2.0
87b000c602SStephan Aßmus 		+ ceilf(fh.ascent);
880fc56ed5SStephan Aßmus 
89b000c602SStephan Aßmus 	SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
90b000c602SStephan Aßmus 		B_DARKEN_3_TINT));
91b000c602SStephan Aßmus 	SetDrawingMode(B_OP_OVER);
92b000c602SStephan Aßmus 	DrawString(fDisabledString.String(), textPos);
930fc56ed5SStephan Aßmus }
940fc56ed5SStephan Aßmus 
950fc56ed5SStephan Aßmus 
960fc56ed5SStephan Aßmus void
97b000c602SStephan Aßmus SeekSlider::DrawThumb()
980fc56ed5SStephan Aßmus {
99b000c602SStephan Aßmus 	if (!IsEnabled())
100b000c602SStephan Aßmus 		return;
1010fc56ed5SStephan Aßmus 
102b000c602SStephan Aßmus 	BRect frame = ThumbFrame();
103b000c602SStephan Aßmus 	be_control_look->DrawSliderTriangle(this, frame, frame, kThumbRed, 0,
104b000c602SStephan Aßmus 		B_HORIZONTAL);
1050fc56ed5SStephan Aßmus }
1060fc56ed5SStephan Aßmus 
1070fc56ed5SStephan Aßmus 
1080fc56ed5SStephan Aßmus void
1090fc56ed5SStephan Aßmus SeekSlider::MouseDown(BPoint where)
1100fc56ed5SStephan Aßmus {
111b000c602SStephan Aßmus 	if (IsEnabled())
1120fc56ed5SStephan Aßmus 		fTracking = true;
113b000c602SStephan Aßmus 	BSlider::MouseDown(where);
1140fc56ed5SStephan Aßmus }
1150fc56ed5SStephan Aßmus 
1160fc56ed5SStephan Aßmus 
1170fc56ed5SStephan Aßmus void
1180fc56ed5SStephan Aßmus SeekSlider::MouseUp(BPoint where)
1190fc56ed5SStephan Aßmus {
1200fc56ed5SStephan Aßmus 	fTracking = false;
121b000c602SStephan Aßmus 	BSlider::MouseUp(where);
1220fc56ed5SStephan Aßmus }
1230fc56ed5SStephan Aßmus 
1240fc56ed5SStephan Aßmus 
1250fc56ed5SStephan Aßmus void
126b000c602SStephan Aßmus SeekSlider::GetPreferredSize(float* _width, float* _height)
1279282400fSStephan Aßmus {
128b000c602SStephan Aßmus 	BSlider::GetPreferredSize(_width, _height);
129b000c602SStephan Aßmus 	if (_width != NULL) {
130b000c602SStephan Aßmus 		float minWidth = 15.0 + StringWidth(fDisabledString.String()) + 15.0;
131b000c602SStephan Aßmus 		*_width = max_c(*_width, minWidth);
1329282400fSStephan Aßmus 	}
133*341ea11eSStephan Aßmus 	if (_height != NULL) {
134*341ea11eSStephan Aßmus 		BRect unscaledThumbFrame = BSlider::ThumbFrame();
135*341ea11eSStephan Aßmus 		BRect scaledThumbFrame = ThumbFrame();
136*341ea11eSStephan Aßmus 		*_height += scaledThumbFrame.Height() - unscaledThumbFrame.Height();
137*341ea11eSStephan Aßmus 	}
138*341ea11eSStephan Aßmus }
139*341ea11eSStephan Aßmus 
140*341ea11eSStephan Aßmus 
141*341ea11eSStephan Aßmus BSize
142*341ea11eSStephan Aßmus SeekSlider::MinSize()
143*341ea11eSStephan Aßmus {
144*341ea11eSStephan Aßmus printf("SeekSlider::MinSize()\n");
145*341ea11eSStephan Aßmus 	BSize size = BSlider::MinSize();
146*341ea11eSStephan Aßmus 
147*341ea11eSStephan Aßmus 	BRect unscaledThumbFrame = BSlider::ThumbFrame();
148*341ea11eSStephan Aßmus 	BRect scaledThumbFrame = ThumbFrame();
149*341ea11eSStephan Aßmus printf("height: %.1f/%.1f\n", unscaledThumbFrame.Height(), scaledThumbFrame.Height());
150*341ea11eSStephan Aßmus 	size.height += scaledThumbFrame.Height() - unscaledThumbFrame.Height();
151*341ea11eSStephan Aßmus 
152*341ea11eSStephan Aßmus 	return size;
153*341ea11eSStephan Aßmus }
154*341ea11eSStephan Aßmus 
155*341ea11eSStephan Aßmus 
156*341ea11eSStephan Aßmus BSize
157*341ea11eSStephan Aßmus SeekSlider::MaxSize()
158*341ea11eSStephan Aßmus {
159*341ea11eSStephan Aßmus printf("SeekSlider::MaxSize()\n");
160*341ea11eSStephan Aßmus 	BSize size = BSlider::MaxSize();
161*341ea11eSStephan Aßmus 
162*341ea11eSStephan Aßmus 	BRect unscaledThumbFrame = BSlider::ThumbFrame();
163*341ea11eSStephan Aßmus 	BRect scaledThumbFrame = ThumbFrame();
164*341ea11eSStephan Aßmus printf("height: %.1f/%.1f\n", unscaledThumbFrame.Height(), scaledThumbFrame.Height());
165*341ea11eSStephan Aßmus 	size.height += scaledThumbFrame.Height() - unscaledThumbFrame.Height();
166*341ea11eSStephan Aßmus 
167*341ea11eSStephan Aßmus 	return size;
1688e9973a0SStephan Aßmus }
1698e9973a0SStephan Aßmus 
1708e9973a0SStephan Aßmus 
1710fc56ed5SStephan Aßmus bool
1720fc56ed5SStephan Aßmus SeekSlider::IsTracking() const
1730fc56ed5SStephan Aßmus {
1740fc56ed5SStephan Aßmus 	if (fTracking)
1750fc56ed5SStephan Aßmus 		return true;
1760fc56ed5SStephan Aßmus 	return system_time() - fLastTrackTime < 250000;
1770fc56ed5SStephan Aßmus }
1780fc56ed5SStephan Aßmus 
1790fc56ed5SStephan Aßmus 
180e663610eSStephan Aßmus void
181e663610eSStephan Aßmus SeekSlider::SetDisabledString(const char* string)
182e663610eSStephan Aßmus {
183e663610eSStephan Aßmus 	if (string == NULL)
184e663610eSStephan Aßmus 		string = kDisabledSeekMessage;
185e663610eSStephan Aßmus 
186e663610eSStephan Aßmus 	if (fDisabledString == string)
187e663610eSStephan Aßmus 		return;
188e663610eSStephan Aßmus 
189e663610eSStephan Aßmus 	fDisabledString = string;
190e663610eSStephan Aßmus 
191e663610eSStephan Aßmus 	if (!IsEnabled())
192e663610eSStephan Aßmus 		Invalidate();
193e663610eSStephan Aßmus }
194e663610eSStephan Aßmus 
195e663610eSStephan Aßmus 
196*341ea11eSStephan Aßmus void
197*341ea11eSStephan Aßmus SeekSlider::SetSymbolScale(float scale)
198*341ea11eSStephan Aßmus {
199*341ea11eSStephan Aßmus 	if (scale == fScale)
200*341ea11eSStephan Aßmus 		return;
201*341ea11eSStephan Aßmus printf("SeekSlider::SetSymbolScale(%.1f)\n", scale);
202*341ea11eSStephan Aßmus 
203*341ea11eSStephan Aßmus 	fScale = scale;
204*341ea11eSStephan Aßmus 	SetBarThickness(fScale * 15.0);
205*341ea11eSStephan Aßmus 	InvalidateLayout();
206*341ea11eSStephan Aßmus }
207*341ea11eSStephan Aßmus 
208*341ea11eSStephan Aßmus 
209