2 * Pixmap Dial, a custom Qt4 widget
3 * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #include "pixmapdial.hpp"
22 #include <QtCore/QTimer>
23 #include <QtGui/QPainter>
24 #include <QtGui/QPaintEvent>
26 PixmapDial::PixmapDial(QWidget
* parent
)
28 fPixmap(":/bitmaps/dial_01d.png"),
30 fCustomPaint(CUSTOM_PAINT_NULL
),
31 fOrientation(fPixmap
.width() > fPixmap
.height() ? HORIZONTAL
: VERTICAL
),
33 fHoverStep(HOVER_MIN
),
35 fLabelPos(0.0f
, 0.0f
),
38 fLabelGradient(0, 0, 0, 1)
40 fLabelFont
.setPointSize(6);
42 if (palette().window().color().lightness() > 100)
45 const QColor
c(palette().dark().color());
47 fColor2
= QColor(c
.red(), c
.green(), c
.blue(), 0);
48 fColorT
[0] = palette().buttonText().color();
49 fColorT
[1] = palette().mid().color();
54 fColor1
= QColor(0, 0, 0, 255);
55 fColor2
= QColor(0, 0, 0, 0);
56 fColorT
[0] = Qt::white
;
57 fColorT
[1] = Qt::darkGray
;
63 int PixmapDial::getSize() const
68 void PixmapDial::setCustomPaint(CustomPaint paint
)
71 fLabelPos
.setY(fSize
+ fLabelHeight
/2);
75 void PixmapDial::setEnabled(bool enabled
)
77 if (isEnabled() != enabled
)
79 fPixmap
.load(QString(":/bitmaps/dial_%1%2.png").arg(fPixmapNum
).arg(enabled
? "" : "d"));
83 QDial::setEnabled(enabled
);
86 void PixmapDial::setLabel(QString label
)
90 fLabelWidth
= QFontMetrics(font()).width(label
);
91 fLabelHeight
= QFontMetrics(font()).height();
93 fLabelPos
.setX(float(fSize
)/2.0f
- float(fLabelWidth
)/2.0f
);
94 fLabelPos
.setY(fSize
+ fLabelHeight
);
96 fLabelGradient
.setColorAt(0.0f
, fColor1
);
97 fLabelGradient
.setColorAt(0.6f
, fColor1
);
98 fLabelGradient
.setColorAt(1.0f
, fColor2
);
100 fLabelGradient
.setStart(0, float(fSize
)/2.0f
);
101 fLabelGradient
.setFinalStop(0, fSize
+ fLabelHeight
+ 5);
103 fLabelGradientRect
= QRectF(float(fSize
)/8.0f
, float(fSize
)/2.0f
, float(fSize
*6)/8.0f
, fSize
+fLabelHeight
+5);
107 void PixmapDial::setPixmap(int pixmapId
)
109 fPixmapNum
.sprintf("%02i", pixmapId
);
110 fPixmap
.load(QString(":/bitmaps/dial_%1%2.png").arg(fPixmapNum
).arg(isEnabled() ? "" : "d"));
112 if (fPixmap
.width() > fPixmap
.height())
113 fOrientation
= HORIZONTAL
;
115 fOrientation
= VERTICAL
;
121 QSize
PixmapDial::minimumSizeHint() const
123 return QSize(fSize
, fSize
);
126 QSize
PixmapDial::sizeHint() const
128 return QSize(fSize
, fSize
);
131 void PixmapDial::updateSizes()
133 fWidth
= fPixmap
.width();
134 fHeight
= fPixmap
.height();
142 if (fOrientation
== HORIZONTAL
)
145 fCount
= fWidth
/fHeight
;
150 fCount
= fHeight
/fWidth
;
153 setMinimumSize(fSize
, fSize
+ fLabelHeight
+ 5);
154 setMaximumSize(fSize
, fSize
+ fLabelHeight
+ 5);
157 void PixmapDial::enterEvent(QEvent
* event
)
160 if (fHoverStep
== HOVER_MIN
)
161 fHoverStep
= HOVER_MIN
+ 1;
162 QDial::enterEvent(event
);
165 void PixmapDial::leaveEvent(QEvent
* event
)
168 if (fHoverStep
== HOVER_MAX
)
169 fHoverStep
= HOVER_MAX
- 1;
170 QDial::leaveEvent(event
);
173 void PixmapDial::paintEvent(QPaintEvent
* event
)
177 QPainter
painter(this);
179 painter
.setRenderHint(QPainter::Antialiasing
, true);
181 if (! fLabel
.isEmpty())
183 if (fCustomPaint
== CUSTOM_PAINT_NULL
)
185 painter
.setPen(fColor2
);
186 painter
.setBrush(fLabelGradient
);
187 painter
.drawRect(fLabelGradientRect
);
190 painter
.setFont(fLabelFont
);
191 painter
.setPen(fColorT
[isEnabled() ? 0 : 1]);
192 painter
.drawText(fLabelPos
, fLabel
);
197 float current
= value()-minimum();
198 float divider
= maximum()-minimum();
203 float value
= current
/divider
;
204 QRectF source
, target(0.0f
, 0.0f
, fSize
, fSize
);
206 int xpos
, ypos
, per
= (fCount
-1)*value
;
208 if (fOrientation
== HORIZONTAL
)
219 source
= QRectF(xpos
, ypos
, fSize
, fSize
);
220 painter
.drawPixmap(target
, fPixmap
, source
);
222 // Custom knobs (Dry/Wet and Volume)
223 if (fCustomPaint
== CUSTOM_PAINT_CARLA_WET
|| fCustomPaint
== CUSTOM_PAINT_CARLA_VOL
)
226 QColor
colorGreen(0x5D, 0xE7, 0x3D, 191 + fHoverStep
*7);
227 QColor
colorBlue(0x3E, 0xB8, 0xBE, 191 + fHoverStep
*7);
230 QRectF
ballRect(8.0f
, 8.0f
, 15.0f
, 15.0f
);
231 QPainterPath ballPath
;
232 ballPath
.addEllipse(ballRect
);
233 //painter.drawRect(ballRect);
234 float tmpValue
= (0.375f
+ 0.75f
*value
);
235 float ballValue
= tmpValue
- std::floor(tmpValue
);
236 QPointF
ballPoint(ballPath
.pointAtPercent(ballValue
));
239 int startAngle
= 216*16;
240 int spanAngle
= -252*16*value
;
242 if (fCustomPaint
== CUSTOM_PAINT_CARLA_WET
)
244 painter
.setBrush(colorBlue
);
245 painter
.setPen(QPen(colorBlue
, 0));
246 painter
.drawEllipse(QRectF(ballPoint
.x(), ballPoint
.y(), 2.2f
, 2.2f
));
248 QConicalGradient
gradient(15.5f
, 15.5f
, -45);
249 gradient
.setColorAt(0.0f
, colorBlue
);
250 gradient
.setColorAt(0.125f
, colorBlue
);
251 gradient
.setColorAt(0.625f
, colorGreen
);
252 gradient
.setColorAt(0.75f
, colorGreen
);
253 gradient
.setColorAt(0.76f
, colorGreen
);
254 gradient
.setColorAt(1.0f
, colorGreen
);
255 painter
.setBrush(gradient
);
256 painter
.setPen(QPen(gradient
, 3));
260 painter
.setBrush(colorBlue
);
261 painter
.setPen(QPen(colorBlue
, 0));
262 painter
.drawEllipse(QRectF(ballPoint
.x(), ballPoint
.y(), 2.2f
, 2.2f
));
264 painter
.setBrush(colorBlue
);
265 painter
.setPen(QPen(colorBlue
, 3));
268 painter
.drawArc(4.0f
, 4.0f
, 26.0f
, 26.0f
, startAngle
, spanAngle
);
270 // Custom knobs (L and R)
271 else if (fCustomPaint
== CUSTOM_PAINT_CARLA_L
|| fCustomPaint
== CUSTOM_PAINT_CARLA_R
)
274 QColor
color(0xAD + fHoverStep
*5, 0xD5 + fHoverStep
*4, 0x4B + fHoverStep
*5);
277 QRectF
ballRect(7.0f
, 8.0f
, 11.0f
, 12.0f
);
278 QPainterPath ballPath
;
279 ballPath
.addEllipse(ballRect
);
280 //painter.drawRect(ballRect);
281 float tmpValue
= (0.375f
+ 0.75f
*value
);
282 float ballValue
= tmpValue
- std::floor(tmpValue
);
283 QPointF
ballPoint(ballPath
.pointAtPercent(ballValue
));
285 painter
.setBrush(color
);
286 painter
.setPen(QPen(color
, 0));
287 painter
.drawEllipse(QRectF(ballPoint
.x(), ballPoint
.y(), 2.0f
, 2.0f
));
289 int startAngle
, spanAngle
;
292 if (fCustomPaint
== CUSTOM_PAINT_CARLA_L
)
295 spanAngle
= -252.0*16*value
;
297 else if (fCustomPaint
== CUSTOM_PAINT_CARLA_R
)
299 startAngle
= 324.0*16;
300 spanAngle
= 252.0*16*(1.0-value
);
305 painter
.setPen(QPen(color
, 2));
306 painter
.drawArc(3.5f
, 4.5f
, 22.0f
, 22.0f
, startAngle
, spanAngle
);
308 if (HOVER_MIN
< fHoverStep
&& fHoverStep
< HOVER_MAX
)
310 fHoverStep
+= fHovered
? 1 : -1;
311 QTimer::singleShot(20, this, SLOT(update()));
315 if (HOVER_MIN
< fHoverStep
&& fHoverStep
< HOVER_MAX
)
317 fHoverStep
+= fHovered
? 1 : -1;
318 QTimer::singleShot(20, this, SLOT(update()));
323 QRectF
target(0.0f
, 0.0f
, fSize
, fSize
);
324 painter
.drawPixmap(target
, fPixmap
, target
);
330 void PixmapDial::resizeEvent(QResizeEvent
* event
)
333 QDial::resizeEvent(event
);