2 # SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # ---------------------------------------------------------------------------------------------------------------------
10 from qt_compat
import qt_config
13 from PyQt5
.QtCore
import pyqtSignal
, pyqtSlot
, Qt
, QPointF
, QRectF
14 from PyQt5
.QtGui
import QColor
, QFont
, QLinearGradient
, QPainter
15 from PyQt5
.QtWidgets
import QDial
17 from PyQt6
.QtCore
import pyqtSignal
, pyqtSlot
, Qt
, QPointF
, QRectF
18 from PyQt6
.QtGui
import QColor
, QFont
, QLinearGradient
, QPainter
19 from PyQt6
.QtWidgets
import QDial
21 # ---------------------------------------------------------------------------------------------------------------------
24 # to be implemented by subclasses
25 #def updateSizes(self):
26 #def paintDial(self, painter):
28 class CommonDial(QDial
):
29 # enum CustomPaintMode
30 CUSTOM_PAINT_MODE_NULL
= 0 # default (NOTE: only this mode has label gradient)
31 CUSTOM_PAINT_MODE_CARLA_WET
= 1 # color blue-green gradient (reserved #3)
32 CUSTOM_PAINT_MODE_CARLA_VOL
= 2 # color blue (reserved #3)
33 CUSTOM_PAINT_MODE_CARLA_L
= 3 # color yellow (reserved #4)
34 CUSTOM_PAINT_MODE_CARLA_R
= 4 # color yellow (reserved #4)
35 CUSTOM_PAINT_MODE_CARLA_PAN
= 5 # color yellow (reserved #3)
36 CUSTOM_PAINT_MODE_COLOR
= 6 # color, selectable (reserved #3)
37 CUSTOM_PAINT_MODE_ZITA
= 7 # custom zita knob (reserved #6)
38 CUSTOM_PAINT_MODE_NO_GRADIENT
= 8 # skip label gradient
51 dragStateChanged
= pyqtSignal(bool)
52 realValueChanged
= pyqtSignal(float)
54 def __init__(self
, parent
, index
):
55 QDial
.__init
__(self
, parent
)
57 self
.fDialMode
= self
.MODE_LINEAR
62 self
.fPrecision
= 10000
63 self
.fIsInteger
= False
65 self
.fIsHovered
= False
66 self
.fIsPressed
= False
67 self
.fHoverStep
= self
.HOVER_MIN
69 self
.fLastDragPos
= None
70 self
.fLastDragValue
= 0.0
75 self
.fLabelPos
= QPointF(0.0, 0.0)
76 self
.fLabelFont
= QFont(self
.font())
77 self
.fLabelFont
.setPixelSize(8)
81 if self
.palette().window().color().lightness() > 100:
83 c
= self
.palette().dark().color()
84 self
.fLabelGradientColor1
= c
85 self
.fLabelGradientColor2
= QColor(c
.red(), c
.green(), c
.blue(), 0)
86 self
.fLabelGradientColorT
= [self
.palette().buttonText().color(), self
.palette().mid().color()]
89 self
.fLabelGradientColor1
= QColor(0, 0, 0, 255)
90 self
.fLabelGradientColor2
= QColor(0, 0, 0, 0)
91 self
.fLabelGradientColorT
= [Qt
.white
, Qt
.darkGray
]
93 self
.fLabelGradient
= QLinearGradient(0, 0, 0, 1)
94 self
.fLabelGradient
.setColorAt(0.0, self
.fLabelGradientColor1
)
95 self
.fLabelGradient
.setColorAt(0.6, self
.fLabelGradientColor1
)
96 self
.fLabelGradient
.setColorAt(1.0, self
.fLabelGradientColor2
)
98 self
.fLabelGradientRect
= QRectF(0.0, 0.0, 0.0, 0.0)
100 self
.fCustomPaintMode
= self
.CUSTOM_PAINT_MODE_NULL
101 self
.fCustomPaintColor
= QColor(0xff, 0xff, 0xff)
103 # Fake internal value, custom precision
104 QDial
.setMinimum(self
, 0)
105 QDial
.setMaximum(self
, self
.fPrecision
)
106 QDial
.setValue(self
, 0)
108 self
.valueChanged
.connect(self
.slot_valueChanged
)
110 def forceWhiteLabelGradientText(self
):
111 self
.fLabelGradientColor1
= QColor(0, 0, 0, 255)
112 self
.fLabelGradientColor2
= QColor(0, 0, 0, 0)
113 self
.fLabelGradientColorT
= [Qt
.white
, Qt
.darkGray
]
115 def setLabelColor(self
, enabled
, disabled
):
116 self
.fLabelGradientColor1
= QColor(0, 0, 0, 255)
117 self
.fLabelGradientColor2
= QColor(0, 0, 0, 0)
118 self
.fLabelGradientColorT
= [enabled
, disabled
]
123 def setIndex(self
, index
):
126 def setPrecision(self
, value
, isInteger
):
127 self
.fPrecision
= value
128 self
.fIsInteger
= isInteger
129 QDial
.setMaximum(self
, int(value
))
131 def setMinimum(self
, value
):
132 self
.fMinimum
= value
134 def setMaximum(self
, value
):
135 self
.fMaximum
= value
138 return self
.fRealValue
140 def setValue(self
, value
, emitSignal
=False):
141 if self
.fRealValue
== value
or isnan(value
):
144 if value
<= self
.fMinimum
:
146 self
.fRealValue
= self
.fMinimum
148 elif value
>= self
.fMaximum
:
149 qtValue
= int(self
.fPrecision
)
150 self
.fRealValue
= self
.fMaximum
153 qtValue
= round(float(value
- self
.fMinimum
) / float(self
.fMaximum
- self
.fMinimum
) * self
.fPrecision
)
154 self
.fRealValue
= value
156 # Block change signal, we'll handle it ourselves
157 self
.blockSignals(True)
158 QDial
.setValue(self
, qtValue
)
159 self
.blockSignals(False)
162 self
.realValueChanged
.emit(self
.fRealValue
)
164 def setCustomPaintMode(self
, paintMode
):
165 if self
.fCustomPaintMode
== paintMode
:
168 self
.fCustomPaintMode
= paintMode
171 def setCustomPaintColor(self
, color
):
172 if self
.fCustomPaintColor
== color
:
175 self
.fCustomPaintColor
= color
178 def setLabel(self
, label
):
179 if self
.fLabel
== label
:
187 def slot_valueChanged(self
, value
):
188 self
.fRealValue
= float(value
)/self
.fPrecision
* (self
.fMaximum
- self
.fMinimum
) + self
.fMinimum
189 self
.realValueChanged
.emit(self
.fRealValue
)
191 def enterEvent(self
, event
):
192 self
.fIsHovered
= True
193 if self
.fHoverStep
== self
.HOVER_MIN
:
194 self
.fHoverStep
= self
.HOVER_MIN
+ 1
195 QDial
.enterEvent(self
, event
)
197 def leaveEvent(self
, event
):
198 self
.fIsHovered
= False
199 if self
.fHoverStep
== self
.HOVER_MAX
:
200 self
.fHoverStep
= self
.HOVER_MAX
- 1
201 QDial
.leaveEvent(self
, event
)
203 def mousePressEvent(self
, event
):
204 if self
.fDialMode
== self
.MODE_DEFAULT
:
205 QDial
.mousePressEvent(self
, event
)
208 if event
.button() == Qt
.LeftButton
:
209 self
.fIsPressed
= True
210 self
.fLastDragPos
= event
.pos()
211 self
.fLastDragValue
= self
.fRealValue
212 self
.dragStateChanged
.emit(True)
214 def mouseMoveEvent(self
, event
):
215 if self
.fDialMode
== self
.MODE_DEFAULT
:
216 QDial
.mouseMoveEvent(self
, event
)
219 if not self
.fIsPressed
:
222 diff
= (self
.fMaximum
- self
.fMinimum
) / 4.0
224 dx
= diff
* float(pos
.x() - self
.fLastDragPos
.x()) / self
.width()
225 dy
= diff
* float(pos
.y() - self
.fLastDragPos
.y()) / self
.height()
226 value
= self
.fLastDragValue
+ dx
- dy
228 if value
< self
.fMinimum
:
229 value
= self
.fMinimum
230 elif value
> self
.fMaximum
:
231 value
= self
.fMaximum
232 elif self
.fIsInteger
:
233 value
= float(round(value
))
235 self
.setValue(value
, True)
237 def mouseReleaseEvent(self
, event
):
238 if self
.fDialMode
== self
.MODE_DEFAULT
:
239 QDial
.mouseReleaseEvent(self
, event
)
243 self
.fIsPressed
= False
244 self
.dragStateChanged
.emit(False)
246 def paintEvent(self
, event
):
247 painter
= QPainter(self
)
251 painter
.setRenderHint(QPainter
.Antialiasing
, True)
254 if self
.fCustomPaintMode
== self
.CUSTOM_PAINT_MODE_NULL
:
255 painter
.setPen(self
.fLabelGradientColor2
)
256 painter
.setBrush(self
.fLabelGradient
)
257 painter
.drawRect(self
.fLabelGradientRect
)
259 painter
.setFont(self
.fLabelFont
)
260 painter
.setPen(self
.fLabelGradientColorT
[0 if self
.isEnabled() else 1])
261 painter
.drawText(self
.fLabelPos
, self
.fLabel
)
263 self
.paintDial(painter
)
267 def resizeEvent(self
, event
):
268 QDial
.resizeEvent(self
, event
)
271 # ---------------------------------------------------------------------------------------------------------------------