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.

carla_skin.py 66KB

10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Carla plugin/slot skin code
  4. # Copyright (C) 2013-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, QRectF
  24. from PyQt5.QtGui import QFont, QFontDatabase, QPen, QPixmap
  25. from PyQt5.QtWidgets import QFrame, QPushButton
  26. else:
  27. from PyQt4.QtCore import Qt, QRectF
  28. from PyQt4.QtGui import QFont, QFontDatabase, QFrame, QPen, QPixmap, QPushButton
  29. # ------------------------------------------------------------------------------------------------------------
  30. # Imports (Custom)
  31. import ui_carla_plugin_calf
  32. import ui_carla_plugin_classic
  33. import ui_carla_plugin_compact
  34. import ui_carla_plugin_default
  35. import ui_carla_plugin_presets
  36. from carla_widgets import *
  37. from digitalpeakmeter import DigitalPeakMeter
  38. from pixmapdial import PixmapDial
  39. # ------------------------------------------------------------------------------------------------------------
  40. # Plugin Skin Rules (WORK IN PROGRESS)
  41. # Base is a QFrame (NoFrame, Plain, 0-size lines), with "PluginWidget" as object name.
  42. # Spacing of the top-most layout must be 1px.
  43. # Top and bottom margins must be 3px (can be splitted between different qt layouts).
  44. # Left and right margins must be 6px (can be splitted between different qt layouts).
  45. # If the left or right side has built-in margins, say a transparent png border,
  46. # those margins must be taken into consideration.
  47. #
  48. # There's a top and bottom layout, separated by a horizontal line.
  49. # Compacted skins do not have the bottom layout and separating line.
  50. # T O P A R E A
  51. #
  52. # -----------------------------------------------------------------
  53. # | <> | <> [ WIDGETS ] [ LEDS ] |
  54. # | BUTTONS <> | <> PLUGIN NAME < spacer > [ WIDGETS ] [ LEDS ] |
  55. # | <> | <> [ WIDGETS ] [ LEDS ] |
  56. # -----------------------------------------------------------------
  57. #
  58. # Buttons area has size fixed. (TBA)
  59. # Spacers at the left of the plugin name must be 8x1 in size (fixed).
  60. # The line before the plugin name must be height-10px (fixed).
  61. # WIDGETS area can be extended to the left, if using meters they should have 80px.
  62. # WIDGETS margins are 4px for left+right and 2px for top+bottom, with 4px spacing.
  63. # ------------------------------------------------------------------------------------------------------------
  64. # Try to "shortify" a parameter name
  65. def getParameterShortName(paramName):
  66. paramName = paramName.split("/",1)[0].split(" (",1)[0].split(" [",1)[0].strip()
  67. paramLow = paramName.lower()
  68. # Cut useless prefix
  69. if paramLow.startswith("compressor "):
  70. paramName = paramName.replace("ompressor ", ".", 1)
  71. paramLow = paramName.lower()
  72. elif paramLow.startswith("room "):
  73. paramName = paramName.split(" ",1)[1]
  74. paramLow = paramName.lower()
  75. # Cut useless suffix
  76. if paramLow.endswith(" level"):
  77. paramName = paramName.rsplit(" ",1)[0]
  78. paramLow = paramName.lower()
  79. elif paramLow.endswith(" time"):
  80. paramName = paramName.rsplit(" ",1)[0]
  81. paramLow = paramName.lower()
  82. # Cut generic names
  83. if "attack" in paramLow:
  84. paramName = paramName.replace("ttack", "tk")
  85. elif "bandwidth" in paramLow:
  86. paramName = paramName.replace("andwidth", "w")
  87. elif "damping" in paramLow:
  88. paramName = paramName.replace("amping", "amp")
  89. elif "distortion" in paramLow:
  90. paramName = paramName.replace("istortion", "ist")
  91. elif "feedback" in paramLow:
  92. paramName = paramName.replace("eedback", "b")
  93. elif "frequency" in paramLow:
  94. paramName = paramName.replace("requency", "req")
  95. elif "input" in paramLow:
  96. paramName = paramName.replace("nput", "n")
  97. elif "makeup" in paramLow:
  98. paramName = paramName.replace("akeup", "kUp" if "Make" in paramName else "kup")
  99. elif "output" in paramLow:
  100. paramName = paramName.replace("utput", "ut")
  101. elif "random" in paramLow:
  102. paramName = paramName.replace("andom", "nd")
  103. elif "threshold" in paramLow:
  104. paramName = paramName.replace("hreshold", "hres")
  105. # remove space if 1st last word is lowercase and the 2nd first is uppercase, or if 2nd is number
  106. if " " in paramName:
  107. name1, name2 = paramName.split(" ", 1)
  108. if (name1[-1].islower() and name2[0].isupper()) or name2.isdigit():
  109. paramName = paramName.replace(" ", "", 1)
  110. # cut stuff if too big
  111. if len(paramName) > 7:
  112. paramName = paramName.replace("a","").replace("e","").replace("i","").replace("o","").replace("u","")
  113. if len(paramName) > 7:
  114. paramName = paramName[:7]
  115. return paramName.strip()
  116. # ------------------------------------------------------------------------------------------------------------
  117. # Get RGB colors for a plugin category
  118. def getColorFromCategory(category):
  119. r = 40
  120. g = 40
  121. b = 40
  122. if category == PLUGIN_CATEGORY_MODULATOR:
  123. r += 10
  124. elif category == PLUGIN_CATEGORY_EQ:
  125. g += 10
  126. elif category == PLUGIN_CATEGORY_FILTER:
  127. b += 10
  128. elif category == PLUGIN_CATEGORY_DELAY:
  129. r += 15
  130. b -= 15
  131. elif category == PLUGIN_CATEGORY_DISTORTION:
  132. g += 10
  133. b += 10
  134. elif category == PLUGIN_CATEGORY_DYNAMICS:
  135. r += 10
  136. b += 10
  137. elif category == PLUGIN_CATEGORY_UTILITY:
  138. r += 10
  139. g += 10
  140. return (r, g, b)
  141. def getModColorFromCategory(category):
  142. if category == PLUGIN_CATEGORY_NONE:
  143. return (40, 40, 40)
  144. if category == PLUGIN_CATEGORY_SYNTH:
  145. return (30, 150, 49)
  146. if category == PLUGIN_CATEGORY_DELAY:
  147. return (47, 47, 47)
  148. if category in (PLUGIN_CATEGORY_EQ, PLUGIN_CATEGORY_FILTER):
  149. return (255, 220, 25)
  150. if category == PLUGIN_CATEGORY_DISTORTION:
  151. return (255, 127, 25)
  152. if category == PLUGIN_CATEGORY_DYNAMICS:
  153. return (255, 25, 25)
  154. if category == PLUGIN_CATEGORY_MODULATOR:
  155. return (109, 31, 142)
  156. if category == PLUGIN_CATEGORY_UTILITY:
  157. return (95, 95, 95)
  158. if category == PLUGIN_CATEGORY_OTHER:
  159. return (92, 210, 254)
  160. return (40, 40, 40)
  161. # ------------------------------------------------------------------------------------------------------------
  162. #
  163. def setPixmapDialStyle(widget, parameterId, parameterCount, skinStyle):
  164. if "calf" in skinStyle:
  165. widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_NO_GRADIENT)
  166. widget.setPixmap(7)
  167. elif skinStyle == "mod":
  168. widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_NO_GRADIENT)
  169. widget.setPixmap(14)
  170. elif skinStyle == "openav":
  171. widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_NO_GRADIENT)
  172. if parameterId == PARAMETER_DRYWET:
  173. widget.setPixmap(13)
  174. elif parameterId == PARAMETER_VOLUME:
  175. widget.setPixmap(12)
  176. else:
  177. widget.setPixmap(11)
  178. else:
  179. if parameterId == PARAMETER_DRYWET:
  180. widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_CARLA_WET)
  181. elif parameterId == PARAMETER_VOLUME:
  182. widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_CARLA_VOL)
  183. else:
  184. _r = 255 - int((float(parameterId)/float(parameterCount))*200.0)
  185. _g = 55 + int((float(parameterId)/float(parameterCount))*200.0)
  186. _b = 0 #(r-40)*4
  187. widget.setCustomPaintColor(QColor(_r, _g, _b))
  188. widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_COLOR)
  189. widget.setPixmap(3)
  190. widget.forceWhiteLabelGradientText()
  191. # ------------------------------------------------------------------------------------------------------------
  192. # Abstract plugin slot
  193. class AbstractPluginSlot(QFrame, PluginEditParentMeta):
  194. #class AbstractPluginSlot(QFrame, PluginEditParentMeta, metaclass=PyQtMetaClass):
  195. def __init__(self, parent, host, pluginId, skinStyle):
  196. QFrame.__init__(self, parent)
  197. self.host = host
  198. if False:
  199. # kdevelop likes this :)
  200. host = CarlaHostNull()
  201. self.host = host
  202. # -------------------------------------------------------------
  203. # Get plugin info
  204. self.fPluginId = pluginId
  205. self.fPluginInfo = host.get_plugin_info(self.fPluginId)
  206. self.fSkinStyle = skinStyle
  207. #if not gCarla.isLocal:
  208. #self.fPluginInfo['hints'] &= ~PLUGIN_HAS_CUSTOM_UI
  209. # -------------------------------------------------------------
  210. # Internal stuff
  211. self.fIsActive = bool(host.get_internal_parameter_value(self.fPluginId, PARAMETER_ACTIVE) >= 0.5)
  212. self.fIsSelected = False
  213. self.fLastGreenLedState = False
  214. self.fLastBlueLedState = False
  215. self.fParameterIconTimer = ICON_STATE_NULL
  216. self.fParameterList = [] # index, widget
  217. audioCountInfo = host.get_audio_port_count_info(self.fPluginId)
  218. self.fPeaksInputCount = int(audioCountInfo['ins'])
  219. self.fPeaksOutputCount = int(audioCountInfo['outs'])
  220. if self.fPeaksInputCount > 2:
  221. self.fPeaksInputCount = 2
  222. if self.fPeaksOutputCount > 2:
  223. self.fPeaksOutputCount = 2
  224. # used during testing
  225. self.fIdleTimerId = 0
  226. # -------------------------------------------------------------
  227. # Set-up GUI
  228. self.fEditDialog = PluginEdit(self, host, self.fPluginId)
  229. # -------------------------------------------------------------
  230. # Set-up common widgets (as none)
  231. self.b_enable = None
  232. self.b_gui = None
  233. self.b_edit = None
  234. self.b_remove = None
  235. self.cb_presets = None
  236. self.label_name = None
  237. self.label_presets = None
  238. self.label_type = None
  239. self.led_control = None
  240. self.led_midi = None
  241. self.led_audio_in = None
  242. self.led_audio_out = None
  243. self.peak_in = None
  244. self.peak_out = None
  245. self.w_knobs_left = None
  246. self.w_knobs_right = None
  247. # -------------------------------------------------------------
  248. # Set-up connections
  249. host.PluginRenamedCallback.connect(self.slot_handlePluginRenamedCallback)
  250. host.PluginUnavailableCallback.connect(self.slot_handlePluginUnavailableCallback)
  251. host.ParameterValueChangedCallback.connect(self.slot_handleParameterValueChangedCallback)
  252. host.ParameterDefaultChangedCallback.connect(self.slot_handleParameterDefaultChangedCallback)
  253. host.ParameterMidiChannelChangedCallback.connect(self.slot_handleParameterMidiChannelChangedCallback)
  254. host.ParameterMidiCcChangedCallback.connect(self.slot_handleParameterMidiCcChangedCallback)
  255. host.ProgramChangedCallback.connect(self.slot_handleProgramChangedCallback)
  256. host.MidiProgramChangedCallback.connect(self.slot_handleMidiProgramChangedCallback)
  257. host.OptionChangedCallback.connect(self.slot_handleOptionChangedCallback)
  258. host.UiStateChangedCallback.connect(self.slot_handleUiStateChangedCallback)
  259. # -----------------------------------------------------------------
  260. @pyqtSlot(int, str)
  261. def slot_handlePluginRenamedCallback(self, pluginId, newName):
  262. if self.fPluginId == pluginId:
  263. self.setName(newName)
  264. @pyqtSlot(int, str)
  265. def slot_handlePluginUnavailableCallback(self, pluginId, errorMsg):
  266. if self.fPluginId == pluginId:
  267. pass
  268. @pyqtSlot(int, int, float)
  269. def slot_handleParameterValueChangedCallback(self, pluginId, index, value):
  270. if self.fPluginId == pluginId:
  271. self.setParameterValue(index, value, True)
  272. @pyqtSlot(int, int, float)
  273. def slot_handleParameterDefaultChangedCallback(self, pluginId, index, value):
  274. if self.fPluginId == pluginId:
  275. self.setParameterDefault(index, value)
  276. @pyqtSlot(int, int, int)
  277. def slot_handleParameterMidiCcChangedCallback(self, pluginId, index, cc):
  278. if self.fPluginId == pluginId:
  279. self.setParameterMidiControl(index, cc)
  280. @pyqtSlot(int, int, int)
  281. def slot_handleParameterMidiChannelChangedCallback(self, pluginId, index, channel):
  282. if self.fPluginId == pluginId:
  283. self.setParameterMidiChannel(index, channel)
  284. @pyqtSlot(int, int)
  285. def slot_handleProgramChangedCallback(self, pluginId, index):
  286. if self.fPluginId == pluginId:
  287. self.setProgram(index, True)
  288. @pyqtSlot(int, int)
  289. def slot_handleMidiProgramChangedCallback(self, pluginId, index):
  290. if self.fPluginId == pluginId:
  291. self.setMidiProgram(index, True)
  292. @pyqtSlot(int, int, bool)
  293. def slot_handleOptionChangedCallback(self, pluginId, option, yesNo):
  294. if self.fPluginId == pluginId:
  295. self.setOption(option, yesNo)
  296. @pyqtSlot(int, int)
  297. def slot_handleUiStateChangedCallback(self, pluginId, state):
  298. if self.fPluginId == pluginId:
  299. self.customUiStateChanged(state)
  300. #------------------------------------------------------------------
  301. def ready(self):
  302. if self.b_enable is not None:
  303. self.b_enable.setChecked(self.fIsActive)
  304. self.b_enable.clicked.connect(self.slot_enableClicked)
  305. if "calf" in self.fSkinStyle and not isinstance(self, PluginSlot_Compact):
  306. self.b_enable.setPixmaps(":/bitmaps/button_calf3.png", ":/bitmaps/button_calf3_down.png", ":/bitmaps/button_calf3.png")
  307. else:
  308. self.b_enable.setPixmaps(":/bitmaps/button_off.png", ":/bitmaps/button_on.png", ":/bitmaps/button_off.png")
  309. if self.b_gui is not None:
  310. self.b_gui.clicked.connect(self.slot_showCustomUi)
  311. self.b_gui.setEnabled(bool(self.fPluginInfo['hints'] & PLUGIN_HAS_CUSTOM_UI))
  312. if "calf" in self.fSkinStyle and not isinstance(self, PluginSlot_Compact):
  313. self.b_gui.setPixmaps(":/bitmaps/button_calf2.png", ":/bitmaps/button_calf2_down.png", ":/bitmaps/button_calf2_hover.png")
  314. elif self.fPluginInfo['iconName'] == "distrho" or self.fSkinStyle in ("3bandeq","3bandsplitter","pingpongpan"):
  315. self.b_gui.setPixmaps(":/bitmaps/button_distrho.png", ":/bitmaps/button_distrho_down.png", ":/bitmaps/button_distrho_hover.png")
  316. elif self.fPluginInfo['iconName'] == "file":
  317. self.b_gui.setPixmaps(":/bitmaps/button_file.png", ":/bitmaps/button_file_down.png", ":/bitmaps/button_file_hover.png")
  318. else:
  319. self.b_gui.setPixmaps(":/bitmaps/button_gui.png", ":/bitmaps/button_gui_down.png", ":/bitmaps/button_gui_hover.png")
  320. if self.b_edit is not None:
  321. self.b_edit.clicked.connect(self.slot_showEditDialog)
  322. if "calf" in self.fSkinStyle and not isinstance(self, PluginSlot_Compact):
  323. self.b_edit.setPixmaps(":/bitmaps/button_calf2.png", ":/bitmaps/button_calf2_down.png", ":/bitmaps/button_calf2_hover.png")
  324. else:
  325. self.b_edit.setPixmaps(":/bitmaps/button_edit.png", ":/bitmaps/button_edit_down.png", ":/bitmaps/button_edit_hover.png")
  326. else:
  327. # Edit button *must* be available
  328. self.b_edit = QPushButton(self)
  329. self.b_edit.setCheckable(True)
  330. self.b_edit.hide()
  331. if self.b_remove is not None:
  332. self.b_remove.clicked.connect(self.slot_removePlugin)
  333. if self.label_name is not None:
  334. self.label_name.setEnabled(self.fIsActive)
  335. self.label_name.setText(self.fPluginInfo['name'])
  336. nameFont = self.label_name.font()
  337. if self.fSkinStyle == "openav":
  338. QFontDatabase.addApplicationFont(":/fonts/uranium.ttf")
  339. nameFont.setFamily("Uranium")
  340. nameFont.setPointSize(13)
  341. nameFont.setCapitalization(QFont.AllUppercase)
  342. elif "calf" in self.fSkinStyle:
  343. nameFont.setBold(True)
  344. nameFont.setPointSize(10)
  345. else:
  346. nameFont.setBold(True)
  347. nameFont.setPointSize(9)
  348. self.label_name.setFont(nameFont)
  349. if self.label_presets is not None:
  350. presetFont = self.label_presets.font()
  351. presetFont.setBold(True)
  352. presetFont.setPointSize(8)
  353. self.label_presets.setFont(presetFont)
  354. if self.label_type is not None:
  355. self.label_type.setText(getPluginTypeAsString(self.fPluginInfo['type']))
  356. if self.led_control is not None:
  357. self.led_control.setColor(self.led_control.YELLOW)
  358. self.led_control.setEnabled(False)
  359. if self.led_midi is not None:
  360. self.led_midi.setColor(self.led_midi.RED)
  361. self.led_midi.setEnabled(False)
  362. if self.led_audio_in is not None:
  363. self.led_audio_in.setColor(self.led_audio_in.GREEN)
  364. self.led_audio_in.setEnabled(False)
  365. if self.led_audio_out is not None:
  366. self.led_audio_out.setColor(self.led_audio_out.BLUE)
  367. self.led_audio_out.setEnabled(False)
  368. if self.peak_in is not None:
  369. self.peak_in.setChannelCount(self.fPeaksInputCount)
  370. self.peak_in.setMeterColor(DigitalPeakMeter.COLOR_GREEN)
  371. self.peak_in.setMeterOrientation(DigitalPeakMeter.HORIZONTAL)
  372. if "calf" in self.fSkinStyle:
  373. self.peak_in.setMeterStyle(DigitalPeakMeter.STYLE_CALF)
  374. elif self.fSkinStyle == "rncbc":
  375. self.peak_in.setMeterStyle(DigitalPeakMeter.STYLE_RNCBC)
  376. elif self.fSkinStyle in ("mod", "openav", "zynfx"):
  377. self.peak_in.setMeterStyle(DigitalPeakMeter.STYLE_OPENAV)
  378. if self.fPeaksInputCount == 0 and not isinstance(self, PluginSlot_Classic):
  379. self.peak_in.hide()
  380. if self.peak_out is not None:
  381. self.peak_out.setChannelCount(self.fPeaksOutputCount)
  382. self.peak_out.setMeterColor(DigitalPeakMeter.COLOR_BLUE)
  383. self.peak_out.setMeterOrientation(DigitalPeakMeter.HORIZONTAL)
  384. if "calf" in self.fSkinStyle:
  385. self.peak_out.setMeterStyle(DigitalPeakMeter.STYLE_CALF)
  386. elif self.fSkinStyle == "rncbc":
  387. self.peak_out.setMeterStyle(DigitalPeakMeter.STYLE_RNCBC)
  388. elif self.fSkinStyle in ("mod", "openav", "zynfx"):
  389. self.peak_out.setMeterStyle(DigitalPeakMeter.STYLE_OPENAV)
  390. if self.fPeaksOutputCount == 0 and not isinstance(self, PluginSlot_Classic):
  391. self.peak_out.hide()
  392. # -------------------------------------------------------------
  393. if self.fSkinStyle == "mod":
  394. styleSheet = """
  395. QFrame#PluginWidget {
  396. background-color: rgb(%i, %i, %i);
  397. }
  398. QLabel#label_name { color: #FFFFFF; }
  399. QLabel#label_name:disabled { color: #505050; }
  400. """ % getModColorFromCategory(self.fPluginInfo['category'])
  401. elif self.fSkinStyle == "openav":
  402. styleSheet = """
  403. QFrame#PluginWidget {
  404. background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
  405. stop: 0 #303030, stop: %f #111111, stop: 1.0 #111111);
  406. }
  407. QLabel#label_name { color: #FF5100; }
  408. QLabel#label_name:disabled { color: #505050; }
  409. """ % (0.95 if isinstance(self, PluginSlot_Compact) else 0.35)
  410. else:
  411. if self.fSkinStyle in ("3bandeq", "calf_black", "calf_blue", "nekobi", "zynfx"):
  412. styleSheet2 = "background-image: url(:/bitmaps/background_%s.png);" % self.fSkinStyle
  413. else:
  414. styleSheet2 = "background-color: rgb(%i, %i, %i);" % getColorFromCategory(self.fPluginInfo['category'])
  415. styleSheet2 += "background-image: url(:/bitmaps/background_noise1.png);"
  416. styleSheet = """
  417. QFrame#PluginWidget {
  418. %s
  419. background-repeat: repeat-xy;
  420. }
  421. QLabel#label_name,
  422. QLabel#label_audio_in,
  423. QLabel#label_audio_out,
  424. QLabel#label_midi,
  425. QLabel#label_presets { color: #BBB; }
  426. QLabel#label_name:disabled { color: #555; }
  427. """ % styleSheet2
  428. self.setStyleSheet(styleSheet)
  429. # -------------------------------------------------------------
  430. # Set-up parameters
  431. if self.w_knobs_left is not None:
  432. parameterCount = self.host.get_parameter_count(self.fPluginId)
  433. if "calf" in self.fSkinStyle:
  434. maxWidgets = 7
  435. else:
  436. maxWidgets = 8
  437. index = 0
  438. for i in range(parameterCount):
  439. if index >= maxWidgets:
  440. break
  441. paramInfo = self.host.get_parameter_info(self.fPluginId, i)
  442. paramData = self.host.get_parameter_data(self.fPluginId, i)
  443. paramRanges = self.host.get_parameter_ranges(self.fPluginId, i)
  444. if paramData['type'] != PARAMETER_INPUT:
  445. continue
  446. if paramData['hints'] & PARAMETER_IS_BOOLEAN:
  447. continue
  448. if (paramData['hints'] & PARAMETER_IS_INTEGER) != 0 and paramRanges['max']-paramRanges['min'] <= 10.0:
  449. continue
  450. if (paramData['hints'] & PARAMETER_IS_ENABLED) == 0:
  451. continue
  452. if paramInfo['name'].startswith("unused"):
  453. continue
  454. paramName = getParameterShortName(paramInfo['name'])
  455. widget = PixmapDial(self, i)
  456. widget.setLabel(paramName)
  457. widget.setMinimum(paramRanges['min'])
  458. widget.setMaximum(paramRanges['max'])
  459. setPixmapDialStyle(widget, i, parameterCount, self.fSkinStyle)
  460. index += 1
  461. self.fParameterList.append([i, widget])
  462. self.w_knobs_left.layout().addWidget(widget)
  463. if self.w_knobs_right is not None and (self.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET) != 0:
  464. widget = PixmapDial(self, PARAMETER_DRYWET)
  465. widget.setLabel("Dry/Wet")
  466. widget.setMinimum(0.0)
  467. widget.setMaximum(1.0)
  468. setPixmapDialStyle(widget, PARAMETER_DRYWET, 0, self.fSkinStyle)
  469. self.fParameterList.append([PARAMETER_DRYWET, widget])
  470. self.w_knobs_right.layout().addWidget(widget)
  471. if self.w_knobs_right is not None and (self.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME) != 0:
  472. widget = PixmapDial(self, PARAMETER_VOLUME)
  473. widget.setLabel("Volume")
  474. widget.setMinimum(0.0)
  475. widget.setMaximum(1.27)
  476. setPixmapDialStyle(widget, PARAMETER_VOLUME, 0, self.fSkinStyle)
  477. self.fParameterList.append([PARAMETER_VOLUME, widget])
  478. self.w_knobs_right.layout().addWidget(widget)
  479. for paramIndex, paramWidget in self.fParameterList:
  480. paramWidget.setContextMenuPolicy(Qt.CustomContextMenu)
  481. paramWidget.customContextMenuRequested.connect(self.slot_knobCustomMenu)
  482. paramWidget.realValueChanged.connect(self.slot_parameterValueChanged)
  483. paramWidget.setValue(self.host.get_internal_parameter_value(self.fPluginId, paramIndex))
  484. # -------------------------------------------------------------
  485. self.setWindowTitle(self.fPluginInfo['name'])
  486. #------------------------------------------------------------------
  487. def getFixedHeight(self):
  488. return 32
  489. def getHints(self):
  490. return self.fPluginInfo['hints']
  491. def getPluginId(self):
  492. return self.fPluginId
  493. #------------------------------------------------------------------
  494. def setPluginId(self, idx):
  495. self.fPluginId = idx
  496. self.fEditDialog.setPluginId(idx)
  497. def setName(self, name):
  498. self.fEditDialog.setName(name)
  499. if self.label_name is not None:
  500. self.label_name.setText(name)
  501. def setSelected(self, yesNo):
  502. if self.fIsSelected == yesNo:
  503. return
  504. self.fIsSelected = yesNo
  505. self.update()
  506. #------------------------------------------------------------------
  507. def setActive(self, active, sendCallback=False, sendHost=True):
  508. self.fIsActive = active
  509. if sendCallback:
  510. self.fParameterIconTimer = ICON_STATE_ON
  511. self.activeChanged(active)
  512. if sendHost:
  513. self.host.set_active(self.fPluginId, active)
  514. if active:
  515. self.fEditDialog.clearNotes()
  516. self.midiActivityChanged(False)
  517. if self.label_name is not None:
  518. self.label_name.setEnabled(self.fIsActive)
  519. # called from rack, checks if param is possible first
  520. def setInternalParameter(self, parameterId, value):
  521. if parameterId <= PARAMETER_MAX or parameterId >= PARAMETER_NULL:
  522. return
  523. elif parameterId == PARAMETER_ACTIVE:
  524. return self.setActive(bool(value), True, True)
  525. elif parameterId == PARAMETER_DRYWET:
  526. if (self.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET) == 0: return
  527. self.host.set_drywet(self.fPluginId, value)
  528. elif parameterId == PARAMETER_VOLUME:
  529. if (self.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME) == 0: return
  530. self.host.set_volume(self.fPluginId, value)
  531. elif parameterId == PARAMETER_BALANCE_LEFT:
  532. if (self.fPluginInfo['hints'] & PLUGIN_CAN_BALANCE) == 0: return
  533. self.host.set_balance_left(self.fPluginId, value)
  534. elif parameterId == PARAMETER_BALANCE_RIGHT:
  535. if (self.fPluginInfo['hints'] & PLUGIN_CAN_BALANCE) == 0: return
  536. self.host.set_balance_right(self.fPluginId, value)
  537. elif parameterId == PARAMETER_PANNING:
  538. if (self.fPluginInfo['hints'] & PLUGIN_CAN_PANNING) == 0: return
  539. self.host.set_panning(self.fPluginId, value)
  540. elif parameterId == PARAMETER_CTRL_CHANNEL:
  541. self.host.set_ctrl_channel(self.fPluginId, value)
  542. self.fEditDialog.setParameterValue(parameterId, value)
  543. #------------------------------------------------------------------
  544. def setParameterValue(self, parameterId, value, sendCallback):
  545. if parameterId == PARAMETER_ACTIVE:
  546. return self.setActive(bool(value), True, False)
  547. self.fEditDialog.setParameterValue(parameterId, value)
  548. if sendCallback:
  549. self.fParameterIconTimer = ICON_STATE_ON
  550. self.editDialogParameterValueChanged(self.fPluginId, parameterId, value)
  551. def setParameterDefault(self, parameterId, value):
  552. self.fEditDialog.setParameterDefault(parameterId, value)
  553. def setParameterMidiControl(self, parameterId, control):
  554. self.fEditDialog.setParameterMidiControl(parameterId, control)
  555. def setParameterMidiChannel(self, parameterId, channel):
  556. self.fEditDialog.setParameterMidiChannel(parameterId, channel)
  557. #------------------------------------------------------------------
  558. def setProgram(self, index, sendCallback):
  559. self.fEditDialog.setProgram(index)
  560. if sendCallback:
  561. self.fParameterIconTimer = ICON_STATE_ON
  562. self.editDialogProgramChanged(self.fPluginId, index)
  563. self.updateParameterValues()
  564. def setMidiProgram(self, index, sendCallback):
  565. self.fEditDialog.setMidiProgram(index)
  566. if sendCallback:
  567. self.fParameterIconTimer = ICON_STATE_ON
  568. self.editDialogMidiProgramChanged(self.fPluginId, index)
  569. self.updateParameterValues()
  570. #------------------------------------------------------------------
  571. def setOption(self, option, yesNo):
  572. self.fEditDialog.setOption(option, yesNo)
  573. #------------------------------------------------------------------
  574. def activeChanged(self, onOff):
  575. self.fIsActive = onOff
  576. if self.b_enable is None:
  577. return
  578. self.b_enable.blockSignals(True)
  579. self.b_enable.setChecked(onOff)
  580. self.b_enable.blockSignals(False)
  581. def customUiStateChanged(self, state):
  582. if self.b_gui is None:
  583. return
  584. self.b_gui.blockSignals(True)
  585. if state == 0:
  586. self.b_gui.setChecked(False)
  587. self.b_gui.setEnabled(True)
  588. elif state == 1:
  589. self.b_gui.setChecked(True)
  590. self.b_gui.setEnabled(True)
  591. elif state == -1:
  592. self.b_gui.setChecked(False)
  593. self.b_gui.setEnabled(False)
  594. self.b_gui.blockSignals(False)
  595. def parameterActivityChanged(self, onOff):
  596. if self.led_control is None:
  597. return
  598. self.led_control.setChecked(onOff)
  599. def midiActivityChanged(self, onOff):
  600. if self.led_midi is None:
  601. return
  602. self.led_midi.setChecked(onOff)
  603. def optionChanged(self, option, yesNo):
  604. pass
  605. # -----------------------------------------------------------------
  606. # PluginEdit callbacks
  607. def editDialogVisibilityChanged(self, pluginId, visible):
  608. if self.b_edit is None:
  609. return
  610. self.b_edit.blockSignals(True)
  611. self.b_edit.setChecked(visible)
  612. self.b_edit.blockSignals(False)
  613. def editDialogPluginHintsChanged(self, pluginId, hints):
  614. self.fPluginInfo['hints'] = hints
  615. for paramIndex, paramWidget in self.fParameterList:
  616. if paramIndex == PARAMETER_DRYWET:
  617. paramWidget.setVisible(hints & PLUGIN_CAN_DRYWET)
  618. elif paramIndex == PARAMETER_VOLUME:
  619. paramWidget.setVisible(hints & PLUGIN_CAN_VOLUME)
  620. if self.b_gui is not None:
  621. self.b_gui.setEnabled(bool(hints & PLUGIN_HAS_CUSTOM_UI))
  622. def editDialogParameterValueChanged(self, pluginId, parameterId, value):
  623. for paramIndex, paramWidget in self.fParameterList:
  624. if paramIndex != parameterId:
  625. continue
  626. paramWidget.blockSignals(True)
  627. paramWidget.setValue(value)
  628. paramWidget.blockSignals(False)
  629. break
  630. def editDialogProgramChanged(self, pluginId, index):
  631. if self.cb_presets is None:
  632. return
  633. self.cb_presets.blockSignals(True)
  634. self.cb_presets.setCurrentIndex(index)
  635. self.cb_presets.blockSignals(False)
  636. # FIXME
  637. self.updateParameterValues()
  638. def editDialogMidiProgramChanged(self, pluginId, index):
  639. if self.cb_presets is None:
  640. return
  641. self.cb_presets.blockSignals(True)
  642. self.cb_presets.setCurrentIndex(index)
  643. self.cb_presets.blockSignals(False)
  644. # FIXME
  645. self.updateParameterValues()
  646. def editDialogNotePressed(self, pluginId, note):
  647. pass
  648. def editDialogNoteReleased(self, pluginId, note):
  649. pass
  650. def editDialogMidiActivityChanged(self, pluginId, onOff):
  651. self.midiActivityChanged(onOff)
  652. #------------------------------------------------------------------
  653. def idleFast(self):
  654. # Input peaks
  655. if self.fPeaksInputCount > 0:
  656. if self.fPeaksInputCount > 1:
  657. peak1 = self.host.get_input_peak_value(self.fPluginId, True)
  658. peak2 = self.host.get_input_peak_value(self.fPluginId, False)
  659. ledState = bool(peak1 != 0.0 or peak2 != 0.0)
  660. if self.peak_in is not None:
  661. self.peak_in.displayMeter(1, peak1)
  662. self.peak_in.displayMeter(2, peak2)
  663. else:
  664. peak = self.host.get_input_peak_value(self.fPluginId, True)
  665. ledState = bool(peak != 0.0)
  666. if self.peak_in is not None:
  667. self.peak_in.displayMeter(1, peak)
  668. if self.fLastGreenLedState != ledState and self.led_audio_in is not None:
  669. self.fLastGreenLedState = ledState
  670. self.led_audio_in.setChecked(ledState)
  671. # Output peaks
  672. if self.fPeaksOutputCount > 0:
  673. if self.fPeaksOutputCount > 1:
  674. peak1 = self.host.get_output_peak_value(self.fPluginId, True)
  675. peak2 = self.host.get_output_peak_value(self.fPluginId, False)
  676. ledState = bool(peak1 != 0.0 or peak2 != 0.0)
  677. if self.peak_out is not None:
  678. self.peak_out.displayMeter(1, peak1)
  679. self.peak_out.displayMeter(2, peak2)
  680. else:
  681. peak = self.host.get_output_peak_value(self.fPluginId, True)
  682. ledState = bool(peak != 0.0)
  683. if self.peak_out is not None:
  684. self.peak_out.displayMeter(1, peak)
  685. if self.fLastBlueLedState != ledState and self.led_audio_out is not None:
  686. self.fLastBlueLedState = ledState
  687. self.led_audio_out.setChecked(ledState)
  688. def idleSlow(self):
  689. if self.fParameterIconTimer == ICON_STATE_ON:
  690. self.parameterActivityChanged(True)
  691. self.fParameterIconTimer = ICON_STATE_WAIT
  692. elif self.fParameterIconTimer == ICON_STATE_WAIT:
  693. self.fParameterIconTimer = ICON_STATE_OFF
  694. elif self.fParameterIconTimer == ICON_STATE_OFF:
  695. self.parameterActivityChanged(False)
  696. self.fParameterIconTimer = ICON_STATE_NULL
  697. self.fEditDialog.idleSlow()
  698. #------------------------------------------------------------------
  699. def drawOutline(self):
  700. painter = QPainter(self)
  701. if self.fIsSelected:
  702. painter.setPen(QPen(Qt.cyan, 4))
  703. painter.setBrush(Qt.transparent)
  704. painter.drawRect(0, 0, self.width(), self.height())
  705. else:
  706. painter.setPen(QPen(Qt.black, 1))
  707. painter.setBrush(Qt.black)
  708. painter.drawLine(0, self.height()-1, self.width(), self.height()-1)
  709. def updateParameterValues(self):
  710. for paramIndex, paramWidget in self.fParameterList:
  711. if paramIndex < 0:
  712. continue
  713. paramWidget.blockSignals(True)
  714. paramWidget.setValue(self.host.get_current_parameter_value(self.fPluginId, paramIndex))
  715. paramWidget.blockSignals(False)
  716. #------------------------------------------------------------------
  717. @pyqtSlot(bool)
  718. def slot_enableClicked(self, yesNo):
  719. self.setActive(yesNo, False, True)
  720. @pyqtSlot()
  721. def slot_showDefaultCustomMenu(self):
  722. menu = QMenu(self)
  723. # -------------------------------------------------------------
  724. # Expand/Minimize
  725. actCompact = menu.addAction(self.tr("Expand") if isinstance(self, PluginSlot_Compact) else self.tr("Minimize"))
  726. menu.addSeparator()
  727. # -------------------------------------------------------------
  728. # Bypass and Enable/Disable
  729. actBypass = menu.addAction(self.tr("Bypass"))
  730. actEnable = menu.addAction(self.tr("Disable") if self.fIsActive else self.tr("Enable"))
  731. menu.addSeparator()
  732. if self.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET:
  733. actBypass.setCheckable(True)
  734. actBypass.setChecked(self.host.get_internal_parameter_value(self.fPluginId, PARAMETER_DRYWET) == 0.0)
  735. else:
  736. actBypass.setVisible(False)
  737. # -------------------------------------------------------------
  738. # Reset and Randomize parameters
  739. actReset = menu.addAction(self.tr("Reset parameters"))
  740. actRandom = menu.addAction(self.tr("Randomize parameters"))
  741. menu.addSeparator()
  742. # -------------------------------------------------------------
  743. # Edit and Show Custom UI
  744. actEdit = menu.addAction(self.tr("Edit"))
  745. actGui = menu.addAction(self.tr("Show Custom UI"))
  746. menu.addSeparator()
  747. if self.b_edit is not None:
  748. actEdit.setCheckable(True)
  749. actEdit.setChecked(self.b_edit.isChecked())
  750. else:
  751. actEdit.setVisible(False)
  752. if self.b_gui is not None:
  753. actGui.setCheckable(True)
  754. actGui.setChecked(self.b_gui.isChecked())
  755. actGui.setEnabled(self.b_gui.isEnabled())
  756. else:
  757. actGui.setVisible(False)
  758. # -------------------------------------------------------------
  759. # Other stuff
  760. actClone = menu.addAction(self.tr("Clone"))
  761. actReplace = menu.addAction(self.tr("Replace..."))
  762. actRename = menu.addAction(self.tr("Rename..."))
  763. actRemove = menu.addAction(self.tr("Remove"))
  764. if self.fIdleTimerId != 0:
  765. actRemove.setVisible(False)
  766. # -------------------------------------------------------------
  767. # exec
  768. actSel = menu.exec_(QCursor.pos())
  769. if not actSel:
  770. return
  771. # -------------------------------------------------------------
  772. # Expand/Minimize
  773. elif actSel == actCompact:
  774. # FIXME
  775. gCarla.gui.compactPlugin(self.fPluginId)
  776. # -------------------------------------------------------------
  777. # Bypass and Enable/Disable
  778. elif actSel == actBypass:
  779. value = 0.0 if actBypass.isChecked() else 1.0
  780. self.host.set_drywet(self.fPluginId, value)
  781. self.setParameterValue(PARAMETER_DRYWET, value, True)
  782. elif actSel == actEnable:
  783. self.setActive(not self.fIsActive, True, True)
  784. # -------------------------------------------------------------
  785. # Reset and Randomize parameters
  786. elif actSel == actReset:
  787. self.host.reset_parameters(self.fPluginId)
  788. elif actSel == actRandom:
  789. self.host.randomize_parameters(self.fPluginId)
  790. # -------------------------------------------------------------
  791. # Edit and Show Custom UI
  792. elif actSel == actEdit:
  793. self.b_edit.click()
  794. elif actSel == actGui:
  795. self.b_gui.click()
  796. # -------------------------------------------------------------
  797. # Clone
  798. elif actSel == actClone:
  799. if not self.host.clone_plugin(self.fPluginId):
  800. CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
  801. self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
  802. # -------------------------------------------------------------
  803. # Rename
  804. elif actSel == actRename:
  805. oldName = self.fPluginInfo['name']
  806. newNameTry = QInputDialog.getText(self, self.tr("Rename Plugin"), self.tr("New plugin name:"), QLineEdit.Normal, oldName)
  807. if not (newNameTry[1] and newNameTry[0] and oldName != newNameTry[0]):
  808. return
  809. newName = newNameTry[0]
  810. if self.host.rename_plugin(self.fPluginId, newName):
  811. self.setName(newName)
  812. else:
  813. CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
  814. self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
  815. # -------------------------------------------------------------
  816. # Replace
  817. elif actSel == actReplace:
  818. # FIXME
  819. gCarla.gui.slot_pluginAdd(self.fPluginId)
  820. # -------------------------------------------------------------
  821. # Remove
  822. elif actSel == actRemove:
  823. if not self.host.remove_plugin(self.fPluginId):
  824. CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
  825. self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
  826. # -------------------------------------------------------------
  827. @pyqtSlot()
  828. def slot_knobCustomMenu(self):
  829. sender = self.sender()
  830. index = sender.fIndex
  831. minimum = sender.fMinimum
  832. maximum = sender.fMaximum
  833. current = sender.fRealValue
  834. label = sender.fLabel
  835. if index in (PARAMETER_DRYWET, PARAMETER_VOLUME):
  836. default = 1.0
  837. resetText = self.tr("Reset (%i%%)" % int(default*100.0))
  838. minimText = self.tr("Set to Minimum (%i%%)" % int(minimum*100.0))
  839. maximText = self.tr("Set to Maximum (%i%%)" % int(maximum*100.0))
  840. else:
  841. default = self.host.get_default_parameter_value(self.fPluginId, index)
  842. resetText = self.tr("Reset (%f)" % default)
  843. minimText = self.tr("Set to Minimum (%f)" % minimum)
  844. maximText = self.tr("Set to Maximum (%f)" % maximum)
  845. menu = QMenu(self)
  846. actReset = menu.addAction(resetText)
  847. menu.addSeparator()
  848. actMinimum = menu.addAction(minimText)
  849. actMaximum = menu.addAction(maximText)
  850. menu.addSeparator()
  851. actSet = menu.addAction(self.tr("Set value..."))
  852. actSelected = menu.exec_(QCursor.pos())
  853. if actSelected == actSet:
  854. valueTry = QInputDialog.getDouble(self, self.tr("Set value"), label, current, minimum, maximum, 3) # FIXME - 3 decimals
  855. if valueTry[1]:
  856. value = valueTry[0] * 10
  857. else:
  858. return
  859. elif actSelected == actMinimum:
  860. value = minimum
  861. elif actSelected == actMaximum:
  862. value = maximum
  863. elif actSelected == actReset:
  864. value = default
  865. else:
  866. return
  867. self.sender().setValue(value)
  868. #------------------------------------------------------------------
  869. @pyqtSlot(bool)
  870. def slot_showCustomUi(self, show):
  871. self.host.show_custom_ui(self.fPluginId, show)
  872. @pyqtSlot(bool)
  873. def slot_showEditDialog(self, show):
  874. self.fEditDialog.setVisible(show)
  875. @pyqtSlot()
  876. def slot_removePlugin(self):
  877. if not self.host.remove_plugin(self.fPluginId):
  878. CustomMessageBox(self, QMessageBox.Warning, self.tr("Error"), self.tr("Operation failed"),
  879. self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok)
  880. #------------------------------------------------------------------
  881. @pyqtSlot(int)
  882. def slot_parameterValueChanged(self, value):
  883. index = self.sender().getIndex()
  884. if index < 0:
  885. self.setInternalParameter(index, value)
  886. else:
  887. self.host.set_parameter_value(self.fPluginId, index, value)
  888. self.setParameterValue(index, value, False)
  889. @pyqtSlot(int)
  890. def slot_programChanged(self, index):
  891. self.host.set_program(self.fPluginId, index)
  892. self.setProgram(index, False)
  893. @pyqtSlot(int)
  894. def slot_midiProgramChanged(self, index):
  895. self.host.set_midi_program(self.fPluginId, index)
  896. self.setMidiProgram(index, False)
  897. #------------------------------------------------------------------
  898. def testTimer(self):
  899. self.fIdleTimerId = self.startTimer(25)
  900. #------------------------------------------------------------------
  901. def mouseDoubleClickEvent(self, event):
  902. QFrame.mouseDoubleClickEvent(self, event)
  903. # FIXME
  904. gCarla.gui.compactPlugin(self.fPluginId)
  905. def closeEvent(self, event):
  906. if self.fIdleTimerId != 0:
  907. self.killTimer(self.fIdleTimerId)
  908. self.fIdleTimerId = 0
  909. self.host.engine_close()
  910. QFrame.closeEvent(self, event)
  911. def timerEvent(self, event):
  912. if event.timerId() == self.fIdleTimerId:
  913. self.host.engine_idle()
  914. self.idleFast()
  915. self.idleSlow()
  916. QFrame.timerEvent(self, event)
  917. def paintEvent(self, event):
  918. self.drawOutline()
  919. QFrame.paintEvent(self, event)
  920. # ------------------------------------------------------------------------------------------------------------
  921. class PluginSlot_Calf(AbstractPluginSlot):
  922. def __init__(self, parent, host, pluginId, skinStyle):
  923. AbstractPluginSlot.__init__(self, parent, host, pluginId, skinStyle)
  924. self.ui = ui_carla_plugin_calf.Ui_PluginWidget()
  925. self.ui.setupUi(self)
  926. audioCount = self.host.get_audio_port_count_info(self.fPluginId)
  927. midiCount = self.host.get_midi_port_count_info(self.fPluginId)
  928. # -------------------------------------------------------------
  929. # Internal stuff
  930. self.fButtonFont = self.ui.b_gui.font()
  931. self.fButtonFont.setBold(False)
  932. self.fButtonFont.setPointSize(8)
  933. self.fButtonColorOn = QColor( 18, 41, 87)
  934. self.fButtonColorOff = QColor(150, 150, 150)
  935. # -------------------------------------------------------------
  936. # Set-up GUI
  937. self.ui.label_active.setFont(self.fButtonFont)
  938. self.ui.b_remove.setPixmaps(":/bitmaps/button_calf1.png", ":/bitmaps/button_calf1_down.png", ":/bitmaps/button_calf1_hover.png")
  939. self.ui.b_edit.setTopText(self.tr("Edit"), self.fButtonColorOn, self.fButtonFont)
  940. self.ui.b_remove.setTopText(self.tr("Remove"), self.fButtonColorOn, self.fButtonFont)
  941. if self.fPluginInfo['hints'] & PLUGIN_HAS_CUSTOM_UI:
  942. self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOn, self.fButtonFont)
  943. else:
  944. self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOff, self.fButtonFont)
  945. if audioCount['ins'] == 0:
  946. self.ui.label_audio_in.hide()
  947. if audioCount['outs'] == 0:
  948. self.ui.label_audio_out.hide()
  949. if midiCount['ins'] == 0:
  950. self.ui.label_midi.hide()
  951. self.ui.led_midi.hide()
  952. if self.fIdleTimerId != 0:
  953. self.ui.b_remove.setEnabled(False)
  954. self.ui.b_remove.setVisible(False)
  955. # -------------------------------------------------------------
  956. self.b_enable = self.ui.b_enable
  957. self.b_gui = self.ui.b_gui
  958. self.b_edit = self.ui.b_edit
  959. self.b_remove = self.ui.b_remove
  960. self.label_name = self.ui.label_name
  961. self.led_midi = self.ui.led_midi
  962. self.peak_in = self.ui.peak_in
  963. self.peak_out = self.ui.peak_out
  964. self.w_knobs_left = self.ui.w_knobs
  965. self.ready()
  966. self.ui.led_midi.setColor(self.ui.led_midi.CALF)
  967. self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu)
  968. #------------------------------------------------------------------
  969. def getFixedHeight(self):
  970. return 94 if max(self.peak_in.channelCount(), self.peak_out.channelCount()) < 2 else 106
  971. #------------------------------------------------------------------
  972. def editDialogPluginHintsChanged(self, pluginId, hints):
  973. if hints & PLUGIN_HAS_CUSTOM_UI:
  974. self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOn, self.fButtonFont)
  975. else:
  976. self.ui.b_gui.setTopText(self.tr("GUI"), self.fButtonColorOff, self.fButtonFont)
  977. AbstractPluginSlot.editDialogPluginHintsChanged(self, pluginId, hints)
  978. #------------------------------------------------------------------
  979. def paintEvent(self, event):
  980. isBlack = bool(self.fSkinStyle == "calf_black")
  981. painter = QPainter(self)
  982. painter.setBrush(Qt.transparent)
  983. painter.setPen(QPen(QColor(20, 20, 20) if isBlack else QColor(75, 86, 99), 1))
  984. painter.drawRect(0, 1, self.width()-1, self.height()-3)
  985. painter.setPen(QPen(QColor(45, 45, 45) if isBlack else QColor(86, 99, 114), 1))
  986. painter.drawLine(0, 0, self.width(), 0)
  987. AbstractPluginSlot.paintEvent(self, event)
  988. # ------------------------------------------------------------------------------------------------------------
  989. class PluginSlot_Classic(AbstractPluginSlot):
  990. def __init__(self, parent, host, pluginId):
  991. AbstractPluginSlot.__init__(self, parent, host, pluginId, "classic")
  992. self.ui = ui_carla_plugin_classic.Ui_PluginWidget()
  993. self.ui.setupUi(self)
  994. # -------------------------------------------------------------
  995. # Internal stuff
  996. self.fColorTop = QColor(60, 60, 60)
  997. self.fColorBottom = QColor(47, 47, 47)
  998. self.fColorSeprtr = QColor(70, 70, 70)
  999. # -------------------------------------------------------------
  1000. self.b_enable = self.ui.b_enable
  1001. self.b_gui = self.ui.b_gui
  1002. self.b_edit = self.ui.b_edit
  1003. self.label_name = self.ui.label_name
  1004. self.led_control = self.ui.led_control
  1005. self.led_midi = self.ui.led_midi
  1006. self.led_audio_in = self.ui.led_audio_in
  1007. self.led_audio_out = self.ui.led_audio_out
  1008. self.peak_in = self.ui.peak_in
  1009. self.peak_out = self.ui.peak_out
  1010. self.ready()
  1011. self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu)
  1012. #------------------------------------------------------------------
  1013. def getFixedHeight(self):
  1014. return 36
  1015. #------------------------------------------------------------------
  1016. def paintEvent(self, event):
  1017. painter = QPainter(self)
  1018. painter.save()
  1019. areaX = self.ui.area_right.x()+7
  1020. width = self.width()
  1021. height = self.height()
  1022. painter.setPen(QPen(QColor(17, 17, 17), 1))
  1023. painter.setBrush(QColor(17, 17, 17))
  1024. painter.drawRect(0, 0, width, height)
  1025. painter.setPen(self.fColorSeprtr.lighter(110))
  1026. painter.setBrush(self.fColorBottom)
  1027. painter.setRenderHint(QPainter.Antialiasing, True)
  1028. # name -> leds arc
  1029. path = QPainterPath()
  1030. path.moveTo(areaX-20, height-4)
  1031. path.cubicTo(areaX, height-5, areaX-20, 4.75, areaX, 4.75)
  1032. path.lineTo(areaX, height-5)
  1033. painter.drawPath(path)
  1034. painter.setPen(self.fColorSeprtr)
  1035. painter.setRenderHint(QPainter.Antialiasing, False)
  1036. # separator lines
  1037. painter.drawLine(0, height-5, areaX-20, height-5)
  1038. painter.drawLine(areaX, 4, width, 4)
  1039. painter.setPen(self.fColorBottom)
  1040. painter.setBrush(self.fColorBottom)
  1041. # top, bottom and left lines
  1042. painter.drawLine(0, 0, width, 0)
  1043. painter.drawRect(0, height-4, areaX, 4)
  1044. painter.drawRoundedRect(areaX-20, height-5, areaX, 5, 22, 22)
  1045. painter.drawLine(0, 0, 0, height)
  1046. # fill the rest
  1047. painter.drawRect(areaX-1, 5, width, height)
  1048. # bottom 1px line
  1049. painter.setPen(self.fColorSeprtr)
  1050. painter.drawLine(0, height-1, width, height-1)
  1051. painter.restore()
  1052. AbstractPluginSlot.paintEvent(self, event)
  1053. # ------------------------------------------------------------------------------------------------------------
  1054. class PluginSlot_Compact(AbstractPluginSlot):
  1055. def __init__(self, parent, host, pluginId, skinStyle):
  1056. AbstractPluginSlot.__init__(self, parent, host, pluginId, skinStyle)
  1057. self.ui = ui_carla_plugin_compact.Ui_PluginWidget()
  1058. self.ui.setupUi(self)
  1059. self.b_enable = self.ui.b_enable
  1060. self.b_gui = self.ui.b_gui
  1061. self.b_edit = self.ui.b_edit
  1062. self.label_name = self.ui.label_name
  1063. self.led_control = self.ui.led_control
  1064. self.led_midi = self.ui.led_midi
  1065. self.led_audio_in = self.ui.led_audio_in
  1066. self.led_audio_out = self.ui.led_audio_out
  1067. self.peak_in = self.ui.peak_in
  1068. self.peak_out = self.ui.peak_out
  1069. self.ready()
  1070. self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu)
  1071. #------------------------------------------------------------------
  1072. def getFixedHeight(self):
  1073. if self.fSkinStyle == "calf_blue":
  1074. return 36
  1075. return 30
  1076. # ------------------------------------------------------------------------------------------------------------
  1077. class PluginSlot_Default(AbstractPluginSlot):
  1078. def __init__(self, parent, host, pluginId, skinStyle):
  1079. AbstractPluginSlot.__init__(self, parent, host, pluginId, skinStyle)
  1080. self.ui = ui_carla_plugin_default.Ui_PluginWidget()
  1081. self.ui.setupUi(self)
  1082. # -------------------------------------------------------------
  1083. self.b_enable = self.ui.b_enable
  1084. self.b_gui = self.ui.b_gui
  1085. self.b_edit = self.ui.b_edit
  1086. self.label_name = self.ui.label_name
  1087. self.led_control = self.ui.led_control
  1088. self.led_midi = self.ui.led_midi
  1089. self.led_audio_in = self.ui.led_audio_in
  1090. self.led_audio_out = self.ui.led_audio_out
  1091. self.peak_in = self.ui.peak_in
  1092. self.peak_out = self.ui.peak_out
  1093. self.w_knobs_left = self.ui.w_knobs_left
  1094. self.w_knobs_right = self.ui.w_knobs_right
  1095. self.ready()
  1096. self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu)
  1097. #------------------------------------------------------------------
  1098. def getFixedHeight(self):
  1099. if self.fSkinStyle == "mod":
  1100. return 86
  1101. return 80
  1102. #------------------------------------------------------------------
  1103. def paintEvent(self, event):
  1104. painter = QPainter(self)
  1105. painter.setBrush(Qt.transparent)
  1106. painter.setPen(QPen(QColor(42, 42, 42), 1))
  1107. painter.drawRect(0, 1, self.width()-1, self.getFixedHeight()-3)
  1108. painter.setPen(QPen(QColor(60, 60, 60), 1))
  1109. painter.drawLine(0, 0, self.width(), 0)
  1110. AbstractPluginSlot.paintEvent(self, event)
  1111. # ------------------------------------------------------------------------------------------------------------
  1112. class PluginSlot_Presets(AbstractPluginSlot):
  1113. def __init__(self, parent, host, pluginId, skinStyle):
  1114. AbstractPluginSlot.__init__(self, parent, host, pluginId, skinStyle)
  1115. self.ui = ui_carla_plugin_presets.Ui_PluginWidget()
  1116. self.ui.setupUi(self)
  1117. usingMidiPrograms = bool(skinStyle != "presets")
  1118. # -------------------------------------------------------------
  1119. # Set-up programs
  1120. if usingMidiPrograms:
  1121. programCount = self.host.get_midi_program_count(self.fPluginId)
  1122. else:
  1123. programCount = self.host.get_program_count(self.fPluginId)
  1124. if programCount > 0:
  1125. self.ui.cb_presets.setEnabled(True)
  1126. self.ui.label_presets.setEnabled(True)
  1127. for i in range(programCount):
  1128. if usingMidiPrograms:
  1129. progName = self.host.get_midi_program_data(self.fPluginId, i)['name']
  1130. else:
  1131. progName = self.host.get_program_name(self.fPluginId, i)
  1132. self.ui.cb_presets.addItem(progName)
  1133. if usingMidiPrograms:
  1134. curProg = self.host.get_current_midi_program_index(self.fPluginId)
  1135. else:
  1136. curProg = self.host.get_current_program_index(self.fPluginId)
  1137. self.ui.cb_presets.setCurrentIndex(curProg)
  1138. else:
  1139. self.ui.cb_presets.setEnabled(False)
  1140. self.ui.cb_presets.setVisible(False)
  1141. self.ui.label_presets.setEnabled(False)
  1142. self.ui.label_presets.setVisible(False)
  1143. # -------------------------------------------------------------
  1144. self.b_enable = self.ui.b_enable
  1145. self.b_gui = self.ui.b_gui
  1146. self.b_edit = self.ui.b_edit
  1147. self.cb_presets = self.ui.cb_presets
  1148. self.label_name = self.ui.label_name
  1149. self.label_presets = self.ui.label_presets
  1150. self.led_control = self.ui.led_control
  1151. self.led_midi = self.ui.led_midi
  1152. self.led_audio_in = self.ui.led_audio_in
  1153. self.led_audio_out = self.ui.led_audio_out
  1154. self.peak_in = self.ui.peak_in
  1155. self.peak_out = self.ui.peak_out
  1156. if skinStyle == "zynfx":
  1157. self.setupZynFxParams()
  1158. else:
  1159. self.w_knobs_left = self.ui.w_knobs_left
  1160. self.w_knobs_right = self.ui.w_knobs_right
  1161. self.ready()
  1162. self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu)
  1163. if usingMidiPrograms:
  1164. self.ui.cb_presets.currentIndexChanged.connect(self.slot_midiProgramChanged)
  1165. else:
  1166. self.ui.cb_presets.currentIndexChanged.connect(self.slot_programChanged)
  1167. # -------------------------------------------------------------
  1168. def setupZynFxParams(self):
  1169. parameterCount = self.host.get_parameter_count(self.fPluginId)
  1170. index = 0
  1171. for i in range(parameterCount):
  1172. if index >= 8:
  1173. break
  1174. paramInfo = self.host.get_parameter_info(self.fPluginId, i)
  1175. paramData = self.host.get_parameter_data(self.fPluginId, i)
  1176. paramRanges = self.host.get_parameter_ranges(self.fPluginId, i)
  1177. if paramData['type'] != PARAMETER_INPUT:
  1178. continue
  1179. if paramData['hints'] & PARAMETER_IS_BOOLEAN:
  1180. continue
  1181. if (paramData['hints'] & PARAMETER_IS_ENABLED) == 0:
  1182. continue
  1183. paramName = paramInfo['name']
  1184. if paramName.startswith("unused"):
  1185. continue
  1186. # real zyn fx plugins
  1187. if self.fPluginInfo['label'] == "zynalienwah":
  1188. if i == 0: paramName = "Freq"
  1189. elif i == 1: paramName = "Rnd"
  1190. elif i == 2: paramName = "L type" # combobox
  1191. elif i == 3: paramName = "St.df"
  1192. elif i == 5: paramName = "Fb"
  1193. elif i == 7: paramName = "L/R"
  1194. elif self.fPluginInfo['label'] == "zynchorus":
  1195. if i == 0: paramName = "Freq"
  1196. elif i == 1: paramName = "Rnd"
  1197. elif i == 2: paramName = "L type" # combobox
  1198. elif i == 3: paramName = "St.df"
  1199. elif i == 6: paramName = "Fb"
  1200. elif i == 7: paramName = "L/R"
  1201. elif i == 8: paramName = "Flngr" # button
  1202. elif i == 9: paramName = "Subst" # button
  1203. elif self.fPluginInfo['label'] == "zyndistortion":
  1204. if i == 0: paramName = "LRc."
  1205. elif i == 4: paramName = "Neg." # button
  1206. elif i == 5: paramName = "LPF"
  1207. elif i == 6: paramName = "HPF"
  1208. elif i == 7: paramName = "St." # button
  1209. elif i == 8: paramName = "PF" # button
  1210. elif self.fPluginInfo['label'] == "zyndynamicfilter":
  1211. if i == 0: paramName = "Freq"
  1212. elif i == 1: paramName = "Rnd"
  1213. elif i == 2: paramName = "L type" # combobox
  1214. elif i == 3: paramName = "St.df"
  1215. elif i == 4: paramName = "LfoD"
  1216. elif i == 5: paramName = "A.S."
  1217. elif i == 6: paramName = "A.Inv." # button
  1218. elif i == 7: paramName = "A.M."
  1219. elif self.fPluginInfo['label'] == "zynecho":
  1220. if i == 1: paramName = "LRdl."
  1221. elif i == 2: paramName = "LRc."
  1222. elif i == 3: paramName = "Fb."
  1223. elif i == 4: paramName = "Damp"
  1224. elif self.fPluginInfo['label'] == "zynphaser":
  1225. if i == 0: paramName = "Freq"
  1226. elif i == 1: paramName = "Rnd"
  1227. elif i == 2: paramName = "L type" # combobox
  1228. elif i == 3: paramName = "St.df"
  1229. elif i == 5: paramName = "Fb"
  1230. elif i == 7: paramName = "L/R"
  1231. elif i == 8: paramName = "Subst" # button
  1232. elif i == 9: paramName = "Phase"
  1233. elif i == 11: paramName = "Dist"
  1234. elif self.fPluginInfo['label'] == "zynreverb":
  1235. if i == 2: paramName = "I.delfb"
  1236. elif i == 5: paramName = "LPF"
  1237. elif i == 6: paramName = "HPF"
  1238. elif i == 9: paramName = "R.S."
  1239. elif i == 10: paramName = "I.del"
  1240. else:
  1241. paramName = getParameterShortName(paramName)
  1242. widget = PixmapDial(self, i)
  1243. widget.setLabel(paramName)
  1244. widget.setMinimum(paramRanges['min'])
  1245. widget.setMaximum(paramRanges['max'])
  1246. widget.setPixmap(3)
  1247. widget.setCustomPaintColor(QColor(83, 173, 10))
  1248. widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_COLOR)
  1249. widget.forceWhiteLabelGradientText()
  1250. if (paramData['hints'] & PARAMETER_IS_ENABLED) == 0:
  1251. widget.setEnabled(False)
  1252. self.fParameterList.append([i, widget])
  1253. self.ui.w_knobs_left.layout().addWidget(widget)
  1254. if self.fPluginInfo['hints'] & PLUGIN_CAN_DRYWET:
  1255. widget = PixmapDial(self, PARAMETER_DRYWET)
  1256. widget.setLabel("Wet")
  1257. widget.setMinimum(0.0)
  1258. widget.setMaximum(1.0)
  1259. widget.setPixmap(3)
  1260. widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_CARLA_WET)
  1261. widget.forceWhiteLabelGradientText()
  1262. self.fParameterList.append([PARAMETER_DRYWET, widget])
  1263. self.ui.w_knobs_right.layout().addWidget(widget)
  1264. if self.fPluginInfo['hints'] & PLUGIN_CAN_VOLUME:
  1265. widget = PixmapDial(self, PARAMETER_VOLUME)
  1266. widget.setLabel("Volume")
  1267. widget.setMinimum(0.0)
  1268. widget.setMaximum(1.27)
  1269. widget.setPixmap(3)
  1270. widget.setCustomPaintMode(PixmapDial.CUSTOM_PAINT_MODE_CARLA_VOL)
  1271. widget.forceWhiteLabelGradientText()
  1272. self.fParameterList.append([PARAMETER_VOLUME, widget])
  1273. self.ui.w_knobs_right.layout().addWidget(widget)
  1274. #------------------------------------------------------------------
  1275. def getFixedHeight(self):
  1276. return 80
  1277. #------------------------------------------------------------------
  1278. def paintEvent(self, event):
  1279. painter = QPainter(self)
  1280. painter.setBrush(Qt.transparent)
  1281. painter.setPen(QPen(QColor(50, 50, 50), 1))
  1282. painter.drawRect(0, 1, self.width()-1, self.height()-3)
  1283. painter.setPen(QPen(QColor(64, 64, 64), 1))
  1284. painter.drawLine(0, 0, self.width(), 0)
  1285. AbstractPluginSlot.paintEvent(self, event)
  1286. # ------------------------------------------------------------------------------------------------------------
  1287. def getSkinStyle(host, pluginId):
  1288. if False:
  1289. # kdevelop likes this :)
  1290. host = CarlaHostNull()
  1291. progCount = 0
  1292. pluginInfo = PyCarlaPluginInfo
  1293. pluginName = ""
  1294. pluginInfo = host.get_plugin_info(pluginId)
  1295. pluginName = host.get_real_plugin_name(pluginId)
  1296. pluginLabel = pluginInfo['label'].lower()
  1297. pluginMaker = pluginInfo['maker']
  1298. uniqueId = pluginInfo['uniqueId']
  1299. if pluginInfo['type'] in (PLUGIN_VST2, PLUGIN_VST3, PLUGIN_AU):
  1300. progCount = host.get_program_count(pluginId)
  1301. else:
  1302. progCount = host.get_midi_program_count(pluginId)
  1303. # Samplers
  1304. if pluginInfo['type'] == PLUGIN_GIG:
  1305. return "gig"
  1306. if pluginInfo['type'] == PLUGIN_SF2:
  1307. return "sf2"
  1308. if pluginInfo['type'] == PLUGIN_SFZ:
  1309. return "sfz"
  1310. # Calf
  1311. if pluginName.split(" ", 1)[0].lower() == "calf":
  1312. return "calf_black" if "mono" in pluginLabel else "calf_blue"
  1313. # MOD
  1314. #if pluginLabel.startswith("http://portalmod.com/") or pluginLabel.startswith("http://plugin.org.uk/swh-plugins/"):
  1315. #return "mod"
  1316. # OpenAV
  1317. if pluginMaker == "OpenAV Productions":
  1318. return "openav"
  1319. # ZynFX
  1320. if pluginInfo['type'] == PLUGIN_INTERNAL:
  1321. if pluginLabel.startswith("zyn") and pluginInfo['category'] != PLUGIN_CATEGORY_SYNTH:
  1322. return "zynfx"
  1323. if pluginInfo['type'] == PLUGIN_LADSPA:
  1324. if pluginLabel.startswith("zyn") and pluginMaker.startswith("Josep Andreu"):
  1325. return "zynfx"
  1326. if pluginInfo['type'] == PLUGIN_LV2:
  1327. if pluginLabel.startswith("http://kxstudio.sf.net/carla/plugins/zyn") and pluginName != "ZynAddSubFX":
  1328. return "zynfx"
  1329. # Presets
  1330. if progCount > 1 and (pluginInfo['hints'] & PLUGIN_USES_MULTI_PROGS) == 0:
  1331. if pluginInfo['type'] in (PLUGIN_VST2, PLUGIN_VST3, PLUGIN_AU):
  1332. return "presets"
  1333. return "mpresets"
  1334. # DISTRHO Plugins (needs to be last)
  1335. if pluginMaker.startswith("falkTX, ") or pluginMaker == "DISTRHO" or pluginLabel.startswith("http://distrho.sf.net/plugins/"):
  1336. return pluginLabel.replace("http://distrho.sf.net/plugins/","")
  1337. return "default"
  1338. def createPluginSlot(parent, host, pluginId, options):
  1339. if not options['useSkins']:
  1340. return PluginSlot_Classic(parent, host, pluginId)
  1341. skinStyle = getSkinStyle(host, pluginId)
  1342. if "compact" in skinStyle or options['compact']:
  1343. return PluginSlot_Compact(parent, host, pluginId, skinStyle)
  1344. if "calf" in skinStyle:
  1345. return PluginSlot_Calf(parent, host, pluginId, skinStyle)
  1346. if skinStyle in ("mpresets", "presets", "zynfx"):
  1347. return PluginSlot_Presets(parent, host, pluginId, skinStyle)
  1348. return PluginSlot_Default(parent, host, pluginId, skinStyle)
  1349. # ------------------------------------------------------------------------------------------------------------
  1350. # Main Testing
  1351. if __name__ == '__main__':
  1352. from carla_app import CarlaApplication
  1353. from carla_host import initHost, loadHostSettings
  1354. import resources_rc
  1355. app = CarlaApplication("Carla-Skins")
  1356. host = initHost("Skins", None, False, False, False)
  1357. loadHostSettings(host)
  1358. host.engine_init("JACK", "Carla-Widgets")
  1359. host.add_plugin(BINARY_NATIVE, PLUGIN_INTERNAL, "", "", "zynreverb", 0, None, 0x0)
  1360. #host.add_plugin(BINARY_NATIVE, PLUGIN_DSSI, "/usr/lib/dssi/karplong.so", "karplong", "karplong", 0, None, 0x0)
  1361. #host.add_plugin(BINARY_NATIVE, PLUGIN_LV2, "", "", "http://www.openavproductions.com/sorcer", 0, None, 0x0)
  1362. #host.add_plugin(BINARY_NATIVE, PLUGIN_LV2, "", "", "http://calf.sourceforge.net/plugins/Compressor", 0, None, 0x0)
  1363. host.set_active(0, True)
  1364. #gui = createPluginSlot(None, host, 0, True)
  1365. gui = PluginSlot_Compact(None, host, 0, "default")
  1366. gui.testTimer()
  1367. gui.show()
  1368. app.exec_()