diff --git a/resources/resources.qrc b/resources/resources.qrc
index 51dc4a126..796bb706f 100644
--- a/resources/resources.qrc
+++ b/resources/resources.qrc
@@ -44,7 +44,7 @@
scalable/carla.svg
scalable/carla-control.svg
-
+
scalable/folder.svgz
scalable/osc.svgz
scalable/warning.svgz
@@ -75,31 +75,32 @@
bitmaps/button_distrho_down-white.png
bitmaps/button_distrho_hover-black.png
bitmaps/button_distrho_hover-white.png
- bitmaps/button_edit-black.png
- bitmaps/button_edit-white.png
- bitmaps/button_edit_down-black.png
- bitmaps/button_edit_down-white.png
- bitmaps/button_edit_hover-black.png
- bitmaps/button_edit_hover-white.png
+ scalable/button_edit-black.svg
+ scalable/button_edit-white.svg
+ scalable/button_edit_down-black.svg
+ scalable/button_edit_down-white.svg
+ scalable/button_edit_hover-black.svg
+ scalable/button_edit_hover-white.svg
bitmaps/button_file-black.png
bitmaps/button_file-white.png
bitmaps/button_file_down-black.png
bitmaps/button_file_down-white.png
bitmaps/button_file_hover-black.png
bitmaps/button_file_hover-white.png
- bitmaps/button_gui-black.png
- bitmaps/button_gui-white.png
- bitmaps/button_gui_down-black.png
- bitmaps/button_gui_down-white.png
- bitmaps/button_gui_hover-black.png
- bitmaps/button_gui_hover-white.png
- bitmaps/button_off.png
- bitmaps/button_on.png
-
- bitmaps/dial_03.png
- bitmaps/dial_03d.png
- bitmaps/dial_04.png
- bitmaps/dial_04d.png
+ scalable/button_gui-black.svg
+ scalable/button_gui-white.svg
+ scalable/button_gui_down-black.svg
+ scalable/button_gui_down-white.svg
+ scalable/button_gui_hover-black.svg
+ scalable/button_gui_hover-white.svg
+
+ scalable/button_off.svg
+ scalable/button_on.svg
+
+ scalable/dial_03.svg
+ scalable/dial_03d.svg
+ scalable/dial_04.svg
+ scalable/dial_04d.svg
bitmaps/dial_06.png
bitmaps/dial_06d.png
bitmaps/dial_07.png
@@ -125,11 +126,11 @@
bitmaps/kbd_down-orange.png
bitmaps/kbd_down-red.png
- bitmaps/led_off.png
- bitmaps/led_blue.png
- bitmaps/led_green.png
- bitmaps/led_red.png
- bitmaps/led_yellow.png
+ scalable/led_off.svg
+ scalable/led_red.svg
+ scalable/led_green.svg
+ scalable/led_blue.svg
+ scalable/led_yellow.svg
bitmaps/led_calf_off.png
bitmaps/led_calf_on.png
@@ -160,6 +161,8 @@
scalable/pb_mplayer.svg
scalable/pb_vlc.svg
+
+
cursors/zoom-generic-white.png
cursors/zoom-generic-black.png
cursors/zoom-in-white.png
diff --git a/resources/ui/carla_edit.ui b/resources/ui/carla_edit.ui
index 95a6068c3..d04137055 100644
--- a/resources/ui/carla_edit.ui
+++ b/resources/ui/carla_edit.ui
@@ -108,7 +108,7 @@
-
-
+
34
@@ -130,7 +130,7 @@
-
-
+
34
@@ -183,7 +183,7 @@
0
-
-
+
26
@@ -205,7 +205,7 @@
-
-
+
26
@@ -246,7 +246,7 @@
0
-
-
+
26
@@ -871,9 +871,9 @@ Plugin Name
- PixmapDial
+ ScalableDial
QDial
-
+
diff --git a/resources/ui/carla_plugin_calf.ui b/resources/ui/carla_plugin_calf.ui
index 625e08c47..1eae2e720 100644
--- a/resources/ui/carla_plugin_calf.ui
+++ b/resources/ui/carla_plugin_calf.ui
@@ -59,7 +59,7 @@
0
-
-
+
Enable
@@ -301,7 +301,7 @@
3
-
-
+
GUI
@@ -311,7 +311,7 @@
-
-
+
Edit
@@ -321,7 +321,7 @@
-
-
+
Remove
@@ -411,9 +411,9 @@
- PixmapButton
+ ScalableButton
QPushButton
-
+
diff --git a/resources/ui/carla_plugin_classic.ui b/resources/ui/carla_plugin_classic.ui
index eb1a38d0c..9ca8af532 100644
--- a/resources/ui/carla_plugin_classic.ui
+++ b/resources/ui/carla_plugin_classic.ui
@@ -54,7 +54,7 @@
4
-
-
+
24
@@ -89,7 +89,7 @@
-
-
+
24
@@ -124,7 +124,7 @@
-
-
+
24
@@ -344,9 +344,9 @@
- PixmapButton
+ ScalableButton
QPushButton
-
+
diff --git a/resources/ui/carla_plugin_compact.ui b/resources/ui/carla_plugin_compact.ui
index 6d3d48913..30e646437 100644
--- a/resources/ui/carla_plugin_compact.ui
+++ b/resources/ui/carla_plugin_compact.ui
@@ -57,7 +57,7 @@
0
-
-
+
24
@@ -92,7 +92,7 @@
-
-
+
24
@@ -127,7 +127,7 @@
-
-
+
24
@@ -405,9 +405,9 @@
- PixmapButton
+ ScalableButton
QPushButton
-
+
diff --git a/resources/ui/carla_plugin_default.ui b/resources/ui/carla_plugin_default.ui
index 641fa7b18..b1d8d9668 100644
--- a/resources/ui/carla_plugin_default.ui
+++ b/resources/ui/carla_plugin_default.ui
@@ -58,11 +58,20 @@
0
-
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
0
-
-
+
24
@@ -79,8 +88,8 @@
-
- :/bitmaps/button_off.png:/bitmaps/button_off.png
+
+ ../scalable/button_off.svg../scalable/button_off.svg
@@ -97,7 +106,7 @@
-
-
+
24
@@ -114,8 +123,8 @@
-
- :/bitmaps/button_gui.png:/bitmaps/button_gui.png
+
+ :/bitmaps/button_gui-black.png:/bitmaps/button_gui-black.png
@@ -132,7 +141,7 @@
-
-
+
24
@@ -307,6 +316,12 @@
-
+
+
+ 0
+ 0
+
+
14
@@ -322,6 +337,10 @@
+
+
+ :/scalable/led_off.svg:/scalable/led_off.svg
+
true
@@ -344,6 +363,10 @@
+
+
+ :/scalable/led_off.svg:/scalable/led_off.svg
+
true
@@ -366,6 +389,10 @@
+
+
+ :/scalable/led_off.svg:/scalable/led_off.svg
+
true
@@ -373,6 +400,9 @@
-
+
+ true
+
14
@@ -388,6 +418,10 @@
+
+
+ :/scalable/led_off.svg:/scalable/led_off.svg
+
true
@@ -433,7 +467,16 @@
-
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
0
@@ -490,9 +533,9 @@
- PixmapButton
+ ScalableButton
QPushButton
-
+
diff --git a/resources/ui/carla_plugin_presets.ui b/resources/ui/carla_plugin_presets.ui
index db3017f85..c6699a6c6 100644
--- a/resources/ui/carla_plugin_presets.ui
+++ b/resources/ui/carla_plugin_presets.ui
@@ -59,7 +59,7 @@
0
-
-
+
24
@@ -94,7 +94,7 @@
-
-
+
24
@@ -129,7 +129,7 @@
-
-
+
24
@@ -517,9 +517,9 @@
- PixmapButton
+ ScalableButton
QPushButton
-
+
diff --git a/source/frontend/carla_skin.py b/source/frontend/carla_skin.py
index 3df24b775..2e5c6b923 100644
--- a/source/frontend/carla_skin.py
+++ b/source/frontend/carla_skin.py
@@ -20,7 +20,7 @@
# Imports (Global)
from PyQt5.QtCore import Qt, QRectF, QLineF
-from PyQt5.QtGui import QFont, QFontDatabase, QPen, QPixmap
+from PyQt5.QtGui import QFont, QFontDatabase, QPen
from PyQt5.QtWidgets import QColorDialog, QFrame, QPushButton
# ------------------------------------------------------------------------------------------------------------
@@ -34,7 +34,7 @@ import ui_carla_plugin_presets
from carla_widgets import *
from widgets.digitalpeakmeter import DigitalPeakMeter
-from widgets.pixmapdial import PixmapDial
+from widgets.scalabledial import ScalableDial
# ------------------------------------------------------------------------------------------------------------
# Plugin Skin Rules (WORK IN PROGRESS)
@@ -43,7 +43,7 @@ from widgets.pixmapdial import PixmapDial
# Spacing of the top-most layout must be 1px.
# Top and bottom margins must be 3px (can be split between different Qt layouts).
# Left and right margins must be 6px (can be split between different Qt layouts).
-# If the left or right side has built-in margins, say a transparent png border,
+# If the left or right side has built-in margins, say a transparent svg border,
# those margins must be taken into consideration.
#
# There's a top and bottom layout, separated by a horizontal line.
@@ -158,33 +158,33 @@ def getColorFromCategory(category):
# ------------------------------------------------------------------------------------------------------------
#
-def setPixmapDialStyle(widget, parameterId, parameterCount, whiteLabels, skinStyle):
+def setScalableDialStyle(widget, parameterId, parameterCount, whiteLabels, skinStyle):
if skinStyle.startswith("calf"):
- widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_NO_GRADIENT)
- widget.setPixmap(7)
+ widget.setCustomPaintMode(ScalableDial.CUSTOM_PAINT_MODE_NO_GRADIENT)
+ widget.setSvg(7)
elif skinStyle.startswith("openav"):
- widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_NO_GRADIENT)
+ widget.setCustomPaintMode(ScalableDial.CUSTOM_PAINT_MODE_NO_GRADIENT)
if parameterId == PARAMETER_DRYWET:
- widget.setPixmap(13)
+ widget.setSvg(13)
elif parameterId == PARAMETER_VOLUME:
- widget.setPixmap(12)
+ widget.setSvg(12)
else:
- widget.setPixmap(11)
+ widget.setSvg(11)
else:
if parameterId == PARAMETER_DRYWET:
- widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_CARLA_WET)
+ widget.setCustomPaintMode(ScalableDial.CUSTOM_PAINT_MODE_CARLA_WET)
elif parameterId == PARAMETER_VOLUME:
- widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_CARLA_VOL)
+ widget.setCustomPaintMode(ScalableDial.CUSTOM_PAINT_MODE_CARLA_VOL)
else:
_r = 255 - int((float(parameterId)/float(parameterCount))*200.0)
_g = 55 + int((float(parameterId)/float(parameterCount))*200.0)
_b = 0 #(r-40)*4
widget.setCustomPaintColor(QColor(_r, _g, _b))
- widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_COLOR)
+ widget.setCustomPaintMode(ScalableDial.CUSTOM_PAINT_MODE_COLOR)
if whiteLabels:
colorEnabled = QColor("#BBB")
@@ -194,7 +194,7 @@ def setPixmapDialStyle(widget, parameterId, parameterCount, whiteLabels, skinSty
colorDisabled = QColor("#AAA")
widget.setLabelColor(colorEnabled, colorDisabled)
- widget.setPixmap(3)
+ widget.setSvg(3)
# ------------------------------------------------------------------------------------------------------------
# Abstract plugin slot
@@ -357,7 +357,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
if self.fPluginId == pluginId:
self.customUiStateChanged(state)
- #------------------------------------------------------------------
+ # ------------------------------------------------------------------
def ready(self):
self.fIsActive = bool(self.host.get_internal_parameter_value(self.fPluginId, PARAMETER_ACTIVE) >= 0.5)
@@ -368,6 +368,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
if self.fSkinStyle.startswith("calf") or self.fSkinStyle.startswith("openav") or self.fSkinStyle in (
"3bandeq", "3bandsplitter", "pingpongpan", "nekobi", "calf_black", "zynfx"):
+
imageSuffix = "white"
whiteLabels = True
@@ -376,46 +377,46 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
self.b_enable.clicked.connect(self.slot_enableClicked)
if isCalfSkin:
- self.b_enable.setPixmaps(":/bitmaps/button_calf3.png",
- ":/bitmaps/button_calf3_down.png",
- ":/bitmaps/button_calf3.png")
+ self.b_enable.setSvgs(":/scalable/button_calf3.svg",
+ ":/scalable/button_calf3_down.svg",
+ ":/scalable/button_calf3.svg")
else:
- self.b_enable.setPixmaps(":/bitmaps/button_off.png",
- ":/bitmaps/button_on.png",
- ":/bitmaps/button_off.png")
+ self.b_enable.setSvgs(":/scalable/button_off.svg",
+ ":/scalable/button_on.svg",
+ ":/scalable/button_off.svg")
if self.b_gui is not None:
self.b_gui.clicked.connect(self.slot_showCustomUi)
self.b_gui.setEnabled(bool(self.fPluginInfo['hints'] & PLUGIN_HAS_CUSTOM_UI))
if isCalfSkin:
- self.b_gui.setPixmaps(":/bitmaps/button_calf2.png",
- ":/bitmaps/button_calf2_down.png",
- ":/bitmaps/button_calf2_hover.png")
- elif self.fPluginInfo['iconName'] == "distrho" or self.fSkinStyle in ("3bandeq","3bandsplitter","pingpongpan", "nekobi"):
- self.b_gui.setPixmaps(":/bitmaps/button_distrho-{}.png".format(imageSuffix),
- ":/bitmaps/button_distrho_down-{}.png".format(imageSuffix),
- ":/bitmaps/button_distrho_hover-{}.png".format(imageSuffix))
+ self.b_gui.setSvgs(":/scalable/button_calf2.svg",
+ ":/scalable/button_calf2_down.svg",
+ ":/scalable/button_calf2_hover.svg")
+ elif self.fPluginInfo['iconName'] == "distrho" or self.fSkinStyle in ("3bandeq", "3bandsplitter", "pingpongpan", "nekobi"):
+ self.b_gui.setSvgs(":/scalable/button_distrho-{}.svg".format(imageSuffix),
+ ":/scalable/button_distrho_down-{}.svg".format(imageSuffix),
+ ":/scalable/button_distrho_hover-{}.svg".format(imageSuffix))
elif self.fPluginInfo['iconName'] == "file":
- self.b_gui.setPixmaps(":/bitmaps/button_file-{}.png".format(imageSuffix),
- ":/bitmaps/button_file_down-{}.png".format(imageSuffix),
- ":/bitmaps/button_file_hover-{}.png".format(imageSuffix))
+ self.b_gui.setSvgs(":/scalable/button_file-{}.svg".format(imageSuffix),
+ ":/scalable/button_file_down-{}.svg".format(imageSuffix),
+ ":/scalable/button_file_hover-{}.svg".format(imageSuffix))
else:
- self.b_gui.setPixmaps(":/bitmaps/button_gui-{}.png".format(imageSuffix),
- ":/bitmaps/button_gui_down-{}.png".format(imageSuffix),
- ":/bitmaps/button_gui_hover-{}.png".format(imageSuffix))
+ self.b_gui.setSvgs(":/scalable/button_gui-{}.svg".format(imageSuffix),
+ ":/scalable/button_gui_down-{}.svg".format(imageSuffix),
+ ":/scalable/button_gui_hover-{}.svg".format(imageSuffix))
if self.b_edit is not None:
self.b_edit.clicked.connect(self.slot_showEditDialog)
if isCalfSkin:
- self.b_edit.setPixmaps(":/bitmaps/button_calf2.png".format(imageSuffix),
- ":/bitmaps/button_calf2_down.png".format(imageSuffix),
- ":/bitmaps/button_calf2_hover.png".format(imageSuffix))
+ self.b_edit.setSvgs(":/scalable/button_calf2.svg",
+ ":/scalable/button_calf2_down.svg",
+ ":/scalable/button_calf2_hover.svg")
else:
- self.b_edit.setPixmaps(":/bitmaps/button_edit-{}.png".format(imageSuffix),
- ":/bitmaps/button_edit_down-{}.png".format(imageSuffix),
- ":/bitmaps/button_edit_hover-{}.png".format(imageSuffix))
+ self.b_edit.setSvgs(":/scalable/button_edit-{}.svg".format(imageSuffix),
+ ":/scalable/button_edit_down-{}.svg".format(imageSuffix),
+ ":/scalable/button_edit_hover-{}.svg".format(imageSuffix))
else:
# Edit button *must* be available
@@ -594,7 +595,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
paramName = getParameterShortName(paramInfo['name'])
- widget = PixmapDial(self, i)
+ widget = ScalableDial(self, i)
widget.setLabel(paramName)
widget.setMinimum(paramRanges['min'])
widget.setMaximum(paramRanges['max'])
@@ -603,28 +604,28 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
if isInteger:
widget.setPrecision(paramRanges['max']-paramRanges['min'], True)
- setPixmapDialStyle(widget, i, parameterCount, whiteLabels, self.fSkinStyle)
+ setScalableDialStyle(widget, i, parameterCount, whiteLabels, self.fSkinStyle)
index += 1
self.fParameterList.append([i, widget])
layout.addWidget(widget)
if self.w_knobs_right is not None and (self.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET) != 0:
- widget = PixmapDial(self, PARAMETER_DRYWET)
+ widget = ScalableDial(self, PARAMETER_DRYWET)
widget.setLabel("Dry/Wet")
widget.setMinimum(0.0)
widget.setMaximum(1.0)
- setPixmapDialStyle(widget, PARAMETER_DRYWET, 0, whiteLabels, self.fSkinStyle)
+ setScalableDialStyle(widget, PARAMETER_DRYWET, 0, whiteLabels, self.fSkinStyle)
self.fParameterList.append([PARAMETER_DRYWET, widget])
self.w_knobs_right.layout().addWidget(widget)
if self.w_knobs_right is not None and (self.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME) != 0:
- widget = PixmapDial(self, PARAMETER_VOLUME)
+ widget = ScalableDial(self, PARAMETER_VOLUME)
widget.setLabel("Volume")
widget.setMinimum(0.0)
widget.setMaximum(1.27)
- setPixmapDialStyle(widget, PARAMETER_VOLUME, 0, whiteLabels, self.fSkinStyle)
+ setScalableDialStyle(widget, PARAMETER_VOLUME, 0, whiteLabels, self.fSkinStyle)
self.fParameterList.append([PARAMETER_VOLUME, widget])
self.w_knobs_right.layout().addWidget(widget)
@@ -646,7 +647,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
self.fAdjustViewableKnobCountScheduled = True
QTimer.singleShot(5, self.adjustViewableKnobCount)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def getFixedHeight(self):
return 32
@@ -657,7 +658,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
def getPluginId(self):
return self.fPluginId
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def setPluginId(self, idx):
self.fPluginId = idx
@@ -677,7 +678,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
self.fIsSelected = yesNo
self.update()
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def setActive(self, active, sendCallback=False, sendHost=True):
self.fIsActive = active
@@ -729,7 +730,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
self.fEditDialog.setParameterValue(parameterId, value)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def setParameterValue(self, parameterId, value, sendCallback):
if parameterId == PARAMETER_ACTIVE:
@@ -753,7 +754,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
def setParameterMidiChannel(self, parameterId, channel):
self.fEditDialog.setParameterMidiChannel(parameterId, channel)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def setProgram(self, index, sendCallback):
self.fEditDialog.setProgram(index)
@@ -773,12 +774,12 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
self.updateParameterValues()
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def setOption(self, option, yesNo):
self.fEditDialog.setOption(option, yesNo)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def showCustomUI(self):
self.host.show_custom_ui(self.fPluginId, True)
@@ -826,7 +827,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
if not ok:
CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def activeChanged(self, onOff):
self.fIsActive = onOff
@@ -933,7 +934,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
def editDialogMidiActivityChanged(self, pluginId, onOff):
self.midiActivityChanged(onOff)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def idleFast(self):
# Input peaks
@@ -994,7 +995,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
self.fEditDialog.idleSlow()
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def drawOutline(self, painter):
painter.save()
@@ -1027,7 +1028,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
paramWidget.setValue(self.host.get_current_parameter_value(self.fPluginId, paramIndex))
paramWidget.blockSignals(False)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
@pyqtSlot(bool)
def slot_enableClicked(self, yesNo):
@@ -1376,7 +1377,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
sender.setValue(value, True)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
@pyqtSlot(bool)
def slot_showCustomUi(self, show):
@@ -1392,7 +1393,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
@pyqtSlot(bool)
def slot_parameterDragStateChanged(self, touch):
@@ -1421,7 +1422,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
self.host.set_midi_program(self.fPluginId, index)
self.setMidiProgram(index, False)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def adjustViewableKnobCount(self):
if self.w_knobs_left is None or self.spacer_knobs is None:
@@ -1457,7 +1458,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
def testTimer(self):
self.fIdleTimerId = self.startTimer(25)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def mouseDoubleClickEvent(self, event):
QFrame.mouseDoubleClickEvent(self, event)
@@ -1529,7 +1530,7 @@ class PluginSlot_Calf(AbstractPluginSlot):
self.ui.label_active.setFont(self.fButtonFont)
- self.ui.b_remove.setPixmaps(":/bitmaps/button_calf1.png", ":/bitmaps/button_calf1_down.png", ":/bitmaps/button_calf1_hover.png")
+ self.ui.b_remove.setSvgs(":/scalable/button_calf1.svg", ":/scalable/button_calf1_down.svg", ":/scalable/button_calf1_hover.svg")
self.ui.b_edit.setTopText(self.tr("Edit"), self.fButtonColorOn, self.fButtonFont)
self.ui.b_remove.setTopText(self.tr("Remove"), self.fButtonColorOn, self.fButtonFont)
@@ -1573,12 +1574,12 @@ class PluginSlot_Calf(AbstractPluginSlot):
self.ui.led_midi.setColor(self.ui.led_midi.CALF)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def getFixedHeight(self):
return 94 if max(self.peak_in.channelCount(), self.peak_out.channelCount()) < 2 else 106
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def editDialogPluginHintsChanged(self, pluginId, hints):
if hints & PLUGIN_HAS_CUSTOM_UI:
@@ -1588,7 +1589,7 @@ class PluginSlot_Calf(AbstractPluginSlot):
AbstractPluginSlot.editDialogPluginHintsChanged(self, pluginId, hints)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def paintEvent(self, event):
isBlack = bool(self.fSkinStyle == "calf_black")
@@ -1636,12 +1637,12 @@ class PluginSlot_Classic(AbstractPluginSlot):
self.ready()
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def getFixedHeight(self):
return 36
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def paintEvent(self, event):
painter = QPainter(self)
@@ -1716,7 +1717,7 @@ class PluginSlot_Compact(AbstractPluginSlot):
self.ready()
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def getFixedHeight(self):
if self.fSkinStyle == "calf_blue":
@@ -1753,12 +1754,12 @@ class PluginSlot_Default(AbstractPluginSlot):
self.ready()
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def getFixedHeight(self):
return 80
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def paintEvent(self, event):
painter = QPainter(self)
@@ -1934,14 +1935,14 @@ class PluginSlot_Presets(AbstractPluginSlot):
else:
paramName = getParameterShortName(paramName)
- widget = PixmapDial(self, i)
+ widget = ScalableDial(self, i)
widget.setLabel(paramName)
widget.setMinimum(paramRanges['min'])
widget.setMaximum(paramRanges['max'])
- widget.setPixmap(3)
+ widget.setSvg(3)
widget.setCustomPaintColor(QColor(83, 173, 10))
- widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_COLOR)
+ widget.setCustomPaintMode(ScalableDial.CUSTOM_PAINT_MODE_COLOR)
widget.forceWhiteLabelGradientText()
widget.hide()
@@ -1952,35 +1953,35 @@ class PluginSlot_Presets(AbstractPluginSlot):
self.ui.w_knobs_left.layout().addWidget(widget)
if self.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET:
- widget = PixmapDial(self, PARAMETER_DRYWET)
+ widget = ScalableDial(self, PARAMETER_DRYWET)
widget.setLabel("Wet")
widget.setMinimum(0.0)
widget.setMaximum(1.0)
- widget.setPixmap(3)
- widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_CARLA_WET)
+ widget.setSvg(3)
+ widget.setCustomPaintMode(ScalableDial.CUSTOM_PAINT_MODE_CARLA_WET)
widget.forceWhiteLabelGradientText()
self.fParameterList.append([PARAMETER_DRYWET, widget])
self.ui.w_knobs_right.layout().addWidget(widget)
if self.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME:
- widget = PixmapDial(self, PARAMETER_VOLUME)
+ widget = ScalableDial(self, PARAMETER_VOLUME)
widget.setLabel("Volume")
widget.setMinimum(0.0)
widget.setMaximum(1.27)
- widget.setPixmap(3)
- widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_CARLA_VOL)
+ widget.setSvg(3)
+ widget.setCustomPaintMode(ScalableDial.CUSTOM_PAINT_MODE_CARLA_VOL)
widget.forceWhiteLabelGradientText()
self.fParameterList.append([PARAMETER_VOLUME, widget])
self.ui.w_knobs_right.layout().addWidget(widget)
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def getFixedHeight(self):
return 80
- #------------------------------------------------------------------
+ # -----------------------------------------------------------------
def paintEvent(self, event):
painter = QPainter(self)
diff --git a/source/frontend/carla_widgets.py b/source/frontend/carla_widgets.py
index e8ba95b2a..78e0c3c47 100755
--- a/source/frontend/carla_widgets.py
+++ b/source/frontend/carla_widgets.py
@@ -585,8 +585,8 @@ class PluginEdit(QDialog):
self.fPlayingNotes = [] # (channel, note)
- self.fTabIconOff = QIcon(":/bitmaps/led_off.png")
- self.fTabIconOn = QIcon(":/bitmaps/led_yellow.png")
+ self.fTabIconOff = QIcon(":/scalable/led_off.svg")
+ self.fTabIconOn = QIcon(":/scalable/led_yellow.svg")
self.fTabIconTimers = []
# used during testing
@@ -601,35 +601,35 @@ class PluginEdit(QDialog):
self.ui.label_plugin.setFont(labelPluginFont)
self.ui.dial_drywet.setCustomPaintMode(self.ui.dial_drywet.CUSTOM_PAINT_MODE_CARLA_WET)
- self.ui.dial_drywet.setPixmap(3)
+ self.ui.dial_drywet.setSvg(3)
self.ui.dial_drywet.setLabel("Dry/Wet")
self.ui.dial_drywet.setMinimum(0.0)
self.ui.dial_drywet.setMaximum(1.0)
self.ui.dial_drywet.setValue(host.get_internal_parameter_value(pluginId, PARAMETER_DRYWET))
self.ui.dial_vol.setCustomPaintMode(self.ui.dial_vol.CUSTOM_PAINT_MODE_CARLA_VOL)
- self.ui.dial_vol.setPixmap(3)
+ self.ui.dial_vol.setSvg(3)
self.ui.dial_vol.setLabel("Volume")
self.ui.dial_vol.setMinimum(0.0)
self.ui.dial_vol.setMaximum(1.27)
self.ui.dial_vol.setValue(host.get_internal_parameter_value(pluginId, PARAMETER_VOLUME))
self.ui.dial_b_left.setCustomPaintMode(self.ui.dial_b_left.CUSTOM_PAINT_MODE_CARLA_L)
- self.ui.dial_b_left.setPixmap(4)
+ self.ui.dial_b_left.setSvg(4)
self.ui.dial_b_left.setLabel("L")
self.ui.dial_b_left.setMinimum(-1.0)
self.ui.dial_b_left.setMaximum(1.0)
self.ui.dial_b_left.setValue(host.get_internal_parameter_value(pluginId, PARAMETER_BALANCE_LEFT))
self.ui.dial_b_right.setCustomPaintMode(self.ui.dial_b_right.CUSTOM_PAINT_MODE_CARLA_R)
- self.ui.dial_b_right.setPixmap(4)
+ self.ui.dial_b_right.setSvg(4)
self.ui.dial_b_right.setLabel("R")
self.ui.dial_b_right.setMinimum(-1.0)
self.ui.dial_b_right.setMaximum(1.0)
self.ui.dial_b_right.setValue(host.get_internal_parameter_value(pluginId, PARAMETER_BALANCE_RIGHT))
self.ui.dial_pan.setCustomPaintMode(self.ui.dial_b_right.CUSTOM_PAINT_MODE_CARLA_PAN)
- self.ui.dial_pan.setPixmap(4)
+ self.ui.dial_pan.setSvg(4)
self.ui.dial_pan.setLabel("Pan")
self.ui.dial_pan.setMinimum(-1.0)
self.ui.dial_pan.setMaximum(1.0)
diff --git a/source/frontend/widgets/ledbutton.cpp b/source/frontend/widgets/ledbutton.cpp
index b9fdeb3ef..c575594a9 100644
--- a/source/frontend/widgets/ledbutton.cpp
+++ b/source/frontend/widgets/ledbutton.cpp
@@ -32,7 +32,7 @@ LEDButton::LEDButton(QWidget* parent):
setColor(BLUE);
// matching fLastColor
- fPixmap.load(":/bitmaps/led_off.png");
+ fPixmap.load(":/scalable/led_off.svg");
}
void LEDButton::setColor(Color color)
@@ -58,19 +58,19 @@ void LEDButton::paintEvent(QPaintEvent* event)
switch (fColor)
{
case OFF:
- fPixmap.load(":/bitmaps/led_off.png");
+ fPixmap.load(":/scalable/led_off.svg");
break;
case BLUE:
- fPixmap.load(":/bitmaps/led_blue.png");
+ fPixmap.load(":/scalable/led_blue.svg");
break;
case GREEN:
- fPixmap.load(":/bitmaps/led_green.png");
+ fPixmap.load(":/scalable/led_green.svg");
break;
case RED:
- fPixmap.load(":/bitmaps/led_red.png");
+ fPixmap.load(":/scalable/led_red.svg");
break;
case YELLOW:
- fPixmap.load(":/bitmaps/led_yellow.png");
+ fPixmap.load(":/scalable/led_yellow.svg");
break;
default:
return;
@@ -81,7 +81,7 @@ void LEDButton::paintEvent(QPaintEvent* event)
}
else if (fLastColor != OFF)
{
- fPixmap.load(":/bitmaps/led_off.png");
+ fPixmap.load(":/scalable/led_off.svg");
fLastColor = OFF;
}
diff --git a/source/frontend/widgets/ledbutton.py b/source/frontend/widgets/ledbutton.py
index 77a3415d1..66d3f8bab 100644
--- a/source/frontend/widgets/ledbutton.py
+++ b/source/frontend/widgets/ledbutton.py
@@ -19,13 +19,13 @@
# ------------------------------------------------------------------------------------------------------------
# Imports (Global)
-from PyQt5.QtCore import QRectF
-from PyQt5.QtGui import QPainter, QPixmap
+from PyQt5.QtSvg import QSvgWidget
from PyQt5.QtWidgets import QPushButton
# ------------------------------------------------------------------------------------------------------------
# Widget Class
+
class LEDButton(QPushButton):
# normal
OFF = 0
@@ -39,60 +39,50 @@ class LEDButton(QPushButton):
def __init__(self, parent):
QPushButton.__init__(self, parent)
- self.fPixmap = QPixmap()
- self.fPixmapRect = QRectF(0, 0, 0, 0)
+ self.fSvgWidget = QSvgWidget(self)
self.setCheckable(True)
self.setText("")
self.fLastColor = self.OFF
- self.fPixmap.load(":/bitmaps/led_off.png")
+ self.fSvgWidget.load(":/scalable/led_off.svg")
self.setColor(self.BLUE)
def setColor(self, color):
self.fColor = color
- self._loadPixmapNow()
+ self._loadSVGNow()
# Fix calf off
if color == self.CALF:
- self.fPixmap.load(":/bitmaps/led_calf_off.png")
-
- size = self.fPixmap.width()
- self.fPixmapRect = QRectF(0, 0, size, size)
-
- self.setMinimumSize(size, size)
- self.setMaximumSize(size, size)
+ self.fSvgWidget.load(":/bitmaps/led_calf_off.png")
def paintEvent(self, event):
- painter = QPainter(self)
event.accept()
- self._loadPixmapNow()
-
- painter.drawPixmap(self.fPixmapRect, self.fPixmap, self.fPixmapRect)
+ self._loadSVGNow()
- def _loadPixmapNow(self):
+ def _loadSVGNow(self):
if self.isChecked():
if self.fLastColor != self.fColor:
if self.fColor == self.OFF:
- self.fPixmap.load(":/bitmaps/led_off.png")
+ self.fSvgWidget.load(":/scalable/led_off.svg")
elif self.fColor == self.BLUE:
- self.fPixmap.load(":/bitmaps/led_blue.png")
+ self.fSvgWidget.load(":/scalable/led_blue.svg")
elif self.fColor == self.GREEN:
- self.fPixmap.load(":/bitmaps/led_green.png")
+ self.fSvgWidget.load(":/scalable/led_green.svg")
elif self.fColor == self.RED:
- self.fPixmap.load(":/bitmaps/led_red.png")
+ self.fSvgWidget.load(":/scalable/led_red.svg")
elif self.fColor == self.YELLOW:
- self.fPixmap.load(":/bitmaps/led_yellow.png")
+ self.fSvgWidget.load(":/scalable/led_yellow.svg")
elif self.fColor == self.CALF:
- self.fPixmap.load(":/bitmaps/led_calf_on.png")
+ self.fSvgWidget.load(":/bitmaps/led_calf_on.png")
else:
return
self.fLastColor = self.fColor
elif self.fLastColor != self.OFF:
- self.fPixmap.load(":/bitmaps/led_calf_off.png" if self.fColor == self.CALF else ":/bitmaps/led_off.png")
+ self.fSvgWidget.load(":/scalable/led_calf_off.png" if self.fColor == self.CALF else ":/scalable/led_off.svg")
self.fLastColor = self.OFF
diff --git a/source/frontend/widgets/scalablebutton.py b/source/frontend/widgets/scalablebutton.py
new file mode 100644
index 000000000..b3a371973
--- /dev/null
+++ b/source/frontend/widgets/scalablebutton.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Svg Button, a custom Qt widget
+# Copyright (C) 2020 Filipe Coelho
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# For a full copy of the GNU General Public License see the doc/GPL.txt file.
+
+# ------------------------------------------------------------------------------------------------------------
+# Imports (Global)
+
+from PyQt5.QtCore import QPointF, QRectF
+from PyQt5.QtGui import QColor, QFont, QPainter
+from PyQt5.QtSvg import QSvgWidget
+from PyQt5.QtWidgets import QPushButton
+
+# ------------------------------------------------------------------------------------------------------------
+# Widget Class
+
+
+class ScalableButton(QPushButton):
+ def __init__(self, parent):
+ QPushButton.__init__(self, parent)
+
+ self.fSvgNormal = QSvgWidget()
+ self.fSvgDown = QSvgWidget()
+ self.fSvgHover = QSvgWidget()
+
+ self.fIsHovered = False
+
+ self.fTopText = ""
+ self.fTopTextColor = QColor()
+ self.fTopTextFont = QFont()
+
+ self.setText("")
+
+ def setSvgs(self, normal, down, hover):
+ self.fSvgNormal.load(normal)
+ self.fSvgDown.load(down)
+ self.fSvgHover.load(hover)
+
+ width = self.fSvgNormal.sizeHint().width()
+ height = self.fSvgNormal.sizeHint().height()
+
+ self.fSvgRect = QRectF(0, 0, width, height)
+
+ self.setMinimumSize(width, height)
+ self.setMaximumSize(width, height)
+
+ def setTopText(self, text, color, font):
+ self.fTopText = text
+ self.fTopTextColor = color
+ self.fTopTextFont = font
+
+ def enterEvent(self, event):
+ self.fIsHovered = True
+ QPushButton.enterEvent(self, event)
+
+ def leaveEvent(self, event):
+ self.fIsHovered = False
+ QPushButton.leaveEvent(self, event)
+
+ def paintEvent(self, event):
+ painter = QPainter(self)
+ event.accept()
+
+ if not self.isEnabled():
+ painter.save()
+ painter.setOpacity(0.2)
+ self.fSvgNormal.renderer().render(painter, self.fSvgRect)
+ painter.restore()
+
+ elif self.isChecked() or self.isDown():
+ self.fSvgDown.renderer().render(painter, self.fSvgRect)
+
+ elif self.fIsHovered:
+ self.fSvgHover.renderer().render(painter, self.fSvgRect)
+ else:
+ self.fSvgNormal.renderer().render(painter, self.fSvgRect)
+ if not self.fTopText:
+ return
+
+ painter.save()
+ painter.setPen(self.fTopTextColor)
+ painter.setBrush(self.fTopTextColor)
+ painter.setFont(self.fTopTextFont)
+ painter.drawText(QPointF(10, 16), self.fTopText)
+ painter.restore()
diff --git a/source/frontend/widgets/scalabledial.py b/source/frontend/widgets/scalabledial.py
new file mode 100644
index 000000000..41991cb5f
--- /dev/null
+++ b/source/frontend/widgets/scalabledial.py
@@ -0,0 +1,519 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Svg Dial, a custom Qt widget
+# Copyright (C) 2011-2019 Filipe Coelho
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# For a full copy of the GNU General Public License see the doc/GPL.txt file.
+
+# ------------------------------------------------------------------------------------------------------------
+# Imports (Global)
+
+from math import cos, floor, pi, sin
+
+from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QEvent, QPointF, QRectF, QTimer, QSize
+from PyQt5.QtGui import QColor, QConicalGradient, QFont, QFontMetrics
+from PyQt5.QtGui import QLinearGradient, QPainter, QPainterPath, QPen
+from PyQt5.QtSvg import QSvgWidget
+from PyQt5.QtWidgets import QDial
+
+# ------------------------------------------------------------------------------------------------------------
+# Widget Class
+
+class ScalableDial(QDial):
+ # enum CustomPaintMode
+ CUSTOM_PAINT_MODE_NULL = 0 # default (NOTE: only this mode has label gradient)
+ CUSTOM_PAINT_MODE_CARLA_WET = 1 # color blue-green gradient (reserved #3)
+ CUSTOM_PAINT_MODE_CARLA_VOL = 2 # color blue (reserved #3)
+ CUSTOM_PAINT_MODE_CARLA_L = 3 # color yellow (reserved #4)
+ CUSTOM_PAINT_MODE_CARLA_R = 4 # color yellow (reserved #4)
+ CUSTOM_PAINT_MODE_CARLA_PAN = 5 # color yellow (reserved #3)
+ CUSTOM_PAINT_MODE_COLOR = 6 # color, selectable (reserved #3)
+ CUSTOM_PAINT_MODE_ZITA = 7 # custom zita knob (reserved #6)
+ CUSTOM_PAINT_MODE_NO_GRADIENT = 8 # skip label gradient
+
+ # enum Orientation
+ HORIZONTAL = 0
+ VERTICAL = 1
+
+ HOVER_MIN = 0
+ HOVER_MAX = 9
+
+ MODE_DEFAULT = 0
+ MODE_LINEAR = 1
+
+ # signals
+ dragStateChanged = pyqtSignal(bool)
+ realValueChanged = pyqtSignal(float)
+
+ def __init__(self, parent, index=0):
+ QDial.__init__(self, parent)
+
+ self.fDialMode = self.MODE_LINEAR
+
+ self.fMinimum = 0.0
+ self.fMaximum = 1.0
+ self.fRealValue = 0.0
+ self.fPrecision = 10000
+ self.fIsInteger = False
+
+ self.fIsHovered = False
+ self.fIsPressed = False
+ self.fHoverStep = self.HOVER_MIN
+
+ self.fLastDragPos = None
+ self.fLastDragValue = 0.0
+
+ self.fIndex = index
+ self.fSvg = QSvgWidget(":/scalable/dial_03.svg")
+ self.fSvgNum = "01"
+
+ if self.fSvg.sizeHint().width() > self.fSvg.sizeHint().height():
+ self.fSvgOrientation = self.HORIZONTAL
+ else:
+ self.fSvgOrientation = self.VERTICAL
+
+ self.fLabel = ""
+ self.fLabelPos = QPointF(0.0, 0.0)
+ self.fLabelFont = QFont(self.font())
+ self.fLabelFont.setPixelSize(8)
+ self.fLabelWidth = 0
+ self.fLabelHeight = 0
+
+ if self.palette().window().color().lightness() > 100:
+ # Light background
+ c = self.palette().dark().color()
+ self.fLabelGradientColor1 = c
+ self.fLabelGradientColor2 = QColor(c.red(), c.green(), c.blue(), 0)
+ self.fLabelGradientColorT = [self.palette().buttonText().color(), self.palette().mid().color()]
+ else:
+ # Dark background
+ self.fLabelGradientColor1 = QColor(0, 0, 0, 255)
+ self.fLabelGradientColor2 = QColor(0, 0, 0, 0)
+ self.fLabelGradientColorT = [Qt.white, Qt.darkGray]
+
+ self.fLabelGradient = QLinearGradient(0, 0, 0, 1)
+ self.fLabelGradient.setColorAt(0.0, self.fLabelGradientColor1)
+ self.fLabelGradient.setColorAt(0.6, self.fLabelGradientColor1)
+ self.fLabelGradient.setColorAt(1.0, self.fLabelGradientColor2)
+
+ self.fLabelGradientRect = QRectF(0.0, 0.0, 0.0, 0.0)
+
+ self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_NULL
+ self.fCustomPaintColor = QColor(0xff, 0xff, 0xff)
+
+ self.updateSizes()
+
+ # Fake internal value, custom precision
+ QDial.setMinimum(self, 0)
+ QDial.setMaximum(self, self.fPrecision)
+ QDial.setValue(self, 0)
+
+ self.valueChanged.connect(self.slot_valueChanged)
+
+ def getIndex(self):
+ return self.fIndex
+
+ def getBaseSize(self):
+ return self.fSvgBaseSize
+
+ def forceWhiteLabelGradientText(self):
+ self.fLabelGradientColor1 = QColor(0, 0, 0, 255)
+ self.fLabelGradientColor2 = QColor(0, 0, 0, 0)
+ self.fLabelGradientColorT = [Qt.white, Qt.darkGray]
+
+ def setLabelColor(self, enabled, disabled):
+ self.fLabelGradientColor1 = QColor(0, 0, 0, 255)
+ self.fLabelGradientColor2 = QColor(0, 0, 0, 0)
+ self.fLabelGradientColorT = [enabled, disabled]
+
+ def updateSizes(self):
+ self.fSvgWidth = self.fSvg.sizeHint().width()
+ self.fSvgHeight = self.fSvg.sizeHint().height()
+
+ if self.fSvgWidth < 1:
+ self.fSvgWidth = 1
+
+ if self.fSvgHeight < 1:
+ self.fSvgHeight = 1
+
+ if self.fSvgOrientation == self.HORIZONTAL:
+ self.fSvgBaseSize = self.fSvgHeight
+ self.fSvgLayersCount = self.fSvgWidth / self.fSvgHeight
+ else:
+ self.fSvgBaseSize = self.fSvgWidth
+ self.fSvgLayersCount = self.fSvgHeight / self.fSvgWidth
+
+ self.setMinimumSize(self.fSvgBaseSize, self.fSvgBaseSize + self.fLabelHeight + 5)
+ self.setMaximumSize(self.fSvgBaseSize, self.fSvgBaseSize + self.fLabelHeight + 5)
+
+ if not self.fLabel:
+ self.fLabelHeight = 0
+ self.fLabelWidth = 0
+ return
+
+ self.fLabelWidth = QFontMetrics(self.fLabelFont).width(self.fLabel)
+ self.fLabelHeight = QFontMetrics(self.fLabelFont).height()
+
+ self.fLabelPos.setX(float(self.fSvgBaseSize)/2.0 - float(self.fLabelWidth)/2.0)
+
+ if self.fSvgNum in ("01", "02", "07", "08", "09", "10"):
+ self.fLabelPos.setY(self.fSvgBaseSize + self.fLabelHeight)
+ elif self.fSvgNum in ("11",):
+ self.fLabelPos.setY(self.fSvgBaseSize + self.fLabelHeight*2/3)
+ else:
+ self.fLabelPos.setY(self.fSvgBaseSize + self.fLabelHeight/2)
+
+ self.fLabelGradient.setStart(0, float(self.fSvgBaseSize)/2.0)
+ self.fLabelGradient.setFinalStop(0, self.fSvgBaseSize + self.fLabelHeight + 5)
+
+ self.fLabelGradientRect = QRectF(float(self.fSvgBaseSize)/8.0, float(self.fSvgBaseSize)/2.0,
+ float(self.fSvgBaseSize*3)/4.0, self.fSvgBaseSize+self.fLabelHeight+5)
+
+ def setCustomPaintMode(self, paintMode):
+ if self.fCustomPaintMode == paintMode:
+ return
+
+ self.fCustomPaintMode = paintMode
+ self.update()
+
+ def setCustomPaintColor(self, color):
+ if self.fCustomPaintColor == color:
+ return
+
+ self.fCustomPaintColor = color
+ self.update()
+
+ def setLabel(self, label):
+ if self.fLabel == label:
+ return
+
+ self.fLabel = label
+ self.updateSizes()
+ self.update()
+
+ def setIndex(self, index):
+ self.fIndex = index
+
+ def setSvg(self, SvgId):
+ self.fSvgNum = "%02i" % SvgId
+ self.fSvg.load(":/scalable/dial_%s%s.svg" % (self.fSvgNum, "" if self.isEnabled() else "d"))
+
+ if self.fSvg.width() > self.fSvg.height():
+ self.fSvgOrientation = self.HORIZONTAL
+ else:
+ self.fSvgOrientation = self.VERTICAL
+
+ # special svg
+ if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL:
+ # reserved for carla-wet, carla-vol, carla-pan and color
+ if self.fSvgNum == "03":
+ self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_COLOR
+
+ # reserved for carla-L and carla-R
+ elif self.fSvgNum == "04":
+ self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_CARLA_L
+
+ # reserved for zita
+ elif self.fSvgNum == "06":
+ self.fCustomPaintMode = self.CUSTOM_PAINT_MODE_ZITA
+
+ self.updateSizes()
+ self.update()
+
+ def setPrecision(self, value, isInteger):
+ self.fPrecision = value
+ self.fIsInteger = isInteger
+ QDial.setMaximum(self, value)
+
+ def setMinimum(self, value):
+ self.fMinimum = value
+
+ def setMaximum(self, value):
+ self.fMaximum = value
+
+ def setValue(self, value, emitSignal=False):
+ if self.fRealValue == value:
+ return
+
+ if value <= self.fMinimum:
+ qtValue = 0
+ self.fRealValue = self.fMinimum
+
+ elif value >= self.fMaximum:
+ qtValue = self.fPrecision
+ self.fRealValue = self.fMaximum
+
+ else:
+ qtValue = round(float(value - self.fMinimum) / float(self.fMaximum - self.fMinimum) * self.fPrecision)
+ self.fRealValue = value
+
+ # Block change signal, we'll handle it ourselves
+ self.blockSignals(True)
+ QDial.setValue(self, qtValue)
+ self.blockSignals(False)
+
+ if emitSignal:
+ self.realValueChanged.emit(self.fRealValue)
+
+ @pyqtSlot(int)
+ def slot_valueChanged(self, value):
+ self.fRealValue = float(value)/self.fPrecision * (self.fMaximum - self.fMinimum) + self.fMinimum
+ self.realValueChanged.emit(self.fRealValue)
+
+ @pyqtSlot()
+ def slot_updateSvg(self):
+ self.seSvg(int(self.fSvgNum))
+
+ def minimumSizeHint(self):
+ return QSize(self.fSvgBaseSize, self.fSvgBaseSize)
+
+ def sizeHint(self):
+ return QSize(self.fSvgBaseSize, self.fSvgBaseSize)
+
+ def changeEvent(self, event):
+ QDial.changeEvent(self, event)
+
+ # Force svg update if enabled state changes
+ if event.type() == QEvent.EnabledChange:
+ self.setSvg(int(self.fSvgNum))
+
+ def enterEvent(self, event):
+ self.fIsHovered = True
+ if self.fHoverStep == self.HOVER_MIN:
+ self.fHoverStep = self.HOVER_MIN + 1
+ QDial.enterEvent(self, event)
+
+ def leaveEvent(self, event):
+ self.fIsHovered = False
+ if self.fHoverStep == self.HOVER_MAX:
+ self.fHoverStep = self.HOVER_MAX - 1
+ QDial.leaveEvent(self, event)
+
+ def mousePressEvent(self, event):
+ if self.fDialMode == self.MODE_DEFAULT:
+ return QDial.mousePressEvent(self, event)
+
+ if event.button() == Qt.LeftButton:
+ self.fIsPressed = True
+ self.fLastDragPos = event.pos()
+ self.fLastDragValue = self.fRealValue
+ self.dragStateChanged.emit(True)
+
+ def mouseMoveEvent(self, event):
+ if self.fDialMode == self.MODE_DEFAULT:
+ return QDial.mouseMoveEvent(self, event)
+
+ if not self.fIsPressed:
+ return
+
+ range = (self.fMaximum - self.fMinimum) / 4.0
+ pos = event.pos()
+ dx = range * float(pos.x() - self.fLastDragPos.x()) / self.width()
+ dy = range * float(pos.y() - self.fLastDragPos.y()) / self.height()
+ value = self.fLastDragValue + dx - dy
+
+ if value < self.fMinimum:
+ value = self.fMinimum
+ elif value > self.fMaximum:
+ value = self.fMaximum
+ elif self.fIsInteger:
+ value = float(round(value))
+
+ self.setValue(value, True)
+
+ def mouseReleaseEvent(self, event):
+ if self.fDialMode == self.MODE_DEFAULT:
+ return QDial.mouseReleaseEvent(self, event)
+
+ if self.fIsPressed:
+ self.fIsPressed = False
+ self.dragStateChanged.emit(False)
+
+ def paintEvent(self, event):
+ painter = QPainter(self)
+ event.accept()
+
+ painter.save()
+ painter.setRenderHint(QPainter.Antialiasing, True)
+
+ if self.fLabel:
+ if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_NULL:
+ painter.setPen(self.fLabelGradientColor2)
+ painter.setBrush(self.fLabelGradient)
+ painter.drawRect(self.fLabelGradientRect)
+
+ painter.setFont(self.fLabelFont)
+ painter.setPen(self.fLabelGradientColorT[0 if self.isEnabled() else 1])
+ painter.drawText(self.fLabelPos, self.fLabel)
+
+ if self.isEnabled():
+ normValue = float(self.fRealValue - self.fMinimum) / float(self.fMaximum - self.fMinimum)
+ curLayer = int((self.fSvgLayersCount - 1) * normValue)
+
+ if self.fSvgOrientation == self.HORIZONTAL:
+ xpos = self.fSvgBaseSize * curLayer
+ ypos = 0.0
+ else:
+ xpos = 0.0
+ ypos = self.fSvgBaseSize * curLayer
+
+ source = QRectF(xpos, ypos, self.fSvgBaseSize, self.fSvgBaseSize)
+ self.fSvg.renderer().render(painter, source)
+
+ # Custom knobs (Dry/Wet and Volume)
+ if self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_WET, self.CUSTOM_PAINT_MODE_CARLA_VOL):
+ # knob color
+ colorGreen = QColor(0x5D, 0xE7, 0x3D).lighter(100 + self.fHoverStep*6)
+ colorBlue = QColor(0x3E, 0xB8, 0xBE).lighter(100 + self.fHoverStep*6)
+
+ # draw small circle
+ ballRect = QRectF(8.0, 8.0, 15.0, 15.0)
+ ballPath = QPainterPath()
+ ballPath.addEllipse(ballRect)
+ #painter.drawRect(ballRect)
+ tmpValue = (0.375 + 0.75*normValue)
+ ballValue = tmpValue - floor(tmpValue)
+ ballPoint = ballPath.pointAtPercent(ballValue)
+
+ # draw arc
+ startAngle = 220*16
+ spanAngle = -258*16*normValue
+
+ if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_WET:
+ painter.setBrush(colorBlue)
+ painter.setPen(QPen(colorBlue, 0))
+ painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2))
+
+ gradient = QConicalGradient(15.5, 15.5, -45)
+ gradient.setColorAt(0.0, colorBlue)
+ gradient.setColorAt(0.125, colorBlue)
+ gradient.setColorAt(0.625, colorGreen)
+ gradient.setColorAt(0.75, colorGreen)
+ gradient.setColorAt(0.76, colorGreen)
+ gradient.setColorAt(1.0, colorGreen)
+ painter.setBrush(gradient)
+ painter.setPen(QPen(gradient, 3))
+
+ else:
+ painter.setBrush(colorBlue)
+ painter.setPen(QPen(colorBlue, 0))
+ painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2))
+
+ painter.setBrush(colorBlue)
+ painter.setPen(QPen(colorBlue, 3))
+
+ painter.drawArc(2.0, 2.0, 30.5, 30.5, startAngle, spanAngle)
+
+ # Custom knobs (L and R)
+ elif self.fCustomPaintMode in (self.CUSTOM_PAINT_MODE_CARLA_L, self.CUSTOM_PAINT_MODE_CARLA_R):
+ # knob color
+ color = QColor(0xAD, 0xD5, 0x48).lighter(100 + self.fHoverStep*6)
+
+ # draw small circle
+ ballRect = QRectF(7.0, 8.0, 11.0, 12.0)
+ ballPath = QPainterPath()
+ ballPath.addEllipse(ballRect)
+ #painter.drawRect(ballRect)
+ tmpValue = (0.375 + 0.75*normValue)
+ ballValue = tmpValue - floor(tmpValue)
+ ballPoint = ballPath.pointAtPercent(ballValue)
+
+ painter.setBrush(color)
+ painter.setPen(QPen(color, 0))
+ painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.0, 2.0))
+
+ # draw arc
+ if self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_CARLA_L:
+ startAngle = 220*16
+ spanAngle = -258.0*16*normValue
+ else:
+ startAngle = 320.0*16
+ spanAngle = 262.0*16*(1.0-normValue)
+
+ painter.setPen(QPen(color, 2))
+ painter.drawArc(2, 2.0, 24.0, 24.0, startAngle, spanAngle)
+
+ # Custom knobs (Color)
+ elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_COLOR:
+ # knob color
+ color = self.fCustomPaintColor.lighter(100 + self.fHoverStep*6)
+
+ # draw small circle
+ ballRect = QRectF(8.0, 8.0, 15.0, 15.0)
+ ballPath = QPainterPath()
+ ballPath.addEllipse(ballRect)
+ tmpValue = (0.375 + 0.75*normValue)
+ ballValue = tmpValue - floor(tmpValue)
+ ballPoint = ballPath.pointAtPercent(ballValue)
+
+ # draw arc
+ startAngle = 220*16
+ spanAngle = -258*16*normValue
+
+ painter.setBrush(color)
+ painter.setPen(QPen(color, 0))
+ painter.drawEllipse(QRectF(ballPoint.x(), ballPoint.y(), 2.2, 2.2))
+
+ painter.setBrush(color)
+ painter.setPen(QPen(color, 3))
+ painter.drawArc(2.0, 2.0, 30.5, 30.5, startAngle, spanAngle)
+
+ # Custom knobs (Zita)
+ elif self.fCustomPaintMode == self.CUSTOM_PAINT_MODE_ZITA:
+ a = normValue * pi * 1.5 - 2.35
+ r = 10.0
+ x = 10.5
+ y = 10.5
+ x += r * sin(a)
+ y -= r * cos(a)
+ painter.setBrush(Qt.black)
+ painter.setPen(QPen(Qt.black, 2))
+ painter.drawLine(QPointF(11.0, 11.0), QPointF(x, y))
+
+ # Custom knobs
+ else:
+ painter.restore()
+ return
+
+ if self.HOVER_MIN < self.fHoverStep < self.HOVER_MAX:
+ self.fHoverStep += 1 if self.fIsHovered else -1
+ QTimer.singleShot(20, self.update)
+
+ else: # isEnabled()
+ target = QRectF(0.0, 0.0, self.fSvgBaseSize, self.fSvgBaseSize)
+ self.fSvg.renderer().render(painter, target)
+
+ painter.restore()
+
+ def resizeEvent(self, event):
+ QDial.resizeEvent(self, event)
+ self.updateSizes()
+
+# ------------------------------------------------------------------------------------------------------------
+# Main Testing
+
+if __name__ == '__main__':
+ import sys
+ from PyQt5.QtWidgets import QApplication
+ import resources_rc
+
+ app = QApplication(sys.argv)
+ gui = ScalableDial(None)
+ #gui.setEnabled(True)
+ #gui.setEnabled(False)
+ gui.setSvg(3)
+ gui.setLabel("hahaha")
+ gui.show()
+
+ sys.exit(app.exec_())