1 
2 #include "RangeSlider.h"
3 #include "defs.h"
4 #include "cfg.h"
5 
6 namespace
7 {
8 
9 const int scHandleSideLength = 11;
10 const int scSliderBarHeight = 3;
11 const int scLeftRightMargin = 1;
12 
13 }
14 
15 
RangeSlider(QWidget * aParent)16 RangeSlider::RangeSlider(QWidget* aParent)
17     : QWidget(aParent),
18       mMinimum(100),
19       mMaximum(cfg["brt_extend"].get<bool>() ? brt_steps_max * 2 : brt_steps_max),
20       mLowerValue(cfg["brt_min"].get<int>()),
21       mUpperValue(cfg["brt_max"].get<int>()),
22       mFirstHandlePressed(false),
23       mSecondHandlePressed(false),
24       mInterval(mMaximum - mMinimum),
25       mBackgroudColorEnabled(QColor(35, 112, 145)),
26       mBackgroudColorDisabled(QColor(15, 92, 125)),
27       mBackgroudColor(mBackgroudColorEnabled)
28 {
29     setMouseTracking(false);
30 }
31 
paintEvent(QPaintEvent * aEvent)32 void RangeSlider::paintEvent(QPaintEvent* aEvent)
33 {
34 	Q_UNUSED(aEvent);
35 	QPainter painter(this);
36 	painter.setRenderHint(QPainter::Antialiasing);
37 
38 	// Background
39 	QRectF backgroundRect = QRectF(scLeftRightMargin, (height() - scSliderBarHeight) / 2, width() - scLeftRightMargin * 2, scSliderBarHeight);
40 
41 	QColor teal      = QColor(35, 112, 145);
42 	QColor grey      = QColor(76, 76, 76);
43 	QColor whiteblue = QColor(235, 225, 255);
44 	//QColor darkteal  = QColor(15, 92, 125);
45 
46 	painter.setPen(QPen(grey, qreal(0)));
47 	painter.setBrush(grey);
48 	painter.drawRoundedRect(backgroundRect, qreal(1), qreal(1));
49 
50 	painter.setPen(QPen(whiteblue, qreal(0)));
51 	painter.setBrush(whiteblue);
52 
53 	QRectF leftHandleRect = firstHandleRect();
54 	painter.drawRoundedRect(leftHandleRect, 4, 4);
55 	QRectF rightHandleRect = secondHandleRect();
56 	painter.drawRoundedRect(rightHandleRect, 4, 4);
57 
58 	painter.setPen(QPen(teal, qreal(0)));
59 	painter.setBrush(QBrush(teal));
60 
61 	QRectF selectedRect(backgroundRect);
62 	selectedRect.setLeft(leftHandleRect.right() + 0.5);
63 	selectedRect.setRight(rightHandleRect.left() - 0.5);
64 
65 	painter.drawRect(selectedRect);
66 }
67 
firstHandleRect() const68 QRectF RangeSlider::firstHandleRect() const
69 {
70     float percentage = (mLowerValue - mMinimum) * 1.0 / mInterval;
71     return handleRect(percentage * validWidth() + scLeftRightMargin);
72 }
73 
secondHandleRect() const74 QRectF RangeSlider::secondHandleRect() const
75 {
76     float percentage = (mUpperValue - mMinimum) * 1.0 / mInterval;
77     return handleRect(percentage * validWidth() + scLeftRightMargin + scHandleSideLength);
78 }
79 
handleRect(int aValue) const80 QRectF RangeSlider::handleRect(int aValue) const
81 {
82     return QRect(aValue, (height()-scHandleSideLength) / 2, scHandleSideLength, scHandleSideLength);
83 }
84 
mousePressEvent(QMouseEvent * aEvent)85 void RangeSlider::mousePressEvent(QMouseEvent* aEvent)
86 {
87     if(aEvent->buttons() & Qt::LeftButton)
88     {
89 	mSecondHandlePressed = secondHandleRect().contains(aEvent->pos());
90 	mFirstHandlePressed = !mSecondHandlePressed && firstHandleRect().contains(aEvent->pos());
91 	if(mFirstHandlePressed)
92 	{
93 	    mDelta = aEvent->pos().x() - (firstHandleRect().x() + scHandleSideLength / 2);
94 	}
95 	else if(mSecondHandlePressed)
96 	{
97 	    mDelta = aEvent->pos().x() - (secondHandleRect().x() + scHandleSideLength / 2);
98 	}
99 	if(aEvent->pos().y() >= 2
100 	   && aEvent->pos().y() <= height()- 2)
101 	{
102 	    int step = mInterval / 10 < 1 ? 1 : mInterval / 10;
103 	    if(aEvent->pos().x() < firstHandleRect().x())
104 	    {
105 		setLowerValue(mLowerValue - step);
106 	    }
107 	    else if(aEvent->pos().x() > firstHandleRect().x() + scHandleSideLength
108 		    && aEvent->pos().x() < secondHandleRect().x())
109 	    {
110 		if(aEvent->pos().x() - (firstHandleRect().x() + scHandleSideLength) <
111 		   (secondHandleRect().x() - (firstHandleRect().x() + scHandleSideLength)) / 2)
112 		{
113 		    if(mLowerValue + step < mUpperValue)
114 		    {
115 			setLowerValue(mLowerValue + step);
116 		    }
117 		    else
118 		    {
119 			setLowerValue(mUpperValue);
120 		    }
121 		}
122 		else
123 		{
124 		    if(mUpperValue - step > mLowerValue)
125 		    {
126 			setUpperValue(mUpperValue - step);
127 		    }
128 		    else
129 		    {
130 			setUpperValue(mLowerValue);
131 		    }
132 		}
133 	    }
134 	    else if(aEvent->pos().x() > secondHandleRect().x() + scHandleSideLength)
135 	    {
136 		setUpperValue(mUpperValue + step);
137 	    }
138 	}
139     }
140 }
141 
mouseMoveEvent(QMouseEvent * aEvent)142 void RangeSlider::mouseMoveEvent(QMouseEvent* aEvent)
143 {
144     if(aEvent->buttons() & Qt::LeftButton)
145     {
146 	if(mFirstHandlePressed)
147 	{
148 	    if(aEvent->pos().x() - mDelta + scHandleSideLength / 2 <= secondHandleRect().x())
149 	    {
150 		setLowerValue((aEvent->pos().x() - mDelta - scLeftRightMargin - scHandleSideLength / 2) * 1.0 / validWidth() * mInterval + mMinimum);
151 	    }
152 	    else
153 	    {
154 		setLowerValue(mUpperValue);
155 	    }
156 	}
157 	else if(mSecondHandlePressed)
158 	{
159 	    if(firstHandleRect().x() + scHandleSideLength * 1.5 <= aEvent->pos().x() - mDelta)
160 	    {
161 		setUpperValue((aEvent->pos().x() - mDelta - scLeftRightMargin - scHandleSideLength / 2 - scHandleSideLength) * 1.0 / validWidth() * mInterval + mMinimum);
162 	    }
163 	    else
164 	    {
165 		setUpperValue(mLowerValue);
166 	    }
167 	}
168     }
169 }
170 
mouseReleaseEvent(QMouseEvent * aEvent)171 void RangeSlider::mouseReleaseEvent(QMouseEvent* aEvent)
172 {
173     Q_UNUSED(aEvent);
174 
175     mFirstHandlePressed = false;
176     mSecondHandlePressed = false;
177 }
178 
changeEvent(QEvent * aEvent)179 void RangeSlider::changeEvent(QEvent* aEvent)
180 {
181     if(aEvent->type() == QEvent::EnabledChange)
182     {
183 	if(isEnabled())
184 	{
185 	    mBackgroudColor = mBackgroudColorEnabled;
186 	}
187 	else
188 	{
189 	    mBackgroudColor = mBackgroudColorDisabled;
190 	}
191 	update();
192     }
193 }
194 
minimumSizeHint() const195 QSize RangeSlider::minimumSizeHint() const
196 {
197     return QSize(scHandleSideLength * 2 + scLeftRightMargin * 2, scHandleSideLength);
198 }
199 
GetMinimun() const200 int RangeSlider::GetMinimun() const
201 {
202     return mMinimum;
203 }
204 
SetMinimum(int aMinimum)205 void RangeSlider::SetMinimum(int aMinimum)
206 {
207     setMinimum(aMinimum);
208 }
209 
GetMaximun() const210 int RangeSlider::GetMaximun() const
211 {
212     return mMaximum;
213 }
214 
SetMaximum(int aMaximum)215 void RangeSlider::SetMaximum(int aMaximum)
216 {
217     setMaximum(aMaximum);
218 }
219 
GetLowerValue() const220 int RangeSlider::GetLowerValue() const
221 {
222     return mLowerValue;
223 }
224 
SetLowerValue(int aLowerValue)225 void RangeSlider::SetLowerValue(int aLowerValue)
226 {
227     setLowerValue(aLowerValue);
228 }
229 
GetUpperValue() const230 int RangeSlider::GetUpperValue() const
231 {
232     return mUpperValue;
233 }
234 
SetUpperValue(int aUpperValue)235 void RangeSlider::SetUpperValue(int aUpperValue)
236 {
237     setUpperValue(aUpperValue);
238 }
239 
setLowerValue(int aLowerValue)240 void RangeSlider::setLowerValue(int aLowerValue)
241 {
242     if(aLowerValue > mMaximum)
243     {
244 	aLowerValue = mMaximum;
245     }
246 
247     if(aLowerValue < mMinimum)
248     {
249 	aLowerValue = mMinimum;
250     }
251 
252     mLowerValue = aLowerValue;
253     emit lowerValueChanged(mLowerValue);
254 
255     update();
256 }
257 
setUpperValue(int aUpperValue)258 void RangeSlider::setUpperValue(int aUpperValue)
259 {
260     if(aUpperValue > mMaximum)
261     {
262 	aUpperValue = mMaximum;
263     }
264 
265     if(aUpperValue < mMinimum)
266     {
267 	aUpperValue = mMinimum;
268     }
269 
270     mUpperValue = aUpperValue;
271     emit upperValueChanged(mUpperValue);
272 
273     update();
274 }
275 
setMinimum(int aMinimum)276 void RangeSlider::setMinimum(int aMinimum)
277 {
278     if(aMinimum <= mMaximum)
279     {
280 	mMinimum = aMinimum;
281     }
282     else
283     {
284 	int oldMax = mMaximum;
285 	mMinimum = oldMax;
286 	mMaximum = aMinimum;
287     }
288     mInterval = mMaximum - mMinimum;
289     update();
290 
291     setLowerValue(mMinimum);
292     setUpperValue(mMaximum);
293 
294     emit rangeChanged(mMinimum, mMaximum);
295 }
296 
setMaximum(int aMaximum)297 void RangeSlider::setMaximum(int aMaximum)
298 {
299     if(aMaximum >= mMinimum)
300     {
301 	mMaximum = aMaximum;
302     }
303     else
304     {
305 	int oldMin = mMinimum;
306 	mMaximum = oldMin;
307 	mMinimum = aMaximum;
308     }
309     mInterval = mMaximum - mMinimum;
310     update();
311 
312     setLowerValue(mMinimum);
313     setUpperValue(mMaximum);
314 
315     emit rangeChanged(mMinimum, mMaximum);
316 }
317 
validWidth() const318 int RangeSlider::validWidth() const
319 {
320     return width() - scLeftRightMargin * 2 - scHandleSideLength * 2;
321 }
322 
SetRange(int aMinimum,int mMaximum)323 void RangeSlider::SetRange(int aMinimum, int mMaximum)
324 {
325     setMinimum(aMinimum);
326     setMaximum(mMaximum);
327 }
328