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 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 41 SeekSlider::~SeekSlider() 42 { 43 } 44 45 46 status_t 47 SeekSlider::Invoke(BMessage* message) 48 { 49 fLastTrackTime = system_time(); 50 return BSlider::Invoke(message); 51 } 52 53 54 BRect 55 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 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 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 107 SeekSlider::MouseDown(BPoint where) 108 { 109 if (IsEnabled()) 110 fTracking = true; 111 BSlider::MouseDown(where); 112 } 113 114 115 void 116 SeekSlider::MouseUp(BPoint where) 117 { 118 fTracking = false; 119 BSlider::MouseUp(where); 120 } 121 122 123 void 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 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 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 166 SeekSlider::IsTracking() const 167 { 168 if (fTracking) 169 return true; 170 return system_time() - fLastTrackTime < 250000; 171 } 172 173 174 void 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 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