Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
6.4KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla patchbay widget code
  4. # Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com>
  5. #
  6. # This program is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU General Public License as
  8. # published by the Free Software Foundation; either version 2 of
  9. # the License, or any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # For a full copy of the GNU General Public License see the doc/GPL.txt file.
  17. # ------------------------------------------------------------------------------------------------------------
  18. # Imports (Global)
  19. # ------------------------------------------------------------------------------------------------------------
  20. # Imports (Custom Stuff)
  21. import patchcanvas
  22. from carla_widgets import *
  23. # ------------------------------------------------------------------------------------------------
  24. # Patchbay widget
  25. class CarlaPatchbayW(QWidget):
  26. def __init__(self, parent):
  27. QWidget.__init__(self, parent)
  28. # -------------------------------------------------------------
  29. # Set-up Canvas
  30. self.scene = patchcanvas.PatchScene(self, self.ui.graphicsView)
  31. self.ui.graphicsView.setScene(self.scene)
  32. self.ui.graphicsView.setRenderHint(QPainter.Antialiasing, bool(self.fSavedSettings["Canvas/Antialiasing"] == patchcanvas.ANTIALIASING_FULL))
  33. if self.fSavedSettings["Canvas/UseOpenGL"] and hasGL:
  34. self.ui.graphicsView.setViewport(QGLWidget(self.ui.graphicsView))
  35. self.ui.graphicsView.setRenderHint(QPainter.HighQualityAntialiasing, self.fSavedSettings["Canvas/HighQualityAntialiasing"])
  36. pOptions = patchcanvas.options_t()
  37. pOptions.theme_name = self.fSavedSettings["Canvas/Theme"]
  38. pOptions.auto_hide_groups = self.fSavedSettings["Canvas/AutoHideGroups"]
  39. pOptions.use_bezier_lines = self.fSavedSettings["Canvas/UseBezierLines"]
  40. pOptions.antialiasing = self.fSavedSettings["Canvas/Antialiasing"]
  41. pOptions.eyecandy = self.fSavedSettings["Canvas/EyeCandy"]
  42. pFeatures = patchcanvas.features_t()
  43. pFeatures.group_info = False
  44. pFeatures.group_rename = False
  45. pFeatures.port_info = False
  46. pFeatures.port_rename = False
  47. pFeatures.handle_group_pos = True
  48. patchcanvas.setOptions(pOptions)
  49. patchcanvas.setFeatures(pFeatures)
  50. patchcanvas.init("Carla", self.scene, canvasCallback, False)
  51. patchcanvas.setCanvasSize(0, 0, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT)
  52. patchcanvas.setInitialPos(DEFAULT_CANVAS_WIDTH / 2, DEFAULT_CANVAS_HEIGHT / 2)
  53. self.ui.graphicsView.setSceneRect(0, 0, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT)
  54. @pyqtSlot()
  55. def slot_canvasArrange(self):
  56. patchcanvas.arrange()
  57. @pyqtSlot()
  58. def slot_canvasRefresh(self):
  59. patchcanvas.clear()
  60. if Carla.host.is_engine_running():
  61. Carla.host.patchbay_refresh()
  62. QTimer.singleShot(1000 if self.fSavedSettings['Canvas/EyeCandy'] else 0, self.ui.miniCanvasPreview, SLOT("update()"))
  63. @pyqtSlot()
  64. def slot_canvasZoomFit(self):
  65. self.scene.zoom_fit()
  66. @pyqtSlot()
  67. def slot_canvasZoomIn(self):
  68. self.scene.zoom_in()
  69. @pyqtSlot()
  70. def slot_canvasZoomOut(self):
  71. self.scene.zoom_out()
  72. @pyqtSlot()
  73. def slot_canvasZoomReset(self):
  74. self.scene.zoom_reset()
  75. @pyqtSlot()
  76. def slot_canvasPrint(self):
  77. self.scene.clearSelection()
  78. self.fExportPrinter = QPrinter()
  79. dialog = QPrintDialog(self.fExportPrinter, self)
  80. if dialog.exec_():
  81. painter = QPainter(self.fExportPrinter)
  82. painter.save()
  83. painter.setRenderHint(QPainter.Antialiasing)
  84. painter.setRenderHint(QPainter.TextAntialiasing)
  85. self.scene.render(painter)
  86. painter.restore()
  87. @pyqtSlot()
  88. def slot_canvasSaveImage(self):
  89. newPath = QFileDialog.getSaveFileName(self, self.tr("Save Image"), filter=self.tr("PNG Image (*.png);;JPEG Image (*.jpg)"))
  90. if newPath:
  91. self.scene.clearSelection()
  92. # FIXME - must be a better way...
  93. if newPath.endswith((".jpg", ".jpG", ".jPG", ".JPG", ".JPg", ".Jpg")):
  94. imgFormat = "JPG"
  95. elif newPath.endswith((".png", ".pnG", ".pNG", ".PNG", ".PNg", ".Png")):
  96. imgFormat = "PNG"
  97. else:
  98. # File-dialog may not auto-add the extension
  99. imgFormat = "PNG"
  100. newPath += ".png"
  101. self.fExportImage = QImage(self.scene.sceneRect().width(), self.scene.sceneRect().height(), QImage.Format_RGB32)
  102. painter = QPainter(self.fExportImage)
  103. painter.save()
  104. painter.setRenderHint(QPainter.Antialiasing) # TODO - set true, cleanup this
  105. painter.setRenderHint(QPainter.TextAntialiasing)
  106. self.scene.render(painter)
  107. self.fExportImage.save(newPath, imgFormat, 100)
  108. painter.restore()
  109. # ------------------------------------------------------------------------------------------------
  110. # ...
  111. def canvasCallback(action, value1, value2, valueStr):
  112. if action == patchcanvas.ACTION_GROUP_INFO:
  113. pass
  114. elif action == patchcanvas.ACTION_GROUP_RENAME:
  115. pass
  116. elif action == patchcanvas.ACTION_GROUP_SPLIT:
  117. groupId = value1
  118. patchcanvas.splitGroup(groupId)
  119. Carla.gui.ui.miniCanvasPreview.update()
  120. elif action == patchcanvas.ACTION_GROUP_JOIN:
  121. groupId = value1
  122. patchcanvas.joinGroup(groupId)
  123. Carla.gui.ui.miniCanvasPreview.update()
  124. elif action == patchcanvas.ACTION_PORT_INFO:
  125. pass
  126. elif action == patchcanvas.ACTION_PORT_RENAME:
  127. pass
  128. elif action == patchcanvas.ACTION_PORTS_CONNECT:
  129. portIdA = value1
  130. portIdB = value2
  131. if not Carla.host.patchbay_connect(portIdA, portIdB):
  132. print("Connection failed:", cString(Carla.host.get_last_error()))
  133. elif action == patchcanvas.ACTION_PORTS_DISCONNECT:
  134. connectionId = value1
  135. if not Carla.host.patchbay_disconnect(connectionId):
  136. print("Disconnect failed:", cString(Carla.host.get_last_error()))