Cleanup
[carla.git] / source / frontend / widgets / pixmapdial.cpp
blob472650d7a8b92cfe086dc8bfcf135b30de8f8d54
1 /*
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"
20 #include <cmath>
22 #include <QtCore/QTimer>
23 #include <QtGui/QPainter>
24 #include <QtGui/QPaintEvent>
26 PixmapDial::PixmapDial(QWidget* parent)
27 : QDial(parent),
28 fPixmap(":/bitmaps/dial_01d.png"),
29 fPixmapNum("01"),
30 fCustomPaint(CUSTOM_PAINT_NULL),
31 fOrientation(fPixmap.width() > fPixmap.height() ? HORIZONTAL : VERTICAL),
32 fHovered(false),
33 fHoverStep(HOVER_MIN),
34 fLabel(""),
35 fLabelPos(0.0f, 0.0f),
36 fLabelWidth(0),
37 fLabelHeight(0),
38 fLabelGradient(0, 0, 0, 1)
40 fLabelFont.setPointSize(6);
42 if (palette().window().color().lightness() > 100)
44 // Light background
45 const QColor c(palette().dark().color());
46 fColor1 = c;
47 fColor2 = QColor(c.red(), c.green(), c.blue(), 0);
48 fColorT[0] = palette().buttonText().color();
49 fColorT[1] = palette().mid().color();
51 else
53 // Dark background
54 fColor1 = QColor(0, 0, 0, 255);
55 fColor2 = QColor(0, 0, 0, 0);
56 fColorT[0] = Qt::white;
57 fColorT[1] = Qt::darkGray;
60 updateSizes();
63 int PixmapDial::getSize() const
65 return fSize;
68 void PixmapDial::setCustomPaint(CustomPaint paint)
70 fCustomPaint = paint;
71 fLabelPos.setY(fSize + fLabelHeight/2);
72 update();
75 void PixmapDial::setEnabled(bool enabled)
77 if (isEnabled() != enabled)
79 fPixmap.load(QString(":/bitmaps/dial_%1%2.png").arg(fPixmapNum).arg(enabled ? "" : "d"));
80 updateSizes();
81 update();
83 QDial::setEnabled(enabled);
86 void PixmapDial::setLabel(QString label)
88 fLabel = 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);
104 update();
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;
114 else
115 fOrientation = VERTICAL;
117 updateSizes();
118 update();
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();
136 if (fWidth < 1)
137 fWidth = 1;
139 if (fHeight < 1)
140 fHeight = 1;
142 if (fOrientation == HORIZONTAL)
144 fSize = fHeight;
145 fCount = fWidth/fHeight;
147 else
149 fSize = fWidth;
150 fCount = fHeight/fWidth;
153 setMinimumSize(fSize, fSize + fLabelHeight + 5);
154 setMaximumSize(fSize, fSize + fLabelHeight + 5);
157 void PixmapDial::enterEvent(QEvent* event)
159 fHovered = true;
160 if (fHoverStep == HOVER_MIN)
161 fHoverStep = HOVER_MIN + 1;
162 QDial::enterEvent(event);
165 void PixmapDial::leaveEvent(QEvent* event)
167 fHovered = false;
168 if (fHoverStep == HOVER_MAX)
169 fHoverStep = HOVER_MAX - 1;
170 QDial::leaveEvent(event);
173 void PixmapDial::paintEvent(QPaintEvent* event)
175 event->accept();
177 QPainter painter(this);
178 painter.save();
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);
195 if (isEnabled())
197 float current = value()-minimum();
198 float divider = maximum()-minimum();
200 if (divider == 0.0f)
201 return;
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)
210 xpos = fSize*per;
211 ypos = 0.0f;
213 else
215 xpos = 0.0f;
216 ypos = fSize*per;
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)
225 // knob color
226 QColor colorGreen(0x5D, 0xE7, 0x3D, 191 + fHoverStep*7);
227 QColor colorBlue(0x3E, 0xB8, 0xBE, 191 + fHoverStep*7);
229 // draw small circle
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));
238 // draw arc
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));
258 else
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)
273 // knob color
274 QColor color(0xAD + fHoverStep*5, 0xD5 + fHoverStep*4, 0x4B + fHoverStep*5);
276 // draw small circle
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;
291 // draw arc
292 if (fCustomPaint == CUSTOM_PAINT_CARLA_L)
294 startAngle = 216*16;
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);
302 else
303 return;
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()));
321 else
323 QRectF target(0.0f, 0.0f, fSize, fSize);
324 painter.drawPixmap(target, fPixmap, target);
327 painter.restore();
330 void PixmapDial::resizeEvent(QResizeEvent* event)
332 updateSizes();
333 QDial::resizeEvent(event);