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
17 static const rgb_color kThumbRed = (rgb_color){ 255, 52, 52, 255 };
18
19
SeekSlider(const char * name,BMessage * message,int32 minValue,int32 maxValue)20 SeekSlider::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(font.Size() * 0.75f);
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
~SeekSlider()41 SeekSlider::~SeekSlider()
42 {
43 }
44
45
46 status_t
Invoke(BMessage * message)47 SeekSlider::Invoke(BMessage* message)
48 {
49 fLastTrackTime = system_time();
50 return BSlider::Invoke(message);
51 }
52
53
54 BRect
ThumbFrame() const55 SeekSlider::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
71 void
DrawBar()72 SeekSlider::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
94 void
DrawThumb()95 SeekSlider::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
106 void
MouseDown(BPoint where)107 SeekSlider::MouseDown(BPoint where)
108 {
109 if (IsEnabled())
110 fTracking = true;
111 BSlider::MouseDown(where);
112 }
113
114
115 void
MouseUp(BPoint where)116 SeekSlider::MouseUp(BPoint where)
117 {
118 fTracking = false;
119 BSlider::MouseUp(where);
120 }
121
122
123 void
GetPreferredSize(float * _width,float * _height)124 SeekSlider::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
139 BSize
MinSize()140 SeekSlider::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
152 BSize
MaxSize()153 SeekSlider::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
165 bool
IsTracking() const166 SeekSlider::IsTracking() const
167 {
168 if (fTracking)
169 return true;
170 return system_time() - fLastTrackTime < 250000;
171 }
172
173
174 void
SetDisabledString(const char * string)175 SeekSlider::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
190 void
SetSymbolScale(float scale)191 SeekSlider::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