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.

235 lines
7.9KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla rack widget code
  4. # Copyright (C) 2011-2014 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 (Config)
  19. from carla_config import *
  20. # ------------------------------------------------------------------------------------------------------------
  21. # Imports (Global)
  22. if config_UseQt5:
  23. from PyQt5.QtCore import Qt, QSize, QTimer
  24. from PyQt5.QtGui import QPixmap
  25. from PyQt5.QtWidgets import QAbstractItemView, QApplication, QHBoxLayout, QLabel, QListWidget, QListWidgetItem
  26. else:
  27. from PyQt4.QtCore import Qt, QSize, QTimer
  28. from PyQt4.QtGui import QAbstractItemView, QApplication, QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QPixmap
  29. # ------------------------------------------------------------------------------------------------------------
  30. # Imports (Custom Stuff)
  31. from carla_host import *
  32. from carla_skin import *
  33. # ------------------------------------------------------------------------------------------------------------
  34. # Rack widget item
  35. class CarlaRackItem(QListWidgetItem):
  36. kRackItemType = QListWidgetItem.UserType + 1
  37. def __init__(self, parent, pluginId, useSkins):
  38. QListWidgetItem.__init__(self, parent, self.kRackItemType)
  39. # ----------------------------------------------------------------------------------------------------
  40. # Internal stuff
  41. self.fParent = parent
  42. self.fPluginId = pluginId
  43. self.fUseSkins = useSkins
  44. self.fWidget = None
  45. self.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
  46. #self.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled|Qt.ItemIsDragEnabled|Qt.ItemIsDropEnabled)
  47. # ----------------------------------------------------------------------------------------------------
  48. # Set-up GUI
  49. self.recreateWidget()
  50. if False:
  51. self.fWidget = AbstractPluginSlot(parent, parent.host, pluginId)
  52. # --------------------------------------------------------------------------------------------------------
  53. def setPluginId(self, pluginId):
  54. self.fPluginId = pluginId
  55. self.fWidget.setPluginId(pluginId)
  56. # --------------------------------------------------------------------------------------------------------
  57. def getEditDialog(self):
  58. return self.fWidget.fEditDialog
  59. def closeEditDialog(self):
  60. self.fWidget.fEditDialog.close()
  61. # --------------------------------------------------------------------------------------------------------
  62. def getWidget(self):
  63. return self.fWidget
  64. def recreateWidget(self):
  65. if self.fWidget is not None:
  66. #self.fWidget.fEditDialog.close()
  67. del self.fWidget
  68. self.fWidget = createPluginSlot(self.fParent, self.fParent.host, self.fPluginId, self.fUseSkins)
  69. self.fWidget.setFixedHeight(self.fWidget.getFixedHeight())
  70. self.setSizeHint(QSize(640, self.fWidget.getFixedHeight()))
  71. self.fParent.setItemWidget(self, self.fWidget)
  72. # ------------------------------------------------------------------------------------------------------------
  73. # Rack widget list
  74. class CarlaRackList(QListWidget):
  75. def __init__(self, parent, host):
  76. QListWidget.__init__(self, parent)
  77. self.host = host
  78. if False:
  79. # kdevelop likes this :)
  80. host = CarlaHostMeta()
  81. self.host = host
  82. # -------------------------------------------------------------
  83. exts = host.get_supported_file_extensions().split(";")
  84. # plugin files
  85. exts.append("dll")
  86. if MACOS:
  87. exts.append("dylib")
  88. if not WINDOWS:
  89. exts.append("so")
  90. self.fSupportedExtensions = tuple(i.replace("*.","") for i in exts)
  91. self.fWasLastDragValid = False
  92. self.setMinimumWidth(640+20) # required by zita, 591 was old value
  93. self.setSelectionMode(QAbstractItemView.SingleSelection)
  94. self.setSortingEnabled(False)
  95. #self.setSortingEnabled(True)
  96. self.setDragEnabled(True)
  97. self.setDragDropMode(QAbstractItemView.DropOnly)
  98. self.setDropIndicatorShown(True)
  99. self.viewport().setAcceptDrops(True)
  100. self.setFrameShape(QFrame.NoFrame)
  101. self.setFrameShadow(QFrame.Plain)
  102. self.fPixmapL = QPixmap(":/bitmaps/rack_interior_left.png")
  103. self.fPixmapR = QPixmap(":/bitmaps/rack_interior_right.png")
  104. self.fPixmapWidth = self.fPixmapL.width()
  105. def isDragEventValid(self, urls):
  106. for url in urls:
  107. filename = url.toLocalFile()
  108. if os.path.isdir(filename):
  109. if os.path.exists(os.path.join(filename, "manifest.ttl")):
  110. return True
  111. elif os.path.isfile(filename):
  112. if filename.lower().endswith(self.fSupportedExtensions):
  113. return True
  114. return False
  115. def dragEnterEvent(self, event):
  116. if self.isDragEventValid(event.mimeData().urls()):
  117. self.fWasLastDragValid = True
  118. event.acceptProposedAction()
  119. return
  120. self.fWasLastDragValid = False
  121. QListWidget.dragEnterEvent(self, event)
  122. def dragMoveEvent(self, event):
  123. if self.fWasLastDragValid:
  124. event.acceptProposedAction()
  125. tryItem = self.itemAt(event.pos())
  126. if tryItem is not None:
  127. self.setCurrentRow(tryItem.widget.getPluginId())
  128. else:
  129. self.setCurrentRow(-1)
  130. return
  131. QListWidget.dragMoveEvent(self, event)
  132. #def dragLeaveEvent(self, event):
  133. #self.fWasLastDragValid = False
  134. #QListWidget.dragLeaveEvent(self, event)
  135. def dropEvent(self, event):
  136. event.acceptProposedAction()
  137. urls = event.mimeData().urls()
  138. if len(urls) == 0:
  139. return
  140. tryItem = self.itemAt(event.pos())
  141. if tryItem is not None:
  142. pluginId = tryItem.widget.getPluginId()
  143. self.host.replace_plugin(pluginId)
  144. for url in urls:
  145. filename = url.toLocalFile()
  146. if not self.host.load_file(filename):
  147. CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"),
  148. self.tr("Failed to load file"),
  149. self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
  150. if tryItem is not None:
  151. self.host.replace_plugin(self.parent().fPluginCount)
  152. #tryItem.widget.setActive(True, True, True)
  153. def mousePressEvent(self, event):
  154. if self.itemAt(event.pos()) is None:
  155. event.accept()
  156. self.setCurrentRow(-1)
  157. return
  158. QListWidget.mousePressEvent(self, event)
  159. def paintEvent(self, event):
  160. painter = QPainter(self.viewport())
  161. painter.drawTiledPixmap(0, 0, self.fPixmapWidth, self.height(), self.fPixmapL)
  162. painter.drawTiledPixmap(self.width()-self.fPixmapWidth-2, 0, self.fPixmapWidth, self.height(), self.fPixmapR)
  163. QListWidget.paintEvent(self, event)
  164. # ------------------------------------------------------------------------------------------------------------
  165. # Rack widget
  166. class CarlaRackW(QFrame):
  167. #class CarlaRackW(QFrame, HostWidgetMeta, metaclass=PyQtMetaClass):
  168. def __init__(self, parent, host, doSetup = True):
  169. QFrame.__init__(self, parent)
  170. self.host = host