Cleanup
[carla.git] / source / frontend / widgets / pixmapdial.py
blob42e1b3c8611e5b0a1b8a0b87795a84ac708d5ecf
1 #!/usr/bin/env python3
2 # SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # ---------------------------------------------------------------------------------------------------------------------
6 # Imports (Global)
8 from math import cos, floor, pi, sin
10 from qt_compat import qt_config
12 if qt_config == 5:
13 from PyQt5.QtCore import pyqtSlot, Qt, QEvent, QPointF, QRectF, QTimer, QSize
14 from PyQt5.QtGui import QColor, QConicalGradient, QFontMetrics, QPainterPath, QPen, QPixmap
15 from PyQt5.QtWidgets import QDial
16 elif qt_config == 6:
17 from PyQt6.QtCore import pyqtSlot, Qt, QEvent, QPointF, QRectF, QTimer, QSize
18 from PyQt6.QtGui import QColor, QConicalGradient, QFontMetrics, QPainterPath, QPen, QPixmap
19 from PyQt6.QtWidgets import QDial
21 from .commondial import CommonDial
22 from carla_shared import fontMetricsHorizontalAdvance
24 # ---------------------------------------------------------------------------------------------------------------------
25 # Widget Class
27 class PixmapDial(CommonDial):
28 def __init__(self, parent, index=0):
29 CommonDial.__init__(self, parent, index)
31 self.fPixmap = QPixmap(":/bitmaps/dial_01d.png")
32 self.fPixmapNum = "01"
34 if self.fPixmap.width() > self.fPixmap.height():
35 self.fPixmapOrientation = self.HORIZONTAL
36 else:
37 self.fPixmapOrientation = self.VERTICAL
39 self.updateSizes()
41 def getBaseSize(self):
42 return self.fPixmapBaseSize
44 def updateSizes(self):
45 self.fPixmapWidth = self.fPixmap.width()
46 self.fPixmapHeight = self.fPixmap.height()
48 if self.fPixmapWidth < 1:
49 self.fPixmapWidth = 1
51 if self.fPixmapHeight < 1:
52 self.fPixmapHeight = 1
54 if self.fPixmapOrientation == self.HORIZONTAL:
55 self.fPixmapBaseSize = self.fPixmapHeight
56 self.fPixmapLayersCount = self.fPixmapWidth / self.fPixmapHeight
57 else:
58 self.fPixmapBaseSize = self.fPixmapWidth
59 self.fPixmapLayersCount = self.fPixmapHeight / self.fPixmapWidth
61 self.setMinimumSize(self.fPixmapBaseSize, self.fPixmapBaseSize + self.fLabelHeight + 5)
62 self.setMaximumSize(self.fPixmapBaseSize, self.fPixmapBaseSize + self.fLabelHeight + 5)
64 if not self.fLabel:
65 self.fLabelHeight = 0
66 self.fLabelWidth = 0
67 return
69 metrics = QFontMetrics(self.fLabelFont)
70 self.fLabelWidth = fontMetricsHorizontalAdvance(metrics, self.fLabel)
71 self.fLabelHeight = metrics.height()
73 self.fLabelPos.setX(float(self.fPixmapBaseSize)/2.0 - float(self.fLabelWidth)/2.0)
75 if self.fPixmapNum in ("01", "02", "07", "08", "09", "10"):
76 self.fLabelPos.setY(self.fPixmapBaseSize + self.fLabelHeight)
77 elif self.fPixmapNum in ("11",):
78 self.fLabelPos.setY(self.fPixmapBaseSize + self.fLabelHeight*2/3)
79 else:
80 self.fLabelPos.setY(self.fPixmapBaseSize + self.fLabelHeight/2)
82 self.fLabelGradient.setStart(0, float(self.fPixmapBaseSize)/2.0)
83 self.fLabelGradient.setFinalStop(0, self.fPixmapBaseSize + self.fLabelHeight + 5)
85 self.fLabelGradientRect = QRectF(float(self.fPixmapBaseSize)/8.0, float(self.fPixmapBaseSize)/2.0, float(self.fPixmapBaseSize*3)/4.0, self.fPixmapBaseSize+self.fLabelHeight+5)
87 def setPixmap(self, pixmapId):
88 self.fPixmapNum = "%02i" % pixmapId
89 self.fPixmap.load(":/bitmaps/dial_%s%s.png" % (self.fPixmapNum, "" if self.isEnabled() else "d"))
91 if self.fPixmap.width() > self.fPixmap.height():
92 self.fPixmapOrientation = self.HORIZONTAL
93 else:
94 self.fPixmapOrientation = self.VERTICAL
96 # special pixmaps
97 if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL:
98 # reserved for carla-wet, carla-vol, carla-pan and color
99 if self.fPixmapNum == "03":
100 self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_COLOR
102 # reserved for carla-L and carla-R
103 elif self.fPixmapNum == "04":
104 self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_CARLA_L
106 # reserved for zita
107 elif self.fPixmapNum == "06":
108 self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_ZITA
110 self.updateSizes()
111 self.update()
113 @pyqtSlot()
114 def slot_updatePixmap(self):
115 self.setPixmap(int(self.fPixmapNum))
117 def minimumSizeHint(self):
118 return QSize(self.fPixmapBaseSize, self.fPixmapBaseSize)
120 def sizeHint(self):
121 return QSize(self.fPixmapBaseSize, self.fPixmapBaseSize)
123 def changeEvent(self, event):
124 CommonDial.changeEvent(self, event)
126 # Force pixmap update if enabled state changes
127 if event.type() == QEvent.EnabledChange:
128 self.setPixmap(int(self.fPixmapNum))
130 def paintDial(self, painter):
131 if self.isEnabled():
132 normValue = float(self.fRealValue - self.fMinimum) / float(self.fMaximum - self.fMinimum)
133 target = QRectF(0.0, 0.0, self.fPixmapBaseSize, self.fPixmapBaseSize)
135 curLayer = int((self.fPixmapLayersCount - 1) * normValue)
137 if self.fPixmapOrientation == self.HORIZONTAL:
138 xpos = self.fPixmapBaseSize * curLayer
139 ypos = 0.0
140 else:
141 xpos = 0.0
142 ypos = self.fPixmapBaseSize * curLayer
144 source = QRectF(xpos, ypos, self.fPixmapBaseSize, self.fPixmapBaseSize)
145 painter.drawPixmap(target, self.fPixmap, source)
147 # Custom knobs (Dry/Wet and Volume)
148 if self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_WET, self.CUSTOM_PAINT_MODE_CARLA_VOL):
149 # knob color
150 colorGreen = QColor(0x5D, 0xE7, 0x3D).lighter(100 + self.fHoverStep*6)
151 colorBlue = QColor(0x3E, 0xB8, 0xBE).lighter(100 + self.fHoverStep*6)
153 # draw small circle
154 ballRect = QRectF(8.0, 8.0, 15.0, 15.0)
155 ballPath = QPainterPath()
156 ballPath.addEllipse(ballRect)
157 #painter.drawRect(ballRect)
158 tmpValue = (0.375 + 0.75*normValue)
159 ballValue = tmpValue - floor(tmpValue)
160 ballPoint = ballPath.pointAtPercent(ballValue)
162 # draw arc
163 startAngle = 216*16
164 spanAngle = -252*16*normValue
166 if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_WET:
167 painter.setBrush(colorBlue)
168 painter.setPen(QPen(colorBlue, 0))
169 painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2))
171 gradient = QConicalGradient(15.5, 15.5, -45)
172 gradient.setColorAt(0.0, colorBlue)
173 gradient.setColorAt(0.125, colorBlue)
174 gradient.setColorAt(0.625, colorGreen)
175 gradient.setColorAt(0.75, colorGreen)
176 gradient.setColorAt(0.76, colorGreen)
177 gradient.setColorAt(1.0, colorGreen)
178 painter.setBrush(gradient)
179 painter.setPen(QPen(gradient, 3))
181 else:
182 painter.setBrush(colorBlue)
183 painter.setPen(QPen(colorBlue, 0))
184 painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2))
186 painter.setBrush(colorBlue)
187 painter.setPen(QPen(colorBlue, 3))
189 painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle)
191 # Custom knobs (L and R)
192 elif self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_L, self.CUSTOM_PAINT_MODE_CARLA_R):
193 # knob color
194 color = QColor(0xAD, 0xD5, 0x48).lighter(100 + self.fHoverStep*6)
196 # draw small circle
197 ballRect = QRectF(7.0, 8.0, 11.0, 12.0)
198 ballPath = QPainterPath()
199 ballPath.addEllipse(ballRect)
200 #painter.drawRect(ballRect)
201 tmpValue = (0.375 + 0.75*normValue)
202 ballValue = tmpValue - floor(tmpValue)
203 ballPoint = ballPath.pointAtPercent(ballValue)
205 painter.setBrush(color)
206 painter.setPen(QPen(color, 0))
207 painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.0, 2.0))
209 # draw arc
210 if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_L:
211 startAngle = 216*16
212 spanAngle = -252.0*16*normValue
213 else:
214 startAngle = 324.0*16
215 spanAngle = 252.0*16*(1.0-normValue)
217 painter.setPen(QPen(color, 2))
218 painter.drawArc(3.5, 4.5, 22.0, 22.0, startAngle, spanAngle)
220 # Custom knobs (Color)
221 elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_COLOR:
222 # knob color
223 color = self.fCustomPaintColor.lighter(100 + self.fHoverStep*6)
225 # draw small circle
226 ballRect = QRectF(8.0, 8.0, 15.0, 15.0)
227 ballPath = QPainterPath()
228 ballPath.addEllipse(ballRect)
229 tmpValue = (0.375 + 0.75*normValue)
230 ballValue = tmpValue - floor(tmpValue)
231 ballPoint = ballPath.pointAtPercent(ballValue)
233 # draw arc
234 startAngle = 216*16
235 spanAngle = -252*16*normValue
237 painter.setBrush(color)
238 painter.setPen(QPen(color, 0))
239 painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2))
241 painter.setBrush(color)
242 painter.setPen(QPen(color, 3))
243 painter.drawArc(4.0, 4.0, 26.0, 26.0, startAngle, spanAngle)
245 # Custom knobs (Zita)
246 elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_ZITA:
247 a = normValue * pi * 1.5 - 2.35
248 r = 10.0
249 x = 10.5
250 y = 10.5
251 x += r * sin(a)
252 y -= r * cos(a)
253 painter.setBrush(Qt.black)
254 painter.setPen(QPen(Qt.black, 2))
255 painter.drawLine(QPointF(11.0, 11.0), QPointF(x, y))
257 # Custom knobs
258 else:
259 painter.restore()
260 return
262 if self.HOVER_MIN < self.fHoverStep < self.HOVER_MAX:
263 self.fHoverStep += 1 if self.fIsHovered else -1
264 QTimer.singleShot(20, self.update)
266 else: # isEnabled()
267 target = QRectF(0.0, 0.0, self.fPixmapBaseSize, self.fPixmapBaseSize)
268 painter.drawPixmap(target, self.fPixmap, target)
270 # ---------------------------------------------------------------------------------------------------------------------