Browse Source

Move PluginWidget to new file, subclass for future skins

tags/1.9.4
falkTX 11 years ago
parent
commit
a529d127a7
3 changed files with 542 additions and 434 deletions
  1. +10
    -23
      source/carla_rack.py
  2. +525
    -0
      source/carla_skin.py
  3. +7
    -411
      source/carla_widgets.py

+ 10
- 23
source/carla_rack.py View File

@@ -25,29 +25,26 @@ from PyQt4.QtGui import QApplication, QListWidget, QListWidgetItem
# ------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff)

from carla_widgets import *
from carla_skin import *

# ------------------------------------------------------------------------------------------------------------
# Rack widget item

class CarlaRackItem(QListWidgetItem):
kRackItemType = QListWidgetItem.UserType + 1
kStaticHeight = 32

def __init__(self, parent, pluginId):
QListWidgetItem.__init__(self, parent, self.kRackItemType)

self.widget = PluginWidget(parent, pluginId)
self.widget.setFixedHeight(self.kStaticHeight)

self.setSizeHint(QSize(300, self.kStaticHeight))
self.widget = createPluginSlot(pluginId, parent)
self.setSizeHint(QSize(300, self.widget.getFixedHeight()))

parent.setItemWidget(self, self.widget)

# -----------------------------------------------------------------

def close(self):
self.widget.ui.edit_dialog.close()
self.widget.fEditDialog.close()

#def setId(self, idx):
#self.widget.setId(idx)
@@ -411,17 +408,7 @@ class CarlaRackW(QListWidget):
if pitem is None:
return

# TODO

if state == 0:
pitem.widget.ui.b_gui.setChecked(False)
pitem.widget.ui.b_gui.setEnabled(True)
elif state == 1:
pitem.widget.ui.b_gui.setChecked(True)
pitem.widget.ui.b_gui.setEnabled(True)
elif state == -1:
pitem.widget.ui.b_gui.setChecked(False)
pitem.widget.ui.b_gui.setEnabled(False)
pitem.widget.customUiStateChanged(state)

# -----------------------------------------------------------------

@@ -458,7 +445,7 @@ class CarlaRackW(QListWidget):
if pitem is None:
return

pitem.widget.ui.edit_dialog.updateInfo()
pitem.widget.fEditDialog.updateInfo()

@pyqtSlot(int)
def slot_handleReloadInfoCallback(self, pluginId):
@@ -469,7 +456,7 @@ class CarlaRackW(QListWidget):
if pitem is None:
return

pitem.widget.ui.edit_dialog.reloadInfo()
pitem.widget.fEditDialog.reloadInfo()

@pyqtSlot(int)
def slot_handleReloadParametersCallback(self, pluginId):
@@ -480,7 +467,7 @@ class CarlaRackW(QListWidget):
if pitem is None:
return

pitem.widget.ui.edit_dialog.reloadParameters()
pitem.widget.fEditDialog.reloadParameters()

@pyqtSlot(int)
def slot_handleReloadProgramsCallback(self, pluginId):
@@ -491,7 +478,7 @@ class CarlaRackW(QListWidget):
if pitem is None:
return

pitem.widget.ui.edit_dialog.reloadPrograms()
pitem.widget.fEditDialog.reloadPrograms()

@pyqtSlot(int)
def slot_handleReloadAllCallback(self, pluginId):
@@ -502,6 +489,6 @@ class CarlaRackW(QListWidget):
if pitem is None:
return

pitem.widget.ui.edit_dialog.reloadAll()
pitem.widget.fEditDialog.reloadAll()

# -----------------------------------------------------------------

+ 525
- 0
source/carla_skin.py View File

@@ -0,0 +1,525 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Carla plugin/slot skin code
# Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
#
# 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 PyQt4.QtCore import pyqtSignal, pyqtSlot
from PyQt4.QtGui import QFrame

# ------------------------------------------------------------------------------------------------------------
# Imports (Custom)

import ui_carla_plugin

from carla_widgets import *

# ------------------------------------------------------------------------------------------------------------

class PluginSlot(QFrame):
def __init__(self, parent, pluginId):
QFrame.__init__(self, parent)

# -------------------------------------------------------------
# Internal stuff

self.fPluginId = pluginId
self.fPluginInfo = Carla.host.get_plugin_info(self.fPluginId) if Carla.host is not None else gFakePluginInfo

self.fPluginInfo['filename'] = charPtrToString(self.fPluginInfo['filename'])
self.fPluginInfo['name'] = charPtrToString(self.fPluginInfo['name'])
self.fPluginInfo['label'] = charPtrToString(self.fPluginInfo['label'])
self.fPluginInfo['maker'] = charPtrToString(self.fPluginInfo['maker'])
self.fPluginInfo['copyright'] = charPtrToString(self.fPluginInfo['copyright'])
self.fPluginInfo['iconName'] = charPtrToString(self.fPluginInfo['iconName'])

self.fParameterIconTimer = ICON_STATE_NULL

if not Carla.isLocal:
self.fPluginInfo['hints'] &= ~PLUGIN_HAS_CUSTOM_UI

if Carla.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK or Carla.host is None:
self.fPeaksInputCount = 2
self.fPeaksOutputCount = 2

else:
audioCountInfo = Carla.host.get_audio_port_count_info(self.fPluginId)

self.fPeaksInputCount = int(audioCountInfo['ins'])
self.fPeaksOutputCount = int(audioCountInfo['outs'])

if self.fPeaksInputCount > 2:
self.fPeaksInputCount = 2

if self.fPeaksOutputCount > 2:
self.fPeaksOutputCount = 2

# -------------------------------------------------------------
# Set-up GUI

self.fEditDialog = PluginEdit(self, self.fPluginId)
self.fEditDialog.hide()

#------------------------------------------------------------------

def getFixedHeight(self):
return 32

def getHints(self):
return self.fPluginInfo['hints']

#------------------------------------------------------------------

def recheckPluginHints(self, hints):
self.fPluginInfo['hints'] = hints

def setId(self, idx):
self.fPluginId = idx
self.fEditDialog.setId(idx)

def setName(self, name):
self.fEditDialog.setName(name)

#------------------------------------------------------------------

def setActive(self, active, sendGui=False, sendCallback=True):
if sendGui: self.activeChanged(active)
if sendCallback: Carla.host.set_active(self.fPluginId, active)

if active:
self.fEditDialog.clearNotes()
self.midiActivityChanged(False)

# called from rack, checks if param is possible first
def setInternalParameter(self, parameterId, value):
if parameterId <= PARAMETER_MAX or parameterId >= PARAMETER_NULL:
return

if parameterId == PARAMETER_ACTIVE:
return self.setActive(bool(value), True, True)

elif parameterId == PARAMETER_DRYWET:
if (self.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET) == 0: return
Carla.host.set_drywet(self.fPluginId, value)

elif parameterId == PARAMETER_VOLUME:
if (self.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME) == 0: return
Carla.host.set_volume(self.fPluginId, value)

elif parameterId == PARAMETER_BALANCE_LEFT:
if (self.fPluginInfo['hints'] & PLUGIN_CAN_BALANCE) == 0: return
Carla.host.set_balance_left(self.fPluginId, value)

elif parameterId == PARAMETER_BALANCE_RIGHT:
if (self.fPluginInfo['hints'] & PLUGIN_CAN_BALANCE) == 0: return
Carla.host.set_balance_right(self.fPluginId, value)

elif parameterId == PARAMETER_PANNING:
if (self.fPluginInfo['hints'] & PLUGIN_CAN_PANNING) == 0: return
Carla.host.set_panning(self.fPluginId, value)

elif parameterId == PARAMETER_CTRL_CHANNEL:
Carla.host.set_ctrl_channel(self.fPluginId, value)

self.fEditDialog.setParameterValue(parameterId, value)

#------------------------------------------------------------------

def setParameterValue(self, parameterId, value):
self.fParameterIconTimer = ICON_STATE_ON

if parameterId == PARAMETER_ACTIVE:
return self.setActive(bool(value), True, False)

self.fEditDialog.setParameterValue(parameterId, value)

def setParameterDefault(self, parameterId, value):
self.fEditDialog.setParameterDefault(parameterId, value)

def setParameterMidiControl(self, parameterId, control):
self.fEditDialog.setParameterMidiControl(parameterId, control)

def setParameterMidiChannel(self, parameterId, channel):
self.fEditDialog.setParameterMidiChannel(parameterId, channel)

#------------------------------------------------------------------

def setProgram(self, index):
self.fParameterIconTimer = ICON_STATE_ON
self.fEditDialog.setProgram(index)

def setMidiProgram(self, index):
self.fParameterIconTimer = ICON_STATE_ON
self.fEditDialog.setMidiProgram(index)

#------------------------------------------------------------------

def sendNoteOn(self, channel, note):
if self.fEditDialog.sendNoteOn(channel, note):
self.midiActivityChanged(True)

def sendNoteOff(self, channel, note):
if self.fEditDialog.sendNoteOff(channel, note):
self.midiActivityChanged(False)

#------------------------------------------------------------------

def activeChanged(self, onOff):
pass

def editDialogChanged(self, visible):
pass

def customUiStateChanged(self, state):
pass

def parameterActivityChanged(self, onOff):
pass

def midiActivityChanged(self, onOff):
pass

#------------------------------------------------------------------

def idleFast(self):
pass

def idleSlow(self):
if self.fParameterIconTimer == ICON_STATE_ON:
self.fParameterIconTimer = ICON_STATE_WAIT
self.parameterActivityChanged(True)
elif self.fParameterIconTimer == ICON_STATE_WAIT:
self.fParameterIconTimer = ICON_STATE_OFF
elif self.fParameterIconTimer == ICON_STATE_OFF:
self.fParameterIconTimer = ICON_STATE_NULL
self.parameterActivityChanged(False)

self.fEditDialog.idleSlow()

#------------------------------------------------------------------

@pyqtSlot(bool)
def slot_showCustomUi(self, show):
Carla.host.show_custom_ui(self.fPluginId, show)

@pyqtSlot(bool)
def slot_showEditDialog(self, show):
self.fEditDialog.setVisible(show)

# ------------------------------------------------------------------------------------------------------------

class PluginSlot_Default(PluginSlot):
def __init__(self, parent, pluginId):
PluginSlot.__init__(self, parent, pluginId)
self.ui = ui_carla_plugin.Ui_PluginWidget()
self.ui.setupUi(self)

# -------------------------------------------------------------
# Internal stuff

self.fLastGreenLedState = False
self.fLastBlueLedState = False

if self.palette().window().color().lightness() > 100:
# Light background
labelColor = "333"
isLight = True

self.fColorTop = QColor(60, 60, 60)
self.fColorBottom = QColor(47, 47, 47)
self.fColorSeprtr = QColor(70, 70, 70)

else:
# Dark background
labelColor = "BBB"
isLight = False

self.fColorTop = QColor(60, 60, 60)
self.fColorBottom = QColor(47, 47, 47)
self.fColorSeprtr = QColor(70, 70, 70)

# -------------------------------------------------------------
# Set-up GUI

self.setStyleSheet("""
QLabel#label_name {
color: #%s;
}""" % labelColor)

if isLight:
self.ui.b_enable.setPixmaps(":/bitmaps/button_off2.png", ":/bitmaps/button_on2.png", ":/bitmaps/button_off2.png")
self.ui.b_edit.setPixmaps(":/bitmaps/button_edit2.png", ":/bitmaps/button_edit_down2.png", ":/bitmaps/button_edit_hover2.png")

if self.fPluginInfo['iconName'] == "distrho":
self.ui.b_gui.setPixmaps(":/bitmaps/button_distrho2.png", ":/bitmaps/button_distrho_down2.png", ":/bitmaps/button_distrho_hover2.png")
elif self.fPluginInfo['iconName'] == "file":
self.ui.b_gui.setPixmaps(":/bitmaps/button_file2.png", ":/bitmaps/button_file_down2.png", ":/bitmaps/button_file_hover2.png")
else:
self.ui.b_gui.setPixmaps(":/bitmaps/button_gui2.png", ":/bitmaps/button_gui_down2.png", ":/bitmaps/button_gui_hover2.png")
else:
self.ui.b_enable.setPixmaps(":/bitmaps/button_off.png", ":/bitmaps/button_on.png", ":/bitmaps/button_off.png")
self.ui.b_edit.setPixmaps(":/bitmaps/button_edit.png", ":/bitmaps/button_edit_down.png", ":/bitmaps/button_edit_hover.png")

if self.fPluginInfo['iconName'] == "distrho":
self.ui.b_gui.setPixmaps(":/bitmaps/button_distrho.png", ":/bitmaps/button_distrho_down.png", ":/bitmaps/button_distrho_hover.png")
elif self.fPluginInfo['iconName'] == "file":
self.ui.b_gui.setPixmaps(":/bitmaps/button_file.png", ":/bitmaps/button_file_down.png", ":/bitmaps/button_file_hover.png")
else:
self.ui.b_gui.setPixmaps(":/bitmaps/button_gui.png", ":/bitmaps/button_gui_down.png", ":/bitmaps/button_gui_hover.png")

self.ui.b_gui.setEnabled((self.fPluginInfo['hints'] & PLUGIN_HAS_CUSTOM_UI) != 0)

self.ui.led_control.setColor(self.ui.led_control.YELLOW)
self.ui.led_control.setEnabled(False)

self.ui.led_midi.setColor(self.ui.led_midi.RED)
self.ui.led_midi.setEnabled(False)

self.ui.led_audio_in.setColor(self.ui.led_audio_in.GREEN)
self.ui.led_audio_in.setEnabled(False)

self.ui.led_audio_out.setColor(self.ui.led_audio_out.BLUE)
self.ui.led_audio_out.setEnabled(False)

self.ui.peak_in.setColor(self.ui.peak_in.GREEN)
self.ui.peak_in.setChannels(self.fPeaksInputCount)
self.ui.peak_in.setOrientation(self.ui.peak_in.HORIZONTAL)

self.ui.peak_out.setColor(self.ui.peak_in.BLUE)
self.ui.peak_out.setChannels(self.fPeaksOutputCount)
self.ui.peak_out.setOrientation(self.ui.peak_out.HORIZONTAL)

self.ui.label_name.setText(self.fPluginInfo['name'])

self.setFixedHeight(32)

# -------------------------------------------------------------
# Set-up connections

self.ui.b_enable.clicked.connect(self.slot_enableClicked)
self.ui.b_gui.clicked.connect(self.slot_showCustomUi)
self.ui.b_edit.clicked.connect(self.slot_showEditDialog)

self.customContextMenuRequested.connect(self.slot_showCustomMenu)

#------------------------------------------------------------------

def getFixedHeight(self):
return 32

#------------------------------------------------------------------

def recheckPluginHints(self, hints):
self.ui.b_gui.setEnabled(hints & PLUGIN_HAS_CUSTOM_UI)
PluginSlot.recheckPluginHints(self, hints)

def setName(self, name):
self.ui.label_name.setText(name)
PluginSlot.setName(self, name)

#------------------------------------------------------------------

def activeChanged(self, onOff):
self.ui.b_enable.setChecked(onOff)

def editDialogChanged(self, visible):
self.ui.b_edit.blockSignals(True)
self.ui.b_edit.setChecked(visible)
self.ui.b_edit.blockSignals(False)

def customUiStateChanged(self, state):
self.ui.b_gui.blockSignals(True)
if state == 0:
self.ui.b_gui.setChecked(False)
self.ui.b_gui.setEnabled(True)
elif state == 1:
self.ui.b_gui.setChecked(True)
self.ui.b_gui.setEnabled(True)
elif state == -1:
self.ui.b_gui.setChecked(False)
self.ui.b_gui.setEnabled(False)
self.ui.b_gui.blockSignals(False)

def parameterActivityChanged(self, onOff):
self.ui.led_control.setChecked(onOff)

def midiActivityChanged(self, onOff):
self.ui.led_midi.setChecked(onOff)

#------------------------------------------------------------------

def idleFast(self):
# Input peaks
if self.fPeaksInputCount > 0:
if self.fPeaksInputCount > 1:
peak1 = Carla.host.get_input_peak_value(self.fPluginId, 1)
peak2 = Carla.host.get_input_peak_value(self.fPluginId, 2)
ledState = bool(peak1 != 0.0 or peak2 != 0.0)

self.ui.peak_in.displayMeter(1, peak1)
self.ui.peak_in.displayMeter(2, peak2)

else:
peak = Carla.host.get_input_peak_value(self.fPluginId, 1)
ledState = bool(peak != 0.0)

self.ui.peak_in.displayMeter(1, peak)

if self.fLastGreenLedState != ledState:
self.fLastGreenLedState = ledState
self.ui.led_audio_in.setChecked(ledState)

# Output peaks
if self.fPeaksOutputCount > 0:
if self.fPeaksOutputCount > 1:
peak1 = Carla.host.get_output_peak_value(self.fPluginId, 1)
peak2 = Carla.host.get_output_peak_value(self.fPluginId, 2)
ledState = bool(peak1 != 0.0 or peak2 != 0.0)

self.ui.peak_out.displayMeter(1, peak1)
self.ui.peak_out.displayMeter(2, peak2)

else:
peak = Carla.host.get_output_peak_value(self.fPluginId, 1)
ledState = bool(peak != 0.0)

self.ui.peak_out.displayMeter(1, peak)

if self.fLastBlueLedState != ledState:
self.fLastBlueLedState = ledState
self.ui.led_audio_out.setChecked(ledState)

#------------------------------------------------------------------

@pyqtSlot(bool)
def slot_enableClicked(self, yesNo):
self.setActive(yesNo, False, True)

@pyqtSlot()
def slot_showCustomMenu(self):
menu = QMenu(self)

actActive = menu.addAction(self.tr("Disable") if self.fIsEnabled else self.tr("Enable"))
menu.addSeparator()

actGui = menu.addAction(self.tr("Show GUI"))
actGui.setCheckable(True)
actGui.setChecked(self.ui.b_gui.isChecked())
actGui.setEnabled(self.ui.b_gui.isEnabled())

actEdit = menu.addAction(self.tr("Edit"))
actEdit.setCheckable(True)
actEdit.setChecked(self.ui.b_edit.isChecked())

menu.addSeparator()
actClone = menu.addAction(self.tr("Clone"))
actRename = menu.addAction(self.tr("Rename..."))
actRemove = menu.addAction(self.tr("Remove"))

actSel = menu.exec_(QCursor.pos())

if not actSel:
return

if actSel == actActive:
self.setActive(not self.ui.b_enable.isChecked(), True, True)
elif actSel == actGui:
self.ui.b_gui.click()
elif actSel == actEdit:
self.ui.b_edit.click()
elif actSel == actClone:
if not Carla.host.clone_plugin(self.fPluginId):
CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
Carla.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)

elif actSel == actRename:
oldName = self.fPluginInfo['name']
newNameTry = QInputDialog.getText(self, self.tr("Rename Plugin"), self.tr("New plugin name:"), QLineEdit.Normal, oldName)

if not (newNameTry[1] and newNameTry[0] and oldName != newNameTry[0]):
return

newName = newNameTry[0]

if Carla.host is None or Carla.host.rename_plugin(self.fPluginId, newName):
self.setName(newName)
else:
CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
Carla.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)

elif actSel == actRemove:
if not Carla.host.remove_plugin(self.fPluginId):
CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
Carla.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)

#------------------------------------------------------------------

def paintEvent(self, event):
painter = QPainter(self)
painter.save()

areaX = self.ui.area_right.x()+7

painter.setPen(self.fColorSeprtr.lighter(110))
painter.setBrush(self.fColorBottom)
painter.setRenderHint(QPainter.Antialiasing, True)

# name -> leds arc
path = QPainterPath()
path.moveTo(areaX-20, self.height()-4)
path.cubicTo(areaX, self.height()-5, areaX-20, 4.75, areaX, 4.75)
path.lineTo(areaX, self.height()-5)
painter.drawPath(path)

painter.setPen(self.fColorSeprtr)
painter.setRenderHint(QPainter.Antialiasing, False)

# separator lines
painter.drawLine(0, self.height()-5, areaX-20, self.height()-5)
painter.drawLine(areaX, 4, self.width(), 4)

painter.setPen(self.fColorBottom)
painter.setBrush(self.fColorBottom)

# top, bottom and left lines
painter.drawLine(0, 0, self.width(), 0)
painter.drawRect(0, self.height()-4, areaX, 4)
painter.drawRoundedRect(areaX-20, self.height()-5, areaX, 5, 22, 22)
painter.drawLine(0, 0, 0, self.height())

# fill the rest
painter.drawRect(areaX-1, 5, self.width(), self.height())

# bottom 1px line
painter.setPen(self.fColorSeprtr)
painter.drawLine(0, self.height()-1, self.width(), self.height()-1)

painter.restore()
PluginSlot.paintEvent(self, event)

# ------------------------------------------------------------------------------------------------------------

def createPluginSlot(pluginId, parent):
pluginInfo = Carla.host.get_plugin_info(pluginId)
pluginInfo['label'] = charPtrToString(pluginInfo['label'])
pluginInfo['maker'] = charPtrToString(pluginInfo['maker'])
pluginInfo['iconName'] = charPtrToString(pluginInfo['iconName'])

return PluginSlot_Default(parent, pluginId)

# ------------------------------------------------------------------------------------------------------------

+ 7
- 411
source/carla_widgets.py View File

@@ -29,7 +29,6 @@ from PyQt4.QtGui import QDialog, QFrame, QInputDialog, QLineEdit, QMenu, QVBoxLa
import ui_carla_about
import ui_carla_edit
import ui_carla_parameter
import ui_carla_plugin

from carla_shared import *

@@ -386,7 +385,8 @@ class PluginEdit(QDialog):
self.fCurrentProgram = -1
self.fCurrentMidiProgram = -1
self.fCurrentStateFilename = None
self.fControlChannel = 0
self.fControlChannel = 0
self.fFirstInit = True
self.fScrollAreaSetup = False

self.fParameterCount = 0
@@ -529,6 +529,8 @@ class PluginEdit(QDialog):
if not self.ui.scrollArea.isEnabled():
self.resize(self.width(), self.height()-self.ui.scrollArea.height())

self.fFirstInit = False

#------------------------------------------------------------------

def reloadInfo(self):
@@ -661,7 +663,7 @@ class PluginEdit(QDialog):
self.ui.scrollArea.setVisible(showKeyboard)

# Force-Update parent for new hints
if self.fRealParent:
if self.fRealParent and not self.fFirstInit:
self.fRealParent.recheckPluginHints(pluginHints)

def reloadParameters(self):
@@ -893,6 +895,7 @@ class PluginEdit(QDialog):
self.fPluginId = idx

def setName(self, name):
self.fPluginInfo['name'] = name
self.ui.label_plugin.setText("\n%s\n" % name)
self.setWindowTitle(name)

@@ -1214,7 +1217,7 @@ class PluginEdit(QDialog):
@pyqtSlot()
def slot_finished(self):
if self.fRealParent is not None:
self.fRealParent.editClosed()
self.fRealParent.editDialogChanged(False)

#------------------------------------------------------------------

@@ -1394,412 +1397,6 @@ class PluginEdit(QDialog):
QDialog.done(self, r)
self.close()

# ------------------------------------------------------------------------------------------------------------
# Plugin Widget

class PluginWidget(QFrame):
def __init__(self, parent, pluginId):
QFrame.__init__(self, parent)
self.ui = ui_carla_plugin.Ui_PluginWidget()
self.ui.setupUi(self)

# -------------------------------------------------------------
# Internal stuff

self.fPluginId = pluginId
self.fPluginInfo = Carla.host.get_plugin_info(self.fPluginId) if Carla.host is not None else gFakePluginInfo

self.fPluginInfo['filename'] = charPtrToString(self.fPluginInfo['filename'])
self.fPluginInfo['name'] = charPtrToString(self.fPluginInfo['name'])
self.fPluginInfo['label'] = charPtrToString(self.fPluginInfo['label'])
self.fPluginInfo['maker'] = charPtrToString(self.fPluginInfo['maker'])
self.fPluginInfo['copyright'] = charPtrToString(self.fPluginInfo['copyright'])
self.fPluginInfo['iconName'] = charPtrToString(self.fPluginInfo['iconName'])

if not Carla.isLocal:
self.fPluginInfo['hints'] &= ~PLUGIN_HAS_CUSTOM_UI

self.fLastGreenLedState = False
self.fLastBlueLedState = False

self.fParameterIconTimer = ICON_STATE_NULL

if Carla.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK or Carla.host is None:
self.fPeaksInputCount = 2
self.fPeaksOutputCount = 2

else:
audioCountInfo = Carla.host.get_audio_port_count_info(self.fPluginId)

self.fPeaksInputCount = int(audioCountInfo['ins'])
self.fPeaksOutputCount = int(audioCountInfo['outs'])

if self.fPeaksInputCount > 2:
self.fPeaksInputCount = 2

if self.fPeaksOutputCount > 2:
self.fPeaksOutputCount = 2

if self.palette().window().color().lightness() > 100:
# Light background
labelColor = "333"
isLight = True

self.fColorTop = QColor(60, 60, 60)
self.fColorBottom = QColor(47, 47, 47)
self.fColorSeprtr = QColor(70, 70, 70)

else:
# Dark background
labelColor = "BBB"
isLight = False

self.fColorTop = QColor(60, 60, 60)
self.fColorBottom = QColor(47, 47, 47)
self.fColorSeprtr = QColor(70, 70, 70)

# -------------------------------------------------------------
# Set-up GUI

self.setStyleSheet("""
QLabel#label_name {
color: #%s;
}""" % labelColor)

if isLight:
self.ui.b_enable.setPixmaps(":/bitmaps/button_off2.png", ":/bitmaps/button_on2.png", ":/bitmaps/button_off2.png")
self.ui.b_edit.setPixmaps(":/bitmaps/button_edit2.png", ":/bitmaps/button_edit_down2.png", ":/bitmaps/button_edit_hover2.png")

if self.fPluginInfo['iconName'] == "distrho":
self.ui.b_gui.setPixmaps(":/bitmaps/button_distrho2.png", ":/bitmaps/button_distrho_down2.png", ":/bitmaps/button_distrho_hover2.png")
elif self.fPluginInfo['iconName'] == "file":
self.ui.b_gui.setPixmaps(":/bitmaps/button_file2.png", ":/bitmaps/button_file_down2.png", ":/bitmaps/button_file_hover2.png")
else:
self.ui.b_gui.setPixmaps(":/bitmaps/button_gui2.png", ":/bitmaps/button_gui_down2.png", ":/bitmaps/button_gui_hover2.png")
else:
self.ui.b_enable.setPixmaps(":/bitmaps/button_off.png", ":/bitmaps/button_on.png", ":/bitmaps/button_off.png")
self.ui.b_edit.setPixmaps(":/bitmaps/button_edit.png", ":/bitmaps/button_edit_down.png", ":/bitmaps/button_edit_hover.png")

if self.fPluginInfo['iconName'] == "distrho":
self.ui.b_gui.setPixmaps(":/bitmaps/button_distrho.png", ":/bitmaps/button_distrho_down.png", ":/bitmaps/button_distrho_hover.png")
elif self.fPluginInfo['iconName'] == "file":
self.ui.b_gui.setPixmaps(":/bitmaps/button_file.png", ":/bitmaps/button_file_down.png", ":/bitmaps/button_file_hover.png")
else:
self.ui.b_gui.setPixmaps(":/bitmaps/button_gui.png", ":/bitmaps/button_gui_down.png", ":/bitmaps/button_gui_hover.png")

self.ui.led_control.setColor(self.ui.led_control.YELLOW)
self.ui.led_control.setEnabled(False)

self.ui.led_midi.setColor(self.ui.led_midi.RED)
self.ui.led_midi.setEnabled(False)

self.ui.led_audio_in.setColor(self.ui.led_audio_in.GREEN)
self.ui.led_audio_in.setEnabled(False)

self.ui.led_audio_out.setColor(self.ui.led_audio_out.BLUE)
self.ui.led_audio_out.setEnabled(False)

self.ui.peak_in.setColor(self.ui.peak_in.GREEN)
self.ui.peak_in.setChannels(self.fPeaksInputCount)
self.ui.peak_in.setOrientation(self.ui.peak_in.HORIZONTAL)

self.ui.peak_out.setColor(self.ui.peak_in.BLUE)
self.ui.peak_out.setChannels(self.fPeaksOutputCount)
self.ui.peak_out.setOrientation(self.ui.peak_out.HORIZONTAL)

self.ui.label_name.setText(self.fPluginInfo['name'])

self.ui.edit_dialog = PluginEdit(self, self.fPluginId)
self.ui.edit_dialog.hide()

self.setFixedHeight(32)

# -------------------------------------------------------------
# Set-up connections

self.customContextMenuRequested.connect(self.slot_showCustomMenu)
self.ui.b_enable.clicked.connect(self.slot_enableClicked)
self.ui.b_gui.clicked.connect(self.slot_guiClicked)
self.ui.b_edit.clicked.connect(self.slot_editClicked)

#------------------------------------------------------------------

def idleFast(self):
# Input peaks
if self.fPeaksInputCount > 0:
if self.fPeaksInputCount > 1:
peak1 = Carla.host.get_input_peak_value(self.fPluginId, 1)
peak2 = Carla.host.get_input_peak_value(self.fPluginId, 2)
ledState = bool(peak1 != 0.0 or peak2 != 0.0)

self.ui.peak_in.displayMeter(1, peak1)
self.ui.peak_in.displayMeter(2, peak2)

else:
peak = Carla.host.get_input_peak_value(self.fPluginId, 1)
ledState = bool(peak != 0.0)

self.ui.peak_in.displayMeter(1, peak)

if self.fLastGreenLedState != ledState:
self.fLastGreenLedState = ledState
self.ui.led_audio_in.setChecked(ledState)

# Output peaks
if self.fPeaksOutputCount > 0:
if self.fPeaksOutputCount > 1:
peak1 = Carla.host.get_output_peak_value(self.fPluginId, 1)
peak2 = Carla.host.get_output_peak_value(self.fPluginId, 2)
ledState = bool(peak1 != 0.0 or peak2 != 0.0)

self.ui.peak_out.displayMeter(1, peak1)
self.ui.peak_out.displayMeter(2, peak2)

else:
peak = Carla.host.get_output_peak_value(self.fPluginId, 1)
ledState = bool(peak != 0.0)

self.ui.peak_out.displayMeter(1, peak)

if self.fLastBlueLedState != ledState:
self.fLastBlueLedState = ledState
self.ui.led_audio_out.setChecked(ledState)

def idleSlow(self):
# Parameter Activity LED
if self.fParameterIconTimer == ICON_STATE_ON:
self.fParameterIconTimer = ICON_STATE_WAIT
self.ui.led_control.setChecked(True)
elif self.fParameterIconTimer == ICON_STATE_WAIT:
self.fParameterIconTimer = ICON_STATE_OFF
elif self.fParameterIconTimer == ICON_STATE_OFF:
self.fParameterIconTimer = ICON_STATE_NULL
self.ui.led_control.setChecked(False)

# Update edit dialog
self.ui.edit_dialog.idleSlow()

#------------------------------------------------------------------

def editClosed(self):
self.ui.b_edit.setChecked(False)

def recheckPluginHints(self, hints):
self.fPluginInfo['hints'] = hints
self.ui.b_gui.setEnabled(hints & PLUGIN_HAS_CUSTOM_UI)

#------------------------------------------------------------------

def getHints(self):
return self.fPluginInfo['hints']

def setId(self, idx):
self.fPluginId = idx
self.ui.edit_dialog.setId(idx)

def setName(self, name):
self.ui.label_name.setText(name)
self.ui.edit_dialog.setName(name)

#------------------------------------------------------------------

def setActive(self, active, sendGui=False, sendCallback=True):
if sendGui: self.ui.b_enable.setChecked(active)
if sendCallback: Carla.host.set_active(self.fPluginId, active)

if active:
self.ui.edit_dialog.clearNotes()
self.ui.led_midi.setChecked(False)

# called from rack, checks if param is possible first
def setInternalParameter(self, parameterId, value):
if parameterId <= PARAMETER_MAX or parameterId >= PARAMETER_NULL:
return

if parameterId == PARAMETER_ACTIVE:
return self.setActive(bool(value), True, True)

elif parameterId == PARAMETER_DRYWET:
if (self.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET) == 0: return
Carla.host.set_drywet(self.fPluginId, value)

elif parameterId == PARAMETER_VOLUME:
if (self.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME) == 0: return
Carla.host.set_volume(self.fPluginId, value)

elif parameterId == PARAMETER_BALANCE_LEFT:
if (self.fPluginInfo['hints'] & PLUGIN_CAN_BALANCE) == 0: return
Carla.host.set_balance_left(self.fPluginId, value)

elif parameterId == PARAMETER_BALANCE_RIGHT:
if (self.fPluginInfo['hints'] & PLUGIN_CAN_BALANCE) == 0: return
Carla.host.set_balance_right(self.fPluginId, value)

elif parameterId == PARAMETER_PANNING:
if (self.fPluginInfo['hints'] & PLUGIN_CAN_PANNING) == 0: return
Carla.host.set_panning(self.fPluginId, value)

elif parameterId == PARAMETER_CTRL_CHANNEL:
Carla.host.set_ctrl_channel(self.fPluginId, value)

self.ui.edit_dialog.setParameterValue(parameterId, value)

def setParameterValue(self, parameterId, value):
self.fParameterIconTimer = ICON_STATE_ON

if parameterId == PARAMETER_ACTIVE:
return self.setActive(bool(value), True, False)

self.ui.edit_dialog.setParameterValue(parameterId, value)

def setParameterDefault(self, parameterId, value):
self.ui.edit_dialog.setParameterDefault(parameterId, value)

def setParameterMidiControl(self, parameterId, control):
self.ui.edit_dialog.setParameterMidiControl(parameterId, control)

def setParameterMidiChannel(self, parameterId, channel):
self.ui.edit_dialog.setParameterMidiChannel(parameterId, channel)

def setProgram(self, index):
self.fParameterIconTimer = ICON_STATE_ON
self.ui.edit_dialog.setProgram(index)

def setMidiProgram(self, index):
self.fParameterIconTimer = ICON_STATE_ON
self.ui.edit_dialog.setMidiProgram(index)

#------------------------------------------------------------------

def sendNoteOn(self, channel, note):
if self.ui.edit_dialog.sendNoteOn(channel, note):
self.ui.led_midi.setChecked(True)

def sendNoteOff(self, channel, note):
if self.ui.edit_dialog.sendNoteOff(channel, note):
self.ui.led_midi.setChecked(False)

#------------------------------------------------------------------

@pyqtSlot()
def slot_showCustomMenu(self):
menu = QMenu(self)

actActive = menu.addAction(self.tr("Disable") if self.ui.b_enable.isChecked() else self.tr("Enable"))
menu.addSeparator()

actGui = menu.addAction(self.tr("Show GUI"))
actGui.setCheckable(True)
actGui.setChecked(self.ui.b_gui.isChecked())
actGui.setEnabled(self.ui.b_gui.isEnabled())

actEdit = menu.addAction(self.tr("Edit"))
actEdit.setCheckable(True)
actEdit.setChecked(self.ui.b_edit.isChecked())

menu.addSeparator()
actClone = menu.addAction(self.tr("Clone"))
actRename = menu.addAction(self.tr("Rename..."))
actRemove = menu.addAction(self.tr("Remove"))

actSel = menu.exec_(QCursor.pos())

if not actSel:
return

if actSel == actActive:
self.setActive(not self.ui.b_enable.isChecked(), True, True)
elif actSel == actGui:
self.ui.b_gui.click()
elif actSel == actEdit:
self.ui.b_edit.click()
elif actSel == actClone:
if not Carla.host.clone_plugin(self.fPluginId):
CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
Carla.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)

elif actSel == actRename:
oldName = self.fPluginInfo['name']
newNameTry = QInputDialog.getText(self, self.tr("Rename Plugin"), self.tr("New plugin name:"), QLineEdit.Normal, oldName)

if not (newNameTry[1] and newNameTry[0] and oldName != newNameTry[0]):
return

newName = newNameTry[0]

if Carla.host is None or Carla.host.rename_plugin(self.fPluginId, newName):
self.fPluginInfo['name'] = newName
self.ui.edit_dialog.fPluginInfo['name'] = newName
self.ui.edit_dialog.reloadInfo()
self.ui.label_name.setText(newName)
else:
CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
Carla.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)

elif actSel == actRemove:
if not Carla.host.remove_plugin(self.fPluginId):
CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
Carla.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)

#------------------------------------------------------------------

@pyqtSlot(bool)
def slot_enableClicked(self, yesNo):
self.setActive(yesNo, False, True)

@pyqtSlot(bool)
def slot_guiClicked(self, show):
Carla.host.show_custom_ui(self.fPluginId, show)

@pyqtSlot(bool)
def slot_editClicked(self, show):
self.ui.edit_dialog.setVisible(show)

#------------------------------------------------------------------

def paintEvent(self, event):
painter = QPainter(self)
painter.save()

areaX = self.ui.area_right.x()+7

painter.setPen(self.fColorSeprtr.lighter(110))
painter.setBrush(self.fColorBottom)
painter.setRenderHint(QPainter.Antialiasing, True)

# name -> leds arc
path = QPainterPath()
path.moveTo(areaX-20, self.height()-4)
path.cubicTo(areaX, self.height()-5, areaX-20, 4.75, areaX, 4.75)
path.lineTo(areaX, self.height()-5)
painter.drawPath(path)

painter.setPen(self.fColorSeprtr)
painter.setRenderHint(QPainter.Antialiasing, False)

# separator lines
painter.drawLine(0, self.height()-5, areaX-20, self.height()-5)
painter.drawLine(areaX, 4, self.width(), 4)

painter.setPen(self.fColorBottom)
painter.setBrush(self.fColorBottom)

# top, bottom and left lines
painter.drawLine(0, 0, self.width(), 0)
painter.drawRect(0, self.height()-4, areaX, 4)
painter.drawRoundedRect(areaX-20, self.height()-5, areaX, 5, 22, 22)
painter.drawLine(0, 0, 0, self.height())

# fill the rest
painter.drawRect(areaX-1, 5, self.width(), self.height())

# bottom 1px line
painter.setPen(self.fColorSeprtr)
painter.drawLine(0, self.height()-1, self.width(), self.height()-1)

painter.restore()
QFrame.paintEvent(self, event)

# ------------------------------------------------------------------------------------------------------------
# Main

@@ -1811,7 +1408,6 @@ if __name__ == '__main__':
#gui = CarlaAboutW(None)
#gui = PluginParameter(None, gFakeParamInfo, 0, 0)
gui = PluginEdit(None, 0)
#gui = PluginWidget(None, 0)
gui.show()

sys.exit(app.exec_())

Loading…
Cancel
Save