Browse Source

Start merging separate rack/patchbay code into one

tags/1.9.5
falkTX 10 years ago
parent
commit
2b55509622
6 changed files with 609 additions and 556 deletions
  1. +1
    -1
      bin/carla.lv2/resources
  2. +1
    -1
      bin/carla.lv2/styles
  3. +82
    -6
      resources/ui/carla_host.ui
  4. +2
    -11
      source/carla
  5. +473
    -37
      source/carla_host.py
  6. +50
    -500
      source/carla_patchbay.py

+ 1
- 1
bin/carla.lv2/resources View File

@@ -1 +1 @@
../../source/modules/native-plugins/resources/
../../../share/carla/resources

+ 1
- 1
bin/carla.lv2/styles View File

@@ -1 +1 @@
../../source/modules/theme/styles/
../../carla/styles

+ 82
- 6
resources/ui/carla_host.ui View File

@@ -6,21 +6,92 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>739</width>
<height>467</height>
<width>870</width>
<height>681</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>MainWindow</string> <string>MainWindow</string>
</property> </property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="plugins">
<attribute name="title">
<string>Plugins</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="pad_left">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
<item>
<widget class="QLabel" name="pad_right">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="patchbay">
<attribute name="title">
<string>Patchbay</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<property name="spacing">
<number>1</number>
</property>
<item row="0" column="1">
<widget class="QGraphicsView" name="graphicsView"/>
</item>
<item row="0" column="2">
<widget class="DigitalPeakMeter" name="peak_out" native="true"/>
</item>
<item row="0" column="0">
<widget class="DigitalPeakMeter" name="peak_in" native="true"/>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar"> <widget class="QMenuBar" name="menubar">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>739</width>
<height>19</height>
<width>870</width>
<height>17</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menu_File"> <widget class="QMenu" name="menu_File">
@@ -310,7 +381,6 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Sunken</enum> <enum>QFrame::Sunken</enum>
</property> </property>
<zorder>tabUtils</zorder>
</widget> </widget>
</item> </item>
</layout> </layout>
@@ -688,6 +758,12 @@
<header>canvaspreviewframe.h</header> <header>canvaspreviewframe.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>DigitalPeakMeter</class>
<extends>QWidget</extends>
<header>digitalpeakmeter.h</header>
<container>1</container>
</customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="../resources.qrc"/> <include location="../resources.qrc"/>


+ 2
- 11
source/carla View File

@@ -67,7 +67,7 @@ class CarlaMultiW(QTabWidget):
#self.fPatchbay.setWindowTitle(parent.windowTitle()) #self.fPatchbay.setWindowTitle(parent.windowTitle())
#self.fPatchbay.show() #self.fPatchbay.show()


self.scene = self.fPatchbay.scene
#self.scene = self.fPatchbay.scene


parent.ui.act_plugins_enable.triggered.connect(self.fRack.slot_pluginsEnable) parent.ui.act_plugins_enable.triggered.connect(self.fRack.slot_pluginsEnable)
parent.ui.act_plugins_disable.triggered.connect(self.fRack.slot_pluginsDisable) parent.ui.act_plugins_disable.triggered.connect(self.fRack.slot_pluginsDisable)
@@ -136,10 +136,6 @@ class CarlaMultiW(QTabWidget):


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


def fixCanvasPreviewSize(self):
self.fPatchbay.resize(self.fRack.size())
self.fPatchbay.slot_miniCanvasCheckSize()

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


def paintEvent(self, event): def paintEvent(self, event):
@@ -170,7 +166,7 @@ class CarlaHostW(HostWindow):
# Set-up container # Set-up container


self.fContainer = CarlaMultiW(self, host) self.fContainer = CarlaMultiW(self, host)
self.setupContainer(True, self.fContainer.fPatchbay.themeData)
self.setupContainer(False)


# ------------------------------------------------------------- # -------------------------------------------------------------
# Set-up GUI stuff # Set-up GUI stuff
@@ -249,11 +245,6 @@ class CarlaHostW(HostWindow):
self.fInfoLabel.move(x, y) self.fInfoLabel.move(x, y)
self.fInfoLabel.resize(self.fContainer.width()-tabBar.width()-20, tabBar.height()) self.fInfoLabel.resize(self.fContainer.width()-tabBar.width()-20, tabBar.height())


# FIXME: Qt4 needs this so it properly creates & resizes the canvas
self.fContainer.setCurrentIndex(1)
self.fContainer.setCurrentIndex(0)
self.fContainer.fixCanvasPreviewSize()

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


+ 473
- 37
source/carla_host.py View File

@@ -25,28 +25,37 @@ from carla_config import *
# Imports (Global) # Imports (Global)


if config_UseQt5: if config_UseQt5:
from PyQt5.QtCore import qCritical, QFileInfo, QModelIndex, QTimer
from PyQt5.QtCore import qCritical, QFileInfo, QModelIndex, QPointF, QTimer
from PyQt5.QtGui import QPalette from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QAction, QApplication, QFileSystemModel, QListWidgetItem, QMainWindow from PyQt5.QtWidgets import QAction, QApplication, QFileSystemModel, QListWidgetItem, QMainWindow
else: else:
from PyQt4.QtCore import qCritical, QFileInfo, QModelIndex, QTimer
from PyQt4.QtCore import qCritical, QFileInfo, QModelIndex, QPointF, QTimer
from PyQt4.QtGui import QApplication, QFileSystemModel, QListWidgetItem, QMainWindow, QPalette from PyQt4.QtGui import QApplication, QFileSystemModel, QListWidgetItem, QMainWindow, QPalette


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


import patchcanvas
import ui_carla_host import ui_carla_host


from carla_app import * from carla_app import *
from carla_database import * from carla_database import *
from carla_settings import * from carla_settings import *
from carla_widgets import * from carla_widgets import *
from digitalpeakmeter import DigitalPeakMeter
from pixmapkeyboard import PixmapKeyboardHArea


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# PatchCanvas defines
# Try Import OpenGL


CANVAS_ANTIALIASING_SMALL = 1
CANVAS_EYECANDY_SMALL = 1
try:
if config_UseQt5:
from PyQt5.QtOpenGL import QGLWidget
else:
from PyQt4.QtOpenGL import QGLWidget
hasGL = True
except:
hasGL = False


# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Session Management support # Session Management support
@@ -99,7 +108,7 @@ class HostWindow(QMainWindow):


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


def __init__(self, host, parent=None):
def __init__(self, host, withCanvas=True, parent=None):
QMainWindow.__init__(self, parent) QMainWindow.__init__(self, parent)
self.host = host self.host = host
self.ui = ui_carla_host.Ui_CarlaHostW() self.ui = ui_carla_host.Ui_CarlaHostW()
@@ -149,6 +158,17 @@ class HostWindow(QMainWindow):
self.fClientName = "Carla" self.fClientName = "Carla"
self.fSessionManagerName = "" self.fSessionManagerName = ""


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

self.fExternalPatchbay = False
self.fSelectedPlugins = []

self.fCanvasWidth = 0
self.fCanvasHeight = 0

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


@@ -192,6 +212,30 @@ class HostWindow(QMainWindow):
self.ui.fileTreeView.setColumnHidden(3, True) self.ui.fileTreeView.setColumnHidden(3, True)
self.ui.fileTreeView.setHeaderHidden(True) self.ui.fileTreeView.setHeaderHidden(True)


# ----------------------------------------------------------------------------------------------------
# Set up GUI (plugins)

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

self.ui.peak_in.setColor(DigitalPeakMeter.BLUE)
self.ui.peak_in.setChannels(2)
self.ui.peak_in.setOrientation(DigitalPeakMeter.VERTICAL)
self.ui.peak_in.setFixedWidth(25)

self.ui.peak_out.setColor(DigitalPeakMeter.GREEN)
self.ui.peak_out.setChannels(2)
self.ui.peak_out.setOrientation(DigitalPeakMeter.VERTICAL)
self.ui.peak_out.setFixedWidth(25)

self.ui.scrollArea = PixmapKeyboardHArea(self.ui.patchbay)
self.ui.keyboard = self.ui.scrollArea.keyboard
self.ui.patchbay.layout().addWidget(self.ui.scrollArea, 1, 0, 1, 0)

self.ui.scrollArea.setEnabled(False)

self.ui.miniCanvasPreview.setRealParent(self)

# ---------------------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------------------
# Set up GUI (special stuff for Mac OS) # Set up GUI (special stuff for Mac OS)


@@ -209,6 +253,22 @@ class HostWindow(QMainWindow):


self.loadSettings(True) self.loadSettings(True)


# ----------------------------------------------------------------------------------------------------
# Set-up Canvas

self.scene = patchcanvas.PatchScene(self, self.ui.graphicsView)
self.ui.graphicsView.setScene(self.scene)
self.ui.graphicsView.setRenderHint(QPainter.Antialiasing, bool(self.fSavedSettings[CARLA_KEY_CANVAS_ANTIALIASING] == patchcanvas.ANTIALIASING_FULL))

if self.fSavedSettings[CARLA_KEY_CANVAS_USE_OPENGL] and hasGL:
self.ui.glView = QGLWidget(self)
self.ui.graphicsView.setViewport(self.ui.glView)
self.ui.graphicsView.setRenderHint(QPainter.HighQualityAntialiasing, self.fSavedSettings[CARLA_KEY_CANVAS_HQ_ANTIALIASING])

self.setupCanvas()

QTimer.singleShot(100, self.slot_restoreScrollbarValues)

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


@@ -229,6 +289,9 @@ class HostWindow(QMainWindow):
self.ui.act_transport_backwards.triggered.connect(self.slot_transportBackwards) self.ui.act_transport_backwards.triggered.connect(self.slot_transportBackwards)
self.ui.act_transport_forwards.triggered.connect(self.slot_transportForwards) self.ui.act_transport_forwards.triggered.connect(self.slot_transportForwards)


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_help_about.triggered.connect(self.slot_aboutCarla) self.ui.act_help_about.triggered.connect(self.slot_aboutCarla)
self.ui.act_help_about_juce.triggered.connect(self.slot_aboutJuce) self.ui.act_help_about_juce.triggered.connect(self.slot_aboutJuce)
self.ui.act_help_about_qt.triggered.connect(self.slot_aboutQt) self.ui.act_help_about_qt.triggered.connect(self.slot_aboutQt)
@@ -238,6 +301,15 @@ class HostWindow(QMainWindow):
self.ui.b_disk_remove.clicked.connect(self.slot_diskFolderRemove) self.ui.b_disk_remove.clicked.connect(self.slot_diskFolderRemove)
self.ui.fileTreeView.doubleClicked.connect(self.slot_fileTreeDoubleClicked) self.ui.fileTreeView.doubleClicked.connect(self.slot_fileTreeDoubleClicked)


self.ui.graphicsView.horizontalScrollBar().valueChanged.connect(self.slot_horizontalScrollBarChanged)
self.ui.graphicsView.verticalScrollBar().valueChanged.connect(self.slot_verticalScrollBarChanged)

self.scene.scaleChanged.connect(self.slot_canvasScaleChanged)
self.scene.sceneGroupMoved.connect(self.slot_canvasItemMoved)
self.scene.pluginSelected.connect(self.slot_canvasPluginSelected)

self.ui.miniCanvasPreview.miniCanvasMoved.connect(self.slot_miniCanvasMoved)

self.SIGUSR1.connect(self.slot_handleSIGUSR1) self.SIGUSR1.connect(self.slot_handleSIGUSR1)
self.SIGTERM.connect(self.slot_handleSIGTERM) self.SIGTERM.connect(self.slot_handleSIGTERM)


@@ -248,6 +320,16 @@ class HostWindow(QMainWindow):
host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback) host.PluginAddedCallback.connect(self.slot_handlePluginAddedCallback)
host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback) host.PluginRemovedCallback.connect(self.slot_handlePluginRemovedCallback)


host.PatchbayClientAddedCallback.connect(self.slot_handlePatchbayClientAddedCallback)
host.PatchbayClientRemovedCallback.connect(self.slot_handlePatchbayClientRemovedCallback)
host.PatchbayClientRenamedCallback.connect(self.slot_handlePatchbayClientRenamedCallback)
host.PatchbayClientDataChangedCallback.connect(self.slot_handlePatchbayClientDataChangedCallback)
host.PatchbayPortAddedCallback.connect(self.slot_handlePatchbayPortAddedCallback)
host.PatchbayPortRemovedCallback.connect(self.slot_handlePatchbayPortRemovedCallback)
host.PatchbayPortRenamedCallback.connect(self.slot_handlePatchbayPortRenamedCallback)
host.PatchbayConnectionAddedCallback.connect(self.slot_handlePatchbayConnectionAddedCallback)
host.PatchbayConnectionRemovedCallback.connect(self.slot_handlePatchbayConnectionRemovedCallback)

host.DebugCallback.connect(self.slot_handleDebugCallback) host.DebugCallback.connect(self.slot_handleDebugCallback)
host.InfoCallback.connect(self.slot_handleInfoCallback) host.InfoCallback.connect(self.slot_handleInfoCallback)
host.ErrorCallback.connect(self.slot_handleErrorCallback) host.ErrorCallback.connect(self.slot_handleErrorCallback)
@@ -258,6 +340,11 @@ class HostWindow(QMainWindow):


self.setProperWindowTitle() self.setProperWindowTitle()


# FIXME: Qt4 needs this so it properly creates & resizes the canvas
self.ui.tabWidget.setCurrentIndex(1)
self.ui.tabWidget.setCurrentIndex(0)
self.fixCanvasPreviewSize()

QTimer.singleShot(0, self.slot_engineStart) QTimer.singleShot(0, self.slot_engineStart)


# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------
@@ -272,6 +359,120 @@ class HostWindow(QMainWindow):


self.setWindowTitle(title) self.setWindowTitle(title)


def setupCanvas(self):
pOptions = patchcanvas.options_t()
pOptions.theme_name = self.fSavedSettings[CARLA_KEY_CANVAS_THEME]
pOptions.auto_hide_groups = self.fSavedSettings[CARLA_KEY_CANVAS_AUTO_HIDE_GROUPS]
pOptions.use_bezier_lines = self.fSavedSettings[CARLA_KEY_CANVAS_USE_BEZIER_LINES]
pOptions.antialiasing = self.fSavedSettings[CARLA_KEY_CANVAS_ANTIALIASING]
pOptions.eyecandy = self.fSavedSettings[CARLA_KEY_CANVAS_EYE_CANDY]

pFeatures = patchcanvas.features_t()
pFeatures.group_info = False
pFeatures.group_rename = False
pFeatures.port_info = False
pFeatures.port_rename = False
pFeatures.handle_group_pos = True

patchcanvas.setOptions(pOptions)
patchcanvas.setFeatures(pFeatures)
patchcanvas.init("Carla2", self.scene, canvasCallback, False)

tryCanvasSize = self.fSavedSettings[CARLA_KEY_CANVAS_SIZE].split("x")

if len(tryCanvasSize) == 2 and tryCanvasSize[0].isdigit() and tryCanvasSize[1].isdigit():
self.fCanvasWidth = int(tryCanvasSize[0])
self.fCanvasHeight = int(tryCanvasSize[1])
else:
self.fCanvasWidth = CARLA_DEFAULT_CANVAS_SIZE_WIDTH
self.fCanvasHeight = CARLA_DEFAULT_CANVAS_SIZE_HEIGHT

patchcanvas.setCanvasSize(0, 0, self.fCanvasWidth, self.fCanvasHeight)
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)

def updateCanvasInitialPos(self):
x = self.ui.graphicsView.horizontalScrollBar().value() + self.width()/4
y = self.ui.graphicsView.verticalScrollBar().value() + self.height()/4
patchcanvas.setInitialPos(x, y)

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

@pyqtSlot(bool)
def slot_showCanvasMeters(self, yesNo):
self.ui.peak_in.setVisible(yesNo)
self.ui.peak_out.setVisible(yesNo)

@pyqtSlot(bool)
def slot_showCanvasKeyboard(self, yesNo):
self.ui.scrollArea.setVisible(yesNo)

@pyqtSlot()
def slot_restoreScrollbarValues(self):
settings = QSettings()
self.ui.graphicsView.horizontalScrollBar().setValue(settings.value("HorizontalScrollBarValue", self.ui.graphicsView.horizontalScrollBar().maximum()/2, type=int))
self.ui.graphicsView.verticalScrollBar().setValue(settings.value("VerticalScrollBarValue", self.ui.graphicsView.verticalScrollBar().maximum()/2, type=int))

@pyqtSlot()
def slot_miniCanvasCheckAll(self):
self.slot_miniCanvasCheckSize()
self.slot_horizontalScrollBarChanged(self.ui.graphicsView.horizontalScrollBar().value())
self.slot_verticalScrollBarChanged(self.ui.graphicsView.verticalScrollBar().value())

@pyqtSlot()
def slot_miniCanvasCheckSize(self):
self.ui.miniCanvasPreview.setViewSize(float(self.width()) / self.fCanvasWidth, float(self.height()) / self.fCanvasHeight)

@pyqtSlot(int)
def slot_horizontalScrollBarChanged(self, value):
if self.fMovingViaMiniCanvas: return

maximum = self.ui.graphicsView.horizontalScrollBar().maximum()
if maximum == 0:
xp = 0
else:
xp = float(value) / maximum
self.ui.miniCanvasPreview.setViewPosX(xp)
self.updateCanvasInitialPos()

@pyqtSlot(int)
def slot_verticalScrollBarChanged(self, value):
if self.fMovingViaMiniCanvas: return

maximum = self.ui.graphicsView.verticalScrollBar().maximum()
if maximum == 0:
yp = 0
else:
yp = float(value) / maximum
self.ui.miniCanvasPreview.setViewPosY(yp)
self.updateCanvasInitialPos()

@pyqtSlot(float)
def slot_canvasScaleChanged(self, scale):
self.ui.miniCanvasPreview.setViewScale(scale)

@pyqtSlot(int, int, QPointF)
def slot_canvasItemMoved(self, group_id, split_mode, pos):
self.ui.miniCanvasPreview.update()

@pyqtSlot(list)
def slot_canvasPluginSelected(self, pluginList):
self.ui.keyboard.allNotesOff(False)
self.ui.scrollArea.setEnabled(len(pluginList) != 0) # and self.fPluginCount > 0
self.fSelectedPlugins = pluginList

@pyqtSlot(float, float)
def slot_miniCanvasMoved(self, xp, yp):
self.fMovingViaMiniCanvas = True
self.ui.graphicsView.horizontalScrollBar().setValue(xp * self.ui.graphicsView.horizontalScrollBar().maximum())
self.ui.graphicsView.verticalScrollBar().setValue(yp * self.ui.graphicsView.verticalScrollBar().maximum())
self.fMovingViaMiniCanvas = False
self.updateCanvasInitialPos()

# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------
# Called by containers # Called by containers


@@ -285,36 +486,37 @@ class HostWindow(QMainWindow):
self.fLadspaRdfNeedsUpdate = True self.fLadspaRdfNeedsUpdate = True


def setupContainer(self, showCanvas, canvasThemeData = []): 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.setCentralWidget(self.fContainer)
self.ui.centralwidget = self.fContainer
#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): def updateContainer(self, canvasThemeData):
canvasWidth, canvasHeight, canvasBg, canvasBrush, canvasPen = canvasThemeData canvasWidth, canvasHeight, canvasBg, canvasBrush, canvasPen = canvasThemeData
self.ui.miniCanvasPreview.setViewTheme(canvasBg, canvasBrush, canvasPen) self.ui.miniCanvasPreview.setViewTheme(canvasBg, canvasBrush, canvasPen)
self.ui.miniCanvasPreview.init(self.fContainer.scene, canvasWidth, canvasHeight, self.fSavedSettings[CARLA_KEY_CUSTOM_PAINTING])
self.ui.miniCanvasPreview.init(self.scene, canvasWidth, canvasHeight, self.fSavedSettings[CARLA_KEY_CUSTOM_PAINTING])


# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------
# Called by the signal handler # Called by the signal handler
@@ -665,6 +867,117 @@ class HostWindow(QMainWindow):
def slot_handlePluginRemovedCallback(self, pluginId): def slot_handlePluginRemovedCallback(self, pluginId):
self.ui.act_plugin_remove_all.setEnabled(self.host.get_current_plugin_count() > 0) self.ui.act_plugin_remove_all.setEnabled(self.host.get_current_plugin_count() > 0)


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

@pyqtSlot(int, int, int, str)
def slot_handlePatchbayClientAddedCallback(self, clientId, clientIcon, pluginId, clientName):
pcSplit = patchcanvas.SPLIT_UNDEF
pcIcon = patchcanvas.ICON_APPLICATION

if clientIcon == PATCHBAY_ICON_PLUGIN:
pcIcon = patchcanvas.ICON_PLUGIN
if clientIcon == PATCHBAY_ICON_HARDWARE:
pcIcon = patchcanvas.ICON_HARDWARE
elif clientIcon == PATCHBAY_ICON_CARLA:
pass
elif clientIcon == PATCHBAY_ICON_DISTRHO:
pcIcon = patchcanvas.ICON_DISTRHO
elif clientIcon == PATCHBAY_ICON_FILE:
pcIcon = patchcanvas.ICON_FILE

patchcanvas.addGroup(clientId, clientName, pcSplit, pcIcon)

QTimer.singleShot(0, self.ui.miniCanvasPreview.update)

if pluginId < 0:
return
if pluginId >= self.fPluginCount:
print("sorry, can't map this plugin to canvas client", pluginId, self.fPluginCount)
return

patchcanvas.setGroupAsPlugin(clientId, pluginId, bool(self.host.get_plugin_info(pluginId)['hints'] & PLUGIN_HAS_CUSTOM_UI))

@pyqtSlot(int)
def slot_handlePatchbayClientRemovedCallback(self, clientId):
#if not self.fEngineStarted: return
patchcanvas.removeGroup(clientId)
QTimer.singleShot(0, self.ui.miniCanvasPreview.update)

@pyqtSlot(int, str)
def slot_handlePatchbayClientRenamedCallback(self, clientId, newClientName):
patchcanvas.renameGroup(clientId, newClientName)
QTimer.singleShot(0, self.ui.miniCanvasPreview.update)

@pyqtSlot(int, int, int)
def slot_handlePatchbayClientDataChangedCallback(self, clientId, clientIcon, pluginId):
pcIcon = patchcanvas.ICON_APPLICATION

if clientIcon == PATCHBAY_ICON_PLUGIN:
pcIcon = patchcanvas.ICON_PLUGIN
if clientIcon == PATCHBAY_ICON_HARDWARE:
pcIcon = patchcanvas.ICON_HARDWARE
elif clientIcon == PATCHBAY_ICON_CARLA:
pass
elif clientIcon == PATCHBAY_ICON_DISTRHO:
pcIcon = patchcanvas.ICON_DISTRHO
elif clientIcon == PATCHBAY_ICON_FILE:
pcIcon = patchcanvas.ICON_FILE

patchcanvas.setGroupIcon(clientId, pcIcon)
QTimer.singleShot(0, self.ui.miniCanvasPreview.update)

if pluginId < 0:
return
if pluginId >= self.fPluginCount:
print("sorry, can't map this plugin to canvas client", pluginId, self.fPluginCount)
return

patchcanvas.setGroupAsPlugin(clientId, pluginId, bool(self.host.get_plugin_info(pluginId)['hints'] & PLUGIN_HAS_CUSTOM_UI))

@pyqtSlot(int, int, int, str)
def slot_handlePatchbayPortAddedCallback(self, clientId, portId, portFlags, portName):
isAlternate = False

if (portFlags & PATCHBAY_PORT_IS_INPUT):
portMode = patchcanvas.PORT_MODE_INPUT
else:
portMode = patchcanvas.PORT_MODE_OUTPUT

if (portFlags & PATCHBAY_PORT_TYPE_AUDIO):
portType = patchcanvas.PORT_TYPE_AUDIO_JACK
elif (portFlags & PATCHBAY_PORT_TYPE_CV):
isAlternate = True
portType = patchcanvas.PORT_TYPE_AUDIO_JACK
elif (portFlags & PATCHBAY_PORT_TYPE_MIDI):
portType = patchcanvas.PORT_TYPE_MIDI_JACK
else:
portType = patchcanvas.PORT_TYPE_NULL

patchcanvas.addPort(clientId, portId, portName, portMode, portType, isAlternate)
QTimer.singleShot(0, self.ui.miniCanvasPreview.update)

@pyqtSlot(int, int)
def slot_handlePatchbayPortRemovedCallback(self, groupId, portId):
#if not self.fEngineStarted: return
patchcanvas.removePort(groupId, portId)
QTimer.singleShot(0, self.ui.miniCanvasPreview.update)

@pyqtSlot(int, int, str)
def slot_handlePatchbayPortRenamedCallback(self, groupId, portId, newPortName):
patchcanvas.renamePort(groupId, portId, newPortName)
QTimer.singleShot(0, self.ui.miniCanvasPreview.update)

@pyqtSlot(int, int, int, int, int)
def slot_handlePatchbayConnectionAddedCallback(self, connectionId, groupOutId, portOutId, groupInId, portInId):
patchcanvas.connectPorts(connectionId, groupOutId, portOutId, groupInId, portInId)
QTimer.singleShot(0, self.ui.miniCanvasPreview.update)

@pyqtSlot(int, int, int)
def slot_handlePatchbayConnectionRemovedCallback(self, connectionId, portOutId, portInId):
#if not self.fEngineStarted: return
patchcanvas.disconnectPorts(connectionId)
QTimer.singleShot(0, self.ui.miniCanvasPreview.update)

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


@@ -852,6 +1165,15 @@ class HostWindow(QMainWindow):
#if MACOS and not settings.value(CARLA_KEY_MAIN_USE_PRO_THEME, True, type=bool): #if MACOS and not settings.value(CARLA_KEY_MAIN_USE_PRO_THEME, True, type=bool):
# self.setUnifiedTitleAndToolBarOnMac(True) # self.setUnifiedTitleAndToolBarOnMac(True)


showMeters = settings.value("ShowMeters", False, type=bool)
self.ui.act_settings_show_meters.setChecked(showMeters)
self.ui.peak_in.setVisible(showMeters)
self.ui.peak_out.setVisible(showMeters)

showKeyboard = settings.value("ShowKeyboard", not(MACOS or WINDOWS), type=bool)
self.ui.act_settings_show_keyboard.setChecked(showKeyboard)
self.ui.scrollArea.setVisible(showKeyboard)

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


# TODO # TODO
@@ -894,6 +1216,11 @@ class HostWindow(QMainWindow):


settings.setValue("DiskFolders", diskFolders) settings.setValue("DiskFolders", diskFolders)


settings.setValue("ShowMeters", self.ui.act_settings_show_meters.isChecked())
settings.setValue("ShowKeyboard", self.ui.act_settings_show_keyboard.isChecked())
settings.setValue("HorizontalScrollBarValue", self.ui.graphicsView.horizontalScrollBar().value())
settings.setValue("VerticalScrollBarValue", self.ui.graphicsView.verticalScrollBar().value())

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


# ----------------------------------------------------------------- # -----------------------------------------------------------------
@@ -994,15 +1321,58 @@ class HostWindow(QMainWindow):


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


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

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

if self.ui.tabWidget.currentIndex() == 0:
self.fixCanvasPreviewSize()
else:
self.slot_miniCanvasCheckSize()

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

def idleFast(self):
self.host.engine_idle()
self.refreshTransport()

if self.fPluginCount == 0:
return

for pluginId in self.fSelectedPlugins:
self.fPeaksCleared = False
if self.ui.peak_in.isVisible():
self.ui.peak_in.displayMeter(1, self.host.get_input_peak_value(pluginId, True))
self.ui.peak_in.displayMeter(2, self.host.get_input_peak_value(pluginId, False))
if self.ui.peak_out.isVisible():
self.ui.peak_out.displayMeter(1, self.host.get_output_peak_value(pluginId, True))
self.ui.peak_out.displayMeter(2, self.host.get_output_peak_value(pluginId, False))
return

if self.fPeaksCleared:
return

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 idleSlow(self):
for pedit in self.fPluginList:
if pedit is None:
break
pedit.idleSlow()

def timerEvent(self, event): def timerEvent(self, event):
if event.timerId() == self.fIdleTimerFast: if event.timerId() == self.fIdleTimerFast:
#if not self.host.isPlugin:
self.fContainer.idleFast()
self.refreshTransport()
self.host.engine_idle()
self.idleFast()


elif event.timerId() == self.fIdleTimerSlow: elif event.timerId() == self.fIdleTimerSlow:
self.fContainer.idleSlow()
self.idleSlow()


QMainWindow.timerEvent(self, event) QMainWindow.timerEvent(self, event)


@@ -1037,6 +1407,72 @@ class HostWindow(QMainWindow):


QMainWindow.closeEvent(self, event) QMainWindow.closeEvent(self, event)


# ------------------------------------------------------------------------------------------------
# Canvas callback

def canvasCallback(action, value1, value2, valueStr):
host = gCarla.gui.host

if action == patchcanvas.ACTION_GROUP_INFO:
pass

elif action == patchcanvas.ACTION_GROUP_RENAME:
pass

elif action == patchcanvas.ACTION_GROUP_SPLIT:
groupId = value1
patchcanvas.splitGroup(groupId)
gCarla.gui.ui.miniCanvasPreview.update()

elif action == patchcanvas.ACTION_GROUP_JOIN:
groupId = value1
patchcanvas.joinGroup(groupId)
gCarla.gui.ui.miniCanvasPreview.update()

elif action == patchcanvas.ACTION_PORT_INFO:
pass

elif action == patchcanvas.ACTION_PORT_RENAME:
pass

elif action == patchcanvas.ACTION_PORTS_CONNECT:
gOut, pOut, gIn, pIn = [int(i) for i in valueStr.split(":")]

if not host.patchbay_connect(gOut, pOut, gIn, pIn):
print("Connection failed:", host.get_last_error())

elif action == patchcanvas.ACTION_PORTS_DISCONNECT:
connectionId = value1

if not host.patchbay_disconnect(connectionId):
print("Disconnect failed:", host.get_last_error())

elif action == patchcanvas.ACTION_PLUGIN_CLONE:
pluginId = value1

host.clone_plugin(pluginId)

elif action == patchcanvas.ACTION_PLUGIN_EDIT:
pluginId = value1

gCarla.gui.fContainer.showEditDialog(pluginId)

elif action == patchcanvas.ACTION_PLUGIN_RENAME:
pluginId = value1
newName = valueStr

host.rename_plugin(pluginId, newName)

elif action == patchcanvas.ACTION_PLUGIN_REMOVE:
pluginId = value1

host.remove_plugin(pluginId)

elif action == patchcanvas.ACTION_PLUGIN_SHOW_UI:
pluginId = value1

host.show_custom_ui(pluginId, True)

# ------------------------------------------------------------------------------------------------------------ # ------------------------------------------------------------------------------------------------------------
# Engine callback # Engine callback




+ 50
- 500
source/carla_patchbay.py View File

@@ -42,24 +42,6 @@ from carla_host import *
from digitalpeakmeter import DigitalPeakMeter from digitalpeakmeter import DigitalPeakMeter
from pixmapkeyboard import PixmapKeyboardHArea from pixmapkeyboard import PixmapKeyboardHArea


# ------------------------------------------------------------------------------------------------------------
# Try Import OpenGL

try:
if config_UseQt5:
from PyQt5.QtOpenGL import QGLWidget
else:
from PyQt4.QtOpenGL import QGLWidget
hasGL = True
except:
hasGL = False

# ------------------------------------------------------------------------------------------------------------
# Carla Canvas defaults

CARLA_DEFAULT_CANVAS_SIZE_WIDTH = 3100
CARLA_DEFAULT_CANVAS_SIZE_HEIGHT = 2400

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


@@ -111,150 +93,44 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):
QFrame.__init__(self, parent) QFrame.__init__(self, parent)
self.host = host self.host = host


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

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

self.fLayout = QGridLayout(self)
self.fLayout.setContentsMargins(0, 0, 0, 0)
self.fLayout.setSpacing(1)
self.setLayout(self.fLayout)

self.fView = QGraphicsView(self)
self.fKeys = PixmapKeyboardHArea(self)

self.fPeaksIn = DigitalPeakMeter(self)
self.fPeaksOut = DigitalPeakMeter(self)
self.fPeaksCleared = True

self.fPeaksIn.setColor(DigitalPeakMeter.BLUE)
self.fPeaksIn.setChannels(2)
self.fPeaksIn.setOrientation(DigitalPeakMeter.VERTICAL)
self.fPeaksIn.setFixedWidth(25)

self.fPeaksOut.setColor(DigitalPeakMeter.GREEN)
self.fPeaksOut.setChannels(2)
self.fPeaksOut.setOrientation(DigitalPeakMeter.VERTICAL)
self.fPeaksOut.setFixedWidth(25)

self.fLayout.addWidget(self.fPeaksIn, 0, 0)
self.fLayout.addWidget(self.fView, 0, 1) # self.fViewWidget if is3D else
self.fLayout.addWidget(self.fPeaksOut, 0, 2)
self.fLayout.addWidget(self.fKeys, 1, 0, 1, 0)

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

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

self.fExternalPatchbay = False
self.fIsOnlyPatchbay = onlyPatchbay
self.fSelectedPlugins = []

self.fCanvasWidth = 0
self.fCanvasHeight = 0

# -------------------------------------------------------------
# Set-up Canvas Preview

self.fMiniCanvasPreview = self.fParent.ui.miniCanvasPreview
self.fMiniCanvasPreview.setRealParent(self)
self.fMovingViaMiniCanvas = False

# -------------------------------------------------------------
# Set-up Canvas

self.scene = patchcanvas.PatchScene(self, self.fView)
self.fView.setScene(self.scene)
self.fView.setRenderHint(QPainter.Antialiasing, bool(parent.fSavedSettings[CARLA_KEY_CANVAS_ANTIALIASING] == patchcanvas.ANTIALIASING_FULL))

if parent.fSavedSettings[CARLA_KEY_CANVAS_USE_OPENGL] and hasGL: # and not is3D:
self.fViewWidget = QGLWidget(self)
self.fView.setViewport(self.fViewWidget)
self.fView.setRenderHint(QPainter.HighQualityAntialiasing, parent.fSavedSettings[CARLA_KEY_CANVAS_HQ_ANTIALIASING])

self.setupCanvas()

QTimer.singleShot(100, self.slot_restoreScrollbarValues)

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


parent.ui.act_settings_show_meters.toggled.connect(self.slot_showCanvasMeters)
parent.ui.act_settings_show_keyboard.toggled.connect(self.slot_showCanvasKeyboard)

self.fView.horizontalScrollBar().valueChanged.connect(self.slot_horizontalScrollBarChanged)
self.fView.verticalScrollBar().valueChanged.connect(self.slot_verticalScrollBarChanged)

self.scene.scaleChanged.connect(self.slot_canvasScaleChanged)
self.scene.sceneGroupMoved.connect(self.slot_canvasItemMoved)
self.scene.pluginSelected.connect(self.slot_canvasPluginSelected)

self.fMiniCanvasPreview.miniCanvasMoved.connect(self.slot_miniCanvasMoved)

self.fKeys.keyboard.noteOn.connect(self.slot_noteOn)
self.fKeys.keyboard.noteOff.connect(self.slot_noteOff)

# -------------------------------------------------------------
# Load Settings

settings = QSettings()

showMeters = settings.value("ShowMeters", False, type=bool)
self.fParent.ui.act_settings_show_meters.setChecked(showMeters)
self.fPeaksIn.setVisible(showMeters)
self.fPeaksOut.setVisible(showMeters)

showKeyboard = settings.value("ShowKeyboard", not(MACOS or WINDOWS), type=bool)
self.fParent.ui.act_settings_show_keyboard.setChecked(showKeyboard)
self.fKeys.setVisible(showKeyboard)
#self.fKeys.keyboard.noteOn.connect(self.slot_noteOn)
#self.fKeys.keyboard.noteOff.connect(self.slot_noteOff)


# ------------------------------------------------------------- # -------------------------------------------------------------
# Connect actions to functions (part 2) # 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)
host.PatchbayClientAddedCallback.connect(self.slot_handlePatchbayClientAddedCallback)
host.PatchbayClientRemovedCallback.connect(self.slot_handlePatchbayClientRemovedCallback)
host.PatchbayClientRenamedCallback.connect(self.slot_handlePatchbayClientRenamedCallback)
host.PatchbayClientDataChangedCallback.connect(self.slot_handlePatchbayClientDataChangedCallback)
host.PatchbayPortAddedCallback.connect(self.slot_handlePatchbayPortAddedCallback)
host.PatchbayPortRemovedCallback.connect(self.slot_handlePatchbayPortRemovedCallback)
host.PatchbayPortRenamedCallback.connect(self.slot_handlePatchbayPortRenamedCallback)
host.PatchbayConnectionAddedCallback.connect(self.slot_handlePatchbayConnectionAddedCallback)
host.PatchbayConnectionRemovedCallback.connect(self.slot_handlePatchbayConnectionRemovedCallback)

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)
#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)


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


@@ -320,7 +196,7 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):
# HostWidgetMeta methods # HostWidgetMeta methods


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


for pedit in self.fPluginList: for pedit in self.fPluginList:
if pedit is None: if pedit is None:
@@ -337,49 +213,20 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):
pass pass


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

def idleFast(self):
if self.fPluginCount == 0:
return

for pluginId in self.fSelectedPlugins:
self.fPeaksCleared = False
if self.fPeaksIn.isVisible():
self.fPeaksIn.displayMeter(1, self.host.get_input_peak_value(pluginId, True))
self.fPeaksIn.displayMeter(2, self.host.get_input_peak_value(pluginId, False))
if self.fPeaksOut.isVisible():
self.fPeaksOut.displayMeter(1, self.host.get_output_peak_value(pluginId, True))
self.fPeaksOut.displayMeter(2, self.host.get_output_peak_value(pluginId, False))
return

if self.fPeaksCleared:
return

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)

def idleSlow(self):
for pedit in self.fPluginList:
if pedit is None:
break
pedit.idleSlow()
pass
#patchcanvas.clear()


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


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


def saveSettings(self, settings): def saveSettings(self, settings):
settings.setValue("ShowMeters", self.fParent.ui.act_settings_show_meters.isChecked())
settings.setValue("ShowKeyboard", self.fParent.ui.act_settings_show_keyboard.isChecked())
settings.setValue("HorizontalScrollBarValue", self.fView.horizontalScrollBar().value())
settings.setValue("VerticalScrollBarValue", self.fView.verticalScrollBar().value())
pass


def showEditDialog(self, pluginId): def showEditDialog(self, pluginId):
pedit = self.getPluginEditDialog(pluginId) pedit = self.getPluginEditDialog(pluginId)
@@ -419,134 +266,18 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):
# ----------------------------------------------------------------- # -----------------------------------------------------------------


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


self.fSelectedPlugins = [] 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)

def setupCanvas(self):
pOptions = patchcanvas.options_t()
pOptions.theme_name = self.fParent.fSavedSettings[CARLA_KEY_CANVAS_THEME]
pOptions.auto_hide_groups = self.fParent.fSavedSettings[CARLA_KEY_CANVAS_AUTO_HIDE_GROUPS]
pOptions.use_bezier_lines = self.fParent.fSavedSettings[CARLA_KEY_CANVAS_USE_BEZIER_LINES]
pOptions.antialiasing = self.fParent.fSavedSettings[CARLA_KEY_CANVAS_ANTIALIASING]
pOptions.eyecandy = self.fParent.fSavedSettings[CARLA_KEY_CANVAS_EYE_CANDY]

pFeatures = patchcanvas.features_t()
pFeatures.group_info = False
pFeatures.group_rename = False
pFeatures.port_info = False
pFeatures.port_rename = False
pFeatures.handle_group_pos = True

patchcanvas.setOptions(pOptions)
patchcanvas.setFeatures(pFeatures)
patchcanvas.init("Carla2", self.scene, canvasCallback, False)

tryCanvasSize = self.fParent.fSavedSettings[CARLA_KEY_CANVAS_SIZE].split("x")

if len(tryCanvasSize) == 2 and tryCanvasSize[0].isdigit() and tryCanvasSize[1].isdigit():
self.fCanvasWidth = int(tryCanvasSize[0])
self.fCanvasHeight = int(tryCanvasSize[1])
else:
self.fCanvasWidth = CARLA_DEFAULT_CANVAS_SIZE_WIDTH
self.fCanvasHeight = CARLA_DEFAULT_CANVAS_SIZE_HEIGHT

patchcanvas.setCanvasSize(0, 0, self.fCanvasWidth, self.fCanvasHeight)
patchcanvas.setInitialPos(self.fCanvasWidth / 2, self.fCanvasHeight / 2)
self.fView.setSceneRect(0, 0, self.fCanvasWidth, self.fCanvasHeight)

self.themeData = [self.fCanvasWidth, self.fCanvasHeight, patchcanvas.canvas.theme.canvas_bg, patchcanvas.canvas.theme.rubberband_brush, patchcanvas.canvas.theme.rubberband_pen.color()]
#self.fKeys.keyboard.allNotesOff(False)
#self.fKeys.setEnabled(False)


def updateCanvasInitialPos(self):
x = self.fView.horizontalScrollBar().value() + self.width()/4
y = self.fView.verticalScrollBar().value() + self.height()/4
patchcanvas.setInitialPos(x, y)

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

@pyqtSlot(bool)
def slot_showCanvasMeters(self, yesNo):
self.fPeaksIn.setVisible(yesNo)
self.fPeaksOut.setVisible(yesNo)

@pyqtSlot(bool)
def slot_showCanvasKeyboard(self, yesNo):
self.fKeys.setVisible(yesNo)

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

@pyqtSlot()
def slot_miniCanvasCheckAll(self):
self.slot_miniCanvasCheckSize()
self.slot_horizontalScrollBarChanged(self.fView.horizontalScrollBar().value())
self.slot_verticalScrollBarChanged(self.fView.verticalScrollBar().value())

@pyqtSlot()
def slot_miniCanvasCheckSize(self):
self.fMiniCanvasPreview.setViewSize(float(self.width()) / self.fCanvasWidth, float(self.height()) / self.fCanvasHeight)

@pyqtSlot(int)
def slot_horizontalScrollBarChanged(self, value):
if self.fMovingViaMiniCanvas: return

maximum = self.fView.horizontalScrollBar().maximum()
if maximum == 0:
xp = 0
else:
xp = float(value) / maximum
self.fMiniCanvasPreview.setViewPosX(xp)
self.updateCanvasInitialPos()

@pyqtSlot(int)
def slot_verticalScrollBarChanged(self, value):
if self.fMovingViaMiniCanvas: return

maximum = self.fView.verticalScrollBar().maximum()
if maximum == 0:
yp = 0
else:
yp = float(value) / maximum
self.fMiniCanvasPreview.setViewPosY(yp)
self.updateCanvasInitialPos()

@pyqtSlot()
def slot_restoreScrollbarValues(self):
settings = QSettings()
self.fView.horizontalScrollBar().setValue(settings.value("HorizontalScrollBarValue", self.fView.horizontalScrollBar().maximum()/2, type=int))
self.fView.verticalScrollBar().setValue(settings.value("VerticalScrollBarValue", self.fView.verticalScrollBar().maximum()/2, type=int))

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

@pyqtSlot(float)
def slot_canvasScaleChanged(self, scale):
self.fMiniCanvasPreview.setViewScale(scale)

@pyqtSlot(int, int, QPointF)
def slot_canvasItemMoved(self, group_id, split_mode, pos):
self.fMiniCanvasPreview.update()

@pyqtSlot(list)
def slot_canvasPluginSelected(self, pluginList):
self.fKeys.keyboard.allNotesOff(False)
self.fKeys.setEnabled(len(pluginList) != 0) # and self.fPluginCount > 0
self.fSelectedPlugins = pluginList

@pyqtSlot(float, float)
def slot_miniCanvasMoved(self, xp, yp):
self.fMovingViaMiniCanvas = True
self.fView.horizontalScrollBar().setValue(xp * self.fView.horizontalScrollBar().maximum())
self.fView.verticalScrollBar().setValue(yp * self.fView.verticalScrollBar().maximum())
self.fMovingViaMiniCanvas = False
self.updateCanvasInitialPos()
#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)


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


@@ -674,124 +405,13 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):


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


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


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


@pyqtSlot(int, int, int, str)
def slot_handlePatchbayClientAddedCallback(self, clientId, clientIcon, pluginId, clientName):
pcSplit = patchcanvas.SPLIT_UNDEF
pcIcon = patchcanvas.ICON_APPLICATION

if clientIcon == PATCHBAY_ICON_PLUGIN:
pcIcon = patchcanvas.ICON_PLUGIN
if clientIcon == PATCHBAY_ICON_HARDWARE:
pcIcon = patchcanvas.ICON_HARDWARE
elif clientIcon == PATCHBAY_ICON_CARLA:
pass
elif clientIcon == PATCHBAY_ICON_DISTRHO:
pcIcon = patchcanvas.ICON_DISTRHO
elif clientIcon == PATCHBAY_ICON_FILE:
pcIcon = patchcanvas.ICON_FILE

patchcanvas.addGroup(clientId, clientName, pcSplit, pcIcon)

QTimer.singleShot(0, self.fMiniCanvasPreview.update)

if pluginId < 0:
return
if pluginId >= self.fPluginCount:
print("sorry, can't map this plugin to canvas client", pluginId, self.fPluginCount)
return

patchcanvas.setGroupAsPlugin(clientId, pluginId, bool(self.host.get_plugin_info(pluginId)['hints'] & PLUGIN_HAS_CUSTOM_UI))

@pyqtSlot(int)
def slot_handlePatchbayClientRemovedCallback(self, clientId):
#if not self.fEngineStarted: return
patchcanvas.removeGroup(clientId)
QTimer.singleShot(0, self.fMiniCanvasPreview.update)

@pyqtSlot(int, str)
def slot_handlePatchbayClientRenamedCallback(self, clientId, newClientName):
patchcanvas.renameGroup(clientId, newClientName)
QTimer.singleShot(0, self.fMiniCanvasPreview.update)

@pyqtSlot(int, int, int)
def slot_handlePatchbayClientDataChangedCallback(self, clientId, clientIcon, pluginId):
pcIcon = patchcanvas.ICON_APPLICATION

if clientIcon == PATCHBAY_ICON_PLUGIN:
pcIcon = patchcanvas.ICON_PLUGIN
if clientIcon == PATCHBAY_ICON_HARDWARE:
pcIcon = patchcanvas.ICON_HARDWARE
elif clientIcon == PATCHBAY_ICON_CARLA:
pass
elif clientIcon == PATCHBAY_ICON_DISTRHO:
pcIcon = patchcanvas.ICON_DISTRHO
elif clientIcon == PATCHBAY_ICON_FILE:
pcIcon = patchcanvas.ICON_FILE

patchcanvas.setGroupIcon(clientId, pcIcon)
QTimer.singleShot(0, self.fMiniCanvasPreview.update)

if pluginId < 0:
return
if pluginId >= self.fPluginCount:
print("sorry, can't map this plugin to canvas client", pluginId, self.fPluginCount)
return

patchcanvas.setGroupAsPlugin(clientId, pluginId, bool(self.host.get_plugin_info(pluginId)['hints'] & PLUGIN_HAS_CUSTOM_UI))

@pyqtSlot(int, int, int, str)
def slot_handlePatchbayPortAddedCallback(self, clientId, portId, portFlags, portName):
isAlternate = False

if (portFlags & PATCHBAY_PORT_IS_INPUT):
portMode = patchcanvas.PORT_MODE_INPUT
else:
portMode = patchcanvas.PORT_MODE_OUTPUT

if (portFlags & PATCHBAY_PORT_TYPE_AUDIO):
portType = patchcanvas.PORT_TYPE_AUDIO_JACK
elif (portFlags & PATCHBAY_PORT_TYPE_CV):
isAlternate = True
portType = patchcanvas.PORT_TYPE_AUDIO_JACK
elif (portFlags & PATCHBAY_PORT_TYPE_MIDI):
portType = patchcanvas.PORT_TYPE_MIDI_JACK
else:
portType = patchcanvas.PORT_TYPE_NULL

patchcanvas.addPort(clientId, portId, portName, portMode, portType, isAlternate)
QTimer.singleShot(0, self.fMiniCanvasPreview.update)

@pyqtSlot(int, int)
def slot_handlePatchbayPortRemovedCallback(self, groupId, portId):
#if not self.fEngineStarted: return
patchcanvas.removePort(groupId, portId)
QTimer.singleShot(0, self.fMiniCanvasPreview.update)

@pyqtSlot(int, int, str)
def slot_handlePatchbayPortRenamedCallback(self, groupId, portId, newPortName):
patchcanvas.renamePort(groupId, portId, newPortName)
QTimer.singleShot(0, self.fMiniCanvasPreview.update)

@pyqtSlot(int, int, int, int, int)
def slot_handlePatchbayConnectionAddedCallback(self, connectionId, groupOutId, portOutId, groupInId, portInId):
patchcanvas.connectPorts(connectionId, groupOutId, portOutId, groupInId, portInId)
QTimer.singleShot(0, self.fMiniCanvasPreview.update)

@pyqtSlot(int, int, int)
def slot_handlePatchbayConnectionRemovedCallback(self, connectionId, portOutId, portInId):
#if not self.fEngineStarted: return
patchcanvas.disconnectPorts(connectionId)
QTimer.singleShot(0, self.fMiniCanvasPreview.update)

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

@pyqtSlot() @pyqtSlot()
def slot_canvasArrange(self): def slot_canvasArrange(self):
patchcanvas.arrange() patchcanvas.arrange()
@@ -820,7 +440,7 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):


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


if self.host.is_engine_running(): if self.host.is_engine_running():
self.host.patchbay_refresh(self.fExternalPatchbay) self.host.patchbay_refresh(self.fExternalPatchbay)
@@ -892,73 +512,3 @@ class CarlaPatchbayW(QFrame, PluginEditParentMeta, HostWidgetMeta):
painter.restore() painter.restore()


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

def resizeEvent(self, event):
QFrame.resizeEvent(self, event)
self.slot_miniCanvasCheckSize()

# ------------------------------------------------------------------------------------------------
# Canvas callback

def canvasCallback(action, value1, value2, valueStr):
host = gCarla.gui.host

if action == patchcanvas.ACTION_GROUP_INFO:
pass

elif action == patchcanvas.ACTION_GROUP_RENAME:
pass

elif action == patchcanvas.ACTION_GROUP_SPLIT:
groupId = value1
patchcanvas.splitGroup(groupId)
gCarla.gui.ui.miniCanvasPreview.update()

elif action == patchcanvas.ACTION_GROUP_JOIN:
groupId = value1
patchcanvas.joinGroup(groupId)
gCarla.gui.ui.miniCanvasPreview.update()

elif action == patchcanvas.ACTION_PORT_INFO:
pass

elif action == patchcanvas.ACTION_PORT_RENAME:
pass

elif action == patchcanvas.ACTION_PORTS_CONNECT:
gOut, pOut, gIn, pIn = [int(i) for i in valueStr.split(":")]

if not host.patchbay_connect(gOut, pOut, gIn, pIn):
print("Connection failed:", host.get_last_error())

elif action == patchcanvas.ACTION_PORTS_DISCONNECT:
connectionId = value1

if not host.patchbay_disconnect(connectionId):
print("Disconnect failed:", host.get_last_error())

elif action == patchcanvas.ACTION_PLUGIN_CLONE:
pluginId = value1

host.clone_plugin(pluginId)

elif action == patchcanvas.ACTION_PLUGIN_EDIT:
pluginId = value1

gCarla.gui.fContainer.showEditDialog(pluginId)

elif action == patchcanvas.ACTION_PLUGIN_RENAME:
pluginId = value1
newName = valueStr

host.rename_plugin(pluginId, newName)

elif action == patchcanvas.ACTION_PLUGIN_REMOVE:
pluginId = value1

host.remove_plugin(pluginId)

elif action == patchcanvas.ACTION_PLUGIN_SHOW_UI:
pluginId = value1

host.show_custom_ui(pluginId, True)

Loading…
Cancel
Save