Browse Source

Continue rework

tags/1.9.5
falkTX 11 years ago
parent
commit
d12bc10779
6 changed files with 589 additions and 941 deletions
  1. +48
    -4
      resources/ui/carla_host.ui
  2. +1
    -3
      source/backend/CarlaStandalone.cpp
  3. +71
    -71
      source/carla
  4. +466
    -100
      source/carla_host.py
  5. +2
    -411
      source/carla_patchbay.py
  6. +1
    -352
      source/carla_rack.py

+ 48
- 4
resources/ui/carla_host.ui View File

@@ -24,30 +24,74 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="plugins">
<widget class="QWidget" name="rack">
<attribute name="title">
<string>Plugins</string>
<string>Rack</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="pad_left">
<property name="minimumSize">
<size>
<width>25</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listWidget"/>
<widget class="QListWidget" name="listWidget">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="pad_right">
<property name="minimumSize">
<size>
<width>25</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QScrollBar" name="verticalScrollBar">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="patchbay">


+ 1
- 3
source/backend/CarlaStandalone.cpp View File

@@ -134,9 +134,7 @@ public:
return;

const lo_address addr = lo_address_new_from_url(NSM_URL);

if (addr == nullptr)
return;
CARLA_SAFE_ASSERT_RETURN(addr != nullptr,);

const int proto = lo_address_get_protocol(addr);



+ 71
- 71
source/carla View File

@@ -165,121 +165,121 @@ class CarlaHostW(HostWindow):
# -------------------------------------------------------------
# Set-up container

self.fContainer = CarlaMultiW(self, host)
self.setupContainer(False)
#self.fContainer = CarlaMultiW(self, host)
#self.setupContainer(False)

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

self.fInfoText = ""
self.fInfoLabel = QLabel(self)
self.fInfoLabel.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
self.fInfoLabel.setText("Engine stopped")
#self.fInfoText = ""
#self.fInfoLabel = QLabel(self)
#self.fInfoLabel.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
#self.fInfoLabel.setText("Engine stopped")

self.fDockLocation = Qt.LeftDockWidgetArea
self.fDockFloating = 0
#self.fDockLocation = Qt.LeftDockWidgetArea
#self.fDockFloating = 0

if MACOS and False: # TODO: check if NOT using pro theme
self.fInfoLabel.hide()
self.setUnifiedTitleAndToolBarOnMac(True)
#if MACOS and False: # TODO: check if NOT using pro theme
#self.fInfoLabel.hide()
#self.setUnifiedTitleAndToolBarOnMac(True)

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

self.ui.act_settings_show_toolbar.triggered.connect(self.slot_toolbarShown)
self.ui.dockWidget.dockLocationChanged.connect(self.slot_dockLocationChanged)
self.ui.dockWidget.topLevelChanged.connect(self.slot_dockTopLevelChanged)
#self.ui.act_settings_show_toolbar.triggered.connect(self.slot_toolbarShown)
#self.ui.dockWidget.dockLocationChanged.connect(self.slot_dockLocationChanged)
#self.ui.dockWidget.topLevelChanged.connect(self.slot_dockTopLevelChanged)

self.ui.dockWidget.installEventFilter(self)
#self.ui.dockWidget.installEventFilter(self)

QTimer.singleShot(0, self.slot_initWidgets)
#QTimer.singleShot(0, self.slot_initWidgets)

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

def engineChanged(self):
self.fInfoText = "Engine running | SampleRate: %g | BufferSize: %i" % (self.host.get_sample_rate(), self.host.get_buffer_size())
self.fInfoLabel.setText("%s | %s" % (self.fInfoText, self.fTransportText))
#def engineChanged(self):
#self.fInfoText = "Engine running | SampleRate: %g | BufferSize: %i" % (self.host.get_sample_rate(), self.host.get_buffer_size())
#self.fInfoLabel.setText("%s | %s" % (self.fInfoText, self.fTransportText))

def engineStarted(self):
self.engineChanged()
#def engineStarted(self):
#self.engineChanged()

def engineStopped(self):
self.fInfoText = ""
self.fInfoLabel.setText("Engine stopped")
#def engineStopped(self):
#self.fInfoText = ""
#self.fInfoLabel.setText("Engine stopped")

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

def updateInfoLabelXandSize(self):
tabBar = self.fContainer.tabBar()
x = tabBar.width() + 20
width = self.fContainer.width() - tabBar.width() - 20
#def updateInfoLabelXandSize(self):
#tabBar = self.fContainer.tabBar()
#x = tabBar.width() + 20
#width = self.fContainer.width() - tabBar.width() - 20

if self.fDockLocation == Qt.LeftDockWidgetArea and self.fDockFloating <= 1:
x += self.ui.dockWidget.width()
#if self.fDockLocation == Qt.LeftDockWidgetArea and self.fDockFloating <= 1:
#x += self.ui.dockWidget.width()

self.fInfoLabel.move(x, self.fInfoLabel.y())
self.fInfoLabel.resize(width, self.fInfoLabel.height())
#self.fInfoLabel.move(x, self.fInfoLabel.y())
#self.fInfoLabel.resize(width, self.fInfoLabel.height())

if self.fDockFloating == 1:
self.fDockFloating = 2
#if self.fDockFloating == 1:
#self.fDockFloating = 2

def updateInfoLabelY(self):
tabBar = self.fContainer.tabBar()
y = tabBar.mapFromParent(self.ui.centralwidget.pos()).y()
#def updateInfoLabelY(self):
#tabBar = self.fContainer.tabBar()
#y = tabBar.mapFromParent(self.ui.centralwidget.pos()).y()

if not self.ui.toolBar.isVisible():
y -= self.ui.toolBar.height()
#if not self.ui.toolBar.isVisible():
#y -= self.ui.toolBar.height()

self.fInfoLabel.move(self.fInfoLabel.x(), y)
#self.fInfoLabel.move(self.fInfoLabel.x(), y)

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

@pyqtSlot()
def slot_initWidgets(self):
tabBar = self.fContainer.tabBar()
x = tabBar.width() + 20
y = tabBar.mapFromParent(self.ui.centralwidget.pos()).y()
#@pyqtSlot()
#def slot_initWidgets(self):
#tabBar = self.fContainer.tabBar()
#x = tabBar.width() + 20
#y = tabBar.mapFromParent(self.ui.centralwidget.pos()).y()

if self.fDockLocation == Qt.LeftDockWidgetArea and self.fDockFloating <= 1:
x += self.ui.tabUtils.width()
#if self.fDockLocation == Qt.LeftDockWidgetArea and self.fDockFloating <= 1:
#x += self.ui.tabUtils.width()

self.fInfoLabel.move(x, y)
self.fInfoLabel.resize(self.fContainer.width()-tabBar.width()-20, tabBar.height())
#self.fInfoLabel.move(x, y)
#self.fInfoLabel.resize(self.fContainer.width()-tabBar.width()-20, tabBar.height())

@pyqtSlot(bool)
def slot_dockTopLevelChanged(self, top):
self.fDockFloating = 1 if top else 0
self.updateInfoLabelXandSize()
#@pyqtSlot(bool)
#def slot_dockTopLevelChanged(self, top):
#self.fDockFloating = 1 if top else 0
#self.updateInfoLabelXandSize()

@pyqtSlot(Qt.DockWidgetArea)
def slot_dockLocationChanged(self, area):
self.fDockLocation = area
self.updateInfoLabelXandSize()
#@pyqtSlot(Qt.DockWidgetArea)
#def slot_dockLocationChanged(self, area):
#self.fDockLocation = area
#self.updateInfoLabelXandSize()

@pyqtSlot()
def slot_toolbarShown(self):
self.updateInfoLabelY()
#@pyqtSlot()
#def slot_toolbarShown(self):
#self.updateInfoLabelY()

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

def eventFilter(self, obj, event):
if obj == self.ui.dockWidget and event.type() == QEvent.Resize:
self.updateInfoLabelXandSize()
return HostWindow.eventFilter(self, obj, event)
#def eventFilter(self, obj, event):
#if obj == self.ui.dockWidget and event.type() == QEvent.Resize:
#self.updateInfoLabelXandSize()
#return HostWindow.eventFilter(self, obj, event)

#def closeEvent(self, event):
#HostWindow.closeEvent(self, event)
## needed if using separate patchbay window
#QApplication.instance().quit()

def resizeEvent(self, event):
HostWindow.resizeEvent(self, event)
self.updateInfoLabelXandSize()
#def resizeEvent(self, event):
#HostWindow.resizeEvent(self, event)
#self.updateInfoLabelXandSize()

def timerEvent(self, event):
HostWindow.timerEvent(self, event)
#def timerEvent(self, event):
#HostWindow.timerEvent(self, event)

if event.timerId() == self.fIdleTimerFast:
self.fInfoLabel.setText("%s | %s" % (self.fInfoText, self.fTransportText))
#if event.timerId() == self.fIdleTimerFast:
#self.fInfoLabel.setText("%s | %s" % (self.fInfoText, self.fTransportText))

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


+ 466
- 100
source/carla_host.py View File

@@ -63,45 +63,11 @@ except:
LADISH_APP_NAME = os.getenv("LADISH_APP_NAME")
NSM_URL = os.getenv("NSM_URL")

# ------------------------------------------------------------------------------------------------------------
# Dummy widget

class HostWidgetMeta(object):
#class HostWidgetMeta(metaclass=ABCMeta):

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

def removeAllPlugins(self):
raise NotImplementedError

def engineStarted(self):
raise NotImplementedError

def engineStopped(self):
raise NotImplementedError

def idleFast(self):
raise NotImplementedError

def idleSlow(self):
raise NotImplementedError

def projectLoadingStarted(self):
raise NotImplementedError

def projectLoadingFinished(self):
raise NotImplementedError

def saveSettings(self, settings):
raise NotImplementedError

def showEditDialog(self, pluginId):
raise NotImplementedError

# ------------------------------------------------------------------------------------------------------------
# Host Window

class HostWindow(QMainWindow):
class HostWindow(QMainWindow, PluginEditParentMeta):
#class HostWindow(QMainWindow, PluginEditParentMeta, metaclass=PyQtMetaClass):
# signals
SIGTERM = pyqtSignal()
SIGUSR1 = pyqtSignal()
@@ -119,24 +85,20 @@ class HostWindow(QMainWindow):
# kdevelop likes this :)
host = CarlaHostMeta()
self.host = host
self.fContainer = HostWidgetMeta(self, host)

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

self.fSampleRate = 0.0

self.fIdleTimerFast = 0
self.fIdleTimerSlow = 0

self.fLadspaRdfNeedsUpdate = True
self.fLadspaRdfList = []

self.fLastTransportFrame = 0
self.fLastTransportState = False
self.fTransportText = ""
self.fPluginCount = 0
self.fPluginList = []

self.fProjectFilename = ""
self.fProjectFilename = ""
self.fIsProjectLoading = False

# first attempt of auto-start engine doesn't show an error
@@ -158,10 +120,17 @@ class HostWindow(QMainWindow):
self.fClientName = "Carla"
self.fSessionManagerName = ""

# ----------------------------------------------------------------------------------------------------
# Internal stuff (rack)

self.fCurrentRow = -1
self.fLastSelectedItem = None

# ----------------------------------------------------------------------------------------------------
# Internal stuff (patchbay)

self.fMovingViaMiniCanvas = False
self.fPeaksCleared = True
self.fPluginCount = 0
self.fPluginList = []

self.fExternalPatchbay = False
self.fSelectedPlugins = []
@@ -169,6 +138,14 @@ class HostWindow(QMainWindow):
self.fCanvasWidth = 0
self.fCanvasHeight = 0

# ----------------------------------------------------------------------------------------------------
# Internal stuff (transport, TODO remove)

self.fSampleRate = 0.0
self.fLastTransportFrame = 0
self.fLastTransportState = False
self.fTransportText = ""

# ----------------------------------------------------------------------------------------------------
# Set up GUI (engine stopped)

@@ -198,6 +175,25 @@ class HostWindow(QMainWindow):

self.setTransportMenuEnabled(False)

if not withCanvas:
self.ui.act_canvas_show_internal.setEnabled(False)
self.ui.act_canvas_show_external.setEnabled(False)
self.ui.act_canvas_arrange.setVisible(False)
self.ui.act_canvas_print.setVisible(False)
self.ui.act_canvas_refresh.setVisible(False)
self.ui.act_canvas_save_image.setVisible(False)
self.ui.act_canvas_zoom_100.setVisible(False)
self.ui.act_canvas_zoom_fit.setVisible(False)
self.ui.act_canvas_zoom_in.setVisible(False)
self.ui.act_canvas_zoom_out.setVisible(False)
self.ui.act_settings_show_meters.setVisible(False)
self.ui.act_settings_show_keyboard.setVisible(False)
self.ui.menu_Canvas.setEnabled(False)
self.ui.menu_Canvas.setVisible(False)
self.ui.menu_Canvas_Zoom.setEnabled(False)
self.ui.menu_Canvas_Zoom.setVisible(False)
self.ui.miniCanvasPreview.hide()

# ----------------------------------------------------------------------------------------------------
# Set up GUI (disk)

@@ -215,6 +211,33 @@ class HostWindow(QMainWindow):
# ----------------------------------------------------------------------------------------------------
# Set up GUI (plugins)

sb = self.ui.rack.verticalScrollBar()
self.ui.rackScrollBar = QScrollBar(Qt.Vertical, self)
self.ui.rackScrollBar.setMinimum(sb.minimum())
self.ui.rackScrollBar.setMaximum(sb.maximum())
self.ui.rackScrollBar.setValue(sb.value())

sb.rangeChanged.connect(self.ui.rackScrollBar.setRange)
sb.valueChanged.connect(self.ui.rackScrollBar.setValue)
self.ui.rackScrollBar.rangeChanged.connect(sb.setRange)
self.ui.rackScrollBar.valueChanged.connect(sb.setValue)

self.ui.rack.currentRowChanged.connect(self.slot_currentRowChanged)

self.ui.rack.setStyleSheet("""
QLabel#pad_left {
background-image: url(:/bitmaps/rack_padding_left.png);
background-repeat: repeat-y;
}
QLabel#pad_right {
background-image: url(:/bitmaps/rack_padding_right.png);
background-repeat: repeat-y;
}
CarlaRackList#CarlaRackList {
background-color: black;
}
""")

# ----------------------------------------------------------------------------------------------------
# Set up GUI (patchbay)

@@ -284,6 +307,27 @@ class HostWindow(QMainWindow):
self.ui.act_plugin_add2.triggered.connect(self.slot_pluginAdd)
self.ui.act_plugin_remove_all.triggered.connect(self.slot_pluginRemoveAll)

self.ui.act_plugins_enable.triggered.connect(self.slot_pluginsEnable)
self.ui.act_plugins_disable.triggered.connect(self.slot_pluginsDisable)
self.ui.act_plugins_volume100.triggered.connect(self.slot_pluginsVolume100)
self.ui.act_plugins_mute.triggered.connect(self.slot_pluginsMute)
self.ui.act_plugins_wet100.triggered.connect(self.slot_pluginsWet100)
self.ui.act_plugins_bypass.triggered.connect(self.slot_pluginsBypass)
self.ui.act_plugins_center.triggered.connect(self.slot_pluginsCenter)
self.ui.act_plugins_panic.triggered.connect(self.slot_pluginsDisable)

self.ui.act_canvas_show_internal.triggered.connect(self.slot_canvasShowInternal)
self.ui.act_canvas_show_external.triggered.connect(self.slot_canvasShowExternal)
self.ui.act_canvas_arrange.setEnabled(False) # TODO, later
self.ui.act_canvas_arrange.triggered.connect(self.slot_canvasArrange)
self.ui.act_canvas_refresh.triggered.connect(self.slot_canvasRefresh)
self.ui.act_canvas_zoom_fit.triggered.connect(self.slot_canvasZoomFit)
self.ui.act_canvas_zoom_in.triggered.connect(self.slot_canvasZoomIn)
self.ui.act_canvas_zoom_out.triggered.connect(self.slot_canvasZoomOut)
self.ui.act_canvas_zoom_100.triggered.connect(self.slot_canvasZoomReset)
self.ui.act_canvas_print.triggered.connect(self.slot_canvasPrint)
self.ui.act_canvas_save_image.triggered.connect(self.slot_canvasSaveImage)

self.ui.act_transport_play.triggered.connect(self.slot_transportPlayPause)
self.ui.act_transport_stop.triggered.connect(self.slot_transportStop)
self.ui.act_transport_backwards.triggered.connect(self.slot_transportBackwards)
@@ -291,6 +335,7 @@ class HostWindow(QMainWindow):

self.ui.act_settings_show_meters.toggled.connect(self.slot_showCanvasMeters)
self.ui.act_settings_show_keyboard.toggled.connect(self.slot_showCanvasKeyboard)
#self.ui.act_settings_configure.triggered.connect(self.slot_configureCarla)

self.ui.act_help_about.triggered.connect(self.slot_aboutCarla)
self.ui.act_help_about_juce.triggered.connect(self.slot_aboutJuce)
@@ -319,6 +364,7 @@ class HostWindow(QMainWindow):

host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback)
host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback)
#host.ReloadAllCallback.connect(self.slot_handleReloadAllCallback)

host.PatchbayClientAddedCallback.connect(self.slot_handlePatchbayClientAddedCallback)
host.PatchbayClientRemovedCallback.connect(self.slot_handlePatchbayClientRemovedCallback)
@@ -391,9 +437,8 @@ class HostWindow(QMainWindow):
patchcanvas.setInitialPos(self.fCanvasWidth / 2, self.fCanvasHeight / 2)
self.ui.graphicsView.setSceneRect(0, 0, self.fCanvasWidth, self.fCanvasHeight)

self.fThemeData = [self.fCanvasWidth, self.fCanvasHeight, patchcanvas.canvas.theme.canvas_bg, patchcanvas.canvas.theme.rubberband_brush, patchcanvas.canvas.theme.rubberband_pen.color()]

self.updateContainer(self.fThemeData)
self.ui.miniCanvasPreview.setViewTheme(patchcanvas.canvas.theme.canvas_bg, patchcanvas.canvas.theme.rubberband_brush, patchcanvas.canvas.theme.rubberband_pen.color())
self.ui.miniCanvasPreview.init(self.scene, self.fCanvasWidth, self.fCanvasHeight, self.fSavedSettings[CARLA_KEY_CUSTOM_PAINTING])

def updateCanvasInitialPos(self):
x = self.ui.graphicsView.horizontalScrollBar().value() + self.width()/4
@@ -485,39 +530,6 @@ class HostWindow(QMainWindow):
def setLoadRDFsNeeded(self):
self.fLadspaRdfNeedsUpdate = True

def setupContainer(self, showCanvas, canvasThemeData = []):
#if showCanvas:
#canvasWidth, canvasHeight, canvasBg, canvasBrush, canvasPen = canvasThemeData
#self.ui.miniCanvasPreview.setViewTheme(canvasBg, canvasBrush, canvasPen)
#self.ui.miniCanvasPreview.init(self.fContainer.scene, canvasWidth, canvasHeight, self.fSavedSettings[CARLA_KEY_CUSTOM_PAINTING])
#else:
#self.ui.act_canvas_show_internal.setEnabled(False)
#self.ui.act_canvas_show_external.setEnabled(False)
#self.ui.act_canvas_arrange.setVisible(False)
#self.ui.act_canvas_print.setVisible(False)
#self.ui.act_canvas_refresh.setVisible(False)
#self.ui.act_canvas_save_image.setVisible(False)
#self.ui.act_canvas_zoom_100.setVisible(False)
#self.ui.act_canvas_zoom_fit.setVisible(False)
#self.ui.act_canvas_zoom_in.setVisible(False)
#self.ui.act_canvas_zoom_out.setVisible(False)
#self.ui.act_settings_show_meters.setVisible(False)
#self.ui.act_settings_show_keyboard.setVisible(False)
#self.ui.menu_Canvas.setEnabled(False)
#self.ui.menu_Canvas.setVisible(False)
#self.ui.menu_Canvas_Zoom.setEnabled(False)
#self.ui.menu_Canvas_Zoom.setVisible(False)
#self.ui.miniCanvasPreview.hide()

self.fContainer.hide()
#self.setCentralWidget(self.fContainer)
#self.ui.centralwidget = self.fContainer

def updateContainer(self, canvasThemeData):
canvasWidth, canvasHeight, canvasBg, canvasBrush, canvasPen = canvasThemeData
self.ui.miniCanvasPreview.setViewTheme(canvasBg, canvasBrush, canvasPen)
self.ui.miniCanvasPreview.init(self.scene, canvasWidth, canvasHeight, self.fSavedSettings[CARLA_KEY_CUSTOM_PAINTING])

# --------------------------------------------------------------------------------------------------------
# Called by the signal handler

@@ -538,13 +550,13 @@ class HostWindow(QMainWindow):
if not self.fProjectFilename:
return qCritical("ERROR: loading project without filename set")

self.fContainer.projectLoadingStarted()
#self.fContainer.projectLoadingStarted()
self.fIsProjectLoading = True

self.host.load_project(self.fProjectFilename)

self.fIsProjectLoading = False
self.fContainer.projectLoadingFinished()
#self.fContainer.projectLoadingFinished()

def loadProjectLater(self, filename):
self.fProjectFilename = QFileInfo(filename).absoluteFilePath()
@@ -557,11 +569,20 @@ class HostWindow(QMainWindow):

self.host.save_project(self.fProjectFilename)

def projectLoadingStarted(self):
self.ui.rack.setEnabled(False)
self.ui.graphicsView.setEnabled(False)

def projectLoadingFinished(self):
self.ui.rack.setEnabled(True)
self.ui.graphicsView.setEnabled(True)
QTimer.singleShot(1000, self.slot_canvasRefresh)

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

@pyqtSlot()
def slot_fileNew(self):
self.fContainer.removeAllPlugins()
#self.fContainer.removeAllPlugins()
self.fProjectFilename = ""
self.setProperWindowTitle()

@@ -583,7 +604,7 @@ class HostWindow(QMainWindow):
newFile = (ask == QMessageBox.Yes)

if newFile:
self.fContainer.removeAllPlugins()
#self.fContainer.removeAllPlugins()
self.fProjectFilename = filename
self.setProperWindowTitle()
self.loadProjectNow()
@@ -740,7 +761,7 @@ class HostWindow(QMainWindow):
return

self.ui.act_plugin_remove_all.setEnabled(False)
self.fContainer.removeAllPlugins()
#self.fContainer.removeAllPlugins()

if self.host.is_engine_running() and not self.host.engine_close():
print(self.host.get_last_error())
@@ -768,16 +789,16 @@ class HostWindow(QMainWindow):
self.fLastTransportFrame = 0
self.fLastTransportState = False
self.refreshTransport(True)
self.fContainer.engineStarted()
self.startTimers()

@pyqtSlot()
def slot_handleEngineStoppedCallback(self):
patchcanvas.clear()
self.killTimers()

# just in case
self.ui.act_plugin_remove_all.setEnabled(False)
self.fContainer.removeAllPlugins()
#self.fContainer.removeAllPlugins()

self.ui.menu_PluginMacros.setEnabled(False)
self.ui.menu_Canvas.setEnabled(False)
@@ -795,7 +816,6 @@ class HostWindow(QMainWindow):

self.fSampleRate = 0.0
self.fTransportText = ""
self.fContainer.engineStopped()

@pyqtSlot(float)
def slot_handleSampleRateChangedCallback(self, newSampleRate):
@@ -805,6 +825,24 @@ class HostWindow(QMainWindow):
# --------------------------------------------------------------------------------------------------------
# Internal stuff (plugins)

def removeAllPlugins(self):
patchcanvas.handleAllPluginsRemoved()

while self.ui.rack.takeItem(0):
pass

#self.clearSideStuff()

for pitem in self.fPluginList:
if pitem is None:
break

pitem.closeEditDialog()
del pitem

self.fPluginCount = 0
self.fPluginList = []

@pyqtSlot()
def slot_pluginAdd(self, pluginToReplace = -1):
dialog = PluginDatabaseW(self, self.host)
@@ -845,14 +883,14 @@ class HostWindow(QMainWindow):
if count == 0:
return

self.fContainer.projectLoadingStarted()
#self.fContainer.projectLoadingStarted()

app = QApplication.instance()
for i in range(count):
app.processEvents()
self.host.remove_plugin(count-i-1)

self.fContainer.projectLoadingFinished()
#self.fContainer.projectLoadingFinished()

#self.fContainer.removeAllPlugins()
#self.host.remove_all_plugins()
@@ -863,9 +901,36 @@ class HostWindow(QMainWindow):
def slot_handlePluginAddedCallback(self, pluginId, pluginName):
self.ui.act_plugin_remove_all.setEnabled(self.host.get_current_plugin_count() > 0)

#pitem = CarlaRackItem(self.fRack, pluginId, self.fParent.getSavedSettings()[CARLA_KEY_MAIN_USE_CUSTOM_SKINS])

#self.fPluginList.append(pitem)
#self.fPluginCount += 1

#if not self.fParent.isProjectLoading():
#pitem.getWidget().setActive(True, True, True)

@pyqtSlot(int)
def slot_handlePluginRemovedCallback(self, pluginId):
self.ui.act_plugin_remove_all.setEnabled(self.host.get_current_plugin_count() > 0)
patchcanvas.handlePluginRemoved(pluginId)

#if pluginId in self.fSelectedPlugins:
#self.clearSideStuff()

#pitem = self.getPluginItem(pluginId)

#self.fPluginCount -= 1
#self.fPluginList.pop(pluginId)
#self.fRack.takeItem(pluginId)

#if pitem is not None:
#pitem.closeEditDialog()
#del pitem

## push all plugins 1 slot back
#for i in range(pluginId, self.fPluginCount):
#pitem = self.fPluginList[i]
#pitem.setPluginId(i)

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

@@ -978,6 +1043,240 @@ class HostWindow(QMainWindow):
patchcanvas.disconnectPorts(connectionId)
QTimer.singleShot(0, self.ui.miniCanvasPreview.update)

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

@pyqtSlot()
def slot_canvasArrange(self):
patchcanvas.arrange()

@pyqtSlot()
def slot_canvasShowInternal(self):
self.fExternalPatchbay = False
self.fParent.ui.act_canvas_show_internal.blockSignals(True)
self.fParent.ui.act_canvas_show_external.blockSignals(True)
self.fParent.ui.act_canvas_show_internal.setChecked(True)
self.fParent.ui.act_canvas_show_external.setChecked(False)
self.fParent.ui.act_canvas_show_internal.blockSignals(False)
self.fParent.ui.act_canvas_show_external.blockSignals(False)
self.slot_canvasRefresh()

@pyqtSlot()
def slot_canvasShowExternal(self):
self.fExternalPatchbay = True
self.fParent.ui.act_canvas_show_internal.blockSignals(True)
self.fParent.ui.act_canvas_show_external.blockSignals(True)
self.fParent.ui.act_canvas_show_internal.setChecked(False)
self.fParent.ui.act_canvas_show_external.setChecked(True)
self.fParent.ui.act_canvas_show_internal.blockSignals(False)
self.fParent.ui.act_canvas_show_external.blockSignals(False)
self.slot_canvasRefresh()

@pyqtSlot()
def slot_canvasRefresh(self):
#patchcanvas.clear()

if self.host.is_engine_running():
self.host.patchbay_refresh(self.fExternalPatchbay)

for pedit in self.fPluginList:
if pedit is None:
break
pedit.reloadAll()

QTimer.singleShot(1000 if self.fParent.fSavedSettings[CARLA_KEY_CANVAS_EYE_CANDY] else 0, self.fMiniCanvasPreview.update)

@pyqtSlot()
def slot_canvasZoomFit(self):
self.scene.zoom_fit()

@pyqtSlot()
def slot_canvasZoomIn(self):
self.scene.zoom_in()

@pyqtSlot()
def slot_canvasZoomOut(self):
self.scene.zoom_out()

@pyqtSlot()
def slot_canvasZoomReset(self):
self.scene.zoom_reset()

@pyqtSlot()
def slot_canvasPrint(self):
self.scene.clearSelection()
self.fExportPrinter = QPrinter()
dialog = QPrintDialog(self.fExportPrinter, self)

if dialog.exec_():
painter = QPainter(self.fExportPrinter)
painter.save()
painter.setRenderHint(QPainter.Antialiasing)
painter.setRenderHint(QPainter.TextAntialiasing)
self.scene.render(painter)
painter.restore()

@pyqtSlot()
def slot_canvasSaveImage(self):
newPath = QFileDialog.getSaveFileName(self, self.tr("Save Image"), filter=self.tr("PNG Image (*.png);;JPEG Image (*.jpg)"))

if config_UseQt5:
newPath = newPath[0]
if not newPath:
return

self.scene.clearSelection()

if newPath.lower().endswith((".jpg",)):
imgFormat = "JPG"
elif newPath.lower().endswith((".png",)):
imgFormat = "PNG"
else:
# File-dialog may not auto-add the extension
imgFormat = "PNG"
newPath += ".png"

self.fExportImage = QImage(self.scene.sceneRect().width(), self.scene.sceneRect().height(), QImage.Format_RGB32)
painter = QPainter(self.fExportImage)
painter.save()
painter.setRenderHint(QPainter.Antialiasing) # TODO - set true, cleanup this
painter.setRenderHint(QPainter.TextAntialiasing)
self.scene.render(painter)
self.fExportImage.save(newPath, imgFormat, 100)
painter.restore()

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

@pyqtSlot(int)
def slot_handleReloadAllCallback(self, pluginId):
if pluginId >= self.fPluginCount:
return

pitem = self.fPluginList[pluginId]
if pitem is None:
return

self.fRack.setCurrentRow(-1)
self.fCurrentRow = -1
self.fLastSelectedItem = None

pitem.recreateWidget()

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

@pyqtSlot(int)
def slot_currentRowChanged(self, row):
self.fCurrentRow = row

if self.fLastSelectedItem is not None:
self.fLastSelectedItem.setSelected(False)

if row < 0 or row >= self.fPluginCount or self.fPluginList[row] is None:
self.fLastSelectedItem = None
return

pitem = self.fPluginList[row]
pitem.getWidget().setSelected(True)
self.fLastSelectedItem = pitem.getWidget()

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

@pyqtSlot()
def slot_pluginsEnable(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setActive(True, True, True)

@pyqtSlot()
def slot_pluginsDisable(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setActive(False, True, True)

@pyqtSlot()
def slot_pluginsVolume100(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setInternalParameter(PLUGIN_CAN_VOLUME, 1.0)

@pyqtSlot()
def slot_pluginsMute(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setInternalParameter(PLUGIN_CAN_VOLUME, 0.0)

@pyqtSlot()
def slot_pluginsWet100(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setInternalParameter(PLUGIN_CAN_DRYWET, 1.0)

@pyqtSlot()
def slot_pluginsBypass(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setInternalParameter(PLUGIN_CAN_DRYWET, 0.0)

@pyqtSlot()
def slot_pluginsCenter(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setInternalParameter(PARAMETER_BALANCE_LEFT, -1.0)
pitem.getWidget().setInternalParameter(PARAMETER_BALANCE_RIGHT, 1.0)
pitem.getWidget().setInternalParameter(PARAMETER_PANNING, 0.0)

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

@pyqtSlot()
def slot_configureCarla(self):
dialog = CarlaSettingsW(self, self.host, True, hasGL)
if not dialog.exec_():
return

self.loadSettings(False)

patchcanvas.clear()

self.setupCanvas()
self.slot_miniCanvasCheckAll()

if self.host.is_engine_running():
self.host.patchbay_refresh(self.fExternalPatchbay)

# --------------------------------------------------------------------------------------------------------
# Internal stuff (plugin data)

@@ -1024,6 +1323,58 @@ class HostWindow(QMainWindow):

frLadspa.close()

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

def clearSideStuff(self):
self.scene.clearSelection()

self.fSelectedPlugins = []

self.ui.keyboard.allNotesOff(False)
self.ui.scrollArea.setEnabled(False)

self.fPeaksCleared = True
self.ui.peak_in.displayMeter(1, 0.0, True)
self.ui.peak_in.displayMeter(2, 0.0, True)
self.ui.peak_out.displayMeter(1, 0.0, True)
self.ui.peak_out.displayMeter(2, 0.0, True)

def getPluginItem(self, pluginId):
if pluginId >= self.fPluginCount:
return None

pitem = self.fPluginList[pluginId]
if pitem is None:
return None
#if False:
#pitem = CarlaRackItem(self, 0, False)

return pitem

def getPluginEditDialog(self, pluginId):
if pluginId >= self.fPluginCount:
return None

pitem = self.fPluginList[pluginId]
if pitem is None:
return None
#if False:
#pitem = CarlaRackItem(self, 0, False)

return pitem.getEditDialog()

def getPluginSlotWidget(self, pluginId):
if pluginId >= self.fPluginCount:
return None

pitem = self.fPluginList[pluginId]
if pitem is None:
return None
#if False:
#pitem = CarlaRackItem(self, 0, False)

return pitem.getWidget()

# --------------------------------------------------------------------------------------------------------
# Internal stuff (timers)

@@ -1221,7 +1572,7 @@ class HostWindow(QMainWindow):
settings.setValue("HorizontalScrollBarValue", self.ui.graphicsView.horizontalScrollBar().value())
settings.setValue("VerticalScrollBarValue", self.ui.graphicsView.verticalScrollBar().value())

self.fContainer.saveSettings(settings)
#self.fContainer.saveSettings(settings)

# -----------------------------------------------------------------
# Internal stuff (gui)
@@ -1322,13 +1673,13 @@ class HostWindow(QMainWindow):
# -----------------------------------------------------------------

def fixCanvasPreviewSize(self):
self.ui.patchbay.resize(self.ui.plugins.size())
self.ui.patchbay.resize(self.ui.rack.size())
self.slot_miniCanvasCheckSize()

def resizeEvent(self, event):
QMainWindow.resizeEvent(self, event)

if self.ui.tabWidget.currentIndex() == 0:
if self.ui.tabWidget.currentIndex() != 1:
self.fixCanvasPreviewSize()
else:
self.slot_miniCanvasCheckSize()
@@ -1342,6 +1693,12 @@ class HostWindow(QMainWindow):
if self.fPluginCount == 0:
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().idleFast()

for pluginId in self.fSelectedPlugins:
self.fPeaksCleared = False
if self.ui.peak_in.isVisible():
@@ -1362,10 +1719,14 @@ class HostWindow(QMainWindow):
self.ui.peak_out.displayMeter(2, 0.0, True)

def idleSlow(self):
for pedit in self.fPluginList:
if pedit is None:
if self.fPluginCount == 0:
return

for pitem in self.fPluginList:
if pitem is None:
break
pedit.idleSlow()

pitem.getWidget().idleSlow()

def timerEvent(self, event):
if event.timerId() == self.fIdleTimerFast:
@@ -1391,7 +1752,7 @@ class HostWindow(QMainWindow):
if count > 0:
# simulate project loading, to disable container
self.ui.act_plugin_remove_all.setEnabled(False)
self.fContainer.projectLoadingStarted()
#self.fContainer.projectLoadingStarted()

app = QApplication.instance()
for i in range(count):
@@ -1400,7 +1761,7 @@ class HostWindow(QMainWindow):

app.processEvents()

#self.fContainer.removeAllPlugins()
#self.removeAllPlugins()
#self.host.remove_all_plugins()

self.slot_engineStop()
@@ -1455,7 +1816,12 @@ def canvasCallback(action, value1, value2, valueStr):
elif action == patchcanvas.ACTION_PLUGIN_EDIT:
pluginId = value1

gCarla.gui.fContainer.showEditDialog(pluginId)
dialog = gCarla.gui.getPluginEditDialog(pluginId)

if dialog is None:
return

dialog.show()

elif action == patchcanvas.ACTION_PLUGIN_RENAME:
pluginId = value1


+ 2
- 411
source/carla_patchbay.py View File

@@ -42,53 +42,11 @@ from carla_host import *
from digitalpeakmeter import DigitalPeakMeter
from pixmapkeyboard import PixmapKeyboardHArea

# ------------------------------------------------------------------------------------------------
# Dummy class used in main carla as replacement for PluginEdit

class DummyPluginEdit(object):
def __init__(self, parent, pluginId):
object.__init__(self)

self.fPluginId = pluginId

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

def clearNotes(self):
pass

def noteOn(self, channel, note, velocity):
pass

def noteOff(self, channel, note):
pass

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

def setPluginId(self, idx):
self.fPluginId = idx

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

def close(self):
pass

def setName(self, name):
pass

def setParameterValue(self, parameterId, value):
pass

def reloadAll(self):
pass

def idleSlow(self):
pass

# ------------------------------------------------------------------------------------------------
# Patchbay widget

class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):
#class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta, metaclass=PyQtMetaClass):
class CarlaPatchbayW(QFrame, PluginEditParentMeta):
#class CarlaPatchbayW(QFrame, PluginEditParentMeta, metaclass=PyQtMetaClass):
def __init__(self, parent, host, doSetup = True, onlyPatchbay = True, is3D = False):
QFrame.__init__(self, parent)
self.host = host
@@ -102,86 +60,11 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):
# -------------------------------------------------------------
# Connect actions to functions (part 2)

#host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback)
#host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback)
#host.NoteOnCallback.connect(self.slot_handleNoteOnCallback)
#host.NoteOffCallback.connect(self.slot_handleNoteOffCallback)

#if not doSetup: return

#parent.ui.act_plugins_enable.triggered.connect(self.slot_pluginsEnable)
#parent.ui.act_plugins_disable.triggered.connect(self.slot_pluginsDisable)
#parent.ui.act_plugins_volume100.triggered.connect(self.slot_pluginsVolume100)
#parent.ui.act_plugins_mute.triggered.connect(self.slot_pluginsMute)
#parent.ui.act_plugins_wet100.triggered.connect(self.slot_pluginsWet100)
#parent.ui.act_plugins_bypass.triggered.connect(self.slot_pluginsBypass)
#parent.ui.act_plugins_center.triggered.connect(self.slot_pluginsCenter)
#parent.ui.act_plugins_panic.triggered.connect(self.slot_pluginsDisable)

#parent.ui.act_canvas_show_internal.triggered.connect(self.slot_canvasShowInternal)
#parent.ui.act_canvas_show_external.triggered.connect(self.slot_canvasShowExternal)
#parent.ui.act_canvas_arrange.setEnabled(False) # TODO, later
#parent.ui.act_canvas_arrange.triggered.connect(self.slot_canvasArrange)
#parent.ui.act_canvas_refresh.triggered.connect(self.slot_canvasRefresh)
#parent.ui.act_canvas_zoom_fit.triggered.connect(self.slot_canvasZoomFit)
#parent.ui.act_canvas_zoom_in.triggered.connect(self.slot_canvasZoomIn)
#parent.ui.act_canvas_zoom_out.triggered.connect(self.slot_canvasZoomOut)
#parent.ui.act_canvas_zoom_100.triggered.connect(self.slot_canvasZoomReset)
#parent.ui.act_canvas_print.triggered.connect(self.slot_canvasPrint)
#parent.ui.act_canvas_save_image.triggered.connect(self.slot_canvasSaveImage)

#parent.ui.act_settings_configure.triggered.connect(self.slot_configureCarla)

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

def getPluginEditDialog(self, pluginId):
if pluginId >= self.fPluginCount:
return None

pedit = self.fPluginList[pluginId]
if pedit is None:
return None
if False:
pedit = DummyPluginEdit(self, 0)

return pedit

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

@pyqtSlot(int, str)
def slot_handlePluginAddedCallback(self, pluginId, pluginName):
if self.fIsOnlyPatchbay:
pedit = PluginEdit(self, self.host, pluginId)
else:
pedit = DummyPluginEdit(self, pluginId)

self.fPluginList.append(pedit)
self.fPluginCount += 1

if self.fIsOnlyPatchbay and not self.fParent.isProjectLoading():
self.host.set_active(pluginId, True)

@pyqtSlot(int)
def slot_handlePluginRemovedCallback(self, pluginId):
patchcanvas.handlePluginRemoved(pluginId)

if pluginId in self.fSelectedPlugins:
self.clearSideStuff()

pedit = self.getPluginEditDialog(pluginId)

self.fPluginCount -= 1
self.fPluginList.pop(pluginId)

if pedit is not None:
pedit.close()
del pedit

# push all plugins 1 slot back
for i in range(pluginId, self.fPluginCount):
pedit = self.fPluginList[i]
pedit.setPluginId(i)

@pyqtSlot(int, int, int, int)
def slot_handleNoteOnCallback(self, pluginId, channel, note, velocity):
if pluginId in self.fSelectedPlugins:
@@ -192,66 +75,9 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):
if pluginId in self.fSelectedPlugins:
self.fKeys.keyboard.sendNoteOff(note, False)

# -----------------------------------------------------------------
# HostWidgetMeta methods

def removeAllPlugins(self):
#patchcanvas.handleAllPluginsRemoved()

for pedit in self.fPluginList:
if pedit is None:
break
pedit.close()
del pedit

self.fPluginCount = 0
self.fPluginList = []

self.clearSideStuff()

def engineStarted(self):
pass

def engineStopped(self):
pass
#patchcanvas.clear()

def projectLoadingStarted(self):
pass
#self.fView.setEnabled(False)

def projectLoadingFinished(self):
pass
#self.fView.setEnabled(True)
#QTimer.singleShot(1000, self.slot_canvasRefresh)

def saveSettings(self, settings):
pass

def showEditDialog(self, pluginId):
pedit = self.getPluginEditDialog(pluginId)

if pedit:
pedit.show()

# -----------------------------------------------------------------
# PluginEdit callbacks

def editDialogVisibilityChanged(self, pluginId, visible):
pass

def editDialogPluginHintsChanged(self, pluginId, hints):
pass

def editDialogParameterValueChanged(self, pluginId, parameterId, value):
pass

def editDialogProgramChanged(self, pluginId, index):
pass

def editDialogMidiProgramChanged(self, pluginId, index):
pass

def editDialogNotePressed(self, pluginId, note):
if pluginId in self.fSelectedPlugins:
self.fKeys.keyboard.sendNoteOn(note, False)
@@ -260,25 +86,6 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):
if pluginId in self.fSelectedPlugins:
self.fKeys.keyboard.sendNoteOff(note, False)

def editDialogMidiActivityChanged(self, pluginId, onOff):
pass

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

def clearSideStuff(self):
#self.scene.clearSelection()

self.fSelectedPlugins = []

#self.fKeys.keyboard.allNotesOff(False)
#self.fKeys.setEnabled(False)

#self.fPeaksCleared = True
#self.fPeaksIn.displayMeter(1, 0.0, True)
#self.fPeaksIn.displayMeter(2, 0.0, True)
#self.fPeaksOut.displayMeter(1, 0.0, True)
#self.fPeaksOut.displayMeter(2, 0.0, True)

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

@pyqtSlot(int)
@@ -296,219 +103,3 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):

pedit = self.getPluginEditDialog(pluginId)
pedit.noteOff(0, note)

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

@pyqtSlot()
def slot_pluginsEnable(self):
if not self.host.is_engine_running():
return

for i in range(self.fPluginCount):
self.host.set_active(i, True)

@pyqtSlot()
def slot_pluginsDisable(self):
if not self.host.is_engine_running():
return

for i in range(self.fPluginCount):
self.host.set_active(i, False)

@pyqtSlot()
def slot_pluginsVolume100(self):
if not self.host.is_engine_running():
return

for i in range(self.fPluginCount):
pedit = self.fPluginList[i]
if pedit is None:
break

if pedit.getHints() & PLUGIN_CAN_VOLUME:
pedit.setParameterValue(PARAMETER_VOLUME, 1.0)
self.host.set_volume(i, 1.0)

@pyqtSlot()
def slot_pluginsMute(self):
if not self.host.is_engine_running():
return

for i in range(self.fPluginCount):
pedit = self.fPluginList[i]
if pedit is None:
break

if pedit.getHints() & PLUGIN_CAN_VOLUME:
pedit.setParameterValue(PARAMETER_VOLUME, 0.0)
self.host.set_volume(i, 0.0)

@pyqtSlot()
def slot_pluginsWet100(self):
if not self.host.is_engine_running():
return

for i in range(self.fPluginCount):
pedit = self.fPluginList[i]
if pedit is None:
break

if pedit.getHints() & PLUGIN_CAN_DRYWET:
pedit.setParameterValue(PARAMETER_DRYWET, 1.0)
self.host.set_drywet(i, 1.0)

@pyqtSlot()
def slot_pluginsBypass(self):
if not self.host.is_engine_running():
return

for i in range(self.fPluginCount):
pedit = self.fPluginList[i]
if pedit is None:
break

if pedit.getHints() & PLUGIN_CAN_DRYWET:
pedit.setParameterValue(PARAMETER_DRYWET, 0.0)
self.host.set_drywet(i, 0.0)

@pyqtSlot()
def slot_pluginsCenter(self):
if not self.host.is_engine_running():
return

for i in range(self.fPluginCount):
pedit = self.fPluginList[i]
if pedit is None:
break

if pedit.getHints() & PLUGIN_CAN_BALANCE:
pedit.setParameterValue(PARAMETER_BALANCE_LEFT, -1.0)
pedit.setParameterValue(PARAMETER_BALANCE_RIGHT, 1.0)
self.host.set_balance_left(i, -1.0)
self.host.set_balance_right(i, 1.0)

if pedit.getHints() & PLUGIN_CAN_PANNING:
pedit.setParameterValue(PARAMETER_PANNING, 0.0)
self.host.set_panning(i, 0.0)

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

@pyqtSlot()
def slot_configureCarla(self):
dialog = CarlaSettingsW(self, self.host, True, hasGL)
if not dialog.exec_():
return

self.fParent.loadSettings(False)

patchcanvas.clear()

self.setupCanvas()
self.fParent.updateContainer(self.themeData)
#self.slot_miniCanvasCheckAll()

if self.host.is_engine_running():
self.host.patchbay_refresh(self.fExternalPatchbay)

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

@pyqtSlot()
def slot_canvasArrange(self):
patchcanvas.arrange()

@pyqtSlot()
def slot_canvasShowInternal(self):
self.fExternalPatchbay = False
self.fParent.ui.act_canvas_show_internal.blockSignals(True)
self.fParent.ui.act_canvas_show_external.blockSignals(True)
self.fParent.ui.act_canvas_show_internal.setChecked(True)
self.fParent.ui.act_canvas_show_external.setChecked(False)
self.fParent.ui.act_canvas_show_internal.blockSignals(False)
self.fParent.ui.act_canvas_show_external.blockSignals(False)
self.slot_canvasRefresh()

@pyqtSlot()
def slot_canvasShowExternal(self):
self.fExternalPatchbay = True
self.fParent.ui.act_canvas_show_internal.blockSignals(True)
self.fParent.ui.act_canvas_show_external.blockSignals(True)
self.fParent.ui.act_canvas_show_internal.setChecked(False)
self.fParent.ui.act_canvas_show_external.setChecked(True)
self.fParent.ui.act_canvas_show_internal.blockSignals(False)
self.fParent.ui.act_canvas_show_external.blockSignals(False)
self.slot_canvasRefresh()

@pyqtSlot()
def slot_canvasRefresh(self):
#patchcanvas.clear()

if self.host.is_engine_running():
self.host.patchbay_refresh(self.fExternalPatchbay)

for pedit in self.fPluginList:
if pedit is None:
break
pedit.reloadAll()

QTimer.singleShot(1000 if self.fParent.fSavedSettings[CARLA_KEY_CANVAS_EYE_CANDY] else 0, self.fMiniCanvasPreview.update)

@pyqtSlot()
def slot_canvasZoomFit(self):
self.scene.zoom_fit()

@pyqtSlot()
def slot_canvasZoomIn(self):
self.scene.zoom_in()

@pyqtSlot()
def slot_canvasZoomOut(self):
self.scene.zoom_out()

@pyqtSlot()
def slot_canvasZoomReset(self):
self.scene.zoom_reset()

@pyqtSlot()
def slot_canvasPrint(self):
self.scene.clearSelection()
self.fExportPrinter = QPrinter()
dialog = QPrintDialog(self.fExportPrinter, self)

if dialog.exec_():
painter = QPainter(self.fExportPrinter)
painter.save()
painter.setRenderHint(QPainter.Antialiasing)
painter.setRenderHint(QPainter.TextAntialiasing)
self.scene.render(painter)
painter.restore()

@pyqtSlot()
def slot_canvasSaveImage(self):
newPath = QFileDialog.getSaveFileName(self, self.tr("Save Image"), filter=self.tr("PNG Image (*.png);;JPEG Image (*.jpg)"))

if config_UseQt5:
newPath = newPath[0]
if not newPath:
return

self.scene.clearSelection()

if newPath.lower().endswith((".jpg",)):
imgFormat = "JPG"
elif newPath.lower().endswith((".png",)):
imgFormat = "PNG"
else:
# File-dialog may not auto-add the extension
imgFormat = "PNG"
newPath += ".png"

self.fExportImage = QImage(self.scene.sceneRect().width(), self.scene.sceneRect().height(), QImage.Format_RGB32)
painter = QPainter(self.fExportImage)
painter.save()
painter.setRenderHint(QPainter.Antialiasing) # TODO - set true, cleanup this
painter.setRenderHint(QPainter.TextAntialiasing)
self.scene.render(painter)
self.fExportImage.save(newPath, imgFormat, 100)
painter.restore()

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

+ 1
- 352
source/carla_rack.py View File

@@ -227,359 +227,8 @@ class CarlaRackList(QListWidget):
# ------------------------------------------------------------------------------------------------------------
# Rack widget

class CarlaRackW(QFrame, HostWidgetMeta):
class CarlaRackW(QFrame):
#class CarlaRackW(QFrame, HostWidgetMeta, metaclass=PyQtMetaClass):
def __init__(self, parent, host, doSetup = True):
QFrame.__init__(self, parent)
self.host = host

if False:
# kdevelop likes this :)
host = CarlaHostMeta()
self.host = host

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

self.fLayout = QHBoxLayout(self)
self.fLayout.setContentsMargins(0, 0, 0, 0)
self.fLayout.setSpacing(0)
self.setLayout(self.fLayout)

self.fPadLeft = QLabel(self)
self.fPadLeft.setFixedWidth(25)
self.fPadLeft.setObjectName("PadLeft")
self.fPadLeft.setText("")

self.fPadRight = QLabel(self)
self.fPadRight.setFixedWidth(25)
self.fPadRight.setObjectName("PadRight")
self.fPadRight.setText("")

self.fRack = CarlaRackList(self, host)
self.fRack.setObjectName("CarlaRackList")
self.fRack.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.fRack.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.fRack.currentRowChanged.connect(self.slot_currentRowChanged)

sb = self.fRack.verticalScrollBar()
self.fScrollBar = QScrollBar(Qt.Vertical, self)
self.fScrollBar.setMinimum(sb.minimum())
self.fScrollBar.setMaximum(sb.maximum())
self.fScrollBar.setValue(sb.value())

#sb.actionTriggered.connect(self.fScrollBar.triggerAction)
#sb.sliderMoved.connect(self.fScrollBar.)
#sb.sliderPressed.connect(self.fScrollBar.)
#sb.sliderReleased.connect(self.fScrollBar.)
sb.rangeChanged.connect(self.fScrollBar.setRange)
sb.valueChanged.connect(self.fScrollBar.setValue)
self.fScrollBar.rangeChanged.connect(sb.setRange)
self.fScrollBar.valueChanged.connect(sb.setValue)

self.fLayout.addWidget(self.fPadLeft)
self.fLayout.addWidget(self.fRack)
self.fLayout.addWidget(self.fPadRight)
self.fLayout.addWidget(self.fScrollBar)

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

self.fParent = parent
self.fPluginCount = 0
self.fPluginList = []

self.fCurrentRow = -1
self.fLastSelectedItem = None

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

#app = QApplication.instance()
#pal1 = app.palette().base().color()
#pal2 = app.palette().button().color()
#col1 = "stop:0 rgb(%i, %i, %i)" % (pal1.red(), pal1.green(), pal1.blue())
#col2 = "stop:1 rgb(%i, %i, %i)" % (pal2.red(), pal2.green(), pal2.blue())

self.setStyleSheet("""
QLabel#PadLeft {
background-image: url(:/bitmaps/rack_padding_left.png);
background-repeat: repeat-y;
}
QLabel#PadRight {
background-image: url(:/bitmaps/rack_padding_right.png);
background-repeat: repeat-y;
}
CarlaRackList#CarlaRackList {
background-color: black;
}
""")

# -------------------------------------------------------------
# Connect actions to functions

host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback)
host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback)
host.ReloadAllCallback.connect(self.slot_handleReloadAllCallback)

if not doSetup: return

parent.ui.menu_Canvas.hide()

parent.ui.act_plugins_enable.triggered.connect(self.slot_pluginsEnable)
parent.ui.act_plugins_disable.triggered.connect(self.slot_pluginsDisable)
parent.ui.act_plugins_volume100.triggered.connect(self.slot_pluginsVolume100)
parent.ui.act_plugins_mute.triggered.connect(self.slot_pluginsMute)
parent.ui.act_plugins_wet100.triggered.connect(self.slot_pluginsWet100)
parent.ui.act_plugins_bypass.triggered.connect(self.slot_pluginsBypass)
parent.ui.act_plugins_center.triggered.connect(self.slot_pluginsCenter)
parent.ui.act_plugins_panic.triggered.connect(self.slot_pluginsDisable)

parent.ui.act_settings_configure.triggered.connect(self.slot_configureCarla)

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

@pyqtSlot(int, str)
def slot_handlePluginAddedCallback(self, pluginId, pluginName):
pitem = CarlaRackItem(self.fRack, pluginId, self.fParent.getSavedSettings()[CARLA_KEY_MAIN_USE_CUSTOM_SKINS])

self.fPluginList.append(pitem)
self.fPluginCount += 1

if not self.fParent.isProjectLoading():
pitem.getWidget().setActive(True, True, True)

@pyqtSlot(int)
def slot_handlePluginRemovedCallback(self, pluginId):
pitem = self.getPluginItem(pluginId)

self.fPluginCount -= 1
self.fPluginList.pop(pluginId)
self.fRack.takeItem(pluginId)

if pitem is not None:
pitem.closeEditDialog()
del pitem

# push all plugins 1 slot back
for i in range(pluginId, self.fPluginCount):
pitem = self.fPluginList[i]
pitem.setPluginId(i)

# -----------------------------------------------------------------
# HostWidgetMeta methods

def removeAllPlugins(self):
while self.fRack.takeItem(0):
pass

for pitem in self.fPluginList:
if pitem is None:
break

pitem.closeEditDialog()
del pitem

self.fPluginCount = 0
self.fPluginList = []

def engineStarted(self):
pass

def engineStopped(self):
pass

def idleFast(self):
for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().idleFast()

def idleSlow(self):
for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().idleSlow()

def projectLoadingStarted(self):
self.fRack.setEnabled(False)

def projectLoadingFinished(self):
self.fRack.setEnabled(True)

def saveSettings(self, settings):
pass

def showEditDialog(self, pluginId):
dialog = self.getPluginEditDialog(pluginId)

if dialog is None:
return

dialog.show()

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

@pyqtSlot()
def slot_pluginsEnable(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setActive(True, True, True)

@pyqtSlot()
def slot_pluginsDisable(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setActive(False, True, True)

@pyqtSlot()
def slot_pluginsVolume100(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setInternalParameter(PLUGIN_CAN_VOLUME, 1.0)

@pyqtSlot()
def slot_pluginsMute(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setInternalParameter(PLUGIN_CAN_VOLUME, 0.0)

@pyqtSlot()
def slot_pluginsWet100(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setInternalParameter(PLUGIN_CAN_DRYWET, 1.0)

@pyqtSlot()
def slot_pluginsBypass(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setInternalParameter(PLUGIN_CAN_DRYWET, 0.0)

@pyqtSlot()
def slot_pluginsCenter(self):
if not self.host.is_engine_running():
return

for pitem in self.fPluginList:
if pitem is None:
break

pitem.getWidget().setInternalParameter(PARAMETER_BALANCE_LEFT, -1.0)
pitem.getWidget().setInternalParameter(PARAMETER_BALANCE_RIGHT, 1.0)
pitem.getWidget().setInternalParameter(PARAMETER_PANNING, 0.0)

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

@pyqtSlot()
def slot_configureCarla(self):
dialog = CarlaSettingsW(self, self.host, False, False)
if not dialog.exec_():
return

self.fParent.loadSettings(False)

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

@pyqtSlot(int)
def slot_handleReloadAllCallback(self, pluginId):
if pluginId >= self.fPluginCount:
return

pitem = self.fPluginList[pluginId]
if pitem is None:
return

self.fRack.setCurrentRow(-1)
self.fCurrentRow = -1
self.fLastSelectedItem = None

pitem.recreateWidget()

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

@pyqtSlot(int)
def slot_currentRowChanged(self, row):
self.fCurrentRow = row

if self.fLastSelectedItem is not None:
self.fLastSelectedItem.setSelected(False)

if row < 0 or row >= self.fPluginCount or self.fPluginList[row] is None:
self.fLastSelectedItem = None
return

pitem = self.fPluginList[row]
pitem.getWidget().setSelected(True)
self.fLastSelectedItem = pitem.getWidget()

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

def getPluginItem(self, pluginId):
if pluginId >= self.fPluginCount:
return None

pitem = self.fPluginList[pluginId]
if pitem is None:
return None
if False:
pitem = CarlaRackItem(self, 0, False)

return pitem

def getPluginEditDialog(self, pluginId):
if pluginId >= self.fPluginCount:
return None

pitem = self.fPluginList[pluginId]
if pitem is None:
return None
if False:
pitem = CarlaRackItem(self, 0, False)

return pitem.getEditDialog()

def getPluginSlotWidget(self, pluginId):
if pluginId >= self.fPluginCount:
return None

pitem = self.fPluginList[pluginId]
if pitem is None:
return None
if False:
pitem = CarlaRackItem(self, 0, False)

return pitem.getWidget()

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

Loading…
Cancel
Save