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.

patchcanvas.py 100KB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # PatchBay Canvas engine using QGraphicsView/Scene
  4. # Copyright (C) 2010-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 pyqtSignal, pyqtSlot, qDebug, qCritical, qFatal, qWarning, Qt, QObject
  24. from PyQt5.QtCore import QAbstractAnimation, QLineF, QPointF, QRectF, QSizeF, QSettings, QTimer
  25. from PyQt5.QtGui import QColor, QLinearGradient, QPen, QPolygonF, QPainter, QPainterPath
  26. from PyQt5.QtGui import QCursor, QFont, QFontMetrics
  27. from PyQt5.QtSvg import QGraphicsSvgItem, QSvgRenderer
  28. from PyQt5.QtWidgets import QGraphicsScene, QGraphicsItem, QGraphicsLineItem, QGraphicsPathItem
  29. from PyQt5.QtWidgets import QGraphicsColorizeEffect, QGraphicsDropShadowEffect
  30. from PyQt5.QtWidgets import QInputDialog, QLineEdit, QMenu
  31. else:
  32. from PyQt4.QtCore import pyqtSignal, pyqtSlot, qDebug, qCritical, qFatal, qWarning, Qt, QObject
  33. from PyQt4.QtCore import QAbstractAnimation, QLineF, QPointF, QRectF, QSizeF, QSettings, QTimer
  34. from PyQt4.QtGui import QColor, QLinearGradient, QPen, QPolygonF, QPainter, QPainterPath
  35. from PyQt4.QtGui import QCursor, QFont, QFontMetrics
  36. from PyQt4.QtGui import QGraphicsScene, QGraphicsItem, QGraphicsLineItem, QGraphicsPathItem
  37. from PyQt4.QtGui import QGraphicsColorizeEffect, QGraphicsDropShadowEffect
  38. from PyQt4.QtGui import QInputDialog, QLineEdit, QMenu
  39. from PyQt4.QtSvg import QGraphicsSvgItem, QSvgRenderer
  40. # ------------------------------------------------------------------------------------------------------------
  41. # Imports (Theme)
  42. from patchcanvas_theme import *
  43. # ------------------------------------------------------------------------------
  44. # patchcanvas-api.h
  45. # Port Mode
  46. PORT_MODE_NULL = 0
  47. PORT_MODE_INPUT = 1
  48. PORT_MODE_OUTPUT = 2
  49. # Port Type
  50. PORT_TYPE_NULL = 0
  51. PORT_TYPE_AUDIO_JACK = 1
  52. PORT_TYPE_MIDI_JACK = 2
  53. PORT_TYPE_MIDI_ALSA = 3
  54. PORT_TYPE_PARAMETER = 4
  55. # Callback Action
  56. ACTION_GROUP_INFO = 0 # group_id, N, N
  57. ACTION_GROUP_RENAME = 1 # group_id, N, new_name
  58. ACTION_GROUP_SPLIT = 2 # group_id, N, N
  59. ACTION_GROUP_JOIN = 3 # group_id, N, N
  60. ACTION_PORT_INFO = 4 # group_id, port_id, N
  61. ACTION_PORT_RENAME = 5 # group_id, port_id, new_name
  62. ACTION_PORTS_CONNECT = 6 # N, N, "outG:outP:inG:inP"
  63. ACTION_PORTS_DISCONNECT = 7 # conn_id, N, N
  64. ACTION_PLUGIN_CLONE = 8 # plugin_id, N, N
  65. ACTION_PLUGIN_EDIT = 9 # plugin_id, N, N
  66. ACTION_PLUGIN_RENAME = 10 # plugin_id, N, N
  67. ACTION_PLUGIN_REMOVE = 11 # plugin_id, N, N
  68. ACTION_PLUGIN_SHOW_UI = 12 # plugin_id, N, new_name
  69. # Icon
  70. ICON_APPLICATION = 0
  71. ICON_HARDWARE = 1
  72. ICON_DISTRHO = 2
  73. ICON_FILE = 3
  74. ICON_PLUGIN = 4
  75. ICON_LADISH_ROOM = 5
  76. # Split Option
  77. SPLIT_UNDEF = 0
  78. SPLIT_NO = 1
  79. SPLIT_YES = 2
  80. # Antialiasing Option
  81. ANTIALIASING_NONE = 0
  82. ANTIALIASING_SMALL = 1
  83. ANTIALIASING_FULL = 2
  84. # Eye-Candy Option
  85. EYECANDY_NONE = 0
  86. EYECANDY_SMALL = 1
  87. EYECANDY_FULL = 2
  88. # Canvas options
  89. class options_t(object):
  90. __slots__ = [
  91. 'theme_name',
  92. 'auto_hide_groups',
  93. 'use_bezier_lines',
  94. 'antialiasing',
  95. 'eyecandy'
  96. ]
  97. # Canvas features
  98. class features_t(object):
  99. __slots__ = [
  100. 'group_info',
  101. 'group_rename',
  102. 'port_info',
  103. 'port_rename',
  104. 'handle_group_pos'
  105. ]
  106. # ------------------------------------------------------------------------------
  107. # patchcanvas.h
  108. # object types
  109. CanvasBoxType = QGraphicsItem.UserType + 1
  110. CanvasIconType = QGraphicsItem.UserType + 2
  111. CanvasPortType = QGraphicsItem.UserType + 3
  112. CanvasLineType = QGraphicsItem.UserType + 4
  113. CanvasBezierLineType = QGraphicsItem.UserType + 5
  114. CanvasLineMovType = QGraphicsItem.UserType + 6
  115. CanvasBezierLineMovType = QGraphicsItem.UserType + 7
  116. # object lists
  117. class group_dict_t(object):
  118. __slots__ = [
  119. 'group_id',
  120. 'group_name',
  121. 'split',
  122. 'icon',
  123. 'plugin_id',
  124. 'widgets'
  125. ]
  126. class port_dict_t(object):
  127. __slots__ = [
  128. 'group_id',
  129. 'port_id',
  130. 'port_name',
  131. 'port_mode',
  132. 'port_type',
  133. 'is_alternate',
  134. 'widget'
  135. ]
  136. class connection_dict_t(object):
  137. __slots__ = [
  138. 'connection_id',
  139. 'group_in_id',
  140. 'port_in_id',
  141. 'group_out_id',
  142. 'port_out_id',
  143. 'widget'
  144. ]
  145. class animation_dict_t(object):
  146. __slots__ = [
  147. 'animation',
  148. 'item'
  149. ]
  150. # Main Canvas object
  151. class Canvas(object):
  152. __slots__ = [
  153. 'scene',
  154. 'callback',
  155. 'debug',
  156. 'last_z_value',
  157. 'last_connection_id',
  158. 'initial_pos',
  159. 'size_rect',
  160. 'group_list',
  161. 'port_list',
  162. 'connection_list',
  163. 'animation_list',
  164. 'qobject',
  165. 'settings',
  166. 'theme',
  167. 'initiated'
  168. ]
  169. # ------------------------------------------------------------------------------
  170. # patchcanvas.cpp
  171. class CanvasObject(QObject):
  172. def __init__(self, parent=None):
  173. QObject.__init__(self, parent)
  174. @pyqtSlot()
  175. def AnimationIdle(self):
  176. animation = self.sender()
  177. if animation:
  178. CanvasRemoveAnimation(animation)
  179. @pyqtSlot()
  180. def AnimationHide(self):
  181. animation = self.sender()
  182. if animation:
  183. item = animation.item()
  184. if item:
  185. item.hide()
  186. CanvasRemoveAnimation(animation)
  187. @pyqtSlot()
  188. def AnimationDestroy(self):
  189. animation = self.sender()
  190. if animation:
  191. item = animation.item()
  192. if item:
  193. CanvasRemoveItemFX(item)
  194. CanvasRemoveAnimation(animation)
  195. @pyqtSlot()
  196. def PortContextMenuDisconnect(self):
  197. try:
  198. connectionId = int(self.sender().data())
  199. except:
  200. return
  201. CanvasCallback(ACTION_PORTS_DISCONNECT, connectionId, 0, "")
  202. # Global objects
  203. canvas = Canvas()
  204. canvas.qobject = None
  205. canvas.settings = None
  206. canvas.theme = None
  207. canvas.initiated = False
  208. canvas.group_list = []
  209. canvas.port_list = []
  210. canvas.connection_list = []
  211. canvas.animation_list = []
  212. options = options_t()
  213. options.theme_name = getDefaultThemeName()
  214. options.auto_hide_groups = False
  215. options.use_bezier_lines = True
  216. options.antialiasing = ANTIALIASING_SMALL
  217. options.eyecandy = EYECANDY_SMALL
  218. features = features_t()
  219. features.group_info = False
  220. features.group_rename = False
  221. features.port_info = False
  222. features.port_rename = False
  223. features.handle_group_pos = False
  224. # Internal functions
  225. def bool2str(check):
  226. return "True" if check else "False"
  227. def port_mode2str(port_mode):
  228. if port_mode == PORT_MODE_NULL:
  229. return "PORT_MODE_NULL"
  230. elif port_mode == PORT_MODE_INPUT:
  231. return "PORT_MODE_INPUT"
  232. elif port_mode == PORT_MODE_OUTPUT:
  233. return "PORT_MODE_OUTPUT"
  234. else:
  235. return "PORT_MODE_???"
  236. def port_type2str(port_type):
  237. if port_type == PORT_TYPE_NULL:
  238. return "PORT_TYPE_NULL"
  239. elif port_type == PORT_TYPE_AUDIO_JACK:
  240. return "PORT_TYPE_AUDIO_JACK"
  241. elif port_type == PORT_TYPE_MIDI_JACK:
  242. return "PORT_TYPE_MIDI_JACK"
  243. elif port_type == PORT_TYPE_MIDI_ALSA:
  244. return "PORT_TYPE_MIDI_ALSA"
  245. elif port_type == PORT_TYPE_PARAMETER:
  246. return "PORT_TYPE_MIDI_PARAMETER"
  247. else:
  248. return "PORT_TYPE_???"
  249. def icon2str(icon):
  250. if icon == ICON_APPLICATION:
  251. return "ICON_APPLICATION"
  252. elif icon == ICON_HARDWARE:
  253. return "ICON_HARDWARE"
  254. elif icon == ICON_DISTRHO:
  255. return "ICON_DISTRHO"
  256. elif icon == ICON_FILE:
  257. return "ICON_FILE"
  258. elif icon == ICON_PLUGIN:
  259. return "ICON_PLUGIN"
  260. elif icon == ICON_LADISH_ROOM:
  261. return "ICON_LADISH_ROOM"
  262. else:
  263. return "ICON_???"
  264. def split2str(split):
  265. if split == SPLIT_UNDEF:
  266. return "SPLIT_UNDEF"
  267. elif split == SPLIT_NO:
  268. return "SPLIT_NO"
  269. elif split == SPLIT_YES:
  270. return "SPLIT_YES"
  271. else:
  272. return "SPLIT_???"
  273. # PatchCanvas API
  274. def setOptions(new_options):
  275. if canvas.initiated: return
  276. options.theme_name = new_options.theme_name
  277. options.auto_hide_groups = new_options.auto_hide_groups
  278. options.use_bezier_lines = new_options.use_bezier_lines
  279. options.antialiasing = new_options.antialiasing
  280. options.eyecandy = new_options.eyecandy
  281. def setFeatures(new_features):
  282. if canvas.initiated: return
  283. features.group_info = new_features.group_info
  284. features.group_rename = new_features.group_rename
  285. features.port_info = new_features.port_info
  286. features.port_rename = new_features.port_rename
  287. features.handle_group_pos = new_features.handle_group_pos
  288. def init(appName, scene, callback, debug=False):
  289. if debug:
  290. qDebug("PatchCanvas::init(\"%s\", %s, %s, %s)" % (appName, scene, callback, bool2str(debug)))
  291. if canvas.initiated:
  292. qCritical("PatchCanvas::init() - already initiated")
  293. return
  294. if not callback:
  295. qFatal("PatchCanvas::init() - fatal error: callback not set")
  296. return
  297. canvas.scene = scene
  298. canvas.callback = callback
  299. canvas.debug = debug
  300. canvas.last_z_value = 0
  301. canvas.last_connection_id = 0
  302. canvas.initial_pos = QPointF(0, 0)
  303. canvas.size_rect = QRectF()
  304. if not canvas.qobject: canvas.qobject = CanvasObject()
  305. if not canvas.settings: canvas.settings = QSettings("falkTX", appName)
  306. if canvas.theme:
  307. del canvas.theme
  308. canvas.theme = None
  309. for i in range(Theme.THEME_MAX):
  310. this_theme_name = getThemeName(i)
  311. if this_theme_name == options.theme_name:
  312. canvas.theme = Theme(i)
  313. break
  314. if not canvas.theme:
  315. canvas.theme = Theme(getDefaultTheme())
  316. canvas.scene.updateTheme()
  317. canvas.initiated = True
  318. def clear():
  319. if canvas.debug:
  320. qDebug("PatchCanvas::clear()")
  321. group_list_ids = []
  322. port_list_ids = []
  323. connection_list_ids = []
  324. for group in canvas.group_list:
  325. group_list_ids.append(group.group_id)
  326. for port in canvas.port_list:
  327. port_list_ids.append((port.group_id, port.port_id))
  328. for connection in canvas.connection_list:
  329. connection_list_ids.append(connection.connection_id)
  330. for idx in connection_list_ids:
  331. disconnectPorts(idx)
  332. for group_id, port_id in port_list_ids:
  333. removePort(group_id, port_id)
  334. for idx in group_list_ids:
  335. removeGroup(idx)
  336. canvas.last_z_value = 0
  337. canvas.last_connection_id = 0
  338. canvas.group_list = []
  339. canvas.port_list = []
  340. canvas.connection_list = []
  341. canvas.scene.clear()
  342. canvas.initiated = False
  343. def setInitialPos(x, y):
  344. if canvas.debug:
  345. qDebug("PatchCanvas::setInitialPos(%i, %i)" % (x, y))
  346. canvas.initial_pos.setX(x)
  347. canvas.initial_pos.setY(y)
  348. def setCanvasSize(x, y, width, height):
  349. if canvas.debug:
  350. qDebug("PatchCanvas::setCanvasSize(%i, %i, %i, %i)" % (x, y, width, height))
  351. canvas.size_rect.setX(x)
  352. canvas.size_rect.setY(y)
  353. canvas.size_rect.setWidth(width)
  354. canvas.size_rect.setHeight(height)
  355. def addGroup(group_id, group_name, split=SPLIT_UNDEF, icon=ICON_APPLICATION):
  356. if canvas.debug:
  357. qDebug("PatchCanvas::addGroup(%i, %s, %s, %s)" % (group_id, group_name.encode(), split2str(split), icon2str(icon)))
  358. for group in canvas.group_list:
  359. if group.group_id == group_id:
  360. qWarning("PatchCanvas::addGroup(%i, %s, %s, %s) - group already exists" % (group_id, group_name.encode(), split2str(split), icon2str(icon)))
  361. return
  362. if split == SPLIT_UNDEF:
  363. isHardware = bool(icon == ICON_HARDWARE)
  364. if features.handle_group_pos:
  365. split = canvas.settings.value("CanvasPositions/%s_SPLIT" % group_name, SPLIT_YES if isHardware else split, type=int)
  366. elif isHardware:
  367. split = SPLIT_YES
  368. group_box = CanvasBox(group_id, group_name, icon)
  369. group_dict = group_dict_t()
  370. group_dict.group_id = group_id
  371. group_dict.group_name = group_name
  372. group_dict.split = bool(split == SPLIT_YES)
  373. group_dict.icon = icon
  374. group_dict.plugin_id = -1
  375. group_dict.widgets = [group_box, None]
  376. if split == SPLIT_YES:
  377. group_box.setSplit(True, PORT_MODE_OUTPUT)
  378. if features.handle_group_pos:
  379. group_box.setPos(canvas.settings.value("CanvasPositions/%s_OUTPUT" % group_name, CanvasGetNewGroupPos(False), type=QPointF))
  380. else:
  381. group_box.setPos(CanvasGetNewGroupPos(False))
  382. group_sbox = CanvasBox(group_id, group_name, icon)
  383. group_sbox.setSplit(True, PORT_MODE_INPUT)
  384. group_dict.widgets[1] = group_sbox
  385. if features.handle_group_pos:
  386. group_sbox.setPos(canvas.settings.value("CanvasPositions/%s_INPUT" % group_name, CanvasGetNewGroupPos(True), type=QPointF))
  387. else:
  388. group_sbox.setPos(CanvasGetNewGroupPos(True))
  389. canvas.last_z_value += 1
  390. group_sbox.setZValue(canvas.last_z_value)
  391. if options.eyecandy == EYECANDY_FULL and not options.auto_hide_groups:
  392. CanvasItemFX(group_sbox, True)
  393. group_sbox.checkItemPos()
  394. else:
  395. group_box.setSplit(False)
  396. if features.handle_group_pos:
  397. group_box.setPos(canvas.settings.value("CanvasPositions/%s" % group_name, CanvasGetNewGroupPos(False), type=QPointF))
  398. else:
  399. # Special ladish fake-split groups
  400. horizontal = bool(icon == ICON_HARDWARE or icon == ICON_LADISH_ROOM)
  401. group_box.setPos(CanvasGetNewGroupPos(horizontal))
  402. group_box.checkItemPos()
  403. canvas.last_z_value += 1
  404. group_box.setZValue(canvas.last_z_value)
  405. canvas.group_list.append(group_dict)
  406. if options.eyecandy == EYECANDY_FULL and not options.auto_hide_groups:
  407. CanvasItemFX(group_box, True)
  408. QTimer.singleShot(0, canvas.scene.update)
  409. def removeGroup(group_id):
  410. if canvas.debug:
  411. qDebug("PatchCanvas::removeGroup(%i)" % group_id)
  412. for group in canvas.group_list:
  413. if group.group_id == group_id:
  414. item = group.widgets[0]
  415. group_name = group.group_name
  416. if group.split:
  417. s_item = group.widgets[1]
  418. if features.handle_group_pos:
  419. canvas.settings.setValue("CanvasPositions/%s_OUTPUT" % group_name, item.pos())
  420. canvas.settings.setValue("CanvasPositions/%s_INPUT" % group_name, s_item.pos())
  421. canvas.settings.setValue("CanvasPositions/%s_SPLIT" % group_name, SPLIT_YES)
  422. if options.eyecandy == EYECANDY_FULL:
  423. CanvasItemFX(s_item, False, True)
  424. else:
  425. s_item.removeIconFromScene()
  426. canvas.scene.removeItem(s_item)
  427. del s_item
  428. else:
  429. if features.handle_group_pos:
  430. canvas.settings.setValue("CanvasPositions/%s" % group_name, item.pos())
  431. canvas.settings.setValue("CanvasPositions/%s_SPLIT" % group_name, SPLIT_NO)
  432. if options.eyecandy == EYECANDY_FULL:
  433. CanvasItemFX(item, False, True)
  434. else:
  435. item.removeIconFromScene()
  436. canvas.scene.removeItem(item)
  437. del item
  438. canvas.group_list.remove(group)
  439. QTimer.singleShot(0, canvas.scene.update)
  440. return
  441. qCritical("PatchCanvas::removeGroup(%i) - unable to find group to remove" % group_id)
  442. def renameGroup(group_id, new_group_name):
  443. if canvas.debug:
  444. qDebug("PatchCanvas::renameGroup(%i, %s)" % (group_id, new_group_name.encode()))
  445. for group in canvas.group_list:
  446. if group.group_id == group_id:
  447. group.group_name = new_group_name
  448. group.widgets[0].setGroupName(new_group_name)
  449. if group.split and group.widgets[1]:
  450. group.widgets[1].setGroupName(new_group_name)
  451. QTimer.singleShot(0, canvas.scene.update)
  452. return
  453. qCritical("PatchCanvas::renameGroup(%i, %s) - unable to find group to rename" % (group_id, new_group_name.encode()))
  454. def splitGroup(group_id):
  455. if canvas.debug:
  456. qDebug("PatchCanvas::splitGroup(%i)" % group_id)
  457. item = None
  458. group_name = ""
  459. group_icon = ICON_APPLICATION
  460. ports_data = []
  461. conns_data = []
  462. # Step 1 - Store all Item data
  463. for group in canvas.group_list:
  464. if group.group_id == group_id:
  465. if group.split:
  466. qCritical("PatchCanvas::splitGroup(%i) - group is already splitted" % group_id)
  467. return
  468. item = group.widgets[0]
  469. group_name = group.group_name
  470. group_icon = group.icon
  471. break
  472. if not item:
  473. qCritical("PatchCanvas::splitGroup(%i) - unable to find group to split" % group_id)
  474. return
  475. port_list_ids = list(item.getPortList())
  476. for port in canvas.port_list:
  477. if port.port_id in port_list_ids:
  478. port_dict = port_dict_t()
  479. port_dict.group_id = port.group_id
  480. port_dict.port_id = port.port_id
  481. port_dict.port_name = port.port_name
  482. port_dict.port_mode = port.port_mode
  483. port_dict.port_type = port.port_type
  484. port_dict.is_alternate = port.is_alternate
  485. port_dict.widget = None
  486. ports_data.append(port_dict)
  487. for connection in canvas.connection_list:
  488. if connection.port_out_id in port_list_ids or connection.port_in_id in port_list_ids:
  489. connection_dict = connection_dict_t()
  490. connection_dict.connection_id = connection.connection_id
  491. connection_dict.group_in_id = connection.group_in_id
  492. connection_dict.port_in_id = connection.port_in_id
  493. connection_dict.group_out_id = connection.group_out_id
  494. connection_dict.port_out_id = connection.port_out_id
  495. connection_dict.widget = None
  496. conns_data.append(connection_dict)
  497. # Step 2 - Remove Item and Children
  498. for conn in conns_data:
  499. disconnectPorts(conn.connection_id)
  500. for port_id in port_list_ids:
  501. removePort(group_id, port_id)
  502. removeGroup(group_id)
  503. # Step 3 - Re-create Item, now splitted
  504. addGroup(group_id, group_name, SPLIT_YES, group_icon)
  505. for port in ports_data:
  506. addPort(group_id, port.port_id, port.port_name, port.port_mode, port.port_type, port.is_alternate)
  507. for conn in conns_data:
  508. connectPorts(conn.connection_id, conn.group_out_id, conn.port_out_id, conn.group_in_id, conn.port_in_id)
  509. QTimer.singleShot(0, canvas.scene.update)
  510. def joinGroup(group_id):
  511. if canvas.debug:
  512. qDebug("PatchCanvas::joinGroup(%i)" % group_id)
  513. item = None
  514. s_item = None
  515. group_name = ""
  516. group_icon = ICON_APPLICATION
  517. ports_data = []
  518. conns_data = []
  519. # Step 1 - Store all Item data
  520. for group in canvas.group_list:
  521. if group.group_id == group_id:
  522. if not group.split:
  523. qCritical("PatchCanvas::joinGroup(%i) - group is not splitted" % group_id)
  524. return
  525. item = group.widgets[0]
  526. s_item = group.widgets[1]
  527. group_name = group.group_name
  528. group_icon = group.icon
  529. break
  530. # FIXME
  531. if not (item and s_item):
  532. qCritical("PatchCanvas::joinGroup(%i) - unable to find groups to join" % group_id)
  533. return
  534. port_list_ids = list(item.getPortList())
  535. port_list_idss = s_item.getPortList()
  536. for port_id in port_list_idss:
  537. if port_id not in port_list_ids:
  538. port_list_ids.append(port_id)
  539. for port in canvas.port_list:
  540. if port.port_id in port_list_ids:
  541. port_dict = port_dict_t()
  542. port_dict.group_id = port.group_id
  543. port_dict.port_id = port.port_id
  544. port_dict.port_name = port.port_name
  545. port_dict.port_mode = port.port_mode
  546. port_dict.port_type = port.port_type
  547. port_dict.is_alternate = port.is_alternate
  548. port_dict.widget = None
  549. ports_data.append(port_dict)
  550. for connection in canvas.connection_list:
  551. if connection.port_out_id in port_list_ids or connection.port_in_id in port_list_ids:
  552. connection_dict = connection_dict_t()
  553. connection_dict.connection_id = connection.connection_id
  554. connection_dict.group_in_id = connection.group_in_id
  555. connection_dict.port_in_id = connection.port_in_id
  556. connection_dict.group_out_id = connection.group_out_id
  557. connection_dict.port_out_id = connection.port_out_id
  558. connection_dict.widget = None
  559. conns_data.append(connection_dict)
  560. # Step 2 - Remove Item and Children
  561. for conn in conns_data:
  562. disconnectPorts(conn.connection_id)
  563. for port_id in port_list_ids:
  564. removePort(group_id, port_id)
  565. removeGroup(group_id)
  566. # Step 3 - Re-create Item, now together
  567. addGroup(group_id, group_name, SPLIT_NO, group_icon)
  568. for port in ports_data:
  569. addPort(group_id, port.port_id, port.port_name, port.port_mode, port.port_type, port.is_alternate)
  570. for conn in conns_data:
  571. connectPorts(conn.connection_id, conn.group_out_id, conn.port_out_id, conn.group_in_id, conn.port_in_id)
  572. QTimer.singleShot(0, canvas.scene.update)
  573. def getGroupPos(group_id, port_mode=PORT_MODE_OUTPUT):
  574. if canvas.debug:
  575. qDebug("PatchCanvas::getGroupPos(%i, %s)" % (group_id, port_mode2str(port_mode)))
  576. for group in canvas.group_list:
  577. if group.group_id == group_id:
  578. if group.split:
  579. if port_mode == PORT_MODE_OUTPUT:
  580. return group.widgets[0].pos()
  581. elif port_mode == PORT_MODE_INPUT:
  582. return group.widgets[1].pos()
  583. else:
  584. return QPointF(0, 0)
  585. else:
  586. return group.widgets[0].pos()
  587. qCritical("PatchCanvas::getGroupPos(%i, %s) - unable to find group" % (group_id, port_mode2str(port_mode)))
  588. return QPointF(0, 0)
  589. def setGroupPos(group_id, group_pos_x, group_pos_y):
  590. setGroupPosFull(group_id, group_pos_x, group_pos_y, group_pos_x, group_pos_y)
  591. def setGroupPosFull(group_id, group_pos_x_o, group_pos_y_o, group_pos_x_i, group_pos_y_i):
  592. if canvas.debug:
  593. qDebug("PatchCanvas::setGroupPos(%i, %i, %i, %i, %i)" % (group_id, group_pos_x_o, group_pos_y_o, group_pos_x_i, group_pos_y_i))
  594. for group in canvas.group_list:
  595. if group.group_id == group_id:
  596. group.widgets[0].setPos(group_pos_x_o, group_pos_y_o)
  597. if group.split and group.widgets[1]:
  598. group.widgets[1].setPos(group_pos_x_i, group_pos_y_i)
  599. QTimer.singleShot(0, canvas.scene.update)
  600. return
  601. qCritical("PatchCanvas::setGroupPos(%i, %i, %i, %i, %i) - unable to find group to reposition" % (group_id, group_pos_x_o, group_pos_y_o, group_pos_x_i, group_pos_y_i))
  602. def setGroupIcon(group_id, icon):
  603. if canvas.debug:
  604. qDebug("PatchCanvas::setGroupIcon(%i, %s)" % (group_id, icon2str(icon)))
  605. for group in canvas.group_list:
  606. if group.group_id == group_id:
  607. group.icon = icon
  608. group.widgets[0].setIcon(icon)
  609. if group.split and group.widgets[1]:
  610. group.widgets[1].setIcon(icon)
  611. QTimer.singleShot(0, canvas.scene.update)
  612. return
  613. qCritical("PatchCanvas::setGroupIcon(%i, %s) - unable to find group to change icon" % (group_id, icon2str(icon)))
  614. def getPluginAsGroup(plugin_id):
  615. if canvas.debug:
  616. qDebug("PatchCanvas::getPluginAsGroup(%i)" % plugin_id)
  617. for group in canvas.group_list:
  618. if group.plugin_id == plugin_id:
  619. return (True, group.group_id)
  620. qCritical("PatchCanvas::getPluginAsGroup(%i) - no such plugin" % plugin_id)
  621. return (False, -1)
  622. def setGroupAsPlugin(group_id, plugin_id, hasUi):
  623. if canvas.debug:
  624. qDebug("PatchCanvas::setGroupAsPlugin(%i, %i, %s)" % (group_id, plugin_id, bool2str(hasUi)))
  625. for group in canvas.group_list:
  626. if group.group_id == group_id:
  627. group.plugin_id = plugin_id
  628. group.widgets[0].setAsPlugin(plugin_id, hasUi)
  629. if group.split and group.widgets[1]:
  630. group.widgets[1].setAsPlugin(plugin_id, hasUi)
  631. return
  632. qCritical("PatchCanvas::setGroupAsPlugin(%i, %i, %s) - unable to find group to set as plugin" % (group_id, plugin_id, bool2str(hasUi)))
  633. def addPort(group_id, port_id, port_name, port_mode, port_type, is_alternate=False):
  634. if canvas.debug:
  635. qDebug("PatchCanvas::addPort(%i, %i, %s, %s, %s, %s)" % (group_id, port_id, port_name.encode(), port_mode2str(port_mode), port_type2str(port_type), bool2str(is_alternate)))
  636. for port in canvas.port_list:
  637. if port.group_id == group_id and port.port_id == port_id:
  638. qWarning("PatchCanvas::addPort(%i, %i, %s, %s, %s) - port already exists" % (group_id, port_id, port_name.encode(), port_mode2str(port_mode), port_type2str(port_type)))
  639. return
  640. box_widget = None
  641. port_widget = None
  642. for group in canvas.group_list:
  643. if group.group_id == group_id:
  644. if group.split and group.widgets[0].getSplittedMode() != port_mode and group.widgets[1]:
  645. n = 1
  646. else:
  647. n = 0
  648. box_widget = group.widgets[n]
  649. port_widget = box_widget.addPortFromGroup(port_id, port_mode, port_type, port_name, is_alternate)
  650. break
  651. if not (box_widget and port_widget):
  652. qCritical("PatchCanvas::addPort(%i, %i, %s, %s, %s) - Unable to find parent group" % (group_id, port_id, port_name.encode(), port_mode2str(port_mode), port_type2str(port_type)))
  653. return
  654. if options.eyecandy == EYECANDY_FULL:
  655. CanvasItemFX(port_widget, True)
  656. port_dict = port_dict_t()
  657. port_dict.group_id = group_id
  658. port_dict.port_id = port_id
  659. port_dict.port_name = port_name
  660. port_dict.port_mode = port_mode
  661. port_dict.port_type = port_type
  662. port_dict.is_alternate = is_alternate
  663. port_dict.widget = port_widget
  664. canvas.port_list.append(port_dict)
  665. box_widget.updatePositions()
  666. QTimer.singleShot(0, canvas.scene.update)
  667. def removePort(group_id, port_id):
  668. if canvas.debug:
  669. qDebug("PatchCanvas::removePort(%i, %i)" % (group_id, port_id))
  670. for port in canvas.port_list:
  671. if port.group_id == group_id and port.port_id == port_id:
  672. item = port.widget
  673. item.parentItem().removePortFromGroup(port_id)
  674. canvas.scene.removeItem(item)
  675. del item
  676. canvas.port_list.remove(port)
  677. QTimer.singleShot(0, canvas.scene.update)
  678. return
  679. qCritical("PatchCanvas::removePort(%i, %i) - Unable to find port to remove" % (group_id, port_id))
  680. def renamePort(group_id, port_id, new_port_name):
  681. if canvas.debug:
  682. qDebug("PatchCanvas::renamePort(%i, %i, %s)" % (group_id, port_id, new_port_name.encode()))
  683. for port in canvas.port_list:
  684. if port.group_id == group_id and port.port_id == port_id:
  685. port.port_name = new_port_name
  686. port.widget.setPortName(new_port_name)
  687. port.widget.parentItem().updatePositions()
  688. QTimer.singleShot(0, canvas.scene.update)
  689. return
  690. qCritical("PatchCanvas::renamePort(%i, %i, %s) - Unable to find port to rename" % (group_id, port_id, new_port_name.encode()))
  691. def connectPorts(connection_id, group_out_id, port_out_id, group_in_id, port_in_id):
  692. if canvas.debug:
  693. qDebug("PatchCanvas::connectPorts(%i, %i, %i, %i, %i)" % (connection_id, group_out_id, port_out_id, group_in_id, port_in_id))
  694. port_out = None
  695. port_in = None
  696. port_out_parent = None
  697. port_in_parent = None
  698. for port in canvas.port_list:
  699. if port.group_id == group_out_id and port.port_id == port_out_id:
  700. port_out = port.widget
  701. port_out_parent = port_out.parentItem()
  702. elif port.group_id == group_in_id and port.port_id == port_in_id:
  703. port_in = port.widget
  704. port_in_parent = port_in.parentItem()
  705. # FIXME
  706. if not (port_out and port_in):
  707. qCritical("PatchCanvas::connectPorts(%i, %i, %i, %i, %i) - unable to find ports to connect" % (connection_id, group_out_id, port_out_id, group_in_id, port_in_id))
  708. return
  709. connection_dict = connection_dict_t()
  710. connection_dict.connection_id = connection_id
  711. connection_dict.group_in_id = group_in_id
  712. connection_dict.port_in_id = port_in_id
  713. connection_dict.group_out_id = group_out_id
  714. connection_dict.port_out_id = port_out_id
  715. if options.use_bezier_lines:
  716. connection_dict.widget = CanvasBezierLine(port_out, port_in, None)
  717. else:
  718. connection_dict.widget = CanvasLine(port_out, port_in, None)
  719. canvas.scene.addItem(connection_dict.widget)
  720. port_out_parent.addLineFromGroup(connection_dict.widget, connection_id)
  721. port_in_parent.addLineFromGroup(connection_dict.widget, connection_id)
  722. canvas.last_z_value += 1
  723. port_out_parent.setZValue(canvas.last_z_value)
  724. port_in_parent.setZValue(canvas.last_z_value)
  725. canvas.last_z_value += 1
  726. connection_dict.widget.setZValue(canvas.last_z_value)
  727. canvas.connection_list.append(connection_dict)
  728. if options.eyecandy == EYECANDY_FULL:
  729. item = connection_dict.widget
  730. CanvasItemFX(item, True)
  731. QTimer.singleShot(0, canvas.scene.update)
  732. def disconnectPorts(connection_id):
  733. if canvas.debug:
  734. qDebug("PatchCanvas::disconnectPorts(%i)" % connection_id)
  735. line = None
  736. item1 = None
  737. item2 = None
  738. group1id = port1id = 0
  739. group2id = port2id = 0
  740. for connection in canvas.connection_list:
  741. if connection.connection_id == connection_id:
  742. group1id = connection.group_out_id
  743. group2id = connection.group_in_id
  744. port1id = connection.port_out_id
  745. port2id = connection.port_in_id
  746. line = connection.widget
  747. canvas.connection_list.remove(connection)
  748. break
  749. if not line:
  750. qCritical("PatchCanvas::disconnectPorts(%i) - unable to find connection ports" % connection_id)
  751. return
  752. for port in canvas.port_list:
  753. if port.group_id == group1id and port.port_id == port1id:
  754. item1 = port.widget
  755. break
  756. if not item1:
  757. qCritical("PatchCanvas::disconnectPorts(%i) - unable to find output port" % connection_id)
  758. return
  759. for port in canvas.port_list:
  760. if port.group_id == group2id and port.port_id == port2id:
  761. item2 = port.widget
  762. break
  763. if not item2:
  764. qCritical("PatchCanvas::disconnectPorts(%i) - unable to find input port" % connection_id)
  765. return
  766. item1.parentItem().removeLineFromGroup(connection_id)
  767. item2.parentItem().removeLineFromGroup(connection_id)
  768. if options.eyecandy == EYECANDY_FULL:
  769. CanvasItemFX(line, False, True)
  770. else:
  771. line.deleteFromScene()
  772. QTimer.singleShot(0, canvas.scene.update)
  773. def arrange():
  774. if canvas.debug:
  775. qDebug("PatchCanvas::arrange()")
  776. def updateZValues():
  777. if canvas.debug:
  778. qDebug("PatchCanvas::updateZValues()")
  779. for group in canvas.group_list:
  780. group.widgets[0].resetLinesZValue()
  781. if group.split and group.widgets[1]:
  782. group.widgets[1].resetLinesZValue()
  783. def handlePluginRemoved(plugin_id):
  784. if canvas.debug:
  785. qDebug("PatchCanvas::handlePluginRemoved(%i)" % plugin_id)
  786. for group in canvas.group_list:
  787. if group.plugin_id < plugin_id:
  788. continue
  789. group.plugin_id -= 1
  790. group.widgets[0].m_plugin_id -= 1
  791. if group.split and group.widgets[1]:
  792. group.widgets[1].m_plugin_id -= 1
  793. def handleAllPluginsRemoved():
  794. if canvas.debug:
  795. qDebug("PatchCanvas::handleAllPluginsRemoved()")
  796. for group in canvas.group_list:
  797. group.plugin_id -= 1
  798. group.widgets[0].m_plugin_id -= 1
  799. if group.split and group.widgets[1]:
  800. group.widgets[1].m_plugin_id -= 1
  801. # Extra Internal functions
  802. def CanvasGetNewGroupPos(horizontal):
  803. if canvas.debug:
  804. qDebug("PatchCanvas::CanvasGetNewGroupPos(%s)" % bool2str(horizontal))
  805. new_pos = QPointF(canvas.initial_pos.x(), canvas.initial_pos.y())
  806. items = canvas.scene.items()
  807. break_loop = False
  808. while not break_loop:
  809. break_for = False
  810. for i in range(len(items)):
  811. item = items[i]
  812. if item and item.type() == CanvasBoxType:
  813. if item.sceneBoundingRect().contains(new_pos):
  814. if horizontal:
  815. new_pos += QPointF(item.boundingRect().width() + 15, 0)
  816. else:
  817. new_pos += QPointF(0, item.boundingRect().height() + 15)
  818. break_for = True
  819. break
  820. if i >= len(items) - 1 and not break_for:
  821. break_loop = True
  822. return new_pos
  823. def CanvasGetFullPortName(group_id, port_id):
  824. if canvas.debug:
  825. qDebug("PatchCanvas::CanvasGetFullPortName(%i, %i)" % (group_id, port_id))
  826. for port in canvas.port_list:
  827. if port.group_id == group_id and port.port_id == port_id:
  828. group_id = port.group_id
  829. for group in canvas.group_list:
  830. if group.group_id == group_id:
  831. return group.group_name + ":" + port.port_name
  832. break
  833. qCritical("PatchCanvas::CanvasGetFullPortName(%i, %i) - unable to find port" % (group_id, port_id))
  834. return ""
  835. def CanvasGetPortConnectionList(group_id, port_id):
  836. if canvas.debug:
  837. qDebug("PatchCanvas::CanvasGetPortConnectionList(%i, %i)" % (group_id, port_id))
  838. conn_list = []
  839. for connection in canvas.connection_list:
  840. if connection.group_out_id == group_id and connection.port_out_id == port_id:
  841. conn_list.append((connection.connection_id, connection.group_in_id, connection.port_in_id))
  842. elif connection.group_in_id == group_id and connection.port_in_id == port_id:
  843. conn_list.append((connection.connection_id, connection.group_out_id, connection.port_out_id))
  844. return conn_list
  845. def CanvasRemoveAnimation(f_animation):
  846. if canvas.debug:
  847. qDebug("PatchCanvas::CanvasRemoveAnimation(%s)" % f_animation)
  848. for animation in canvas.animation_list:
  849. if animation.animation == f_animation:
  850. canvas.animation_list.remove(animation)
  851. del animation.animation
  852. break
  853. def CanvasCallback(action, value1, value2, value_str):
  854. if canvas.debug:
  855. qDebug("PatchCanvas::CanvasCallback(%i, %i, %i, %s)" % (action, value1, value2, value_str.encode()))
  856. canvas.callback(action, value1, value2, value_str)
  857. def CanvasItemFX(item, show, destroy=False):
  858. if canvas.debug:
  859. qDebug("PatchCanvas::CanvasItemFX(%s, %s, %s)" % (item, bool2str(show), bool2str(destroy)))
  860. # Check if item already has an animationItemFX
  861. for animation in canvas.animation_list:
  862. if animation.item == item:
  863. animation.animation.stop()
  864. canvas.animation_list.remove(animation)
  865. del animation.animation
  866. break
  867. animation = CanvasFadeAnimation(item, show)
  868. animation.setDuration(750 if show else 500)
  869. animation_dict = animation_dict_t()
  870. animation_dict.animation = animation
  871. animation_dict.item = item
  872. canvas.animation_list.append(animation_dict)
  873. if show:
  874. animation.finished.connect(canvas.qobject.AnimationIdle)
  875. else:
  876. if destroy:
  877. animation.finished.connect(canvas.qobject.AnimationDestroy)
  878. else:
  879. animation.finished.connect(canvas.qobject.AnimationHide)
  880. animation.start()
  881. def CanvasRemoveItemFX(item):
  882. if canvas.debug:
  883. qDebug("PatchCanvas::CanvasRemoveItemFX(%s)" % item)
  884. if item.type() == CanvasBoxType:
  885. item.removeIconFromScene()
  886. canvas.scene.removeItem(item)
  887. elif item.type() == CanvasPortType:
  888. canvas.scene.removeItem(item)
  889. elif item.type() in (CanvasLineType, CanvasBezierLineType):
  890. pass #item.deleteFromScene()
  891. # Force deletion of item if needed
  892. if item.type() in (CanvasBoxType, CanvasPortType):
  893. del item
  894. # ------------------------------------------------------------------------------
  895. # patchscene.cpp
  896. class PatchScene(QGraphicsScene):
  897. scaleChanged = pyqtSignal(float)
  898. sceneGroupMoved = pyqtSignal(int, int, QPointF)
  899. pluginSelected = pyqtSignal(list)
  900. def __init__(self, parent, view):
  901. QGraphicsScene.__init__(self, parent)
  902. self.m_ctrl_down = False
  903. self.m_mouse_down_init = False
  904. self.m_mouse_rubberband = False
  905. self.addRubberBand()
  906. self.m_view = view
  907. if not self.m_view:
  908. qFatal("PatchCanvas::PatchScene() - invalid view")
  909. self.selectionChanged.connect(self.slot_selectionChanged)
  910. def addRubberBand(self):
  911. self.m_rubberband = self.addRect(QRectF(0, 0, 0, 0))
  912. self.m_rubberband.setZValue(-1)
  913. self.m_rubberband.hide()
  914. self.m_rubberband_selection = False
  915. self.m_rubberband_orig_point = QPointF(0, 0)
  916. def clear(self):
  917. QGraphicsScene.clear(self)
  918. # Re-add rubberband, that just got deleted
  919. self.addRubberBand()
  920. def fixScaleFactor(self):
  921. scale = self.m_view.transform().m11()
  922. if scale > 3.0:
  923. self.m_view.resetTransform()
  924. self.m_view.scale(3.0, 3.0)
  925. elif scale < 0.2:
  926. self.m_view.resetTransform()
  927. self.m_view.scale(0.2, 0.2)
  928. self.scaleChanged.emit(self.m_view.transform().m11())
  929. def updateTheme(self):
  930. self.setBackgroundBrush(canvas.theme.canvas_bg)
  931. self.m_rubberband.setPen(canvas.theme.rubberband_pen)
  932. self.m_rubberband.setBrush(canvas.theme.rubberband_brush)
  933. def zoom_fit(self):
  934. min_x = min_y = max_x = max_y = None
  935. first_value = True
  936. items_list = self.items()
  937. if len(items_list) > 0:
  938. for item in items_list:
  939. if item and item.isVisible() and item.type() == CanvasBoxType:
  940. pos = item.scenePos()
  941. rect = item.boundingRect()
  942. if first_value:
  943. min_x = pos.x()
  944. elif pos.x() < min_x:
  945. min_x = pos.x()
  946. if first_value:
  947. min_y = pos.y()
  948. elif pos.y() < min_y:
  949. min_y = pos.y()
  950. if first_value:
  951. max_x = pos.x() + rect.width()
  952. elif pos.x() + rect.width() > max_x:
  953. max_x = pos.x() + rect.width()
  954. if first_value:
  955. max_y = pos.y() + rect.height()
  956. elif pos.y() + rect.height() > max_y:
  957. max_y = pos.y() + rect.height()
  958. first_value = False
  959. if not first_value:
  960. self.m_view.fitInView(min_x, min_y, abs(max_x - min_x), abs(max_y - min_y), Qt.KeepAspectRatio)
  961. self.fixScaleFactor()
  962. def zoom_in(self):
  963. if self.m_view.transform().m11() < 3.0:
  964. self.m_view.scale(1.2, 1.2)
  965. self.scaleChanged.emit(self.m_view.transform().m11())
  966. def zoom_out(self):
  967. if self.m_view.transform().m11() > 0.2:
  968. self.m_view.scale(0.8, 0.8)
  969. self.scaleChanged.emit(self.m_view.transform().m11())
  970. def zoom_reset(self):
  971. self.m_view.resetTransform()
  972. self.scaleChanged.emit(1.0)
  973. @pyqtSlot()
  974. def slot_selectionChanged(self):
  975. items_list = self.selectedItems()
  976. if len(items_list) == 0:
  977. self.pluginSelected.emit([])
  978. return
  979. plugin_list = []
  980. for item in items_list:
  981. if item and item.isVisible():
  982. group_item = None
  983. if item.type() == CanvasBoxType:
  984. group_item = item
  985. elif item.type() == CanvasPortType:
  986. group_item = item.parentItem()
  987. #elif item.type() in (CanvasLineType, CanvasBezierLineType, CanvasLineMovType, CanvasBezierLineMovType):
  988. #plugin_list = []
  989. #break
  990. if group_item is not None and group_item.m_plugin_id >= 0:
  991. plugin_list.append(group_item.m_plugin_id)
  992. self.pluginSelected.emit(plugin_list)
  993. def keyPressEvent(self, event):
  994. if not self.m_view:
  995. return event.ignore()
  996. if event.key() == Qt.Key_Control:
  997. self.m_ctrl_down = True
  998. elif event.key() == Qt.Key_Home:
  999. self.zoom_fit()
  1000. return event.accept()
  1001. elif self.m_ctrl_down:
  1002. if event.key() == Qt.Key_Plus:
  1003. self.zoom_in()
  1004. return event.accept()
  1005. elif event.key() == Qt.Key_Minus:
  1006. self.zoom_out()
  1007. return event.accept()
  1008. elif event.key() == Qt.Key_1:
  1009. self.zoom_reset()
  1010. return event.accept()
  1011. QGraphicsScene.keyPressEvent(self, event)
  1012. def keyReleaseEvent(self, event):
  1013. if event.key() == Qt.Key_Control:
  1014. self.m_ctrl_down = False
  1015. QGraphicsScene.keyReleaseEvent(self, event)
  1016. def mousePressEvent(self, event):
  1017. self.m_mouse_down_init = bool(event.button() == Qt.LeftButton)
  1018. self.m_mouse_rubberband = False
  1019. QGraphicsScene.mousePressEvent(self, event)
  1020. def mouseMoveEvent(self, event):
  1021. if self.m_mouse_down_init:
  1022. self.m_mouse_down_init = False
  1023. self.m_mouse_rubberband = bool(len(self.selectedItems()) == 0)
  1024. if self.m_mouse_rubberband:
  1025. if not self.m_rubberband_selection:
  1026. self.m_rubberband.show()
  1027. self.m_rubberband_selection = True
  1028. self.m_rubberband_orig_point = event.scenePos()
  1029. pos = event.scenePos()
  1030. if pos.x() > self.m_rubberband_orig_point.x():
  1031. x = self.m_rubberband_orig_point.x()
  1032. else:
  1033. x = pos.x()
  1034. if pos.y() > self.m_rubberband_orig_point.y():
  1035. y = self.m_rubberband_orig_point.y()
  1036. else:
  1037. y = pos.y()
  1038. self.m_rubberband.setRect(x, y, abs(pos.x() - self.m_rubberband_orig_point.x()), abs(pos.y() - self.m_rubberband_orig_point.y()))
  1039. return event.accept()
  1040. QGraphicsScene.mouseMoveEvent(self, event)
  1041. def mouseReleaseEvent(self, event):
  1042. if self.m_rubberband_selection:
  1043. items_list = self.items()
  1044. if len(items_list) > 0:
  1045. for item in items_list:
  1046. if item and item.isVisible() and item.type() == CanvasBoxType:
  1047. item_rect = item.sceneBoundingRect()
  1048. item_top_left = QPointF(item_rect.x(), item_rect.y())
  1049. item_bottom_right = QPointF(item_rect.x() + item_rect.width(), item_rect.y() + item_rect.height())
  1050. if self.m_rubberband.contains(item_top_left) and self.m_rubberband.contains(item_bottom_right):
  1051. item.setSelected(True)
  1052. self.m_rubberband.hide()
  1053. self.m_rubberband.setRect(0, 0, 0, 0)
  1054. self.m_rubberband_selection = False
  1055. else:
  1056. items_list = self.selectedItems()
  1057. for item in items_list:
  1058. if item and item.isVisible() and item.type() == CanvasBoxType:
  1059. item.checkItemPos()
  1060. self.sceneGroupMoved.emit(item.getGroupId(), item.getSplittedMode(), item.scenePos())
  1061. if len(items_list) > 1:
  1062. canvas.scene.update()
  1063. self.m_mouse_down_init = False
  1064. self.m_mouse_rubberband = False
  1065. QGraphicsScene.mouseReleaseEvent(self, event)
  1066. def wheelEvent(self, event):
  1067. if not self.m_view:
  1068. return event.ignore()
  1069. if self.m_ctrl_down:
  1070. factor = 1.41 ** (event.delta() / 240.0)
  1071. self.m_view.scale(factor, factor)
  1072. self.fixScaleFactor()
  1073. return event.accept()
  1074. QGraphicsScene.wheelEvent(self, event)
  1075. # ------------------------------------------------------------------------------
  1076. # canvasfadeanimation.cpp
  1077. class CanvasFadeAnimation(QAbstractAnimation):
  1078. def __init__(self, item, show, parent=None):
  1079. QAbstractAnimation.__init__(self, parent)
  1080. self.m_show = show
  1081. self.m_duration = 0
  1082. self.m_item = item
  1083. def item(self):
  1084. return self.m_item
  1085. def setDuration(self, time):
  1086. if self.m_item.opacity() == 0 and not self.m_show:
  1087. self._duration = 0
  1088. else:
  1089. self.m_item.show()
  1090. self.m_duration = time
  1091. def duration(self):
  1092. return self.m_duration
  1093. def updateCurrentTime(self, time):
  1094. if self.m_duration == 0:
  1095. return
  1096. if self.m_show:
  1097. value = float(time) / self.m_duration
  1098. else:
  1099. value = 1.0 - (float(time) / self.m_duration)
  1100. self.m_item.setOpacity(value)
  1101. if self.m_item.type() == CanvasBoxType:
  1102. self.m_item.setShadowOpacity(value)
  1103. def updateDirection(self, direction):
  1104. pass
  1105. def updateState(self, oldState, newState):
  1106. pass
  1107. # ------------------------------------------------------------------------------
  1108. # canvasline.cpp
  1109. class CanvasLine(QGraphicsLineItem):
  1110. def __init__(self, item1, item2, parent):
  1111. QGraphicsLineItem.__init__(self, parent)
  1112. self.item1 = item1
  1113. self.item2 = item2
  1114. self.m_locked = False
  1115. self.m_lineSelected = False
  1116. self.setGraphicsEffect(None)
  1117. self.updateLinePos()
  1118. def deleteFromScene(self):
  1119. canvas.scene.removeItem(self)
  1120. del self
  1121. def isLocked(self):
  1122. return self.m_locked
  1123. def setLocked(self, yesno):
  1124. self.m_locked = yesno
  1125. def isLineSelected(self):
  1126. return self.m_lineSelected
  1127. def setLineSelected(self, yesno):
  1128. if self.m_locked:
  1129. return
  1130. if options.eyecandy == EYECANDY_FULL:
  1131. if yesno:
  1132. self.setGraphicsEffect(CanvasPortGlow(self.item1.getPortType(), self.toGraphicsObject()))
  1133. else:
  1134. self.setGraphicsEffect(None)
  1135. self.m_lineSelected = yesno
  1136. self.updateLineGradient()
  1137. def updateLinePos(self):
  1138. if self.item1.getPortMode() == PORT_MODE_OUTPUT:
  1139. line = QLineF(self.item1.scenePos().x() + self.item1.getPortWidth() + 12,
  1140. self.item1.scenePos().y() + float(canvas.theme.port_height)/2,
  1141. self.item2.scenePos().x(),
  1142. self.item2.scenePos().y() + float(canvas.theme.port_height)/2)
  1143. self.setLine(line)
  1144. self.m_lineSelected = False
  1145. self.updateLineGradient()
  1146. def type(self):
  1147. return CanvasLineType
  1148. def updateLineGradient(self):
  1149. pos_top = self.boundingRect().top()
  1150. pos_bot = self.boundingRect().bottom()
  1151. if self.item2.scenePos().y() >= self.item1.scenePos().y():
  1152. pos1 = 0
  1153. pos2 = 1
  1154. else:
  1155. pos1 = 1
  1156. pos2 = 0
  1157. port_type1 = self.item1.getPortType()
  1158. port_type2 = self.item2.getPortType()
  1159. port_gradient = QLinearGradient(0, pos_top, 0, pos_bot)
  1160. if port_type1 == PORT_TYPE_AUDIO_JACK:
  1161. port_gradient.setColorAt(pos1, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack)
  1162. elif port_type1 == PORT_TYPE_MIDI_JACK:
  1163. port_gradient.setColorAt(pos1, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack)
  1164. elif port_type1 == PORT_TYPE_MIDI_ALSA:
  1165. port_gradient.setColorAt(pos1, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa)
  1166. elif port_type1 == PORT_TYPE_PARAMETER:
  1167. port_gradient.setColorAt(pos1, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter)
  1168. if port_type2 == PORT_TYPE_AUDIO_JACK:
  1169. port_gradient.setColorAt(pos2, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack)
  1170. elif port_type2 == PORT_TYPE_MIDI_JACK:
  1171. port_gradient.setColorAt(pos2, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack)
  1172. elif port_type2 == PORT_TYPE_MIDI_ALSA:
  1173. port_gradient.setColorAt(pos2, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa)
  1174. elif port_type2 == PORT_TYPE_PARAMETER:
  1175. port_gradient.setColorAt(pos2, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter)
  1176. self.setPen(QPen(port_gradient, 2))
  1177. def paint(self, painter, option, widget):
  1178. painter.save()
  1179. painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing))
  1180. QGraphicsLineItem.paint(self, painter, option, widget)
  1181. painter.restore()
  1182. # ------------------------------------------------------------------------------
  1183. # canvasbezierline.cpp
  1184. class CanvasBezierLine(QGraphicsPathItem):
  1185. def __init__(self, item1, item2, parent):
  1186. QGraphicsPathItem.__init__(self, parent)
  1187. self.item1 = item1
  1188. self.item2 = item2
  1189. self.m_locked = False
  1190. self.m_lineSelected = False
  1191. self.setBrush(QColor(0, 0, 0, 0))
  1192. self.setGraphicsEffect(None)
  1193. self.updateLinePos()
  1194. def deleteFromScene(self):
  1195. canvas.scene.removeItem(self)
  1196. del self
  1197. def isLocked(self):
  1198. return self.m_locked
  1199. def setLocked(self, yesno):
  1200. self.m_locked = yesno
  1201. def isLineSelected(self):
  1202. return self.m_lineSelected
  1203. def setLineSelected(self, yesno):
  1204. if self.m_locked:
  1205. return
  1206. if options.eyecandy == EYECANDY_FULL:
  1207. if yesno:
  1208. self.setGraphicsEffect(CanvasPortGlow(self.item1.getPortType(), self.toGraphicsObject()))
  1209. else:
  1210. self.setGraphicsEffect(None)
  1211. self.m_lineSelected = yesno
  1212. self.updateLineGradient()
  1213. def updateLinePos(self):
  1214. if self.item1.getPortMode() == PORT_MODE_OUTPUT:
  1215. item1_x = self.item1.scenePos().x() + self.item1.getPortWidth() + 12
  1216. item1_y = self.item1.scenePos().y() + float(canvas.theme.port_height)/2
  1217. item2_x = self.item2.scenePos().x()
  1218. item2_y = self.item2.scenePos().y() + float(canvas.theme.port_height)/2
  1219. item1_mid_x = abs(item1_x - item2_x) / 2
  1220. item1_new_x = item1_x + item1_mid_x
  1221. item2_mid_x = abs(item1_x - item2_x) / 2
  1222. item2_new_x = item2_x - item2_mid_x
  1223. path = QPainterPath(QPointF(item1_x, item1_y))
  1224. path.cubicTo(item1_new_x, item1_y, item2_new_x, item2_y, item2_x, item2_y)
  1225. self.setPath(path)
  1226. self.m_lineSelected = False
  1227. self.updateLineGradient()
  1228. def type(self):
  1229. return CanvasBezierLineType
  1230. def updateLineGradient(self):
  1231. pos_top = self.boundingRect().top()
  1232. pos_bot = self.boundingRect().bottom()
  1233. if self.item2.scenePos().y() >= self.item1.scenePos().y():
  1234. pos1 = 0
  1235. pos2 = 1
  1236. else:
  1237. pos1 = 1
  1238. pos2 = 0
  1239. port_type1 = self.item1.getPortType()
  1240. port_type2 = self.item2.getPortType()
  1241. port_gradient = QLinearGradient(0, pos_top, 0, pos_bot)
  1242. if port_type1 == PORT_TYPE_AUDIO_JACK:
  1243. port_gradient.setColorAt(pos1, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack)
  1244. elif port_type1 == PORT_TYPE_MIDI_JACK:
  1245. port_gradient.setColorAt(pos1, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack)
  1246. elif port_type1 == PORT_TYPE_MIDI_ALSA:
  1247. port_gradient.setColorAt(pos1, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa)
  1248. elif port_type1 == PORT_TYPE_PARAMETER:
  1249. port_gradient.setColorAt(pos1, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter)
  1250. if port_type2 == PORT_TYPE_AUDIO_JACK:
  1251. port_gradient.setColorAt(pos2, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack)
  1252. elif port_type2 == PORT_TYPE_MIDI_JACK:
  1253. port_gradient.setColorAt(pos2, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack)
  1254. elif port_type2 == PORT_TYPE_MIDI_ALSA:
  1255. port_gradient.setColorAt(pos2, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa)
  1256. elif port_type2 == PORT_TYPE_PARAMETER:
  1257. port_gradient.setColorAt(pos2, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter)
  1258. self.setPen(QPen(port_gradient, 2))
  1259. def paint(self, painter, option, widget):
  1260. painter.save()
  1261. painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing))
  1262. QGraphicsPathItem.paint(self, painter, option, widget)
  1263. painter.restore()
  1264. # ------------------------------------------------------------------------------
  1265. # canvaslivemov.cpp
  1266. class CanvasLineMov(QGraphicsLineItem):
  1267. def __init__(self, port_mode, port_type, parent):
  1268. QGraphicsLineItem.__init__(self, parent)
  1269. self.m_port_mode = port_mode
  1270. self.m_port_type = port_type
  1271. # Port position doesn't change while moving around line
  1272. self.p_lineX = self.scenePos().x()
  1273. self.p_lineY = self.scenePos().y()
  1274. self.p_width = self.parentItem().getPortWidth()
  1275. if port_type == PORT_TYPE_AUDIO_JACK:
  1276. pen = QPen(canvas.theme.line_audio_jack, 2)
  1277. elif port_type == PORT_TYPE_MIDI_JACK:
  1278. pen = QPen(canvas.theme.line_midi_jack, 2)
  1279. elif port_type == PORT_TYPE_MIDI_ALSA:
  1280. pen = QPen(canvas.theme.line_midi_alsa, 2)
  1281. elif port_type == PORT_TYPE_PARAMETER:
  1282. pen = QPen(canvas.theme.line_parameter, 2)
  1283. else:
  1284. qWarning("PatchCanvas::CanvasLineMov(%s, %s, %s) - invalid port type" % (port_mode2str(port_mode), port_type2str(port_type), parent))
  1285. pen = QPen(Qt.black)
  1286. self.setPen(pen)
  1287. def deleteFromScene(self):
  1288. canvas.scene.removeItem(self)
  1289. del self
  1290. def updateLinePos(self, scenePos):
  1291. item_pos = [0, 0]
  1292. if self.m_port_mode == PORT_MODE_INPUT:
  1293. item_pos[0] = 0
  1294. item_pos[1] = float(canvas.theme.port_height)/2
  1295. elif self.m_port_mode == PORT_MODE_OUTPUT:
  1296. item_pos[0] = self.p_width + 12
  1297. item_pos[1] = float(canvas.theme.port_height)/2
  1298. else:
  1299. return
  1300. line = QLineF(item_pos[0], item_pos[1], scenePos.x() - self.p_lineX, scenePos.y() - self.p_lineY)
  1301. self.setLine(line)
  1302. def type(self):
  1303. return CanvasLineMovType
  1304. def paint(self, painter, option, widget):
  1305. painter.save()
  1306. painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing))
  1307. QGraphicsLineItem.paint(self, painter, option, widget)
  1308. painter.restore()
  1309. # ------------------------------------------------------------------------------
  1310. # canvasbezierlinemov.cpp
  1311. class CanvasBezierLineMov(QGraphicsPathItem):
  1312. def __init__(self, port_mode, port_type, parent):
  1313. QGraphicsPathItem.__init__(self, parent)
  1314. self.m_port_mode = port_mode
  1315. self.m_port_type = port_type
  1316. # Port position doesn't change while moving around line
  1317. self.p_itemX = self.scenePos().x()
  1318. self.p_itemY = self.scenePos().y()
  1319. self.p_width = self.parentItem().getPortWidth()
  1320. if port_type == PORT_TYPE_AUDIO_JACK:
  1321. pen = QPen(canvas.theme.line_audio_jack, 2)
  1322. elif port_type == PORT_TYPE_MIDI_JACK:
  1323. pen = QPen(canvas.theme.line_midi_jack, 2)
  1324. elif port_type == PORT_TYPE_MIDI_ALSA:
  1325. pen = QPen(canvas.theme.line_midi_alsa, 2)
  1326. elif port_type == PORT_TYPE_PARAMETER:
  1327. pen = QPen(canvas.theme.line_parameter, 2)
  1328. else:
  1329. qWarning("PatchCanvas::CanvasBezierLineMov(%s, %s, %s) - invalid port type" % (port_mode2str(port_mode), port_type2str(port_type), parent))
  1330. pen = QPen(Qt.black)
  1331. self.setBrush(QColor(0, 0, 0, 0))
  1332. self.setPen(pen)
  1333. def deleteFromScene(self):
  1334. canvas.scene.removeItem(self)
  1335. del self
  1336. def updateLinePos(self, scenePos):
  1337. if self.m_port_mode == PORT_MODE_INPUT:
  1338. old_x = 0
  1339. old_y = float(canvas.theme.port_height)/2
  1340. mid_x = abs(scenePos.x() - self.p_itemX) / 2
  1341. new_x = old_x - mid_x
  1342. elif self.m_port_mode == PORT_MODE_OUTPUT:
  1343. old_x = self.p_width + 12
  1344. old_y = float(canvas.theme.port_height)/2
  1345. mid_x = abs(scenePos.x() - (self.p_itemX + old_x)) / 2
  1346. new_x = old_x + mid_x
  1347. else:
  1348. return
  1349. final_x = scenePos.x() - self.p_itemX
  1350. final_y = scenePos.y() - self.p_itemY
  1351. path = QPainterPath(QPointF(old_x, old_y))
  1352. path.cubicTo(new_x, old_y, new_x, final_y, final_x, final_y)
  1353. self.setPath(path)
  1354. def type(self):
  1355. return CanvasBezierLineMovType
  1356. def paint(self, painter, option, widget):
  1357. painter.save()
  1358. painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing))
  1359. QGraphicsPathItem.paint(self, painter, option, widget)
  1360. painter.restore()
  1361. # ------------------------------------------------------------------------------
  1362. # canvasport.cpp
  1363. class CanvasPort(QGraphicsItem):
  1364. def __init__(self, group_id, port_id, port_name, port_mode, port_type, is_alternate, parent):
  1365. QGraphicsItem.__init__(self, parent)
  1366. # Save Variables, useful for later
  1367. self.m_group_id = group_id
  1368. self.m_port_id = port_id
  1369. self.m_port_mode = port_mode
  1370. self.m_port_type = port_type
  1371. self.m_port_name = port_name
  1372. self.m_is_alternate = is_alternate
  1373. # Base Variables
  1374. self.m_port_width = 15
  1375. self.m_port_height = canvas.theme.port_height
  1376. self.m_port_font = QFont()
  1377. self.m_port_font.setFamily(canvas.theme.port_font_name)
  1378. self.m_port_font.setPixelSize(canvas.theme.port_font_size)
  1379. self.m_port_font.setWeight(canvas.theme.port_font_state)
  1380. self.m_line_mov = None
  1381. self.m_hover_item = None
  1382. self.m_last_selected_state = False
  1383. self.m_mouse_down = False
  1384. self.m_cursor_moving = False
  1385. self.setFlags(QGraphicsItem.ItemIsSelectable)
  1386. def getGroupId(self):
  1387. return self.m_group_id
  1388. def getPortId(self):
  1389. return self.m_port_id
  1390. def getPortMode(self):
  1391. return self.m_port_mode
  1392. def getPortType(self):
  1393. return self.m_port_type
  1394. def getPortName(self):
  1395. return self.m_port_name
  1396. def getFullPortName(self):
  1397. return self.parentItem().getGroupName() + ":" + self.m_port_name
  1398. def getPortWidth(self):
  1399. return self.m_port_width
  1400. def getPortHeight(self):
  1401. return self.m_port_height
  1402. def setPortMode(self, port_mode):
  1403. self.m_port_mode = port_mode
  1404. self.update()
  1405. def setPortType(self, port_type):
  1406. self.m_port_type = port_type
  1407. self.update()
  1408. def setPortName(self, port_name):
  1409. if QFontMetrics(self.m_port_font).width(port_name) < QFontMetrics(self.m_port_font).width(self.m_port_name):
  1410. QTimer.singleShot(0, canvas.scene.update)
  1411. self.m_port_name = port_name
  1412. self.update()
  1413. def setPortWidth(self, port_width):
  1414. if port_width < self.m_port_width:
  1415. QTimer.singleShot(0, canvas.scene.update)
  1416. self.m_port_width = port_width
  1417. self.update()
  1418. def type(self):
  1419. return CanvasPortType
  1420. def mousePressEvent(self, event):
  1421. self.m_hover_item = None
  1422. self.m_mouse_down = bool(event.button() == Qt.LeftButton)
  1423. self.m_cursor_moving = False
  1424. QGraphicsItem.mousePressEvent(self, event)
  1425. def mouseMoveEvent(self, event):
  1426. if self.m_mouse_down:
  1427. if not self.m_cursor_moving:
  1428. self.setCursor(QCursor(Qt.CrossCursor))
  1429. self.m_cursor_moving = True
  1430. for connection in canvas.connection_list:
  1431. if ((connection.group_out_id == self.m_group_id and connection.port_out_id == self.m_port_id) or
  1432. (connection.group_in_id == self.m_group_id and connection.port_in_id == self.m_port_id)):
  1433. connection.widget.setLocked(True)
  1434. if not self.m_line_mov:
  1435. if options.use_bezier_lines:
  1436. self.m_line_mov = CanvasBezierLineMov(self.m_port_mode, self.m_port_type, self)
  1437. else:
  1438. self.m_line_mov = CanvasLineMov(self.m_port_mode, self.m_port_type, self)
  1439. canvas.last_z_value += 1
  1440. self.m_line_mov.setZValue(canvas.last_z_value)
  1441. canvas.last_z_value += 1
  1442. self.parentItem().setZValue(canvas.last_z_value)
  1443. item = None
  1444. items = canvas.scene.items(event.scenePos(), Qt.ContainsItemShape, Qt.AscendingOrder)
  1445. for i in range(len(items)):
  1446. if items[i].type() == CanvasPortType:
  1447. if items[i] != self:
  1448. if not item:
  1449. item = items[i]
  1450. elif items[i].parentItem().zValue() > item.parentItem().zValue():
  1451. item = items[i]
  1452. if self.m_hover_item and self.m_hover_item != item:
  1453. self.m_hover_item.setSelected(False)
  1454. if item:
  1455. if item.getPortMode() != self.m_port_mode and item.getPortType() == self.m_port_type:
  1456. item.setSelected(True)
  1457. self.m_hover_item = item
  1458. else:
  1459. self.m_hover_item = None
  1460. else:
  1461. self.m_hover_item = None
  1462. self.m_line_mov.updateLinePos(event.scenePos())
  1463. return event.accept()
  1464. QGraphicsItem.mouseMoveEvent(self, event)
  1465. def mouseReleaseEvent(self, event):
  1466. if self.m_mouse_down:
  1467. if self.m_line_mov:
  1468. self.m_line_mov.deleteFromScene()
  1469. self.m_line_mov = None
  1470. for connection in canvas.connection_list:
  1471. if ((connection.group_out_id == self.m_group_id and connection.port_out_id == self.m_port_id) or
  1472. (connection.group_in_id == self.m_group_id and connection.port_in_id == self.m_port_id)):
  1473. connection.widget.setLocked(False)
  1474. if self.m_hover_item:
  1475. # TODO: a better way to check already existing connection
  1476. for connection in canvas.connection_list:
  1477. hover_group_id = self.m_hover_item.getGroupId()
  1478. hover_port_id = self.m_hover_item.getPortId()
  1479. if (
  1480. (connection.group_out_id == self.m_group_id and connection.port_out_id == self.m_port_id and
  1481. connection.group_in_id == hover_group_id and connection.port_in_id == hover_port_id) or
  1482. (connection.group_out_id == hover_group_id and connection.port_out_id == hover_port_id and
  1483. connection.group_in_id == self.m_group_id and connection.port_in_id == self.m_port_id)
  1484. ):
  1485. canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, "")
  1486. break
  1487. else:
  1488. if self.m_port_mode == PORT_MODE_OUTPUT:
  1489. conn = "%i:%i:%i:%i" % (self.m_group_id, self.m_port_id, self.m_hover_item.getGroupId(), self.m_hover_item.getPortId())
  1490. canvas.callback(ACTION_PORTS_CONNECT, 0, 0, conn)
  1491. else:
  1492. conn = "%i:%i:%i:%i" % (self.m_hover_item.getGroupId(), self.m_hover_item.getPortId(), self.m_group_id, self.m_port_id)
  1493. canvas.callback(ACTION_PORTS_CONNECT, 0, 0, conn)
  1494. canvas.scene.clearSelection()
  1495. if self.m_cursor_moving:
  1496. self.setCursor(QCursor(Qt.ArrowCursor))
  1497. self.m_hover_item = None
  1498. self.m_mouse_down = False
  1499. self.m_cursor_moving = False
  1500. QGraphicsItem.mouseReleaseEvent(self, event)
  1501. def contextMenuEvent(self, event):
  1502. canvas.scene.clearSelection()
  1503. self.setSelected(True)
  1504. menu = QMenu()
  1505. discMenu = QMenu("Disconnect", menu)
  1506. conn_list = CanvasGetPortConnectionList(self.m_group_id, self.m_port_id)
  1507. if len(conn_list) > 0:
  1508. for conn_id, group_id, port_id in conn_list:
  1509. act_x_disc = discMenu.addAction(CanvasGetFullPortName(group_id, port_id))
  1510. act_x_disc.setData(conn_id)
  1511. act_x_disc.triggered.connect(canvas.qobject.PortContextMenuDisconnect)
  1512. else:
  1513. act_x_disc = discMenu.addAction("No connections")
  1514. act_x_disc.setEnabled(False)
  1515. menu.addMenu(discMenu)
  1516. act_x_disc_all = menu.addAction("Disconnect &All")
  1517. act_x_sep_1 = menu.addSeparator()
  1518. act_x_info = menu.addAction("Get &Info")
  1519. act_x_rename = menu.addAction("&Rename")
  1520. if not features.port_info:
  1521. act_x_info.setVisible(False)
  1522. if not features.port_rename:
  1523. act_x_rename.setVisible(False)
  1524. if not (features.port_info and features.port_rename):
  1525. act_x_sep_1.setVisible(False)
  1526. act_selected = menu.exec_(event.screenPos())
  1527. if act_selected == act_x_disc_all:
  1528. for conn_id, group_id, port_id in conn_list:
  1529. canvas.callback(ACTION_PORTS_DISCONNECT, conn_id, 0, "")
  1530. elif act_selected == act_x_info:
  1531. canvas.callback(ACTION_PORT_INFO, self.m_group_id, self.m_port_id, "")
  1532. elif act_selected == act_x_rename:
  1533. new_name_try = QInputDialog.getText(None, "Rename Port", "New name:", QLineEdit.Normal, self.m_port_name)
  1534. if new_name_try[1] and new_name_try[0]: # 1 - bool ok, 0 - return text
  1535. canvas.callback(ACTION_PORT_RENAME, self.m_group_id, self.m_port_id, new_name_try[0])
  1536. event.accept()
  1537. def boundingRect(self):
  1538. return QRectF(0, 0, self.m_port_width + 12, self.m_port_height)
  1539. def paint(self, painter, option, widget):
  1540. painter.save()
  1541. painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing == ANTIALIASING_FULL))
  1542. poly_locx = [0, 0, 0, 0, 0]
  1543. if self.m_port_mode == PORT_MODE_INPUT:
  1544. text_pos = QPointF(3, canvas.theme.port_text_ypos)
  1545. if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON:
  1546. poly_locx[0] = 0
  1547. poly_locx[1] = self.m_port_width + 5
  1548. poly_locx[2] = self.m_port_width + 12
  1549. poly_locx[3] = self.m_port_width + 5
  1550. poly_locx[4] = 0
  1551. elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE:
  1552. poly_locx[0] = 0
  1553. poly_locx[1] = self.m_port_width + 5
  1554. poly_locx[2] = self.m_port_width + 5
  1555. poly_locx[3] = self.m_port_width + 5
  1556. poly_locx[4] = 0
  1557. else:
  1558. qCritical("PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode)
  1559. return
  1560. elif self.m_port_mode == PORT_MODE_OUTPUT:
  1561. text_pos = QPointF(9, canvas.theme.port_text_ypos)
  1562. if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON:
  1563. poly_locx[0] = self.m_port_width + 12
  1564. poly_locx[1] = 7
  1565. poly_locx[2] = 0
  1566. poly_locx[3] = 7
  1567. poly_locx[4] = self.m_port_width + 12
  1568. elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE:
  1569. poly_locx[0] = self.m_port_width + 12
  1570. poly_locx[1] = 5
  1571. poly_locx[2] = 5
  1572. poly_locx[3] = 5
  1573. poly_locx[4] = self.m_port_width + 12
  1574. else:
  1575. qCritical("PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode)
  1576. return
  1577. else:
  1578. qCritical("PatchCanvas::CanvasPort.paint() - invalid port mode '%s'" % port_mode2str(self.m_port_mode))
  1579. return
  1580. if self.m_port_type == PORT_TYPE_AUDIO_JACK:
  1581. poly_color = canvas.theme.port_audio_jack_bg_sel if self.isSelected() else canvas.theme.port_audio_jack_bg
  1582. poly_pen = canvas.theme.port_audio_jack_pen_sel if self.isSelected() else canvas.theme.port_audio_jack_pen
  1583. text_pen = canvas.theme.port_audio_jack_text_sel if self.isSelected() else canvas.theme.port_audio_jack_text
  1584. conn_pen = canvas.theme.port_audio_jack_pen_sel
  1585. elif self.m_port_type == PORT_TYPE_MIDI_JACK:
  1586. poly_color = canvas.theme.port_midi_jack_bg_sel if self.isSelected() else canvas.theme.port_midi_jack_bg
  1587. poly_pen = canvas.theme.port_midi_jack_pen_sel if self.isSelected() else canvas.theme.port_midi_jack_pen
  1588. text_pen = canvas.theme.port_midi_jack_text_sel if self.isSelected() else canvas.theme.port_midi_jack_text
  1589. conn_pen = canvas.theme.port_midi_jack_pen_sel
  1590. elif self.m_port_type == PORT_TYPE_MIDI_ALSA:
  1591. poly_color = canvas.theme.port_midi_alsa_bg_sel if self.isSelected() else canvas.theme.port_midi_alsa_bg
  1592. poly_pen = canvas.theme.port_midi_alsa_pen_sel if self.isSelected() else canvas.theme.port_midi_alsa_pen
  1593. text_pen = canvas.theme.port_midi_alsa_text_sel if self.isSelected() else canvas.theme.port_midi_alsa_text
  1594. conn_pen = canvas.theme.port_midi_alsa_pen_sel
  1595. elif self.m_port_type == PORT_TYPE_PARAMETER:
  1596. poly_color = canvas.theme.port_parameter_bg_sel if self.isSelected() else canvas.theme.port_parameter_bg
  1597. poly_pen = canvas.theme.port_parameter_pen_sel if self.isSelected() else canvas.theme.port_parameter_pen
  1598. text_pen = canvas.theme.port_parameter_text_sel if self.isSelected() else canvas.theme.port_parameter_text
  1599. conn_pen = canvas.theme.port_parameter_pen_sel
  1600. else:
  1601. qCritical("PatchCanvas::CanvasPort.paint() - invalid port type '%s'" % port_type2str(self.m_port_type))
  1602. return
  1603. if self.m_is_alternate:
  1604. poly_color = poly_color.darker(180)
  1605. #poly_pen.setColor(poly_pen.color().darker(110))
  1606. #text_pen.setColor(text_pen.color()) #.darker(150))
  1607. #conn_pen.setColor(conn_pen.color()) #.darker(150))
  1608. polygon = QPolygonF()
  1609. polygon += QPointF(poly_locx[0], 0)
  1610. polygon += QPointF(poly_locx[1], 0)
  1611. polygon += QPointF(poly_locx[2], float(canvas.theme.port_height)/2)
  1612. polygon += QPointF(poly_locx[3], canvas.theme.port_height)
  1613. polygon += QPointF(poly_locx[4], canvas.theme.port_height)
  1614. if canvas.theme.port_bg_pixmap:
  1615. portRect = polygon.boundingRect()
  1616. portPos = portRect.topLeft()
  1617. painter.drawTiledPixmap(portRect, canvas.theme.port_bg_pixmap, portPos)
  1618. else:
  1619. painter.setBrush(poly_color) #.lighter(200))
  1620. painter.setPen(poly_pen)
  1621. painter.drawPolygon(polygon)
  1622. painter.setPen(text_pen)
  1623. painter.setFont(self.m_port_font)
  1624. painter.drawText(text_pos, self.m_port_name)
  1625. if self.isSelected() != self.m_last_selected_state:
  1626. for connection in canvas.connection_list:
  1627. if ((connection.group_out_id == self.m_group_id and connection.port_out_id == self.m_port_id) or
  1628. (connection.group_in_id == self.m_group_id and connection.port_in_id == self.m_port_id)):
  1629. connection.widget.setLineSelected(self.isSelected())
  1630. if canvas.theme.idx == Theme.THEME_OOSTUDIO and canvas.theme.port_bg_pixmap:
  1631. painter.setPen(Qt.NoPen)
  1632. painter.setBrush(conn_pen.brush())
  1633. if self.m_port_mode == PORT_MODE_INPUT:
  1634. connRect = QRectF(portRect.topLeft(), QSizeF(2, portRect.height()))
  1635. else:
  1636. connRect = QRectF(QPointF(portRect.right()-2, portRect.top()), QSizeF(2, portRect.height()))
  1637. painter.drawRect(connRect)
  1638. self.m_last_selected_state = self.isSelected()
  1639. painter.restore()
  1640. # ------------------------------------------------------------------------------
  1641. # canvasbox.cpp
  1642. class cb_line_t(object):
  1643. __slots__ = [
  1644. 'line',
  1645. 'connection_id'
  1646. ]
  1647. class CanvasBox(QGraphicsItem):
  1648. def __init__(self, group_id, group_name, icon, parent=None):
  1649. QGraphicsItem.__init__(self, parent)
  1650. # Save Variables, useful for later
  1651. self.m_group_id = group_id
  1652. self.m_group_name = group_name
  1653. # plugin Id, < 0 if invalid
  1654. self.m_plugin_id = -1
  1655. self.m_plugin_ui = False
  1656. # Base Variables
  1657. self.p_width = 50
  1658. self.p_height = canvas.theme.box_header_height + canvas.theme.box_header_spacing + 1
  1659. self.m_last_pos = QPointF()
  1660. self.m_splitted = False
  1661. self.m_splitted_mode = PORT_MODE_NULL
  1662. self.m_cursor_moving = False
  1663. self.m_forced_split = False
  1664. self.m_mouse_down = False
  1665. self.m_port_list_ids = []
  1666. self.m_connection_lines = []
  1667. # Set Font
  1668. self.m_font_name = QFont()
  1669. self.m_font_name.setFamily(canvas.theme.box_font_name)
  1670. self.m_font_name.setPixelSize(canvas.theme.box_font_size)
  1671. self.m_font_name.setWeight(canvas.theme.box_font_state)
  1672. self.m_font_port = QFont()
  1673. self.m_font_port.setFamily(canvas.theme.port_font_name)
  1674. self.m_font_port.setPixelSize(canvas.theme.port_font_size)
  1675. self.m_font_port.setWeight(canvas.theme.port_font_state)
  1676. # Icon
  1677. if canvas.theme.box_use_icon:
  1678. self.icon_svg = CanvasIcon(icon, self.m_group_name, self)
  1679. else:
  1680. self.icon_svg = None
  1681. # Shadow
  1682. if options.eyecandy:
  1683. self.shadow = CanvasBoxShadow(self.toGraphicsObject())
  1684. self.shadow.setFakeParent(self)
  1685. self.setGraphicsEffect(self.shadow)
  1686. else:
  1687. self.shadow = None
  1688. # Final touches
  1689. self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable)
  1690. # Wait for at least 1 port
  1691. if options.auto_hide_groups:
  1692. self.setVisible(False)
  1693. self.setFlag(QGraphicsItem.ItemIsFocusable, True)
  1694. self.updatePositions()
  1695. canvas.scene.addItem(self)
  1696. def getGroupId(self):
  1697. return self.m_group_id
  1698. def getGroupName(self):
  1699. return self.m_group_name
  1700. def isSplitted(self):
  1701. return self.m_splitted
  1702. def getSplittedMode(self):
  1703. return self.m_splitted_mode
  1704. def getPortCount(self):
  1705. return len(self.m_port_list_ids)
  1706. def getPortList(self):
  1707. return self.m_port_list_ids
  1708. def setAsPlugin(self, plugin_id, hasUi):
  1709. self.m_plugin_id = plugin_id
  1710. self.m_plugin_ui = hasUi
  1711. def setIcon(self, icon):
  1712. if self.icon_svg:
  1713. self.icon_svg.setIcon(icon, self.m_group_name)
  1714. def setSplit(self, split, mode=PORT_MODE_NULL):
  1715. self.m_splitted = split
  1716. self.m_splitted_mode = mode
  1717. def setGroupName(self, group_name):
  1718. self.m_group_name = group_name
  1719. self.updatePositions()
  1720. def setShadowOpacity(self, opacity):
  1721. if self.shadow:
  1722. self.shadow.setOpacity(opacity)
  1723. def addPortFromGroup(self, port_id, port_mode, port_type, port_name, is_alternate):
  1724. if len(self.m_port_list_ids) == 0:
  1725. if options.auto_hide_groups:
  1726. if options.eyecandy == EYECANDY_FULL:
  1727. CanvasItemFX(self, True)
  1728. self.setVisible(True)
  1729. new_widget = CanvasPort(self.m_group_id, port_id, port_name, port_mode, port_type, is_alternate, self)
  1730. port_dict = port_dict_t()
  1731. port_dict.group_id = self.m_group_id
  1732. port_dict.port_id = port_id
  1733. port_dict.port_name = port_name
  1734. port_dict.port_mode = port_mode
  1735. port_dict.port_type = port_type
  1736. port_dict.is_alternate = is_alternate
  1737. port_dict.widget = new_widget
  1738. self.m_port_list_ids.append(port_id)
  1739. return new_widget
  1740. def removePortFromGroup(self, port_id):
  1741. if port_id in self.m_port_list_ids:
  1742. self.m_port_list_ids.remove(port_id)
  1743. else:
  1744. qCritical("PatchCanvas::CanvasBox.removePort(%i) - unable to find port to remove" % port_id)
  1745. return
  1746. if len(self.m_port_list_ids) > 0:
  1747. self.updatePositions()
  1748. elif self.isVisible():
  1749. if options.auto_hide_groups:
  1750. if options.eyecandy == EYECANDY_FULL:
  1751. CanvasItemFX(self, False)
  1752. else:
  1753. self.setVisible(False)
  1754. def addLineFromGroup(self, line, connection_id):
  1755. new_cbline = cb_line_t()
  1756. new_cbline.line = line
  1757. new_cbline.connection_id = connection_id
  1758. self.m_connection_lines.append(new_cbline)
  1759. def removeLineFromGroup(self, connection_id):
  1760. for connection in self.m_connection_lines:
  1761. if connection.connection_id == connection_id:
  1762. self.m_connection_lines.remove(connection)
  1763. return
  1764. qCritical("PatchCanvas::CanvasBox.removeLineFromGroup(%i) - unable to find line to remove" % connection_id)
  1765. def checkItemPos(self):
  1766. if not canvas.size_rect.isNull():
  1767. pos = self.scenePos()
  1768. if not (canvas.size_rect.contains(pos) and canvas.size_rect.contains(pos + QPointF(self.p_width, self.p_height))):
  1769. if pos.x() < canvas.size_rect.x():
  1770. self.setPos(canvas.size_rect.x(), pos.y())
  1771. elif pos.x() + self.p_width > canvas.size_rect.width():
  1772. self.setPos(canvas.size_rect.width() - self.p_width, pos.y())
  1773. pos = self.scenePos()
  1774. if pos.y() < canvas.size_rect.y():
  1775. self.setPos(pos.x(), canvas.size_rect.y())
  1776. elif pos.y() + self.p_height > canvas.size_rect.height():
  1777. self.setPos(pos.x(), canvas.size_rect.height() - self.p_height)
  1778. def removeIconFromScene(self):
  1779. if self.icon_svg:
  1780. canvas.scene.removeItem(self.icon_svg)
  1781. def updatePositions(self):
  1782. self.prepareGeometryChange()
  1783. max_in_width = 0
  1784. max_in_height = canvas.theme.box_header_height + canvas.theme.box_header_spacing
  1785. max_out_width = 0
  1786. max_out_height = canvas.theme.box_header_height + canvas.theme.box_header_spacing
  1787. port_spacing = canvas.theme.port_height + canvas.theme.port_spacing
  1788. have_audio_jack_in = have_midi_jack_in = have_midi_alsa_in = have_parameter_in = False
  1789. have_audio_jack_out = have_midi_jack_out = have_midi_alsa_out = have_parameter_out = False
  1790. # reset box size
  1791. self.p_width = 50
  1792. self.p_height = canvas.theme.box_header_height + canvas.theme.box_header_spacing + 1
  1793. # Check Text Name size
  1794. app_name_size = QFontMetrics(self.m_font_name).width(self.m_group_name) + 30
  1795. if app_name_size > self.p_width:
  1796. self.p_width = app_name_size
  1797. # Get Port List
  1798. port_list = []
  1799. for port in canvas.port_list:
  1800. if port.group_id == self.m_group_id and port.port_id in self.m_port_list_ids:
  1801. port_list.append(port)
  1802. # Get Max Box Width/Height
  1803. for port in port_list:
  1804. if port.port_mode == PORT_MODE_INPUT:
  1805. max_in_height += port_spacing
  1806. size = QFontMetrics(self.m_font_port).width(port.port_name)
  1807. if size > max_in_width:
  1808. max_in_width = size
  1809. if port.port_type == PORT_TYPE_AUDIO_JACK and not have_audio_jack_in:
  1810. have_audio_jack_in = True
  1811. max_in_height += canvas.theme.port_spacingT
  1812. elif port.port_type == PORT_TYPE_MIDI_JACK and not have_midi_jack_in:
  1813. have_midi_jack_in = True
  1814. max_in_height += canvas.theme.port_spacingT
  1815. elif port.port_type == PORT_TYPE_MIDI_ALSA and not have_midi_alsa_in:
  1816. have_midi_alsa_in = True
  1817. max_in_height += canvas.theme.port_spacingT
  1818. elif port.port_type == PORT_TYPE_PARAMETER and not have_parameter_in:
  1819. have_parameter_in = True
  1820. max_in_height += canvas.theme.port_spacingT
  1821. elif port.port_mode == PORT_MODE_OUTPUT:
  1822. max_out_height += port_spacing
  1823. size = QFontMetrics(self.m_font_port).width(port.port_name)
  1824. if size > max_out_width:
  1825. max_out_width = size
  1826. if port.port_type == PORT_TYPE_AUDIO_JACK and not have_audio_jack_out:
  1827. have_audio_jack_out = True
  1828. max_out_height += canvas.theme.port_spacingT
  1829. elif port.port_type == PORT_TYPE_MIDI_JACK and not have_midi_jack_out:
  1830. have_midi_jack_out = True
  1831. max_out_height += canvas.theme.port_spacingT
  1832. elif port.port_type == PORT_TYPE_MIDI_ALSA and not have_midi_alsa_out:
  1833. have_midi_alsa_out = True
  1834. max_out_height += canvas.theme.port_spacingT
  1835. elif port.port_type == PORT_TYPE_PARAMETER and not have_parameter_out:
  1836. have_parameter_out = True
  1837. max_out_height += canvas.theme.port_spacingT
  1838. if canvas.theme.port_spacingT == 0:
  1839. max_in_height += 2
  1840. max_out_height += 2
  1841. final_width = 30 + max_in_width + max_out_width
  1842. if final_width > self.p_width:
  1843. self.p_width = final_width
  1844. if max_in_height > self.p_height:
  1845. self.p_height = max_in_height
  1846. if max_out_height > self.p_height:
  1847. self.p_height = max_out_height
  1848. # Remove bottom space
  1849. self.p_height -= canvas.theme.port_spacingT
  1850. if canvas.theme.box_header_spacing > 0:
  1851. if len(port_list) == 0:
  1852. self.p_height -= canvas.theme.box_header_spacing
  1853. else:
  1854. self.p_height -= canvas.theme.box_header_spacing/2
  1855. last_in_pos = canvas.theme.box_header_height + canvas.theme.box_header_spacing
  1856. last_out_pos = canvas.theme.box_header_height + canvas.theme.box_header_spacing
  1857. last_in_type = PORT_TYPE_NULL
  1858. last_out_type = PORT_TYPE_NULL
  1859. # Re-position ports, AUDIO_JACK
  1860. for port in port_list:
  1861. if port.port_type != PORT_TYPE_AUDIO_JACK:
  1862. continue
  1863. if port.port_mode == PORT_MODE_INPUT:
  1864. if last_in_type != PORT_TYPE_NULL and port.port_type != last_in_type:
  1865. last_in_pos += canvas.theme.port_spacingT
  1866. port.widget.setPos(QPointF(1 + canvas.theme.port_offset, last_in_pos))
  1867. port.widget.setPortWidth(max_in_width)
  1868. last_in_pos += port_spacing
  1869. last_in_type = port.port_type
  1870. elif port.port_mode == PORT_MODE_OUTPUT:
  1871. if last_out_type != PORT_TYPE_NULL and port.port_type != last_out_type:
  1872. last_out_pos += canvas.theme.port_spacingT
  1873. port.widget.setPos(QPointF(self.p_width - max_out_width - canvas.theme.port_offset - 13, last_out_pos))
  1874. port.widget.setPortWidth(max_out_width)
  1875. last_out_pos += port_spacing
  1876. last_out_type = port.port_type
  1877. # Re-position ports, MIDI_JACK
  1878. for port in port_list:
  1879. if port.port_type != PORT_TYPE_MIDI_JACK:
  1880. continue
  1881. if port.port_mode == PORT_MODE_INPUT:
  1882. if last_in_type != PORT_TYPE_NULL and port.port_type != last_in_type:
  1883. last_in_pos += canvas.theme.port_spacingT
  1884. port.widget.setPos(QPointF(1 + canvas.theme.port_offset, last_in_pos))
  1885. port.widget.setPortWidth(max_in_width)
  1886. last_in_pos += port_spacing
  1887. last_in_type = port.port_type
  1888. elif port.port_mode == PORT_MODE_OUTPUT:
  1889. if last_out_type != PORT_TYPE_NULL and port.port_type != last_out_type:
  1890. last_out_pos += canvas.theme.port_spacingT
  1891. port.widget.setPos(QPointF(self.p_width - max_out_width - canvas.theme.port_offset - 13, last_out_pos))
  1892. port.widget.setPortWidth(max_out_width)
  1893. last_out_pos += port_spacing
  1894. last_out_type = port.port_type
  1895. # Re-position ports, MIDI_ALSA
  1896. for port in port_list:
  1897. if port.port_type != PORT_TYPE_MIDI_ALSA:
  1898. continue
  1899. if port.port_mode == PORT_MODE_INPUT:
  1900. if last_in_type != PORT_TYPE_NULL and port.port_type != last_in_type:
  1901. last_in_pos += canvas.theme.port_spacingT
  1902. port.widget.setPos(QPointF(1 + canvas.theme.port_offset, last_in_pos))
  1903. port.widget.setPortWidth(max_in_width)
  1904. last_in_pos += port_spacing
  1905. last_in_type = port.port_type
  1906. elif port.port_mode == PORT_MODE_OUTPUT:
  1907. if last_out_type != PORT_TYPE_NULL and port.port_type != last_out_type:
  1908. last_out_pos += canvas.theme.port_spacingT
  1909. port.widget.setPos(QPointF(self.p_width - max_out_width - canvas.theme.port_offset - 13, last_out_pos))
  1910. port.widget.setPortWidth(max_out_width)
  1911. last_out_pos += port_spacing
  1912. last_out_type = port.port_type
  1913. # Re-position ports, PARAMETER
  1914. for port in port_list:
  1915. if port.port_type != PORT_TYPE_PARAMETER:
  1916. continue
  1917. if port.port_mode == PORT_MODE_INPUT:
  1918. if last_in_type != PORT_TYPE_NULL and port.port_type != last_in_type:
  1919. last_in_pos += canvas.theme.port_spacingT
  1920. port.widget.setPos(QPointF(1 + canvas.theme.port_offset, last_in_pos))
  1921. port.widget.setPortWidth(max_in_width)
  1922. last_in_pos += port_spacing
  1923. last_in_type = port.port_type
  1924. elif port.port_mode == PORT_MODE_OUTPUT:
  1925. if last_out_type != PORT_TYPE_NULL and port.port_type != last_out_type:
  1926. last_out_pos += canvas.theme.port_spacingT
  1927. port.widget.setPos(QPointF(self.p_width - max_out_width - canvas.theme.port_offset - 13, last_out_pos))
  1928. port.widget.setPortWidth(max_out_width)
  1929. last_out_pos += port_spacing
  1930. last_out_type = port.port_type
  1931. self.repaintLines(True)
  1932. self.update()
  1933. def repaintLines(self, forced=False):
  1934. if self.pos() != self.m_last_pos or forced:
  1935. for connection in self.m_connection_lines:
  1936. connection.line.updateLinePos()
  1937. self.m_last_pos = self.pos()
  1938. def resetLinesZValue(self):
  1939. for connection in canvas.connection_list:
  1940. if connection.port_out_id in self.m_port_list_ids and connection.port_in_id in self.m_port_list_ids:
  1941. z_value = canvas.last_z_value
  1942. else:
  1943. z_value = canvas.last_z_value - 1
  1944. connection.widget.setZValue(z_value)
  1945. def type(self):
  1946. return CanvasBoxType
  1947. def contextMenuEvent(self, event):
  1948. menu = QMenu()
  1949. discMenu = QMenu("Disconnect", menu)
  1950. conn_list = []
  1951. conn_list_ids = []
  1952. for port_id in self.m_port_list_ids:
  1953. tmp_conn_list = CanvasGetPortConnectionList(self.m_group_id, port_id)
  1954. for conn_id, group_id, port_id in tmp_conn_list:
  1955. if conn_id not in conn_list_ids:
  1956. conn_list.append((conn_id, group_id, port_id))
  1957. conn_list_ids.append(conn_id)
  1958. if len(conn_list) > 0:
  1959. for conn_id, group_id, port_id in conn_list:
  1960. act_x_disc = discMenu.addAction(CanvasGetFullPortName(group_id, port_id))
  1961. act_x_disc.setData(conn_id)
  1962. act_x_disc.triggered.connect(canvas.qobject.PortContextMenuDisconnect)
  1963. else:
  1964. act_x_disc = discMenu.addAction("No connections")
  1965. act_x_disc.setEnabled(False)
  1966. menu.addMenu(discMenu)
  1967. act_x_disc_all = menu.addAction("Disconnect &All")
  1968. act_x_sep1 = menu.addSeparator()
  1969. act_x_info = menu.addAction("&Info")
  1970. act_x_rename = menu.addAction("&Rename")
  1971. act_x_sep2 = menu.addSeparator()
  1972. act_x_split_join = menu.addAction("Join" if self.m_splitted else "Split")
  1973. if not features.group_info:
  1974. act_x_info.setVisible(False)
  1975. if not features.group_rename:
  1976. act_x_rename.setVisible(False)
  1977. if not (features.group_info and features.group_rename):
  1978. act_x_sep1.setVisible(False)
  1979. if self.m_plugin_id >= 0:
  1980. menu.addSeparator()
  1981. act_p_edit = menu.addAction("&Edit")
  1982. act_p_ui = menu.addAction("&Show Custom UI")
  1983. menu.addSeparator()
  1984. act_p_clone = menu.addAction("&Clone")
  1985. act_p_rename = menu.addAction("&Rename...")
  1986. act_p_remove = menu.addAction("Re&move")
  1987. if not self.m_plugin_ui:
  1988. act_p_ui.setVisible(False)
  1989. else:
  1990. act_p_edit = act_p_ui = None
  1991. act_p_clone = act_p_rename = act_p_remove = None
  1992. haveIns = haveOuts = False
  1993. for port in canvas.port_list:
  1994. if port.group_id == self.m_group_id and port.port_id in self.m_port_list_ids:
  1995. if port.port_mode == PORT_MODE_INPUT:
  1996. haveIns = True
  1997. elif port.port_mode == PORT_MODE_OUTPUT:
  1998. haveOuts = True
  1999. if not (self.m_splitted or bool(haveIns and haveOuts)):
  2000. act_x_sep2.setVisible(False)
  2001. act_x_split_join.setVisible(False)
  2002. act_selected = menu.exec_(event.screenPos())
  2003. if act_selected is None:
  2004. pass
  2005. elif act_selected == act_x_disc_all:
  2006. for conn_id in conn_list_ids:
  2007. canvas.callback(ACTION_PORTS_DISCONNECT, conn_id, 0, "")
  2008. elif act_selected == act_x_info:
  2009. canvas.callback(ACTION_GROUP_INFO, self.m_group_id, 0, "")
  2010. elif act_selected == act_x_rename:
  2011. new_name_try = QInputDialog.getText(None, "Rename Group", "New name:", QLineEdit.Normal, self.m_group_name)
  2012. if new_name_try[1] and new_name_try[0]: # 1 - bool ok, 0 - return text
  2013. canvas.callback(ACTION_GROUP_RENAME, self.m_group_id, 0, new_name_try[0])
  2014. elif act_selected == act_x_split_join:
  2015. if self.m_splitted:
  2016. canvas.callback(ACTION_GROUP_JOIN, self.m_group_id, 0, "")
  2017. else:
  2018. canvas.callback(ACTION_GROUP_SPLIT, self.m_group_id, 0, "")
  2019. elif act_selected == act_p_edit:
  2020. canvas.callback(ACTION_PLUGIN_EDIT, self.m_plugin_id, 0, "")
  2021. elif act_selected == act_p_ui:
  2022. canvas.callback(ACTION_PLUGIN_SHOW_UI, self.m_plugin_id, 0, "")
  2023. elif act_selected == act_p_clone:
  2024. canvas.callback(ACTION_PLUGIN_CLONE, self.m_plugin_id, 0, "")
  2025. elif act_selected == act_p_rename:
  2026. new_name_try = QInputDialog.getText(None, "Rename Plugin", "New name:", QLineEdit.Normal, self.m_group_name)
  2027. if new_name_try[1] and new_name_try[0]: # 1 - bool ok, 0 - return text
  2028. canvas.callback(ACTION_PLUGIN_RENAME, self.m_plugin_id, 0, new_name_try[0])
  2029. elif act_selected == act_p_remove:
  2030. canvas.callback(ACTION_PLUGIN_REMOVE, self.m_plugin_id, 0, "")
  2031. event.accept()
  2032. def keyPressEvent(self, event):
  2033. if self.m_plugin_id >= 0 and event.key() == Qt.Key_Delete:
  2034. canvas.callback(ACTION_PLUGIN_REMOVE, self.m_plugin_id, 0, "")
  2035. return event.accept()
  2036. QGraphicsItem.keyPressEvent(self, event)
  2037. def mouseDoubleClickEvent(self, event):
  2038. if self.m_plugin_id >= 0:
  2039. canvas.callback(ACTION_PLUGIN_SHOW_UI if self.m_plugin_ui else ACTION_PLUGIN_EDIT, self.m_plugin_id, 0, "")
  2040. return event.accept()
  2041. QGraphicsItem.mouseDoubleClickEvent(self, event)
  2042. def mousePressEvent(self, event):
  2043. canvas.last_z_value += 1
  2044. self.setZValue(canvas.last_z_value)
  2045. self.resetLinesZValue()
  2046. self.m_cursor_moving = False
  2047. if event.button() == Qt.RightButton:
  2048. canvas.scene.clearSelection()
  2049. self.setSelected(True)
  2050. self.m_mouse_down = False
  2051. return event.accept()
  2052. elif event.button() == Qt.LeftButton:
  2053. if self.sceneBoundingRect().contains(event.scenePos()):
  2054. self.m_mouse_down = True
  2055. else:
  2056. # Fix a weird Qt behaviour with right-click mouseMove
  2057. self.m_mouse_down = False
  2058. return event.ignore()
  2059. else:
  2060. self.m_mouse_down = False
  2061. QGraphicsItem.mousePressEvent(self, event)
  2062. def mouseMoveEvent(self, event):
  2063. if self.m_mouse_down:
  2064. if not self.m_cursor_moving:
  2065. self.setCursor(QCursor(Qt.SizeAllCursor))
  2066. self.m_cursor_moving = True
  2067. self.repaintLines()
  2068. QGraphicsItem.mouseMoveEvent(self, event)
  2069. def mouseReleaseEvent(self, event):
  2070. if self.m_cursor_moving:
  2071. self.setCursor(QCursor(Qt.ArrowCursor))
  2072. self.m_mouse_down = False
  2073. self.m_cursor_moving = False
  2074. QGraphicsItem.mouseReleaseEvent(self, event)
  2075. def boundingRect(self):
  2076. return QRectF(0, 0, self.p_width, self.p_height)
  2077. def paint(self, painter, option, widget):
  2078. painter.save()
  2079. painter.setRenderHint(QPainter.Antialiasing, False)
  2080. # Draw rectangle
  2081. if self.isSelected():
  2082. painter.setPen(canvas.theme.box_pen_sel)
  2083. else:
  2084. painter.setPen(canvas.theme.box_pen)
  2085. if canvas.theme.box_bg_type == Theme.THEME_BG_GRADIENT:
  2086. box_gradient = QLinearGradient(0, 0, 0, self.p_height)
  2087. box_gradient.setColorAt(0, canvas.theme.box_bg_1)
  2088. box_gradient.setColorAt(1, canvas.theme.box_bg_2)
  2089. painter.setBrush(box_gradient)
  2090. else:
  2091. painter.setBrush(canvas.theme.box_bg_1)
  2092. painter.drawRect(0, 0, self.p_width, self.p_height)
  2093. # Draw pixmap header
  2094. if canvas.theme.box_header_pixmap:
  2095. painter.setPen(Qt.NoPen)
  2096. painter.setBrush(canvas.theme.box_bg_2)
  2097. painter.drawRect(1, 1, self.p_width-2, canvas.theme.box_header_height)
  2098. headerPos = QPointF(1, 1)
  2099. headerRect = QRectF(2, 2, self.p_width-4, canvas.theme.box_header_height-3)
  2100. painter.drawTiledPixmap(headerRect, canvas.theme.box_header_pixmap, headerPos)
  2101. # Draw text
  2102. painter.setFont(self.m_font_name)
  2103. if self.isSelected():
  2104. painter.setPen(canvas.theme.box_text_sel)
  2105. else:
  2106. painter.setPen(canvas.theme.box_text)
  2107. if canvas.theme.box_use_icon:
  2108. textPos = QPointF(25, canvas.theme.box_text_ypos)
  2109. else:
  2110. appNameSize = QFontMetrics(self.m_font_name).width(self.m_group_name)
  2111. rem = self.p_width - appNameSize
  2112. textPos = QPointF(rem/2, canvas.theme.box_text_ypos)
  2113. painter.drawText(textPos, self.m_group_name)
  2114. self.repaintLines()
  2115. painter.restore()
  2116. # ------------------------------------------------------------------------------
  2117. # canvasicon.cpp
  2118. class CanvasIcon(QGraphicsSvgItem):
  2119. def __init__(self, icon, name, parent):
  2120. QGraphicsSvgItem.__init__(self, parent)
  2121. self.m_renderer = None
  2122. self.p_size = QRectF(0, 0, 0, 0)
  2123. self.m_colorFX = QGraphicsColorizeEffect(self)
  2124. self.m_colorFX.setColor(canvas.theme.box_text.color())
  2125. self.setGraphicsEffect(self.m_colorFX)
  2126. self.setIcon(icon, name)
  2127. def setIcon(self, icon, name):
  2128. name = name.lower()
  2129. icon_path = ""
  2130. if icon == ICON_APPLICATION:
  2131. self.p_size = QRectF(3, 2, 19, 18)
  2132. if "audacious" in name:
  2133. icon_path = ":/scalable/pb_audacious.svg"
  2134. self.p_size = QRectF(5, 4, 16, 16)
  2135. elif "clementine" in name:
  2136. icon_path = ":/scalable/pb_clementine.svg"
  2137. self.p_size = QRectF(5, 4, 16, 16)
  2138. elif "distrho" in name:
  2139. icon_path = ":/scalable/pb_distrho.svg"
  2140. self.p_size = QRectF(5, 4, 14, 14)
  2141. elif "jamin" in name:
  2142. icon_path = ":/scalable/pb_jamin.svg"
  2143. self.p_size = QRectF(5, 3, 16, 16)
  2144. elif "mplayer" in name:
  2145. icon_path = ":/scalable/pb_mplayer.svg"
  2146. self.p_size = QRectF(5, 4, 16, 16)
  2147. elif "vlc" in name:
  2148. icon_path = ":/scalable/pb_vlc.svg"
  2149. self.p_size = QRectF(5, 3, 16, 16)
  2150. else:
  2151. icon_path = ":/scalable/pb_generic.svg"
  2152. self.p_size = QRectF(4, 3, 16, 16)
  2153. elif icon == ICON_HARDWARE:
  2154. icon_path = ":/scalable/pb_hardware.svg"
  2155. self.p_size = QRectF(5, 2, 16, 16)
  2156. elif icon == ICON_DISTRHO:
  2157. icon_path = ":/scalable/pb_distrho.svg"
  2158. self.p_size = QRectF(5, 4, 14, 14)
  2159. elif icon == ICON_FILE:
  2160. icon_path = ":/scalable/pb_file.svg"
  2161. self.p_size = QRectF(5, 4, 12, 14)
  2162. elif icon == ICON_PLUGIN:
  2163. icon_path = ":/scalable/pb_plugin.svg"
  2164. self.p_size = QRectF(5, 4, 14, 14)
  2165. elif icon == ICON_LADISH_ROOM:
  2166. # TODO - make a unique ladish-room icon
  2167. icon_path = ":/scalable/pb_hardware.svg"
  2168. self.p_size = QRectF(5, 2, 16, 16)
  2169. else:
  2170. self.p_size = QRectF(0, 0, 0, 0)
  2171. qCritical("PatchCanvas::CanvasIcon.setIcon(%s, %s) - unsupported icon requested" % (icon2str(icon), name.encode()))
  2172. return
  2173. self.m_renderer = QSvgRenderer(icon_path, canvas.scene)
  2174. self.setSharedRenderer(self.m_renderer)
  2175. self.update()
  2176. def type(self):
  2177. return CanvasIconType
  2178. def boundingRect(self):
  2179. return self.p_size
  2180. def paint(self, painter, option, widget):
  2181. if self.m_renderer:
  2182. painter.save()
  2183. painter.setRenderHint(QPainter.Antialiasing, False)
  2184. painter.setRenderHint(QPainter.TextAntialiasing, False)
  2185. self.m_renderer.render(painter, self.p_size)
  2186. painter.restore()
  2187. else:
  2188. QGraphicsSvgItem.paint(self, painter, option, widget)
  2189. # ------------------------------------------------------------------------------
  2190. # canvasportglow.cpp
  2191. class CanvasPortGlow(QGraphicsDropShadowEffect):
  2192. def __init__(self, port_type, parent):
  2193. QGraphicsDropShadowEffect.__init__(self, parent)
  2194. self.setBlurRadius(12)
  2195. self.setOffset(0, 0)
  2196. if port_type == PORT_TYPE_AUDIO_JACK:
  2197. self.setColor(canvas.theme.line_audio_jack_glow)
  2198. elif port_type == PORT_TYPE_MIDI_JACK:
  2199. self.setColor(canvas.theme.line_midi_jack_glow)
  2200. elif port_type == PORT_TYPE_MIDI_ALSA:
  2201. self.setColor(canvas.theme.line_midi_alsa_glow)
  2202. elif port_type == PORT_TYPE_PARAMETER:
  2203. self.setColor(canvas.theme.line_parameter_glow)
  2204. # ------------------------------------------------------------------------------
  2205. # canvasboxshadow.cpp
  2206. class CanvasBoxShadow(QGraphicsDropShadowEffect):
  2207. def __init__(self, parent):
  2208. QGraphicsDropShadowEffect.__init__(self, parent)
  2209. self.m_fakeParent = None
  2210. self.setBlurRadius(20)
  2211. self.setColor(canvas.theme.box_shadow)
  2212. self.setOffset(0, 0)
  2213. def setFakeParent(self, fakeParent):
  2214. self.m_fakeParent = fakeParent
  2215. def setOpacity(self, opacity):
  2216. color = QColor(canvas.theme.box_shadow)
  2217. color.setAlphaF(opacity)
  2218. self.setColor(color)
  2219. def draw(self, painter):
  2220. if self.m_fakeParent:
  2221. self.m_fakeParent.repaintLines()
  2222. QGraphicsDropShadowEffect.draw(self, painter)