Collection of tools useful for audio production
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

326 lines
9.0KB

  1. /*
  2. * Pixmap Dial, a custom Qt4 widget
  3. * Copyright (C) 2011-2012 Filipe Coelho <falktx@gmail.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * any later version.
  9. *
  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.
  14. *
  15. * For a full copy of the GNU General Public License see the COPYING file
  16. */
  17. #include "pixmapdial.h"
  18. #include <QtCore/QTimer>
  19. #include <QtGui/QPainter>
  20. PixmapDial::PixmapDial(QWidget* parent)
  21. : QDial(parent)
  22. {
  23. m_pixmap.load(":/bitmaps/dial_01d.png");
  24. m_pixmap_n_str = "01";
  25. m_custom_paint = CUSTOM_PAINT_NULL;
  26. m_hovered = false;
  27. m_hover_step = HOVER_MIN;
  28. if (m_pixmap.width() > m_pixmap.height())
  29. m_orientation = HORIZONTAL;
  30. else
  31. m_orientation = VERTICAL;
  32. m_label = "";
  33. m_label_pos = QPointF(0.0f, 0.0f);
  34. m_label_width = 0;
  35. m_label_height = 0;
  36. m_label_gradient = QLinearGradient(0, 0, 0, 1);
  37. if (palette().window().color().lightness() > 100)
  38. {
  39. // Light background
  40. QColor c = palette().dark().color();
  41. m_color1 = c;
  42. m_color2 = QColor(c.red(), c.green(), c.blue(), 0);
  43. m_colorT[0] = palette().buttonText().color();
  44. m_colorT[1] = palette().mid().color();
  45. }
  46. else
  47. {
  48. // Dark background
  49. m_color1 = QColor(0, 0, 0, 255);
  50. m_color2 = QColor(0, 0, 0, 0);
  51. m_colorT[0] = Qt::white;
  52. m_colorT[1] = Qt::darkGray;
  53. }
  54. updateSizes();
  55. }
  56. int PixmapDial::getSize() const
  57. {
  58. return p_size;
  59. }
  60. void PixmapDial::setCustomPaint(CustomPaint paint)
  61. {
  62. m_custom_paint = paint;
  63. update();
  64. }
  65. void PixmapDial::setEnabled(bool enabled)
  66. {
  67. if (isEnabled() != enabled)
  68. {
  69. m_pixmap.load(QString(":/dial_%1%2.png").arg(m_pixmap_n_str).arg(enabled ? "" : "d"));
  70. updateSizes();
  71. update();
  72. }
  73. QDial::setEnabled(enabled);
  74. }
  75. void PixmapDial::setLabel(QString label)
  76. {
  77. m_label = label;
  78. m_label_width = QFontMetrics(font()).width(label);
  79. m_label_height = QFontMetrics(font()).height();
  80. m_label_pos.setX(float(p_size)/2 - float(m_label_width)/2);
  81. m_label_pos.setY(p_size + m_label_height);
  82. m_label_gradient.setColorAt(0.0f, m_color1);
  83. m_label_gradient.setColorAt(0.6f, m_color1);
  84. m_label_gradient.setColorAt(1.0f, m_color2);
  85. m_label_gradient.setStart(0, float(p_size)/2);
  86. m_label_gradient.setFinalStop(0, p_size+m_label_height+5);
  87. m_label_gradient_rect = QRectF(float(p_size)/8, float(p_size)/2, float(p_size*6)/8, p_size+m_label_height+5);
  88. update();
  89. }
  90. void PixmapDial::setPixmap(int pixmapId)
  91. {
  92. m_pixmap_n_str.sprintf("%02i", pixmapId);
  93. m_pixmap.load(QString(":/bitmaps/dial_%1%2.png").arg(m_pixmap_n_str).arg(isEnabled() ? "" : "d"));
  94. if (m_pixmap.width() > m_pixmap.height())
  95. m_orientation = HORIZONTAL;
  96. else
  97. m_orientation = VERTICAL;
  98. updateSizes();
  99. update();
  100. }
  101. QSize PixmapDial::minimumSizeHint() const
  102. {
  103. return QSize(p_size, p_size);
  104. }
  105. QSize PixmapDial::sizeHint() const
  106. {
  107. return QSize(p_size, p_size);
  108. }
  109. void PixmapDial::updateSizes()
  110. {
  111. p_width = m_pixmap.width();
  112. p_height = m_pixmap.height();
  113. if (p_width < 1)
  114. p_width = 1;
  115. if (p_height < 1)
  116. p_height = 1;
  117. if (m_orientation == HORIZONTAL)
  118. {
  119. p_size = p_height;
  120. p_count = p_width/p_height;
  121. }
  122. else
  123. {
  124. p_size = p_width;
  125. p_count = p_height/p_width;
  126. }
  127. setMinimumSize(p_size, p_size + m_label_height + 5);
  128. setMaximumSize(p_size, p_size + m_label_height + 5);
  129. }
  130. void PixmapDial::enterEvent(QEvent* event)
  131. {
  132. m_hovered = true;
  133. if (m_hover_step == HOVER_MIN)
  134. m_hover_step += 1;
  135. QDial::enterEvent(event);
  136. }
  137. void PixmapDial::leaveEvent(QEvent* event)
  138. {
  139. m_hovered = false;
  140. if (m_hover_step == HOVER_MAX)
  141. m_hover_step -= 1;
  142. QDial::leaveEvent(event);
  143. }
  144. void PixmapDial::paintEvent(QPaintEvent*)
  145. {
  146. QPainter painter(this);
  147. if (! m_label.isEmpty())
  148. {
  149. painter.setPen(m_color2);
  150. painter.setBrush(m_label_gradient);
  151. painter.drawRect(m_label_gradient_rect);
  152. painter.setPen(m_colorT[isEnabled() ? 0 : 1]);
  153. painter.drawText(m_label_pos, m_label);
  154. }
  155. if (isEnabled())
  156. {
  157. float current = value()-minimum();
  158. float divider = maximum()-minimum();
  159. if (divider == 0.0f)
  160. return;
  161. float value = current/divider;
  162. QRectF source, target(0.0f, 0.0f, p_size, p_size);
  163. int xpos, ypos, per = (p_count-1)*value;
  164. if (m_orientation == HORIZONTAL)
  165. {
  166. xpos = p_size*per;
  167. ypos = 0.0f;
  168. }
  169. else
  170. {
  171. xpos = 0.0f;
  172. ypos = p_size*per;
  173. }
  174. source = QRectF(xpos, ypos, p_size, p_size);
  175. painter.drawPixmap(target, m_pixmap, source);
  176. // Custom knobs (Dry/Wet and Volume)
  177. if (m_custom_paint == CUSTOM_PAINT_CARLA_WET || m_custom_paint == CUSTOM_PAINT_CARLA_VOL)
  178. {
  179. // knob color
  180. QColor colorGreen(0x5D, 0xE7, 0x3D, 191 + m_hover_step*7);
  181. QColor colorBlue(0x3E, 0xB8, 0xBE, 191 + m_hover_step*7);
  182. // draw small circle
  183. QRectF ballRect(8.0, 8.0, 15.0, 15.0);
  184. QPainterPath ballPath;
  185. ballPath.addEllipse(ballRect);
  186. //painter.drawRect(ballRect);
  187. float tmpValue = (0.375f + 0.75f*value);
  188. float ballValue = tmpValue - floorf(tmpValue);
  189. QPointF ballPoint(ballPath.pointAtPercent(ballValue));
  190. // draw arc
  191. int startAngle = 216*16;
  192. int spanAngle = -252*16*value;
  193. if (m_custom_paint == CUSTOM_PAINT_CARLA_WET)
  194. {
  195. painter.setBrush(colorBlue);
  196. painter.setPen(QPen(colorBlue, 0));
  197. painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2));
  198. QConicalGradient gradient(15.5, 15.5, -45);
  199. gradient.setColorAt(0.0, colorBlue);
  200. gradient.setColorAt(0.125, colorBlue);
  201. gradient.setColorAt(0.625, colorGreen);
  202. gradient.setColorAt(0.75, colorGreen);
  203. gradient.setColorAt(0.76, colorGreen);
  204. gradient.setColorAt(1.0, colorGreen);
  205. painter.setBrush(gradient);
  206. painter.setPen(QPen(gradient, 3));
  207. }
  208. else
  209. {
  210. painter.setBrush(colorBlue);
  211. painter.setPen(QPen(colorBlue, 0));
  212. painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2));
  213. painter.setBrush(colorBlue);
  214. painter.setPen(QPen(colorBlue, 3));
  215. }
  216. painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle);
  217. }
  218. // Custom knobs (L and R)
  219. else if (m_custom_paint == CUSTOM_PAINT_CARLA_L || m_custom_paint == CUSTOM_PAINT_CARLA_R)
  220. {
  221. // knob color
  222. QColor color(0xAD + m_hover_step*5, 0xD5 + m_hover_step*4, 0x4B + m_hover_step*5);
  223. // draw small circle
  224. QRectF ballRect(7.0, 8.0, 11.0, 12.0);
  225. QPainterPath ballPath;
  226. ballPath.addEllipse(ballRect);
  227. //painter.drawRect(ballRect);
  228. float tmpValue = (0.375f + 0.75f*value);
  229. float ballValue = tmpValue - floorf(tmpValue);
  230. QPointF ballPoint(ballPath.pointAtPercent(ballValue));
  231. painter.setBrush(color);
  232. painter.setPen(QPen(color, 0));
  233. painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.0f, 2.0f));
  234. int startAngle, spanAngle;
  235. // draw arc
  236. if (m_custom_paint == CUSTOM_PAINT_CARLA_L)
  237. {
  238. startAngle = 216*16;
  239. spanAngle = -252.0*16*value;
  240. }
  241. else if (m_custom_paint == CUSTOM_PAINT_CARLA_R)
  242. {
  243. startAngle = 324.0*16;
  244. spanAngle = 252.0*16*(1.0-value);
  245. }
  246. else
  247. return;
  248. painter.setPen(QPen(color, 2));
  249. painter.drawArc(3.5, 4.5, 22.0, 22.0, startAngle, spanAngle);
  250. if (HOVER_MIN < m_hover_step && m_hover_step < HOVER_MAX)
  251. {
  252. m_hover_step += m_hovered ? 1 : -1;
  253. QTimer::singleShot(20, this, SLOT(update()));
  254. }
  255. }
  256. if (HOVER_MIN < m_hover_step && m_hover_step < HOVER_MAX)
  257. {
  258. m_hover_step += m_hovered ? 1 : -1;
  259. QTimer::singleShot(20, this, SLOT(update()));
  260. }
  261. }
  262. else
  263. {
  264. QRectF target(0.0, 0.0, p_size, p_size);
  265. painter.drawPixmap(target, m_pixmap, target);
  266. }
  267. }
  268. void PixmapDial::resizeEvent(QResizeEvent* event)
  269. {
  270. updateSizes();
  271. QDial::resizeEvent(event);
  272. }