Audio plugin host https://kx.studio/carla
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.

328 lines
9.0KB

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