1/*
2 * Copyright 2006-2010 Stephan Aßmus <superstippi@gmx.de>
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
5
6
7#include "SeekSlider.h"
8
9#include <stdio.h>
10#include <string.h>
11
12#include <ControlLook.h>
13#include <Region.h>
14#include <Shape.h>
15
16
17static const rgb_color kThumbRed = (rgb_color){ 255, 52, 52, 255 };
18
19
20SeekSlider::SeekSlider(const char* name, BMessage* message, int32 minValue,
21		int32 maxValue)
22	:
23	BSlider(name, NULL, NULL, minValue, maxValue, B_HORIZONTAL,
24		B_TRIANGLE_THUMB),
25	fTracking(false),
26	fLastTrackTime(0),
27	fDisabledString(""),
28	fScale(0.0f)
29{
30	BFont font(be_plain_font);
31	font.SetSize(9.0);
32	SetFont(&font);
33	SetSymbolScale(1.0);
34	rgb_color fillColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
35		B_DARKEN_3_TINT);
36	UseFillColor(true, &fillColor);
37	SetModificationMessage(message);
38}
39
40
41SeekSlider::~SeekSlider()
42{
43}
44
45
46status_t
47SeekSlider::Invoke(BMessage* message)
48{
49	fLastTrackTime = system_time();
50	return BSlider::Invoke(message);
51}
52
53
54BRect
55SeekSlider::ThumbFrame() const
56{
57	BRect frame = BSlider::ThumbFrame();
58
59	float center = (frame.left + frame.right) / 2.0f;
60	float height = ceilf(frame.Height() * fScale);
61	float width = ceilf(frame.Width() * fScale);
62
63	frame.left = floorf(center - width / 2) + 1;
64	frame.right = frame.left + width;
65	frame.bottom = frame.top + height;
66
67	return frame;
68}
69
70
71void
72SeekSlider::DrawBar()
73{
74	BSlider::DrawBar();
75	if (IsEnabled())
76		return;
77
78	BRect r(BarFrame());
79	font_height fh;
80	GetFontHeight(&fh);
81	float width = ceilf(StringWidth(fDisabledString.String()));
82	BPoint textPos;
83	textPos.x = r.left + (r.Width() - width) / 2.0;
84	textPos.y = (r.top + r.bottom - ceilf(fh.ascent + fh.descent)) / 2.0
85		+ ceilf(fh.ascent);
86
87	SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
88		B_DARKEN_3_TINT));
89	SetDrawingMode(B_OP_OVER);
90	DrawString(fDisabledString.String(), textPos);
91}
92
93
94void
95SeekSlider::DrawThumb()
96{
97	if (!IsEnabled())
98		return;
99
100	BRect frame = ThumbFrame();
101	be_control_look->DrawSliderTriangle(this, frame, frame, kThumbRed, 0,
102		B_HORIZONTAL);
103}
104
105
106void
107SeekSlider::MouseDown(BPoint where)
108{
109	if (IsEnabled())
110		fTracking = true;
111	BSlider::MouseDown(where);
112}
113
114
115void
116SeekSlider::MouseUp(BPoint where)
117{
118	fTracking = false;
119	BSlider::MouseUp(where);
120}
121
122
123void
124SeekSlider::GetPreferredSize(float* _width, float* _height)
125{
126	BSlider::GetPreferredSize(_width, _height);
127	if (_width != NULL) {
128		float minWidth = 15.0 + StringWidth(fDisabledString.String()) + 15.0;
129		*_width = max_c(*_width, minWidth);
130	}
131	if (_height != NULL) {
132		BRect unscaledThumbFrame = BSlider::ThumbFrame();
133		BRect scaledThumbFrame = ThumbFrame();
134		*_height += scaledThumbFrame.Height() - unscaledThumbFrame.Height();
135	}
136}
137
138
139BSize
140SeekSlider::MinSize()
141{
142	BSize size = BSlider::MinSize();
143
144	BRect unscaledThumbFrame = BSlider::ThumbFrame();
145	BRect scaledThumbFrame = ThumbFrame();
146	size.height += scaledThumbFrame.Height() - unscaledThumbFrame.Height();
147
148	return size;
149}
150
151
152BSize
153SeekSlider::MaxSize()
154{
155	BSize size = BSlider::MaxSize();
156
157	BRect unscaledThumbFrame = BSlider::ThumbFrame();
158	BRect scaledThumbFrame = ThumbFrame();
159	size.height += scaledThumbFrame.Height() - unscaledThumbFrame.Height();
160
161	return size;
162}
163
164
165bool
166SeekSlider::IsTracking() const
167{
168	if (fTracking)
169		return true;
170	return system_time() - fLastTrackTime < 250000;
171}
172
173
174void
175SeekSlider::SetDisabledString(const char* string)
176{
177	if (string == NULL)
178		string = "";
179
180	if (fDisabledString == string)
181		return;
182
183	fDisabledString = string;
184
185	if (!IsEnabled())
186		Invalidate();
187}
188
189
190void
191SeekSlider::SetSymbolScale(float scale)
192{
193	if (scale == fScale)
194		return;
195
196	fScale = scale;
197	SetBarThickness(fScale * 15.0);
198	InvalidateLayout();
199}
200
201
202