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 70KB

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