2 # SPDX-FileCopyrightText: 2011-2024 Filipe Coelho <falktx@falktx.com>
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # ------------------------------------------------------------------------------------------------------------
8 from qt_compat
import qt_config
11 from PyQt5
.QtCore
import pyqtSlot
, qCritical
, qFatal
, qWarning
, QObject
12 from PyQt5
.QtCore
import QPointF
, QRectF
, QTimer
13 from PyQt5
.QtWidgets
import QGraphicsObject
15 from PyQt6
.QtCore
import pyqtSlot
, qCritical
, qFatal
, qWarning
, QObject
16 from PyQt6
.QtCore
import QPointF
, QRectF
, QTimer
17 from PyQt6
.QtWidgets
import QGraphicsObject
19 # ------------------------------------------------------------------------------------------------------------
36 ACTION_PORTS_DISCONNECT
,
46 MAX_PLUGIN_ID_ALLOWED
,
49 from .canvasbox
import CanvasBox
50 from .canvasbezierline
import CanvasBezierLine
51 from .canvasline
import CanvasLine
52 from .theme
import Theme
, getDefaultTheme
, getThemeName
53 from .utils
import CanvasCallback
, CanvasGetNewGroupPos
, CanvasItemFX
, CanvasRemoveItemFX
57 from .scene
import PatchScene
59 from utils
import QSafeSettings
61 # ------------------------------------------------------------------------------------------------------------
63 class CanvasObject(QObject
):
64 def __init__(self
, parent
=None):
65 QObject
.__init
__(self
, parent
)
68 def AnimationFinishedShow(self
):
69 animation
= self
.sender()
72 canvas
.animation_list
.remove(animation
)
75 def AnimationFinishedHide(self
):
76 animation
= self
.sender()
79 canvas
.animation_list
.remove(animation
)
80 item
= animation
.item()
82 if isinstance(item
, QGraphicsObject
):
83 item
.blockSignals(True)
85 item
.blockSignals(False)
90 def AnimationFinishedDestroy(self
):
91 animation
= self
.sender()
94 canvas
.animation_list
.remove(animation
)
95 item
= animation
.item()
97 CanvasRemoveItemFX(item
)
100 def PortContextMenuConnect(self
):
102 sources
, targets
= self
.sender().data()
106 for port_type
in (PORT_TYPE_AUDIO_JACK
, PORT_TYPE_MIDI_JACK
, PORT_TYPE_MIDI_ALSA
, PORT_TYPE_PARAMETER
):
107 source_ports
= sources
[port_type
]
108 target_ports
= targets
[port_type
]
110 source_ports_len
= len(source_ports
)
111 target_ports_len
= len(target_ports
)
113 if source_ports_len
== 0 or target_ports_len
== 0:
116 for i
in range(min(source_ports_len
, target_ports_len
)):
117 data
= "%i:%i:%i:%i" % (source_ports
[i
][0],
121 CanvasCallback(ACTION_PORTS_CONNECT
, 0, 0, data
)
123 if source_ports_len
== 1 and target_ports_len
> 1:
124 for i
in range(1, target_ports_len
):
125 data
= "%i:%i:%i:%i" % (source_ports
[0][0],
129 CanvasCallback(ACTION_PORTS_CONNECT
, 0, 0, data
)
132 def PortContextMenuDisconnect(self
):
134 connectionId
= int(self
.sender().data())
138 CanvasCallback(ACTION_PORTS_DISCONNECT
, connectionId
, 0, "")
140 @pyqtSlot(int, bool, int, int)
141 def boxPositionChanged(self
, groupId
, split
, x
, y
):
145 for group
in canvas
.group_list
:
146 if group
.group_id
== groupId
:
148 pos
= group
.widgets
[1].pos()
153 valueStr
= "%i:%i:%i:%i" % (x
, y
, x2
, y2
)
154 CanvasCallback(ACTION_GROUP_POSITION
, groupId
, 0, valueStr
)
156 @pyqtSlot(int, bool, int, int)
157 def sboxPositionChanged(self
, groupId
, split
, x2
, y2
):
160 for group
in canvas
.group_list
:
161 if group
.group_id
== groupId
:
162 pos
= group
.widgets
[0].pos()
167 valueStr
= "%i:%i:%i:%i" % (x
, y
, x2
, y2
)
168 CanvasCallback(ACTION_GROUP_POSITION
, groupId
, 0, valueStr
)
170 # ------------------------------------------------------------------------------------------------------------
172 def getStoredCanvasPosition(key
, fallback_pos
):
174 return canvas
.settings
.value("CanvasPositions/" + key
, fallback_pos
, type=QPointF
)
178 def getStoredCanvasSplit(group_name
, fallback_split_mode
):
180 return canvas
.settings
.value("CanvasPositions/%s_SPLIT" % group_name
, fallback_split_mode
, type=int)
182 return fallback_split_mode
184 # ------------------------------------------------------------------------------------------------------------
186 def init(appName
, scene
, callback
, debug
=False):
188 print("PatchCanvas::init(\"%s\", %s, %s, %s)" % (appName
, scene
, callback
, bool2str(debug
)))
191 qCritical("PatchCanvas::init() - already initiated")
195 qFatal("PatchCanvas::init() - fatal error: callback not set")
198 canvas
.callback
= callback
202 canvas
.last_z_value
= 0
203 canvas
.last_connection_id
= 0
204 canvas
.initial_pos
= QPointF(0, 0)
205 canvas
.size_rect
= QRectF()
207 if not canvas
.qobject
:
208 canvas
.qobject
= CanvasObject()
209 if not canvas
.settings
:
210 canvas
.settings
= QSafeSettings("falkTX", appName
)
216 for i
in range(Theme
.THEME_MAX
):
217 this_theme_name
= getThemeName(i
)
218 if this_theme_name
== options
.theme_name
:
219 canvas
.theme
= Theme(i
)
223 canvas
.theme
= Theme(getDefaultTheme())
225 canvas
.scene
.updateTheme()
227 canvas
.initiated
= True
231 print("PatchCanvas::clear()")
236 connection_list_ids
= []
238 for group
in canvas
.group_list
:
239 group_pos
[group
.group_name
] = (
241 group
.widgets
[0].pos(),
242 group
.widgets
[1].pos() if group
.split
else None,
244 group_list_ids
.append(group
.group_id
)
246 for port
in canvas
.port_list
:
247 port_list_ids
.append((port
.group_id
, port
.port_id
))
249 for connection
in canvas
.connection_list
:
250 connection_list_ids
.append(connection
.connection_id
)
252 for idx
in connection_list_ids
:
255 for group_id
, port_id
in port_list_ids
:
256 removePort(group_id
, port_id
)
258 for idx
in group_list_ids
:
261 canvas
.last_z_value
= 0
262 canvas
.last_connection_id
= 0
264 canvas
.group_list
= []
265 canvas
.port_list
= []
266 canvas
.connection_list
= []
267 canvas
.group_plugin_map
= {}
268 canvas
.old_group_pos
= group_pos
270 canvas
.scene
.clearSelection()
273 for animation
in canvas
.animation_list
:
274 animatedItems
.append(animation
.item())
276 for item
in canvas
.scene
.items():
277 if item
.type() in (CanvasIconType
, CanvasRubberbandType
) or item
in animatedItems
:
279 canvas
.scene
.removeItem(item
)
282 canvas
.initiated
= False
284 QTimer
.singleShot(0, canvas
.scene
.update
)
286 # ------------------------------------------------------------------------------------------------------------
288 def setInitialPos(x
, y
):
290 print("PatchCanvas::setInitialPos(%i, %i)" % (x
, y
))
292 canvas
.initial_pos
.setX(x
)
293 canvas
.initial_pos
.setY(y
)
295 def setCanvasSize(x
, y
, width
, height
):
297 print("PatchCanvas::setCanvasSize(%i, %i, %i, %i)" % (x
, y
, width
, height
))
299 canvas
.size_rect
.setX(x
)
300 canvas
.size_rect
.setY(y
)
301 canvas
.size_rect
.setWidth(width
)
302 canvas
.size_rect
.setHeight(height
)
303 canvas
.scene
.updateLimits()
304 canvas
.scene
.fixScaleFactor()
306 def addGroup(group_id
, group_name
, split
=SPLIT_UNDEF
, icon
=ICON_APPLICATION
):
308 print("PatchCanvas::addGroup(%i, %s, %s, %s)" % (
309 group_id
, group_name
.encode(), split2str(split
), icon2str(icon
)))
311 for group
in canvas
.group_list
:
312 if group
.group_id
== group_id
:
313 qWarning("PatchCanvas::addGroup(%i, %s, %s, %s) - group already exists" % (
314 group_id
, group_name
.encode(), split2str(split
), icon2str(icon
)))
317 old_matching_group
= canvas
.old_group_pos
.pop(group_name
, None)
319 if split
== SPLIT_UNDEF
:
320 isHardware
= bool(icon
== ICON_HARDWARE
)
322 if features
.handle_group_pos
:
323 split
= getStoredCanvasSplit(group_name
, SPLIT_YES
if isHardware
else split
)
326 elif old_matching_group
is not None and old_matching_group
[0]:
329 group_box
= CanvasBox(group_id
, group_name
, icon
)
330 group_box
.positionChanged
.connect(canvas
.qobject
.boxPositionChanged
)
331 group_box
.blockSignals(True)
333 group_dict
= group_dict_t()
334 group_dict
.group_id
= group_id
335 group_dict
.group_name
= group_name
336 group_dict
.split
= bool(split
== SPLIT_YES
)
337 group_dict
.icon
= icon
338 group_dict
.plugin_id
= -1
339 group_dict
.plugin_ui
= False
340 group_dict
.plugin_inline
= False
341 group_dict
.widgets
= [group_box
, None]
343 if split
== SPLIT_YES
:
344 group_box
.setSplit(True, PORT_MODE_OUTPUT
)
346 if features
.handle_group_pos
:
347 group_box
.setPos(getStoredCanvasPosition(group_name
+ "_OUTPUT", CanvasGetNewGroupPos(False)))
348 elif old_matching_group
is not None:
349 group_box
.setPos(old_matching_group
[1])
351 group_box
.setPos(CanvasGetNewGroupPos(False))
353 group_sbox
= CanvasBox(group_id
, group_name
, icon
)
354 group_sbox
.positionChanged
.connect(canvas
.qobject
.sboxPositionChanged
)
355 group_sbox
.blockSignals(True)
356 group_sbox
.setSplit(True, PORT_MODE_INPUT
)
358 group_dict
.widgets
[1] = group_sbox
360 if features
.handle_group_pos
:
361 group_sbox
.setPos(getStoredCanvasPosition(group_name
+ "_INPUT", CanvasGetNewGroupPos(True)))
362 elif old_matching_group
is not None and old_matching_group
[0]:
363 group_sbox
.setPos(old_matching_group
[2])
365 group_sbox
.setPos(group_box
.x() + group_box
.boundingRect().width() + 300, group_box
.y())
367 canvas
.last_z_value
+= 1
368 group_sbox
.setZValue(canvas
.last_z_value
)
370 if options
.eyecandy
== EYECANDY_FULL
and not options
.auto_hide_groups
:
371 CanvasItemFX(group_sbox
, True, False)
373 group_sbox
.checkItemPos()
374 group_sbox
.blockSignals(False)
377 group_box
.setSplit(False)
379 if features
.handle_group_pos
:
380 group_box
.setPos(getStoredCanvasPosition(group_name
, CanvasGetNewGroupPos(False)))
381 elif old_matching_group
is not None:
382 group_box
.setPos(old_matching_group
[1])
384 # Special ladish fake-split groups
385 horizontal
= bool(icon
== ICON_HARDWARE
or icon
== ICON_LADISH_ROOM
)
386 group_box
.setPos(CanvasGetNewGroupPos(horizontal
))
388 canvas
.last_z_value
+= 1
389 group_box
.setZValue(canvas
.last_z_value
)
391 group_box
.checkItemPos()
392 group_box
.blockSignals(False)
394 canvas
.group_list
.append(group_dict
)
396 if options
.eyecandy
== EYECANDY_FULL
and not options
.auto_hide_groups
:
397 CanvasItemFX(group_box
, True, False)
399 QTimer
.singleShot(0, canvas
.scene
.update
)
403 def removeGroup(group_id
):
405 print("PatchCanvas::removeGroup(%i)" % group_id
)
407 for group
in canvas
.group_list
:
408 if group
.group_id
== group_id
:
409 item
= group
.widgets
[0]
410 group_name
= group
.group_name
413 s_item
= group
.widgets
[1]
415 if features
.handle_group_pos
:
416 canvas
.settings
.setValue("CanvasPositions/%s_OUTPUT" % group_name
, item
.pos())
417 canvas
.settings
.setValue("CanvasPositions/%s_INPUT" % group_name
, s_item
.pos())
418 canvas
.settings
.setValue("CanvasPositions/%s_SPLIT" % group_name
, SPLIT_YES
)
420 if options
.eyecandy
== EYECANDY_FULL
:
421 CanvasItemFX(s_item
, False, True)
423 s_item
.removeIconFromScene()
424 canvas
.scene
.removeItem(s_item
)
428 if features
.handle_group_pos
:
429 canvas
.settings
.setValue("CanvasPositions/%s" % group_name
, item
.pos())
430 canvas
.settings
.setValue("CanvasPositions/%s_SPLIT" % group_name
, SPLIT_NO
)
432 if options
.eyecandy
== EYECANDY_FULL
:
433 CanvasItemFX(item
, False, True)
435 item
.removeIconFromScene()
436 canvas
.scene
.removeItem(item
)
439 canvas
.group_list
.remove(group
)
440 canvas
.group_plugin_map
.pop(group
.plugin_id
, None)
442 QTimer
.singleShot(0, canvas
.scene
.update
)
445 qCritical("PatchCanvas::removeGroup(%i) - unable to find group to remove" % group_id
)
447 def renameGroup(group_id
, new_group_name
):
449 print("PatchCanvas::renameGroup(%i, %s)" % (group_id
, new_group_name
.encode()))
451 for group
in canvas
.group_list
:
452 if group
.group_id
== group_id
:
453 group
.group_name
= new_group_name
454 group
.widgets
[0].setGroupName(new_group_name
)
456 if group
.split
and group
.widgets
[1]:
457 group
.widgets
[1].setGroupName(new_group_name
)
459 QTimer
.singleShot(0, canvas
.scene
.update
)
462 qCritical("PatchCanvas::renameGroup(%i, %s) - unable to find group to rename" % (group_id
, new_group_name
.encode()))
464 def splitGroup(group_id
):
466 print("PatchCanvas::splitGroup(%i)" % group_id
)
470 group_icon
= ICON_APPLICATION
474 plugin_inline
= False
478 # Step 1 - Store all Item data
479 for group
in canvas
.group_list
:
480 if group
.group_id
== group_id
:
483 print("PatchCanvas::splitGroup(%i) - group is already split" % group_id
)
486 item
= group
.widgets
[0]
487 group_name
= group
.group_name
488 group_icon
= group
.icon
489 group_pos
= item
.pos()
490 plugin_id
= group
.plugin_id
491 plugin_ui
= group
.plugin_ui
492 plugin_inline
= group
.plugin_inline
496 qCritical("PatchCanvas::splitGroup(%i) - unable to find group to split" % group_id
)
499 port_list_ids
= list(item
.getPortList())
501 for port
in canvas
.port_list
:
502 if port
.group_id
== group_id
and port
.port_id
in port_list_ids
:
503 port_dict
= port_dict_t()
504 port_dict
.group_id
= port
.group_id
505 port_dict
.port_id
= port
.port_id
506 port_dict
.port_name
= port
.port_name
507 port_dict
.port_mode
= port
.port_mode
508 port_dict
.port_type
= port
.port_type
509 port_dict
.is_alternate
= port
.is_alternate
510 port_dict
.widget
= None
511 ports_data
.append(port_dict
)
513 for connection
in canvas
.connection_list
:
514 if (connection
.group_in_id
== group_id
and connection
.port_in_id
in port_list_ids
) or \
515 (connection
.group_out_id
== group_id
and connection
.port_out_id
in port_list_ids
):
516 connection_dict
= connection_dict_t()
517 connection_dict
.connection_id
= connection
.connection_id
518 connection_dict
.group_in_id
= connection
.group_in_id
519 connection_dict
.port_in_id
= connection
.port_in_id
520 connection_dict
.group_out_id
= connection
.group_out_id
521 connection_dict
.port_out_id
= connection
.port_out_id
522 connection_dict
.widget
= None
523 conns_data
.append(connection_dict
)
525 # Step 2 - Remove Item and Children
526 for conn
in conns_data
:
527 disconnectPorts(conn
.connection_id
)
529 for port_id
in port_list_ids
:
530 removePort(group_id
, port_id
)
532 removeGroup(group_id
)
534 # Step 3 - Re-create Item, now split
535 group
= addGroup(group_id
, group_name
, SPLIT_YES
, group_icon
)
538 setGroupAsPlugin(group_id
, plugin_id
, plugin_ui
, plugin_inline
)
540 for port
in ports_data
:
541 addPort(group_id
, port
.port_id
, port
.port_name
, port
.port_mode
, port
.port_type
, port
.is_alternate
)
543 for conn
in conns_data
:
544 connectPorts(conn
.connection_id
, conn
.group_out_id
, conn
.port_out_id
, conn
.group_in_id
, conn
.port_in_id
, True)
546 if group
is not None:
547 pos1
= group
.widgets
[0].pos()
548 pos2
= group
.widgets
[1].pos()
549 group2_pos
= QPointF(group_pos
.x() + group
.widgets
[1].boundingRect().width() * 3/2, group_pos
.y())
550 group
.widgets
[0].blockSignals(True)
551 group
.widgets
[0].setPos(group_pos
)
552 group
.widgets
[0].blockSignals(False)
553 group
.widgets
[1].blockSignals(True)
554 group
.widgets
[1].setPos(group2_pos
)
555 group
.widgets
[1].checkItemPos()
556 group
.widgets
[1].blockSignals(False)
557 valueStr
= "%i:%i:%i:%i" % (group_pos
.x(), group_pos
.y(), group2_pos
.x(), group2_pos
.y())
558 CanvasCallback(ACTION_GROUP_POSITION
, group_id
, 0, valueStr
)
560 QTimer
.singleShot(0, canvas
.scene
.update
)
562 def joinGroup(group_id
):
564 print("PatchCanvas::joinGroup(%i)" % group_id
)
569 group_icon
= ICON_APPLICATION
573 plugin_inline
= False
577 # Step 1 - Store all Item data
578 for group
in canvas
.group_list
:
579 if group
.group_id
== group_id
:
582 print("PatchCanvas::joinGroup(%i) - group is not split" % group_id
)
585 item
= group
.widgets
[0]
586 s_item
= group
.widgets
[1]
587 group_name
= group
.group_name
588 group_icon
= group
.icon
589 group_pos
= item
.pos()
590 plugin_id
= group
.plugin_id
591 plugin_ui
= group
.plugin_ui
592 plugin_inline
= group
.plugin_inline
596 if not (item
and s_item
):
597 qCritical("PatchCanvas::joinGroup(%i) - unable to find groups to join" % group_id
)
600 port_list_ids
= list(item
.getPortList())
601 port_list_idss
= s_item
.getPortList()
603 for port_id
in port_list_idss
:
604 if port_id
not in port_list_ids
:
605 port_list_ids
.append(port_id
)
607 for port
in canvas
.port_list
:
608 if port
.group_id
== group_id
and port
.port_id
in port_list_ids
:
609 port_dict
= port_dict_t()
610 port_dict
.group_id
= port
.group_id
611 port_dict
.port_id
= port
.port_id
612 port_dict
.port_name
= port
.port_name
613 port_dict
.port_mode
= port
.port_mode
614 port_dict
.port_type
= port
.port_type
615 port_dict
.is_alternate
= port
.is_alternate
616 port_dict
.widget
= None
617 ports_data
.append(port_dict
)
619 for connection
in canvas
.connection_list
:
620 if (connection
.group_in_id
== group_id
and connection
.port_in_id
in port_list_ids
) or \
621 (connection
.group_out_id
== group_id
and connection
.port_out_id
in port_list_ids
):
622 connection_dict
= connection_dict_t()
623 connection_dict
.connection_id
= connection
.connection_id
624 connection_dict
.group_in_id
= connection
.group_in_id
625 connection_dict
.port_in_id
= connection
.port_in_id
626 connection_dict
.group_out_id
= connection
.group_out_id
627 connection_dict
.port_out_id
= connection
.port_out_id
628 connection_dict
.widget
= None
629 conns_data
.append(connection_dict
)
631 # Step 2 - Remove Item and Children
632 for conn
in conns_data
:
633 disconnectPorts(conn
.connection_id
)
635 for port_id
in port_list_ids
:
636 removePort(group_id
, port_id
)
638 removeGroup(group_id
)
640 # Step 3 - Re-create Item, now together
641 group
= addGroup(group_id
, group_name
, SPLIT_NO
, group_icon
)
644 setGroupAsPlugin(group_id
, plugin_id
, plugin_ui
, plugin_inline
)
646 for port
in ports_data
:
647 addPort(group_id
, port
.port_id
, port
.port_name
, port
.port_mode
, port
.port_type
, port
.is_alternate
)
649 for conn
in conns_data
:
650 connectPorts(conn
.connection_id
, conn
.group_out_id
, conn
.port_out_id
, conn
.group_in_id
, conn
.port_in_id
, True)
652 if group
is not None:
653 group
.widgets
[0].blockSignals(True)
654 group
.widgets
[0].setPos(group_pos
)
655 group
.widgets
[0].checkItemPos()
656 group
.widgets
[0].blockSignals(False)
657 valueStr
= "%i:%i:%i:%i" % (group_pos
.x(), group_pos
.y(), 0, 0)
658 CanvasCallback(ACTION_GROUP_POSITION
, group_id
, 0, valueStr
)
660 QTimer
.singleShot(0, canvas
.scene
.update
)
662 # ------------------------------------------------------------------------------------------------------------
664 def getGroupPos(group_id
, port_mode
=PORT_MODE_OUTPUT
):
666 print("PatchCanvas::getGroupPos(%i, %s)" % (group_id
, port_mode2str(port_mode
)))
668 for group
in canvas
.group_list
:
669 if group
.group_id
== group_id
:
670 return group
.widgets
[1 if (group
.split
and port_mode
== PORT_MODE_INPUT
) else 0].pos()
672 qCritical("PatchCanvas::getGroupPos(%i, %s) - unable to find group" % (group_id
, port_mode2str(port_mode
)))
675 def saveGroupPositions():
677 print("PatchCanvas::getGroupPositions()")
681 for group
in canvas
.group_list
:
683 pos1
= group
.widgets
[0].pos()
684 pos2
= group
.widgets
[1].pos()
686 pos1
= group
.widgets
[0].pos()
690 "name" : group
.group_name
,
695 "split": group
.split
,
700 def restoreGroupPositions(dataList
):
702 print("PatchCanvas::restoreGroupPositions(...)")
706 for group
in canvas
.group_list
:
707 mapping
[group
.group_name
] = group
709 for data
in dataList
:
711 group
= mapping
.get(name
, None)
716 group
.widgets
[0].blockSignals(True)
717 group
.widgets
[0].setPos(data
['pos1x'], data
['pos1y'])
718 group
.widgets
[0].blockSignals(False)
720 if group
.split
and group
.widgets
[1]:
721 group
.widgets
[1].blockSignals(True)
722 group
.widgets
[1].setPos(data
['pos2x'], data
['pos2y'])
723 group
.widgets
[1].blockSignals(False)
725 def setGroupPos(group_id
, group_pos_x
, group_pos_y
):
726 setGroupPosFull(group_id
, group_pos_x
, group_pos_y
, group_pos_x
, group_pos_y
)
728 def setGroupPosFull(group_id
, group_pos_x_o
, group_pos_y_o
, group_pos_x_i
, group_pos_y_i
):
730 print("PatchCanvas::setGroupPos(%i, %i, %i, %i, %i)" % (
731 group_id
, group_pos_x_o
, group_pos_y_o
, group_pos_x_i
, group_pos_y_i
))
733 for group
in canvas
.group_list
:
734 if group
.group_id
== group_id
:
735 group
.widgets
[0].blockSignals(True)
736 group
.widgets
[0].setPos(group_pos_x_o
, group_pos_y_o
)
737 group
.widgets
[0].checkItemPos()
738 group
.widgets
[0].blockSignals(False)
740 if group
.split
and group
.widgets
[1]:
741 group
.widgets
[1].blockSignals(True)
742 group
.widgets
[1].setPos(group_pos_x_i
, group_pos_y_i
)
743 group
.widgets
[1].checkItemPos()
744 group
.widgets
[1].blockSignals(False)
746 QTimer
.singleShot(0, canvas
.scene
.update
)
749 qCritical("PatchCanvas::setGroupPos(%i, %i, %i, %i, %i) - unable to find group to reposition" % (
750 group_id
, group_pos_x_o
, group_pos_y_o
, group_pos_x_i
, group_pos_y_i
))
752 # ------------------------------------------------------------------------------------------------------------
754 def setGroupIcon(group_id
, icon
):
756 print("PatchCanvas::setGroupIcon(%i, %s)" % (group_id
, icon2str(icon
)))
758 for group
in canvas
.group_list
:
759 if group
.group_id
== group_id
:
761 group
.widgets
[0].setIcon(icon
)
763 if group
.split
and group
.widgets
[1]:
764 group
.widgets
[1].setIcon(icon
)
766 QTimer
.singleShot(0, canvas
.scene
.update
)
769 qCritical("PatchCanvas::setGroupIcon(%i, %s) - unable to find group to change icon" % (group_id
, icon2str(icon
)))
771 def setGroupAsPlugin(group_id
, plugin_id
, hasUI
, hasInlineDisplay
):
773 print("PatchCanvas::setGroupAsPlugin(%i, %i, %s, %s)" % (
774 group_id
, plugin_id
, bool2str(hasUI
), bool2str(hasInlineDisplay
)))
776 for group
in canvas
.group_list
:
777 if group
.group_id
== group_id
:
778 group
.plugin_id
= plugin_id
779 group
.plugin_ui
= hasUI
780 group
.plugin_inline
= hasInlineDisplay
781 group
.widgets
[0].setAsPlugin(plugin_id
, hasUI
, hasInlineDisplay
)
783 if group
.split
and group
.widgets
[1]:
784 group
.widgets
[1].setAsPlugin(plugin_id
, hasUI
, hasInlineDisplay
)
786 canvas
.group_plugin_map
[plugin_id
] = group
789 qCritical("PatchCanvas::setGroupAsPlugin(%i, %i, %s, %s) - unable to find group to set as plugin" % (
790 group_id
, plugin_id
, bool2str(hasUI
), bool2str(hasInlineDisplay
)))
792 # ------------------------------------------------------------------------------------------------------------
794 def focusGroupUsingPluginId(plugin_id
):
796 print("PatchCanvas::focusGroupUsingPluginId(%i)" % (plugin_id
,))
798 if plugin_id
< 0 or plugin_id
>= MAX_PLUGIN_ID_ALLOWED
:
801 for group
in canvas
.group_list
:
802 if group
.plugin_id
== plugin_id
:
803 item
= group
.widgets
[0]
804 canvas
.scene
.clearSelection()
805 canvas
.scene
.getView().centerOn(item
)
806 item
.setSelected(True)
809 def focusGroupUsingGroupName(group_name
):
811 print("PatchCanvas::focusGroupUsingGroupName(%s)" % (group_name
,))
813 for group
in canvas
.group_list
:
814 if group
.group_name
== group_name
:
815 item
= group
.widgets
[0]
816 canvas
.scene
.clearSelection()
817 canvas
.scene
.getView().centerOn(item
)
818 item
.setSelected(True)
821 # ------------------------------------------------------------------------------------------------------------
823 def addPort(group_id
, port_id
, port_name
, port_mode
, port_type
, is_alternate
=False):
825 print("PatchCanvas::addPort(%i, %i, %s, %s, %s, %s)" % (
826 group_id
, port_id
, port_name
.encode(),
827 port_mode2str(port_mode
), port_type2str(port_type
), bool2str(is_alternate
)))
829 for port
in canvas
.port_list
:
830 if port
.group_id
== group_id
and port
.port_id
== port_id
:
831 qWarning("PatchCanvas::addPort(%i, %i, %s, %s, %s) - port already exists" % (
832 group_id
, port_id
, port_name
.encode(), port_mode2str(port_mode
), port_type2str(port_type
)))
838 for group
in canvas
.group_list
:
839 if group
.group_id
== group_id
:
840 if group
.split
and group
.widgets
[0].getSplitMode() != port_mode
and group
.widgets
[1]:
844 box_widget
= group
.widgets
[n
]
845 port_widget
= box_widget
.addPortFromGroup(port_id
, port_mode
, port_type
, port_name
, is_alternate
)
848 if not (box_widget
and port_widget
):
849 qCritical("PatchCanvas::addPort(%i, %i, %s, %s, %s) - Unable to find parent group" % (
850 group_id
, port_id
, port_name
.encode(), port_mode2str(port_mode
), port_type2str(port_type
)))
853 port_dict
= port_dict_t()
854 port_dict
.group_id
= group_id
855 port_dict
.port_id
= port_id
856 port_dict
.port_name
= port_name
857 port_dict
.port_mode
= port_mode
858 port_dict
.port_type
= port_type
859 port_dict
.is_alternate
= is_alternate
860 port_dict
.widget
= port_widget
861 canvas
.port_list
.append(port_dict
)
863 box_widget
.updatePositions()
865 if options
.eyecandy
== EYECANDY_FULL
:
866 CanvasItemFX(port_widget
, True, False)
869 QTimer
.singleShot(0, canvas
.scene
.update
)
871 def removePort(group_id
, port_id
):
873 print("PatchCanvas::removePort(%i, %i)" % (group_id
, port_id
))
875 for port
in canvas
.port_list
:
876 if port
.group_id
== group_id
and port
.port_id
== port_id
:
879 pitem
= item
.parentItem()
880 canvas
.scene
.removeItem(item
)
884 pitem
.removePortFromGroup(port_id
)
885 canvas
.port_list
.remove(port
)
888 QTimer
.singleShot(0, canvas
.scene
.update
)
891 qCritical("PatchCanvas::removePort(%i, %i) - Unable to find port to remove" % (group_id
, port_id
))
893 def renamePort(group_id
, port_id
, new_port_name
):
895 print("PatchCanvas::renamePort(%i, %i, %s)" % (group_id
, port_id
, new_port_name
.encode()))
897 for port
in canvas
.port_list
:
898 if port
.group_id
== group_id
and port
.port_id
== port_id
:
899 port
.port_name
= new_port_name
900 port
.widget
.setPortName(new_port_name
)
901 port
.widget
.parentItem().updatePositions()
903 QTimer
.singleShot(0, canvas
.scene
.update
)
906 qCritical("PatchCanvas::renamePort(%i, %i, %s) - Unable to find port to rename" % (
907 group_id
, port_id
, new_port_name
.encode()))
909 def connectPorts(connection_id
, group_out_id
, port_out_id
, group_in_id
, port_in_id
, fromSplitOrJoin
= False):
910 if canvas
.last_connection_id
>= connection_id
and not fromSplitOrJoin
:
911 print("PatchCanvas::connectPorts(%i, %i, %i, %i, %i) - invalid connection id received (last: %i)" % (
912 connection_id
, group_out_id
, port_out_id
, group_in_id
, port_in_id
, canvas
.last_connection_id
))
915 canvas
.last_connection_id
= connection_id
918 print("PatchCanvas::connectPorts(%i, %i, %i, %i, %i)" % (
919 connection_id
, group_out_id
, port_out_id
, group_in_id
, port_in_id
))
923 port_out_parent
= None
924 port_in_parent
= None
926 for port
in canvas
.port_list
:
927 if port
.group_id
== group_out_id
and port
.port_id
== port_out_id
:
928 port_out
= port
.widget
929 port_out_parent
= port_out
.parentItem()
930 elif port
.group_id
== group_in_id
and port
.port_id
== port_in_id
:
931 port_in
= port
.widget
932 port_in_parent
= port_in
.parentItem()
935 if not (port_out
and port_in
):
936 qCritical("PatchCanvas::connectPorts(%i, %i, %i, %i, %i) - unable to find ports to connect" % (
937 connection_id
, group_out_id
, port_out_id
, group_in_id
, port_in_id
))
940 connection_dict
= connection_dict_t()
941 connection_dict
.connection_id
= connection_id
942 connection_dict
.group_in_id
= group_in_id
943 connection_dict
.port_in_id
= port_in_id
944 connection_dict
.group_out_id
= group_out_id
945 connection_dict
.port_out_id
= port_out_id
947 if options
.use_bezier_lines
:
948 connection_dict
.widget
= CanvasBezierLine(port_out
, port_in
, None)
950 connection_dict
.widget
= CanvasLine(port_out
, port_in
, None)
952 canvas
.scene
.addItem(connection_dict
.widget
)
954 port_out_parent
.addLineFromGroup(connection_dict
.widget
, connection_id
)
955 port_in_parent
.addLineFromGroup(connection_dict
.widget
, connection_id
)
957 canvas
.last_z_value
+= 1
958 port_out_parent
.setZValue(canvas
.last_z_value
)
959 port_in_parent
.setZValue(canvas
.last_z_value
)
961 canvas
.last_z_value
+= 1
962 connection_dict
.widget
.setZValue(canvas
.last_z_value
)
964 canvas
.connection_list
.append(connection_dict
)
966 if options
.eyecandy
== EYECANDY_FULL
:
967 item
= connection_dict
.widget
968 CanvasItemFX(item
, True, False)
971 QTimer
.singleShot(0, canvas
.scene
.update
)
973 def disconnectPorts(connection_id
):
975 print("PatchCanvas::disconnectPorts(%i)" % connection_id
)
980 group1id
= port1id
= 0
981 group2id
= port2id
= 0
983 for connection
in canvas
.connection_list
:
984 if connection
.connection_id
== connection_id
:
985 group1id
= connection
.group_out_id
986 group2id
= connection
.group_in_id
987 port1id
= connection
.port_out_id
988 port2id
= connection
.port_in_id
989 line
= connection
.widget
990 canvas
.connection_list
.remove(connection
)
994 qCritical("PatchCanvas::disconnectPorts(%i) - unable to find connection ports" % connection_id
)
997 for port
in canvas
.port_list
:
998 if port
.group_id
== group1id
and port
.port_id
== port1id
:
1003 qCritical("PatchCanvas::disconnectPorts(%i) - unable to find output port" % connection_id
)
1006 for port
in canvas
.port_list
:
1007 if port
.group_id
== group2id
and port
.port_id
== port2id
:
1012 qCritical("PatchCanvas::disconnectPorts(%i) - unable to find input port" % connection_id
)
1015 item1p
= item1
.parentItem()
1016 item2p
= item2
.parentItem()
1018 item1p
.removeLineFromGroup(connection_id
)
1020 item2p
.removeLineFromGroup(connection_id
)
1022 if options
.eyecandy
== EYECANDY_FULL
:
1023 CanvasItemFX(line
, False, True)
1026 canvas
.scene
.removeItem(line
)
1029 QTimer
.singleShot(0, canvas
.scene
.update
)
1031 # ------------------------------------------------------------------------------------------------------------
1035 print("PatchCanvas::arrange()")
1037 # ------------------------------------------------------------------------------------------------------------
1039 def updateZValues():
1041 print("PatchCanvas::updateZValues()")
1043 for group
in canvas
.group_list
:
1044 group
.widgets
[0].resetLinesZValue()
1046 if group
.split
and group
.widgets
[1]:
1047 group
.widgets
[1].resetLinesZValue()
1049 # ------------------------------------------------------------------------------------------------------------
1051 def redrawPluginGroup(plugin_id
):
1052 group
= canvas
.group_plugin_map
.get(plugin_id
, None)
1055 #qCritical("PatchCanvas::redrawPluginGroup(%i) - unable to find group" % plugin_id)
1058 group
.widgets
[0].redrawInlineDisplay()
1060 if group
.split
and group
.widgets
[1]:
1061 group
.widgets
[1].redrawInlineDisplay()
1063 def handlePluginRemoved(plugin_id
):
1065 print("PatchCanvas::handlePluginRemoved(%i)" % plugin_id
)
1067 canvas
.scene
.clearSelection()
1069 group
= canvas
.group_plugin_map
.pop(plugin_id
, None)
1071 if group
is not None:
1072 group
.plugin_id
= -1
1073 group
.plugin_ui
= False
1074 group
.plugin_inline
= False
1075 group
.widgets
[0].removeAsPlugin()
1077 if group
.split
and group
.widgets
[1]:
1078 group
.widgets
[1].removeAsPlugin()
1080 for group
in canvas
.group_list
:
1081 if group
.plugin_id
< plugin_id
or group
.plugin_id
> MAX_PLUGIN_ID_ALLOWED
:
1084 group
.plugin_id
-= 1
1085 group
.widgets
[0].m_plugin_id
-= 1
1087 if group
.split
and group
.widgets
[1]:
1088 group
.widgets
[1].m_plugin_id
-= 1
1090 canvas
.group_plugin_map
[plugin_id
] = group
1092 def handleAllPluginsRemoved():
1094 print("PatchCanvas::handleAllPluginsRemoved()")
1096 canvas
.group_plugin_map
= {}
1098 for group
in canvas
.group_list
:
1099 if group
.plugin_id
< 0:
1101 if group
.plugin_id
> MAX_PLUGIN_ID_ALLOWED
:
1104 group
.plugin_id
= -1
1105 group
.plugin_ui
= False
1106 group
.plugin_inline
= False
1107 group
.widgets
[0].removeAsPlugin()
1109 if group
.split
and group
.widgets
[1]:
1110 group
.widgets
[1].removeAsPlugin()
1112 # ------------------------------------------------------------------------------------------------------------