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