|
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
-
- # PatchBay Canvas engine using QGraphicsView/Scene
- # Copyright (C) 2010-2014 Filipe Coelho <falktx@falktx.com>
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License as
- # published by the Free Software Foundation; either version 2 of
- # the License, or any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # For a full copy of the GNU General Public License see the doc/GPL.txt file.
-
- # ------------------------------------------------------------------------------------------------------------
- # Imports (Config)
-
- from carla_config import *
-
- # ------------------------------------------------------------------------------------------------------------
- # Imports (Global)
-
- from math import floor
-
- if config_UseQt5:
- from PyQt5.QtCore import pyqtSignal, pyqtSlot, qCritical, qFatal, qWarning, Qt, QObject
- from PyQt5.QtCore import QAbstractAnimation, QLineF, QPointF, QRectF, QSizeF, QSettings, QTimer
- from PyQt5.QtGui import QColor, QLinearGradient, QPen, QPolygonF, QPainter, QPainterPath
- from PyQt5.QtGui import QCursor, QFont, QFontMetrics
- from PyQt5.QtSvg import QGraphicsSvgItem, QSvgRenderer
- from PyQt5.QtWidgets import QGraphicsScene, QGraphicsItem, QGraphicsLineItem, QGraphicsPathItem
- from PyQt5.QtWidgets import QGraphicsColorizeEffect, QGraphicsDropShadowEffect, QMenu
- else:
- from PyQt4.QtCore import pyqtSignal, pyqtSlot, qCritical, qFatal, qWarning, Qt, QObject
- from PyQt4.QtCore import QAbstractAnimation, QLineF, QPointF, QRectF, QSizeF, QSettings, QTimer
- from PyQt4.QtGui import QColor, QLinearGradient, QPen, QPolygonF, QPainter, QPainterPath
- from PyQt4.QtGui import QCursor, QFont, QFontMetrics
- from PyQt4.QtGui import QGraphicsScene, QGraphicsItem, QGraphicsLineItem, QGraphicsPathItem
- from PyQt4.QtGui import QGraphicsColorizeEffect, QGraphicsDropShadowEffect, QMenu
- from PyQt4.QtSvg import QGraphicsSvgItem, QSvgRenderer
-
- # ------------------------------------------------------------------------------------------------------------
- # Imports (Theme)
-
- from patchcanvas_theme import *
-
- # ------------------------------------------------------------------------------
- # patchcanvas-api.h
-
- # Maximum Id for a plugin, treated as invalid/zero if above this value
- MAX_PLUGIN_ID_ALLOWED = 0x7FF
-
- # Port Mode
- PORT_MODE_NULL = 0
- PORT_MODE_INPUT = 1
- PORT_MODE_OUTPUT = 2
-
- # Port Type
- PORT_TYPE_NULL = 0
- PORT_TYPE_AUDIO_JACK = 1
- PORT_TYPE_MIDI_JACK = 2
- PORT_TYPE_MIDI_ALSA = 3
- PORT_TYPE_PARAMETER = 4
-
- # Callback Action
- ACTION_GROUP_INFO = 0 # group_id, N, N
- ACTION_GROUP_RENAME = 1 # group_id, N, N
- ACTION_GROUP_SPLIT = 2 # group_id, N, N
- ACTION_GROUP_JOIN = 3 # group_id, N, N
- ACTION_PORT_INFO = 4 # group_id, port_id, N
- ACTION_PORT_RENAME = 5 # group_id, port_id, N
- ACTION_PORTS_CONNECT = 6 # N, N, "outG:outP:inG:inP"
- ACTION_PORTS_DISCONNECT = 7 # conn_id, N, N
- ACTION_PLUGIN_CLONE = 8 # plugin_id, N, N
- ACTION_PLUGIN_EDIT = 9 # plugin_id, N, N
- ACTION_PLUGIN_RENAME = 10 # plugin_id, N, N
- ACTION_PLUGIN_REPLACE = 11 # plugin_id, N, N
- ACTION_PLUGIN_REMOVE = 12 # plugin_id, N, N
- ACTION_PLUGIN_SHOW_UI = 13 # plugin_id, N, N
- ACTION_BG_RIGHT_CLICK = 14 # N, N, N
-
- # Icon
- ICON_APPLICATION = 0
- ICON_HARDWARE = 1
- ICON_DISTRHO = 2
- ICON_FILE = 3
- ICON_PLUGIN = 4
- ICON_LADISH_ROOM = 5
-
- # Split Option
- SPLIT_UNDEF = 0
- SPLIT_NO = 1
- SPLIT_YES = 2
-
- # Antialiasing Option
- ANTIALIASING_NONE = 0
- ANTIALIASING_SMALL = 1
- ANTIALIASING_FULL = 2
-
- # Eye-Candy Option
- EYECANDY_NONE = 0
- EYECANDY_SMALL = 1
- EYECANDY_FULL = 2
-
- # Canvas options
- class options_t(object):
- __slots__ = [
- 'theme_name',
- 'auto_hide_groups',
- 'auto_select_items',
- 'use_bezier_lines',
- 'antialiasing',
- 'eyecandy'
- ]
-
- # Canvas features
- class features_t(object):
- __slots__ = [
- 'group_info',
- 'group_rename',
- 'port_info',
- 'port_rename',
- 'handle_group_pos'
- ]
-
- # ------------------------------------------------------------------------------
- # patchcanvas.h
-
- # object types
- CanvasBoxType = QGraphicsItem.UserType + 1
- CanvasIconType = QGraphicsItem.UserType + 2
- CanvasPortType = QGraphicsItem.UserType + 3
- CanvasLineType = QGraphicsItem.UserType + 4
- CanvasBezierLineType = QGraphicsItem.UserType + 5
- CanvasLineMovType = QGraphicsItem.UserType + 6
- CanvasBezierLineMovType = QGraphicsItem.UserType + 7
-
- # object lists
- class group_dict_t(object):
- __slots__ = [
- 'group_id',
- 'group_name',
- 'split',
- 'icon',
- 'plugin_id',
- 'plugin_ui',
- 'widgets'
- ]
-
- class port_dict_t(object):
- __slots__ = [
- 'group_id',
- 'port_id',
- 'port_name',
- 'port_mode',
- 'port_type',
- 'is_alternate',
- 'widget'
- ]
-
- class connection_dict_t(object):
- __slots__ = [
- 'connection_id',
- 'group_in_id',
- 'port_in_id',
- 'group_out_id',
- 'port_out_id',
- 'widget'
- ]
-
- class animation_dict_t(object):
- __slots__ = [
- 'animation',
- 'item'
- ]
-
- # Main Canvas object
- class Canvas(object):
- __slots__ = [
- 'scene',
- 'callback',
- 'debug',
- 'last_z_value',
- 'last_connection_id',
- 'initial_pos',
- 'size_rect',
- 'group_list',
- 'port_list',
- 'connection_list',
- 'animation_list',
- 'qobject',
- 'settings',
- 'theme',
- 'initiated'
- ]
-
- # ------------------------------------------------------------------------------
- # patchcanvas.cpp
-
- class CanvasObject(QObject):
- def __init__(self, parent=None):
- QObject.__init__(self, parent)
-
- @pyqtSlot()
- def AnimationFinishedShow(self):
- animation = self.sender()
- if animation:
- animation.forceStop()
- canvas.animation_list.remove(animation)
-
- @pyqtSlot()
- def AnimationFinishedHide(self):
- animation = self.sender()
- if animation:
- animation.forceStop()
- canvas.animation_list.remove(animation)
- item = animation.item()
- if item: item.hide()
-
- @pyqtSlot()
- def AnimationFinishedDestroy(self):
- animation = self.sender()
- if animation:
- animation.forceStop()
- canvas.animation_list.remove(animation)
- item = animation.item()
- if item: CanvasRemoveItemFX(item)
-
- @pyqtSlot()
- def PortContextMenuDisconnect(self):
- try:
- connectionId = int(self.sender().data())
- except:
- return
-
- CanvasCallback(ACTION_PORTS_DISCONNECT, connectionId, 0, "")
-
- # Global objects
- canvas = Canvas()
- canvas.qobject = None
- canvas.settings = None
- canvas.theme = None
- canvas.initiated = False
- canvas.group_list = []
- canvas.port_list = []
- canvas.connection_list = []
- canvas.animation_list = []
-
- options = options_t()
- options.theme_name = getDefaultThemeName()
- options.auto_hide_groups = False
- options.auto_select_items = False
- options.use_bezier_lines = True
- options.antialiasing = ANTIALIASING_SMALL
- options.eyecandy = EYECANDY_SMALL
-
- features = features_t()
- features.group_info = False
- features.group_rename = False
- features.port_info = False
- features.port_rename = False
- features.handle_group_pos = False
-
- # Internal functions
- def bool2str(check):
- return "True" if check else "False"
-
- def port_mode2str(port_mode):
- if port_mode == PORT_MODE_NULL:
- return "PORT_MODE_NULL"
- elif port_mode == PORT_MODE_INPUT:
- return "PORT_MODE_INPUT"
- elif port_mode == PORT_MODE_OUTPUT:
- return "PORT_MODE_OUTPUT"
- else:
- return "PORT_MODE_???"
-
- def port_type2str(port_type):
- if port_type == PORT_TYPE_NULL:
- return "PORT_TYPE_NULL"
- elif port_type == PORT_TYPE_AUDIO_JACK:
- return "PORT_TYPE_AUDIO_JACK"
- elif port_type == PORT_TYPE_MIDI_JACK:
- return "PORT_TYPE_MIDI_JACK"
- elif port_type == PORT_TYPE_MIDI_ALSA:
- return "PORT_TYPE_MIDI_ALSA"
- elif port_type == PORT_TYPE_PARAMETER:
- return "PORT_TYPE_MIDI_PARAMETER"
- else:
- return "PORT_TYPE_???"
-
- def icon2str(icon):
- if icon == ICON_APPLICATION:
- return "ICON_APPLICATION"
- elif icon == ICON_HARDWARE:
- return "ICON_HARDWARE"
- elif icon == ICON_DISTRHO:
- return "ICON_DISTRHO"
- elif icon == ICON_FILE:
- return "ICON_FILE"
- elif icon == ICON_PLUGIN:
- return "ICON_PLUGIN"
- elif icon == ICON_LADISH_ROOM:
- return "ICON_LADISH_ROOM"
- else:
- return "ICON_???"
-
- def split2str(split):
- if split == SPLIT_UNDEF:
- return "SPLIT_UNDEF"
- elif split == SPLIT_NO:
- return "SPLIT_NO"
- elif split == SPLIT_YES:
- return "SPLIT_YES"
- else:
- return "SPLIT_???"
-
- def getStoredCanvasPosition(key, fallback_pos):
- try:
- return canvas.settings.value("CanvasPositions/" + key, fallback_pos, type=QPointF)
- except:
- return fallback_pos
-
- def getStoredCanvasSplit(group_name, fallback_split_mode):
- try:
- return canvas.settings.value("CanvasPositions/%s_SPLIT" % group_name, fallback_split_mode, type=int)
- except:
- return fallback_split_mode
-
- # PatchCanvas API
- def setOptions(new_options):
- if canvas.initiated: return
- options.theme_name = new_options.theme_name
- options.auto_hide_groups = new_options.auto_hide_groups
- options.auto_select_items = new_options.auto_select_items
- options.use_bezier_lines = new_options.use_bezier_lines
- options.antialiasing = new_options.antialiasing
- options.eyecandy = new_options.eyecandy
-
- def setFeatures(new_features):
- if canvas.initiated: return
- features.group_info = new_features.group_info
- features.group_rename = new_features.group_rename
- features.port_info = new_features.port_info
- features.port_rename = new_features.port_rename
- features.handle_group_pos = new_features.handle_group_pos
-
- def init(appName, scene, callback, debug=False):
- if debug:
- print("PatchCanvas::init(\"%s\", %s, %s, %s)" % (appName, scene, callback, bool2str(debug)))
-
- if canvas.initiated:
- qCritical("PatchCanvas::init() - already initiated")
- return
-
- if not callback:
- qFatal("PatchCanvas::init() - fatal error: callback not set")
- return
-
- canvas.scene = scene
- canvas.callback = callback
- canvas.debug = debug
-
- canvas.last_z_value = 0
- canvas.last_connection_id = 0
- canvas.initial_pos = QPointF(0, 0)
- canvas.size_rect = QRectF()
-
- if not canvas.qobject: canvas.qobject = CanvasObject()
- if not canvas.settings: canvas.settings = QSettings("falkTX", appName)
-
- if canvas.theme:
- del canvas.theme
- canvas.theme = None
-
- for i in range(Theme.THEME_MAX):
- this_theme_name = getThemeName(i)
- if this_theme_name == options.theme_name:
- canvas.theme = Theme(i)
- break
-
- if not canvas.theme:
- canvas.theme = Theme(getDefaultTheme())
-
- canvas.scene.updateTheme()
-
- canvas.initiated = True
-
- def clear():
- if canvas.debug:
- print("PatchCanvas::clear()")
-
- group_list_ids = []
- port_list_ids = []
- connection_list_ids = []
-
- for group in canvas.group_list:
- group_list_ids.append(group.group_id)
-
- for port in canvas.port_list:
- port_list_ids.append((port.group_id, port.port_id))
-
- for connection in canvas.connection_list:
- connection_list_ids.append(connection.connection_id)
-
- for idx in connection_list_ids:
- disconnectPorts(idx)
-
- for group_id, port_id in port_list_ids:
- removePort(group_id, port_id)
-
- for idx in group_list_ids:
- removeGroup(idx)
-
- canvas.last_z_value = 0
- canvas.last_connection_id = 0
-
- canvas.group_list = []
- canvas.port_list = []
- canvas.connection_list = []
-
- canvas.scene.clearSelection()
-
- animatedItems = []
- for animation in canvas.animation_list:
- animatedItems.append(animation.item())
-
- for item in canvas.scene.items():
- if item.type() != CanvasIconType and item not in animatedItems:
- canvas.scene.removeItem(item)
- del item
-
- canvas.initiated = False
-
- QTimer.singleShot(0, canvas.scene.update)
-
- def setInitialPos(x, y):
- if canvas.debug:
- print("PatchCanvas::setInitialPos(%i, %i)" % (x, y))
-
- canvas.initial_pos.setX(x)
- canvas.initial_pos.setY(y)
-
- def setCanvasSize(x, y, width, height):
- if canvas.debug:
- print("PatchCanvas::setCanvasSize(%i, %i, %i, %i)" % (x, y, width, height))
-
- canvas.size_rect.setX(x)
- canvas.size_rect.setY(y)
- canvas.size_rect.setWidth(width)
- canvas.size_rect.setHeight(height)
-
- def addGroup(group_id, group_name, split=SPLIT_UNDEF, icon=ICON_APPLICATION):
- if canvas.debug:
- print("PatchCanvas::addGroup(%i, %s, %s, %s)" % (group_id, group_name.encode(), split2str(split), icon2str(icon)))
-
- for group in canvas.group_list:
- if group.group_id == group_id:
- qWarning("PatchCanvas::addGroup(%i, %s, %s, %s) - group already exists" % (group_id, group_name.encode(), split2str(split), icon2str(icon)))
- return
-
- if split == SPLIT_UNDEF:
- isHardware = bool(icon == ICON_HARDWARE)
-
- if features.handle_group_pos:
- split = getStoredCanvasSplit(group_name, SPLIT_YES if isHardware else split)
- elif isHardware:
- split = SPLIT_YES
-
- group_box = CanvasBox(group_id, group_name, icon)
-
- group_dict = group_dict_t()
- group_dict.group_id = group_id
- group_dict.group_name = group_name
- group_dict.split = bool(split == SPLIT_YES)
- group_dict.icon = icon
- group_dict.plugin_id = -1
- group_dict.plugin_ui = False
- group_dict.widgets = [group_box, None]
-
- if split == SPLIT_YES:
- group_box.setSplit(True, PORT_MODE_OUTPUT)
-
- if features.handle_group_pos:
- group_box.setPos(getStoredCanvasPosition(group_name + "_OUTPUT", CanvasGetNewGroupPos(False)))
- else:
- group_box.setPos(CanvasGetNewGroupPos(False))
-
- group_sbox = CanvasBox(group_id, group_name, icon)
- group_sbox.setSplit(True, PORT_MODE_INPUT)
-
- group_dict.widgets[1] = group_sbox
-
- if features.handle_group_pos:
- group_sbox.setPos(getStoredCanvasPosition(group_name + "_INPUT", CanvasGetNewGroupPos(True)))
- else:
- group_sbox.setPos(CanvasGetNewGroupPos(True))
-
- canvas.last_z_value += 1
- group_sbox.setZValue(canvas.last_z_value)
-
- if options.eyecandy == EYECANDY_FULL and not options.auto_hide_groups:
- CanvasItemFX(group_sbox, True, False)
-
- group_sbox.checkItemPos()
-
- else:
- group_box.setSplit(False)
-
- if features.handle_group_pos:
- group_box.setPos(getStoredCanvasPosition(group_name, CanvasGetNewGroupPos(False)))
- else:
- # Special ladish fake-split groups
- horizontal = bool(icon == ICON_HARDWARE or icon == ICON_LADISH_ROOM)
- group_box.setPos(CanvasGetNewGroupPos(horizontal))
-
- group_box.checkItemPos()
-
- canvas.last_z_value += 1
- group_box.setZValue(canvas.last_z_value)
-
- canvas.group_list.append(group_dict)
-
- if options.eyecandy == EYECANDY_FULL and not options.auto_hide_groups:
- return CanvasItemFX(group_box, True, False)
-
- QTimer.singleShot(0, canvas.scene.update)
-
- def removeGroup(group_id):
- if canvas.debug:
- print("PatchCanvas::removeGroup(%i)" % group_id)
-
- for group in canvas.group_list:
- if group.group_id == group_id:
- item = group.widgets[0]
- group_name = group.group_name
-
- if group.split:
- s_item = group.widgets[1]
-
- if features.handle_group_pos:
- canvas.settings.setValue("CanvasPositions/%s_OUTPUT" % group_name, item.pos())
- canvas.settings.setValue("CanvasPositions/%s_INPUT" % group_name, s_item.pos())
- canvas.settings.setValue("CanvasPositions/%s_SPLIT" % group_name, SPLIT_YES)
-
- if options.eyecandy == EYECANDY_FULL:
- CanvasItemFX(s_item, False, True)
- else:
- s_item.removeIconFromScene()
- canvas.scene.removeItem(s_item)
- del s_item
-
- else:
- if features.handle_group_pos:
- canvas.settings.setValue("CanvasPositions/%s" % group_name, item.pos())
- canvas.settings.setValue("CanvasPositions/%s_SPLIT" % group_name, SPLIT_NO)
-
- if options.eyecandy == EYECANDY_FULL:
- CanvasItemFX(item, False, True)
- else:
- item.removeIconFromScene()
- canvas.scene.removeItem(item)
- del item
-
- canvas.group_list.remove(group)
-
- QTimer.singleShot(0, canvas.scene.update)
- return
-
- qCritical("PatchCanvas::removeGroup(%i) - unable to find group to remove" % group_id)
-
- def renameGroup(group_id, new_group_name):
- if canvas.debug:
- print("PatchCanvas::renameGroup(%i, %s)" % (group_id, new_group_name.encode()))
-
- for group in canvas.group_list:
- if group.group_id == group_id:
- group.group_name = new_group_name
- group.widgets[0].setGroupName(new_group_name)
-
- if group.split and group.widgets[1]:
- group.widgets[1].setGroupName(new_group_name)
-
- QTimer.singleShot(0, canvas.scene.update)
- return
-
- qCritical("PatchCanvas::renameGroup(%i, %s) - unable to find group to rename" % (group_id, new_group_name.encode()))
-
- def splitGroup(group_id):
- if canvas.debug:
- print("PatchCanvas::splitGroup(%i)" % group_id)
-
- item = None
- group_name = ""
- group_icon = ICON_APPLICATION
- plugin_id = -1
- plugin_ui = False
- ports_data = []
- conns_data = []
-
- # Step 1 - Store all Item data
- for group in canvas.group_list:
- if group.group_id == group_id:
- if group.split:
- qCritical("PatchCanvas::splitGroup(%i) - group is already splitted" % group_id)
- return
-
- item = group.widgets[0]
- group_name = group.group_name
- group_icon = group.icon
- plugin_id = group.plugin_id
- plugin_ui = group.plugin_ui
- break
-
- if not item:
- qCritical("PatchCanvas::splitGroup(%i) - unable to find group to split" % group_id)
- return
-
- port_list_ids = list(item.getPortList())
-
- for port in canvas.port_list:
- if port.port_id in port_list_ids:
- port_dict = port_dict_t()
- port_dict.group_id = port.group_id
- port_dict.port_id = port.port_id
- port_dict.port_name = port.port_name
- port_dict.port_mode = port.port_mode
- port_dict.port_type = port.port_type
- port_dict.is_alternate = port.is_alternate
- port_dict.widget = None
- ports_data.append(port_dict)
-
- for connection in canvas.connection_list:
- if connection.port_out_id in port_list_ids or connection.port_in_id in port_list_ids:
- connection_dict = connection_dict_t()
- connection_dict.connection_id = connection.connection_id
- connection_dict.group_in_id = connection.group_in_id
- connection_dict.port_in_id = connection.port_in_id
- connection_dict.group_out_id = connection.group_out_id
- connection_dict.port_out_id = connection.port_out_id
- connection_dict.widget = None
- conns_data.append(connection_dict)
-
- # Step 2 - Remove Item and Children
- for conn in conns_data:
- disconnectPorts(conn.connection_id)
-
- for port_id in port_list_ids:
- removePort(group_id, port_id)
-
- removeGroup(group_id)
-
- # Step 3 - Re-create Item, now splitted
- addGroup(group_id, group_name, SPLIT_YES, group_icon)
-
- if plugin_id >= 0:
- setGroupAsPlugin(group_id, plugin_id, plugin_ui)
-
- for port in ports_data:
- addPort(group_id, port.port_id, port.port_name, port.port_mode, port.port_type, port.is_alternate)
-
- for conn in conns_data:
- connectPorts(conn.connection_id, conn.group_out_id, conn.port_out_id, conn.group_in_id, conn.port_in_id)
-
- QTimer.singleShot(0, canvas.scene.update)
-
- def joinGroup(group_id):
- if canvas.debug:
- print("PatchCanvas::joinGroup(%i)" % group_id)
-
- item = None
- s_item = None
- group_name = ""
- group_icon = ICON_APPLICATION
- plugin_id = -1
- plugin_ui = False
- ports_data = []
- conns_data = []
-
- # Step 1 - Store all Item data
- for group in canvas.group_list:
- if group.group_id == group_id:
- if not group.split:
- qCritical("PatchCanvas::joinGroup(%i) - group is not splitted" % group_id)
- return
-
- item = group.widgets[0]
- s_item = group.widgets[1]
- group_name = group.group_name
- group_icon = group.icon
- plugin_id = group.plugin_id
- plugin_ui = group.plugin_ui
- break
-
- # FIXME
- if not (item and s_item):
- qCritical("PatchCanvas::joinGroup(%i) - unable to find groups to join" % group_id)
- return
-
- port_list_ids = list(item.getPortList())
- port_list_idss = s_item.getPortList()
-
- for port_id in port_list_idss:
- if port_id not in port_list_ids:
- port_list_ids.append(port_id)
-
- for port in canvas.port_list:
- if port.port_id in port_list_ids:
- port_dict = port_dict_t()
- port_dict.group_id = port.group_id
- port_dict.port_id = port.port_id
- port_dict.port_name = port.port_name
- port_dict.port_mode = port.port_mode
- port_dict.port_type = port.port_type
- port_dict.is_alternate = port.is_alternate
- port_dict.widget = None
- ports_data.append(port_dict)
-
- for connection in canvas.connection_list:
- if connection.port_out_id in port_list_ids or connection.port_in_id in port_list_ids:
- connection_dict = connection_dict_t()
- connection_dict.connection_id = connection.connection_id
- connection_dict.group_in_id = connection.group_in_id
- connection_dict.port_in_id = connection.port_in_id
- connection_dict.group_out_id = connection.group_out_id
- connection_dict.port_out_id = connection.port_out_id
- connection_dict.widget = None
- conns_data.append(connection_dict)
-
- # Step 2 - Remove Item and Children
- for conn in conns_data:
- disconnectPorts(conn.connection_id)
-
- for port_id in port_list_ids:
- removePort(group_id, port_id)
-
- removeGroup(group_id)
-
- # Step 3 - Re-create Item, now together
- addGroup(group_id, group_name, SPLIT_NO, group_icon)
-
- if plugin_id >= 0:
- setGroupAsPlugin(group_id, plugin_id, plugin_ui)
-
- for port in ports_data:
- addPort(group_id, port.port_id, port.port_name, port.port_mode, port.port_type, port.is_alternate)
-
- for conn in conns_data:
- connectPorts(conn.connection_id, conn.group_out_id, conn.port_out_id, conn.group_in_id, conn.port_in_id)
-
- QTimer.singleShot(0, canvas.scene.update)
-
- def getGroupPos(group_id, port_mode=PORT_MODE_OUTPUT):
- if canvas.debug:
- print("PatchCanvas::getGroupPos(%i, %s)" % (group_id, port_mode2str(port_mode)))
-
- for group in canvas.group_list:
- if group.group_id == group_id:
- if group.split:
- if port_mode == PORT_MODE_OUTPUT:
- return group.widgets[0].pos()
- elif port_mode == PORT_MODE_INPUT:
- return group.widgets[1].pos()
- else:
- return QPointF(0, 0)
- else:
- return group.widgets[0].pos()
-
- qCritical("PatchCanvas::getGroupPos(%i, %s) - unable to find group" % (group_id, port_mode2str(port_mode)))
- return QPointF(0, 0)
-
- def saveGroupPositions():
- if canvas.debug:
- print("PatchCanvas::getGroupPositions()")
-
- ret = []
-
- for group in canvas.group_list:
- if group.split:
- pos1 = group.widgets[0].pos()
- pos2 = group.widgets[1].pos()
- else:
- pos1 = group.widgets[0].pos()
- pos2 = QPointF(0, 0)
-
- ret.append({
- "name" : group.group_name,
- "pos1x": pos1.x(),
- "pos1y": pos1.y(),
- "pos2x": pos2.x(),
- "pos2y": pos2.y(),
- "split": group.split,
- })
-
- return ret
-
- def restoreGroupPositions(dataList):
- if canvas.debug:
- print("PatchCanvas::restoreGroupPositions(...)")
-
- map = {}
-
- for group in canvas.group_list:
- map[group.group_name] = group
-
- for data in dataList:
- name = data['name']
- group = map.get(name, None)
-
- if group is None:
- continue
-
- group.widgets[0].setPos(data['pos1x'], data['pos1y'])
-
- if group.split and group.widgets[1]:
- group.widgets[1].setPos(data['pos2x'], data['pos2y'])
-
- def setGroupPos(group_id, group_pos_x, group_pos_y):
- setGroupPosFull(group_id, group_pos_x, group_pos_y, group_pos_x, group_pos_y)
-
- def setGroupPosFull(group_id, group_pos_x_o, group_pos_y_o, group_pos_x_i, group_pos_y_i):
- if canvas.debug:
- print("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))
-
- for group in canvas.group_list:
- if group.group_id == group_id:
- group.widgets[0].setPos(group_pos_x_o, group_pos_y_o)
-
- if group.split and group.widgets[1]:
- group.widgets[1].setPos(group_pos_x_i, group_pos_y_i)
-
- QTimer.singleShot(0, canvas.scene.update)
- return
-
- 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))
-
- def setGroupIcon(group_id, icon):
- if canvas.debug:
- print("PatchCanvas::setGroupIcon(%i, %s)" % (group_id, icon2str(icon)))
-
- for group in canvas.group_list:
- if group.group_id == group_id:
- group.icon = icon
- group.widgets[0].setIcon(icon)
-
- if group.split and group.widgets[1]:
- group.widgets[1].setIcon(icon)
-
- QTimer.singleShot(0, canvas.scene.update)
- return
-
- qCritical("PatchCanvas::setGroupIcon(%i, %s) - unable to find group to change icon" % (group_id, icon2str(icon)))
-
- def setGroupAsPlugin(group_id, plugin_id, hasUi):
- if canvas.debug:
- print("PatchCanvas::setGroupAsPlugin(%i, %i, %s)" % (group_id, plugin_id, bool2str(hasUi)))
-
- for group in canvas.group_list:
- if group.group_id == group_id:
- group.plugin_id = plugin_id
- group.plugin_ui = hasUi
- group.widgets[0].setAsPlugin(plugin_id, hasUi)
-
- if group.split and group.widgets[1]:
- group.widgets[1].setAsPlugin(plugin_id, hasUi)
- return
-
- qCritical("PatchCanvas::setGroupAsPlugin(%i, %i, %s) - unable to find group to set as plugin" % (group_id, plugin_id, bool2str(hasUi)))
-
- def addPort(group_id, port_id, port_name, port_mode, port_type, is_alternate=False):
- if canvas.debug:
- print("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)))
-
- for port in canvas.port_list:
- if port.group_id == group_id and port.port_id == port_id:
- 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)))
- return
-
- box_widget = None
- port_widget = None
-
- for group in canvas.group_list:
- if group.group_id == group_id:
- if group.split and group.widgets[0].getSplittedMode() != port_mode and group.widgets[1]:
- n = 1
- else:
- n = 0
- box_widget = group.widgets[n]
- port_widget = box_widget.addPortFromGroup(port_id, port_mode, port_type, port_name, is_alternate)
- break
-
- if not (box_widget and port_widget):
- 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)))
- return
-
- port_dict = port_dict_t()
- port_dict.group_id = group_id
- port_dict.port_id = port_id
- port_dict.port_name = port_name
- port_dict.port_mode = port_mode
- port_dict.port_type = port_type
- port_dict.is_alternate = is_alternate
- port_dict.widget = port_widget
- canvas.port_list.append(port_dict)
-
- box_widget.updatePositions()
-
- if options.eyecandy == EYECANDY_FULL:
- return CanvasItemFX(port_widget, True, False)
-
- QTimer.singleShot(0, canvas.scene.update)
-
- def removePort(group_id, port_id):
- if canvas.debug:
- print("PatchCanvas::removePort(%i, %i)" % (group_id, port_id))
-
- for port in canvas.port_list:
- if port.group_id == group_id and port.port_id == port_id:
- item = port.widget
- item.parentItem().removePortFromGroup(port_id)
- canvas.scene.removeItem(item)
- canvas.port_list.remove(port)
- del item
-
- QTimer.singleShot(0, canvas.scene.update)
- return
-
- qCritical("PatchCanvas::removePort(%i, %i) - Unable to find port to remove" % (group_id, port_id))
-
- def renamePort(group_id, port_id, new_port_name):
- if canvas.debug:
- print("PatchCanvas::renamePort(%i, %i, %s)" % (group_id, port_id, new_port_name.encode()))
-
- for port in canvas.port_list:
- if port.group_id == group_id and port.port_id == port_id:
- port.port_name = new_port_name
- port.widget.setPortName(new_port_name)
- port.widget.parentItem().updatePositions()
-
- QTimer.singleShot(0, canvas.scene.update)
- return
-
- qCritical("PatchCanvas::renamePort(%i, %i, %s) - Unable to find port to rename" % (group_id, port_id, new_port_name.encode()))
-
- def connectPorts(connection_id, group_out_id, port_out_id, group_in_id, port_in_id):
- if canvas.debug:
- print("PatchCanvas::connectPorts(%i, %i, %i, %i, %i)" % (connection_id, group_out_id, port_out_id, group_in_id, port_in_id))
-
- port_out = None
- port_in = None
- port_out_parent = None
- port_in_parent = None
-
- for port in canvas.port_list:
- if port.group_id == group_out_id and port.port_id == port_out_id:
- port_out = port.widget
- port_out_parent = port_out.parentItem()
- elif port.group_id == group_in_id and port.port_id == port_in_id:
- port_in = port.widget
- port_in_parent = port_in.parentItem()
-
- # FIXME
- if not (port_out and port_in):
- 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))
- return
-
- connection_dict = connection_dict_t()
- connection_dict.connection_id = connection_id
- connection_dict.group_in_id = group_in_id
- connection_dict.port_in_id = port_in_id
- connection_dict.group_out_id = group_out_id
- connection_dict.port_out_id = port_out_id
-
- if options.use_bezier_lines:
- connection_dict.widget = CanvasBezierLine(port_out, port_in, None)
- else:
- connection_dict.widget = CanvasLine(port_out, port_in, None)
-
- canvas.scene.addItem(connection_dict.widget)
-
- port_out_parent.addLineFromGroup(connection_dict.widget, connection_id)
- port_in_parent.addLineFromGroup(connection_dict.widget, connection_id)
-
- canvas.last_z_value += 1
- port_out_parent.setZValue(canvas.last_z_value)
- port_in_parent.setZValue(canvas.last_z_value)
-
- canvas.last_z_value += 1
- connection_dict.widget.setZValue(canvas.last_z_value)
-
- canvas.connection_list.append(connection_dict)
-
- if options.eyecandy == EYECANDY_FULL:
- item = connection_dict.widget
- return CanvasItemFX(item, True, False)
-
- QTimer.singleShot(0, canvas.scene.update)
-
- def disconnectPorts(connection_id):
- if canvas.debug:
- print("PatchCanvas::disconnectPorts(%i)" % connection_id)
-
- line = None
- item1 = None
- item2 = None
- group1id = port1id = 0
- group2id = port2id = 0
-
- for connection in canvas.connection_list:
- if connection.connection_id == connection_id:
- group1id = connection.group_out_id
- group2id = connection.group_in_id
- port1id = connection.port_out_id
- port2id = connection.port_in_id
- line = connection.widget
- canvas.connection_list.remove(connection)
- break
-
- if not line:
- qCritical("PatchCanvas::disconnectPorts(%i) - unable to find connection ports" % connection_id)
- return
-
- for port in canvas.port_list:
- if port.group_id == group1id and port.port_id == port1id:
- item1 = port.widget
- break
-
- if not item1:
- qCritical("PatchCanvas::disconnectPorts(%i) - unable to find output port" % connection_id)
- return
-
- for port in canvas.port_list:
- if port.group_id == group2id and port.port_id == port2id:
- item2 = port.widget
- break
-
- if not item2:
- qCritical("PatchCanvas::disconnectPorts(%i) - unable to find input port" % connection_id)
- return
-
- item1.parentItem().removeLineFromGroup(connection_id)
- item2.parentItem().removeLineFromGroup(connection_id)
-
- if options.eyecandy == EYECANDY_FULL:
- return CanvasItemFX(line, False, True)
-
- canvas.scene.removeItem(line)
- del line
-
- QTimer.singleShot(0, canvas.scene.update)
-
- def arrange():
- if canvas.debug:
- print("PatchCanvas::arrange()")
-
- def updateZValues():
- if canvas.debug:
- print("PatchCanvas::updateZValues()")
-
- for group in canvas.group_list:
- group.widgets[0].resetLinesZValue()
-
- if group.split and group.widgets[1]:
- group.widgets[1].resetLinesZValue()
-
- def handlePluginRemoved(plugin_id):
- if canvas.debug:
- print("PatchCanvas::handlePluginRemoved(%i)" % plugin_id)
-
- for group in canvas.group_list:
- if group.plugin_id < plugin_id or group.plugin_id > MAX_PLUGIN_ID_ALLOWED:
- continue
-
- group.plugin_id -= 1
- group.widgets[0].m_plugin_id -= 1
-
- if group.split and group.widgets[1]:
- group.widgets[1].m_plugin_id -= 1
-
- def handleAllPluginsRemoved():
- if canvas.debug:
- print("PatchCanvas::handleAllPluginsRemoved()")
-
- for group in canvas.group_list:
- if group.plugin_id > MAX_PLUGIN_ID_ALLOWED:
- continue
-
- group.plugin_id = -1
- group.plugin_ui = False
- group.widgets[0].m_plugin_id = -1
- group.widgets[0].m_plugin_ui = False
-
- if group.split and group.widgets[1]:
- group.widgets[1].m_plugin_id = -1
- group.widgets[1].m_plugin_ui = False
-
- # Extra Internal functions
-
- def CanvasGetNewGroupPos(horizontal):
- if canvas.debug:
- print("PatchCanvas::CanvasGetNewGroupPos(%s)" % bool2str(horizontal))
-
- new_pos = QPointF(canvas.initial_pos.x(), canvas.initial_pos.y())
- items = canvas.scene.items()
-
- break_loop = False
- while not break_loop:
- break_for = False
- for i in range(len(items)):
- item = items[i]
- if item and item.type() == CanvasBoxType:
- if item.sceneBoundingRect().contains(new_pos):
- if horizontal:
- new_pos += QPointF(item.boundingRect().width() + 15, 0)
- else:
- new_pos += QPointF(0, item.boundingRect().height() + 15)
- break_for = True
- break
-
- if i >= len(items) - 1 and not break_for:
- break_loop = True
-
- return new_pos
-
- def CanvasGetFullPortName(group_id, port_id):
- if canvas.debug:
- print("PatchCanvas::CanvasGetFullPortName(%i, %i)" % (group_id, port_id))
-
- for port in canvas.port_list:
- if port.group_id == group_id and port.port_id == port_id:
- group_id = port.group_id
- for group in canvas.group_list:
- if group.group_id == group_id:
- return group.group_name + ":" + port.port_name
- break
-
- qCritical("PatchCanvas::CanvasGetFullPortName(%i, %i) - unable to find port" % (group_id, port_id))
- return ""
-
- def CanvasGetPortConnectionList(group_id, port_id):
- if canvas.debug:
- print("PatchCanvas::CanvasGetPortConnectionList(%i, %i)" % (group_id, port_id))
-
- conn_list = []
-
- for connection in canvas.connection_list:
- if connection.group_out_id == group_id and connection.port_out_id == port_id:
- conn_list.append((connection.connection_id, connection.group_in_id, connection.port_in_id))
- elif connection.group_in_id == group_id and connection.port_in_id == port_id:
- conn_list.append((connection.connection_id, connection.group_out_id, connection.port_out_id))
-
- return conn_list
-
- def CanvasCallback(action, value1, value2, value_str):
- if canvas.debug:
- print("PatchCanvas::CanvasCallback(%i, %i, %i, %s)" % (action, value1, value2, value_str.encode()))
-
- canvas.callback(action, value1, value2, value_str)
-
- def CanvasItemFX(item, show, destroy):
- if canvas.debug:
- print("PatchCanvas::CanvasItemFX(%s, %s, %s)" % (item, bool2str(show), bool2str(destroy)))
-
- # Check if the item already has an animation
- for animation in canvas.animation_list:
- if animation.item() == item:
- animation.forceStop()
- canvas.animation_list.remove(animation)
- del animation
- break
-
- animation = CanvasFadeAnimation(item, show)
- animation.setDuration(750 if show else 500)
-
- if show:
- animation.finished.connect(canvas.qobject.AnimationFinishedShow)
- else:
- if destroy:
- animation.finished.connect(canvas.qobject.AnimationFinishedDestroy)
- else:
- animation.finished.connect(canvas.qobject.AnimationFinishedHide)
-
- canvas.animation_list.append(animation)
-
- animation.start()
-
- def CanvasRemoveItemFX(item):
- if canvas.debug:
- print("PatchCanvas::CanvasRemoveItemFX(%s)" % item)
-
- if item.type() == CanvasBoxType:
- item.removeIconFromScene()
-
- canvas.scene.removeItem(item)
- del item
-
- QTimer.singleShot(0, canvas.scene.update)
-
- # ------------------------------------------------------------------------------
- # patchscene.cpp
-
- class PatchScene(QGraphicsScene):
- scaleChanged = pyqtSignal(float)
- sceneGroupMoved = pyqtSignal(int, int, QPointF)
- pluginSelected = pyqtSignal(list)
-
- def __init__(self, parent, view):
- QGraphicsScene.__init__(self, parent)
-
- self.m_ctrl_down = False
- self.m_mouse_down_init = False
- self.m_mouse_rubberband = False
- self.m_mid_button_down = False
- self.m_pointer_border = QRectF(0.0, 0.0, 1.0, 1.0)
-
- self.addRubberBand()
-
- self.m_view = view
- if not self.m_view:
- qFatal("PatchCanvas::PatchScene() - invalid view")
-
- self.selectionChanged.connect(self.slot_selectionChanged)
-
- def addRubberBand(self):
- self.m_rubberband = self.addRect(QRectF(0, 0, 0, 0))
- self.m_rubberband.setZValue(-1)
- self.m_rubberband.hide()
- self.m_rubberband_selection = False
- self.m_rubberband_orig_point = QPointF(0, 0)
-
- def clear(self):
- QGraphicsScene.clear(self)
-
- # Re-add rubberband, that just got deleted
- self.addRubberBand()
-
- def fixScaleFactor(self):
- scale = self.m_view.transform().m11()
- if scale > 3.0:
- self.m_view.resetTransform()
- self.m_view.scale(3.0, 3.0)
- elif scale < 0.2:
- self.m_view.resetTransform()
- self.m_view.scale(0.2, 0.2)
- self.scaleChanged.emit(self.m_view.transform().m11())
-
- def updateTheme(self):
- self.setBackgroundBrush(canvas.theme.canvas_bg)
- self.m_rubberband.setPen(canvas.theme.rubberband_pen)
- self.m_rubberband.setBrush(canvas.theme.rubberband_brush)
-
- def zoom_fit(self):
- min_x = min_y = max_x = max_y = None
- first_value = True
-
- items_list = self.items()
-
- if len(items_list) > 0:
- for item in items_list:
- if item and item.isVisible() and item.type() == CanvasBoxType:
- pos = item.scenePos()
- rect = item.boundingRect()
-
- if first_value:
- min_x = pos.x()
- elif pos.x() < min_x:
- min_x = pos.x()
-
- if first_value:
- min_y = pos.y()
- elif pos.y() < min_y:
- min_y = pos.y()
-
- if first_value:
- max_x = pos.x() + rect.width()
- elif pos.x() + rect.width() > max_x:
- max_x = pos.x() + rect.width()
-
- if first_value:
- max_y = pos.y() + rect.height()
- elif pos.y() + rect.height() > max_y:
- max_y = pos.y() + rect.height()
-
- first_value = False
-
- if not first_value:
- self.m_view.fitInView(min_x, min_y, abs(max_x - min_x), abs(max_y - min_y), Qt.KeepAspectRatio)
- self.fixScaleFactor()
-
- def zoom_in(self):
- if self.m_view.transform().m11() < 3.0:
- self.m_view.scale(1.2, 1.2)
- self.scaleChanged.emit(self.m_view.transform().m11())
-
- def zoom_out(self):
- if self.m_view.transform().m11() > 0.2:
- self.m_view.scale(0.8, 0.8)
- self.scaleChanged.emit(self.m_view.transform().m11())
-
- def zoom_reset(self):
- self.m_view.resetTransform()
- self.scaleChanged.emit(1.0)
-
- @pyqtSlot()
- def slot_selectionChanged(self):
- items_list = self.selectedItems()
-
- if len(items_list) == 0:
- self.pluginSelected.emit([])
- return
-
- plugin_list = []
-
- for item in items_list:
- if item and item.isVisible():
- group_item = None
-
- if item.type() == CanvasBoxType:
- group_item = item
- elif item.type() == CanvasPortType:
- group_item = item.parentItem()
- #elif item.type() in (CanvasLineType, CanvasBezierLineType, CanvasLineMovType, CanvasBezierLineMovType):
- #plugin_list = []
- #break
-
- if group_item is not None and group_item.m_plugin_id >= 0:
- plugin_id = group_item.m_plugin_id
- if plugin_id > MAX_PLUGIN_ID_ALLOWED:
- plugin_id = 0
- plugin_list.append(plugin_id)
-
- self.pluginSelected.emit(plugin_list)
-
- def keyPressEvent(self, event):
- if not self.m_view:
- return event.ignore()
-
- if event.key() == Qt.Key_Control:
- self.m_ctrl_down = True
-
- elif event.key() == Qt.Key_Home:
- self.zoom_fit()
- return event.accept()
-
- elif self.m_ctrl_down:
- if event.key() == Qt.Key_Plus:
- self.zoom_in()
- return event.accept()
- elif event.key() == Qt.Key_Minus:
- self.zoom_out()
- return event.accept()
- elif event.key() == Qt.Key_1:
- self.zoom_reset()
- return event.accept()
-
- QGraphicsScene.keyPressEvent(self, event)
-
- def keyReleaseEvent(self, event):
- if event.key() == Qt.Key_Control:
- self.m_ctrl_down = False
- QGraphicsScene.keyReleaseEvent(self, event)
-
- def mousePressEvent(self, event):
- self.m_mouse_down_init = bool(event.button() == Qt.LeftButton)
- self.m_mouse_rubberband = False
- if event.button() == Qt.MidButton and self.m_ctrl_down:
- self.m_mid_button_down = True
- pos = event.scenePos()
- self.m_pointer_border.moveTo(floor(pos.x()), floor(pos.y()))
-
- items = self.items(self.m_pointer_border)
- for item in items:
- if item and item.type() in [CanvasLineType, CanvasBezierLineType]:
- item.triggerDisconnect()
- QGraphicsScene.mousePressEvent(self, event)
-
- def mouseMoveEvent(self, event):
- if self.m_mouse_down_init:
- self.m_mouse_down_init = False
- self.m_mouse_rubberband = bool(len(self.selectedItems()) == 0)
-
- if self.m_mouse_rubberband:
- if not self.m_rubberband_selection:
- self.m_rubberband.show()
- self.m_rubberband_selection = True
- self.m_rubberband_orig_point = event.scenePos()
-
- pos = event.scenePos()
-
- if pos.x() > self.m_rubberband_orig_point.x():
- x = self.m_rubberband_orig_point.x()
- else:
- x = pos.x()
-
- if pos.y() > self.m_rubberband_orig_point.y():
- y = self.m_rubberband_orig_point.y()
- else:
- y = pos.y()
-
- lineHinting = canvas.theme.rubberband_pen.widthF() / 2
- self.m_rubberband.setRect(x+lineHinting, y+lineHinting, abs(pos.x() - self.m_rubberband_orig_point.x()), abs(pos.y() - self.m_rubberband_orig_point.y()))
- return event.accept()
-
- if self.m_mid_button_down and self.m_ctrl_down:
- trail = QPolygonF([event.scenePos(), event.lastScenePos(), event.scenePos()])
- items = self.items(trail)
- for item in items:
- if item and item.type() in [CanvasLineType, CanvasBezierLineType]:
- item.triggerDisconnect()
-
- QGraphicsScene.mouseMoveEvent(self, event)
-
- def mouseReleaseEvent(self, event):
- if event.button() == Qt.MidButton:
- self.m_mid_button_down = False
- return event.accept()
-
- if self.m_rubberband_selection:
- items_list = self.items()
- if len(items_list) > 0:
- for item in items_list:
- if item and item.isVisible() and item.type() == CanvasBoxType:
- item_rect = item.sceneBoundingRect()
- item_top_left = QPointF(item_rect.x(), item_rect.y())
- item_bottom_right = QPointF(item_rect.x() + item_rect.width(), item_rect.y() + item_rect.height())
-
- if self.m_rubberband.contains(item_top_left) and self.m_rubberband.contains(item_bottom_right):
- item.setSelected(True)
-
- self.m_rubberband.hide()
- self.m_rubberband.setRect(0, 0, 0, 0)
- self.m_rubberband_selection = False
-
- else:
- items_list = self.selectedItems()
- for item in items_list:
- if item and item.isVisible() and item.type() == CanvasBoxType:
- item.checkItemPos()
- self.sceneGroupMoved.emit(item.getGroupId(), item.getSplittedMode(), item.scenePos())
-
- if len(items_list) > 1:
- canvas.scene.update()
-
- self.m_mouse_down_init = False
- self.m_mouse_rubberband = False
- QGraphicsScene.mouseReleaseEvent(self, event)
-
- def wheelEvent(self, event):
- if not self.m_view:
- return event.ignore()
-
- if self.m_ctrl_down:
- factor = 1.41 ** (event.delta() / 240.0)
- self.m_view.scale(factor, factor)
-
- self.fixScaleFactor()
- return event.accept()
-
- QGraphicsScene.wheelEvent(self, event)
-
- def contextMenuEvent(self, event):
- if len(self.selectedItems()) == 0:
- event.accept()
- canvas.callback(ACTION_BG_RIGHT_CLICK, 0, 0, "")
- else:
- QGraphicsScene.contextMenuEvent(self, event)
-
- # ------------------------------------------------------------------------------
- # canvasfadeanimation.cpp
-
- class CanvasFadeAnimation(QAbstractAnimation):
- def __init__(self, item, show):
- QAbstractAnimation.__init__(self)
-
- self.m_show = show
- self.m_duration = 0
- self.m_item = item
-
- def item(self):
- return self.m_item
-
- def forceStop(self):
- self.blockSignals(True)
- self.stop()
-
- def setDuration(self, time):
- if self.m_item.opacity() == 0 and not self.m_show:
- self._duration = 0
- else:
- self.m_item.show()
- self.m_duration = time
-
- def duration(self):
- return self.m_duration
-
- def updateCurrentTime(self, time):
- if self.m_duration == 0:
- return
-
- if self.m_show:
- value = float(time) / self.m_duration
- else:
- value = 1.0 - (float(time) / self.m_duration)
-
- try:
- self.m_item.setOpacity(value)
- except:
- print("Error: failed to animate canvas item, already destroyed?")
- self.forceStop()
- canvas.animation_list.remove(self)
- return
-
- if self.m_item.type() == CanvasBoxType:
- self.m_item.setShadowOpacity(value)
-
- def updateDirection(self, direction):
- pass
-
- def updateState(self, oldState, newState):
- pass
-
- # ------------------------------------------------------------------------------
- # canvasline.cpp
-
- class CanvasLine(QGraphicsLineItem):
- def __init__(self, item1, item2, parent):
- QGraphicsLineItem.__init__(self, parent)
-
- self.item1 = item1
- self.item2 = item2
-
- self.m_locked = False
- self.m_lineSelected = False
-
- self.setGraphicsEffect(None)
- self.updateLinePos()
-
- def isLocked(self):
- return self.m_locked
-
- def setLocked(self, yesno):
- self.m_locked = yesno
-
- def isLineSelected(self):
- return self.m_lineSelected
-
- def setLineSelected(self, yesno):
- if self.m_locked:
- return
-
- if options.eyecandy == EYECANDY_FULL:
- if yesno:
- self.setGraphicsEffect(CanvasPortGlow(self.item1.getPortType(), self.toGraphicsObject()))
- else:
- self.setGraphicsEffect(None)
-
- self.m_lineSelected = yesno
- self.updateLineGradient()
-
- def triggerDisconnect(self):
- for connection in canvas.connection_list:
- if (connection.port_out_id == self.item1.getPortId() and connection.port_in_id == self.item2.getPortId()):
- canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, "")
- break
-
- def updateLinePos(self):
- if self.item1.getPortMode() == PORT_MODE_OUTPUT:
- line = QLineF(self.item1.scenePos().x() + self.item1.getPortWidth() + 12,
- self.item1.scenePos().y() + float(canvas.theme.port_height)/2,
- self.item2.scenePos().x(),
- self.item2.scenePos().y() + float(canvas.theme.port_height)/2)
- self.setLine(line)
-
- self.m_lineSelected = False
- self.updateLineGradient()
-
- def type(self):
- return CanvasLineType
-
- def updateLineGradient(self):
- pos_top = self.boundingRect().top()
- pos_bot = self.boundingRect().bottom()
- if self.item2.scenePos().y() >= self.item1.scenePos().y():
- pos1 = 0
- pos2 = 1
- else:
- pos1 = 1
- pos2 = 0
-
- port_type1 = self.item1.getPortType()
- port_type2 = self.item2.getPortType()
- port_gradient = QLinearGradient(0, pos_top, 0, pos_bot)
-
- if port_type1 == PORT_TYPE_AUDIO_JACK:
- port_gradient.setColorAt(pos1, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack)
- elif port_type1 == PORT_TYPE_MIDI_JACK:
- port_gradient.setColorAt(pos1, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack)
- elif port_type1 == PORT_TYPE_MIDI_ALSA:
- port_gradient.setColorAt(pos1, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa)
- elif port_type1 == PORT_TYPE_PARAMETER:
- port_gradient.setColorAt(pos1, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter)
-
- if port_type2 == PORT_TYPE_AUDIO_JACK:
- port_gradient.setColorAt(pos2, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack)
- elif port_type2 == PORT_TYPE_MIDI_JACK:
- port_gradient.setColorAt(pos2, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack)
- elif port_type2 == PORT_TYPE_MIDI_ALSA:
- port_gradient.setColorAt(pos2, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa)
- elif port_type2 == PORT_TYPE_PARAMETER:
- port_gradient.setColorAt(pos2, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter)
-
- self.setPen(QPen(port_gradient, 2))
-
- def paint(self, painter, option, widget):
- painter.save()
- painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing))
- QGraphicsLineItem.paint(self, painter, option, widget)
- painter.restore()
-
- # ------------------------------------------------------------------------------
- # canvasbezierline.cpp
-
- class CanvasBezierLine(QGraphicsPathItem):
- def __init__(self, item1, item2, parent):
- QGraphicsPathItem.__init__(self, parent)
-
- self.item1 = item1
- self.item2 = item2
-
- self.m_locked = False
- self.m_lineSelected = False
-
- self.setBrush(QColor(0, 0, 0, 0))
- self.setGraphicsEffect(None)
- self.updateLinePos()
-
- def isLocked(self):
- return self.m_locked
-
- def setLocked(self, yesno):
- self.m_locked = yesno
-
- def isLineSelected(self):
- return self.m_lineSelected
-
- def setLineSelected(self, yesno):
- if self.m_locked:
- return
-
- if options.eyecandy == EYECANDY_FULL:
- if yesno:
- self.setGraphicsEffect(CanvasPortGlow(self.item1.getPortType(), self.toGraphicsObject()))
- else:
- self.setGraphicsEffect(None)
-
- self.m_lineSelected = yesno
- self.updateLineGradient()
-
- def triggerDisconnect(self):
- for connection in canvas.connection_list:
- if (connection.port_out_id == self.item1.getPortId() and connection.port_in_id == self.item2.getPortId()):
- canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, "")
- break
-
- def updateLinePos(self):
- if self.item1.getPortMode() == PORT_MODE_OUTPUT:
- item1_x = self.item1.scenePos().x() + self.item1.getPortWidth() + 12
- item1_y = self.item1.scenePos().y() + float(canvas.theme.port_height)/2
-
- item2_x = self.item2.scenePos().x()
- item2_y = self.item2.scenePos().y() + float(canvas.theme.port_height)/2
-
- item1_mid_x = abs(item1_x - item2_x) / 2
- item1_new_x = item1_x + item1_mid_x
-
- item2_mid_x = abs(item1_x - item2_x) / 2
- item2_new_x = item2_x - item2_mid_x
-
- path = QPainterPath(QPointF(item1_x, item1_y))
- path.cubicTo(item1_new_x, item1_y, item2_new_x, item2_y, item2_x, item2_y)
- self.setPath(path)
-
- self.m_lineSelected = False
- self.updateLineGradient()
-
- def type(self):
- return CanvasBezierLineType
-
- def updateLineGradient(self):
- pos_top = self.boundingRect().top()
- pos_bot = self.boundingRect().bottom()
- if self.item2.scenePos().y() >= self.item1.scenePos().y():
- pos1 = 0
- pos2 = 1
- else:
- pos1 = 1
- pos2 = 0
-
- port_type1 = self.item1.getPortType()
- port_type2 = self.item2.getPortType()
- port_gradient = QLinearGradient(0, pos_top, 0, pos_bot)
-
- if port_type1 == PORT_TYPE_AUDIO_JACK:
- port_gradient.setColorAt(pos1, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack)
- elif port_type1 == PORT_TYPE_MIDI_JACK:
- port_gradient.setColorAt(pos1, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack)
- elif port_type1 == PORT_TYPE_MIDI_ALSA:
- port_gradient.setColorAt(pos1, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa)
- elif port_type1 == PORT_TYPE_PARAMETER:
- port_gradient.setColorAt(pos1, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter)
-
- if port_type2 == PORT_TYPE_AUDIO_JACK:
- port_gradient.setColorAt(pos2, canvas.theme.line_audio_jack_sel if self.m_lineSelected else canvas.theme.line_audio_jack)
- elif port_type2 == PORT_TYPE_MIDI_JACK:
- port_gradient.setColorAt(pos2, canvas.theme.line_midi_jack_sel if self.m_lineSelected else canvas.theme.line_midi_jack)
- elif port_type2 == PORT_TYPE_MIDI_ALSA:
- port_gradient.setColorAt(pos2, canvas.theme.line_midi_alsa_sel if self.m_lineSelected else canvas.theme.line_midi_alsa)
- elif port_type2 == PORT_TYPE_PARAMETER:
- port_gradient.setColorAt(pos2, canvas.theme.line_parameter_sel if self.m_lineSelected else canvas.theme.line_parameter)
-
- self.setPen(QPen(port_gradient, 2))
-
- def paint(self, painter, option, widget):
- painter.save()
- painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing))
- QGraphicsPathItem.paint(self, painter, option, widget)
- painter.restore()
-
- # ------------------------------------------------------------------------------
- # canvaslivemov.cpp
-
- class CanvasLineMov(QGraphicsLineItem):
- def __init__(self, port_mode, port_type, parent):
- QGraphicsLineItem.__init__(self, parent)
-
- self.m_port_mode = port_mode
- self.m_port_type = port_type
-
- # Port position doesn't change while moving around line
- self.p_lineX = self.scenePos().x()
- self.p_lineY = self.scenePos().y()
- self.p_width = self.parentItem().getPortWidth()
-
- if port_type == PORT_TYPE_AUDIO_JACK:
- pen = QPen(canvas.theme.line_audio_jack, 2)
- elif port_type == PORT_TYPE_MIDI_JACK:
- pen = QPen(canvas.theme.line_midi_jack, 2)
- elif port_type == PORT_TYPE_MIDI_ALSA:
- pen = QPen(canvas.theme.line_midi_alsa, 2)
- elif port_type == PORT_TYPE_PARAMETER:
- pen = QPen(canvas.theme.line_parameter, 2)
- else:
- qWarning("PatchCanvas::CanvasLineMov(%s, %s, %s) - invalid port type" % (port_mode2str(port_mode), port_type2str(port_type), parent))
- pen = QPen(Qt.black)
-
- self.setPen(pen)
-
- def updateLinePos(self, scenePos):
- item_pos = [0, 0]
-
- if self.m_port_mode == PORT_MODE_INPUT:
- item_pos[0] = 0
- item_pos[1] = float(canvas.theme.port_height)/2
- elif self.m_port_mode == PORT_MODE_OUTPUT:
- item_pos[0] = self.p_width + 12
- item_pos[1] = float(canvas.theme.port_height)/2
- else:
- return
-
- line = QLineF(item_pos[0], item_pos[1], scenePos.x() - self.p_lineX, scenePos.y() - self.p_lineY)
- self.setLine(line)
-
- def type(self):
- return CanvasLineMovType
-
- def paint(self, painter, option, widget):
- painter.save()
- painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing))
- QGraphicsLineItem.paint(self, painter, option, widget)
- painter.restore()
-
- # ------------------------------------------------------------------------------
- # canvasbezierlinemov.cpp
-
- class CanvasBezierLineMov(QGraphicsPathItem):
- def __init__(self, port_mode, port_type, parent):
- QGraphicsPathItem.__init__(self, parent)
-
- self.m_port_mode = port_mode
- self.m_port_type = port_type
-
- # Port position doesn't change while moving around line
- self.p_itemX = self.scenePos().x()
- self.p_itemY = self.scenePos().y()
- self.p_width = self.parentItem().getPortWidth()
-
- if port_type == PORT_TYPE_AUDIO_JACK:
- pen = QPen(canvas.theme.line_audio_jack, 2)
- elif port_type == PORT_TYPE_MIDI_JACK:
- pen = QPen(canvas.theme.line_midi_jack, 2)
- elif port_type == PORT_TYPE_MIDI_ALSA:
- pen = QPen(canvas.theme.line_midi_alsa, 2)
- elif port_type == PORT_TYPE_PARAMETER:
- pen = QPen(canvas.theme.line_parameter, 2)
- else:
- qWarning("PatchCanvas::CanvasBezierLineMov(%s, %s, %s) - invalid port type" % (port_mode2str(port_mode), port_type2str(port_type), parent))
- pen = QPen(Qt.black)
-
- self.setBrush(QColor(0, 0, 0, 0))
- self.setPen(pen)
-
- def updateLinePos(self, scenePos):
- if self.m_port_mode == PORT_MODE_INPUT:
- old_x = 0
- old_y = float(canvas.theme.port_height)/2
- mid_x = abs(scenePos.x() - self.p_itemX) / 2
- new_x = old_x - mid_x
- elif self.m_port_mode == PORT_MODE_OUTPUT:
- old_x = self.p_width + 12
- old_y = float(canvas.theme.port_height)/2
- mid_x = abs(scenePos.x() - (self.p_itemX + old_x)) / 2
- new_x = old_x + mid_x
- else:
- return
-
- final_x = scenePos.x() - self.p_itemX
- final_y = scenePos.y() - self.p_itemY
-
- path = QPainterPath(QPointF(old_x, old_y))
- path.cubicTo(new_x, old_y, new_x, final_y, final_x, final_y)
- self.setPath(path)
-
- def type(self):
- return CanvasBezierLineMovType
-
- def paint(self, painter, option, widget):
- painter.save()
- painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing))
- QGraphicsPathItem.paint(self, painter, option, widget)
- painter.restore()
-
- # ------------------------------------------------------------------------------
- # canvasport.cpp
-
- class CanvasPort(QGraphicsItem):
- def __init__(self, group_id, port_id, port_name, port_mode, port_type, is_alternate, parent):
- QGraphicsItem.__init__(self, parent)
-
- # Save Variables, useful for later
- self.m_group_id = group_id
- self.m_port_id = port_id
- self.m_port_mode = port_mode
- self.m_port_type = port_type
- self.m_port_name = port_name
- self.m_is_alternate = is_alternate
-
- # Base Variables
- self.m_port_width = 15
- self.m_port_height = canvas.theme.port_height
- self.m_port_font = QFont()
- self.m_port_font.setFamily(canvas.theme.port_font_name)
- self.m_port_font.setPixelSize(canvas.theme.port_font_size)
- self.m_port_font.setWeight(canvas.theme.port_font_state)
-
- self.m_line_mov = None
- self.m_hover_item = None
- self.m_last_selected_state = False
-
- self.m_mouse_down = False
- self.m_cursor_moving = False
-
- self.setFlags(QGraphicsItem.ItemIsSelectable)
-
- if options.auto_select_items:
- self.setAcceptHoverEvents(True)
-
- def getGroupId(self):
- return self.m_group_id
-
- def getPortId(self):
- return self.m_port_id
-
- def getPortMode(self):
- return self.m_port_mode
-
- def getPortType(self):
- return self.m_port_type
-
- def getPortName(self):
- return self.m_port_name
-
- def getFullPortName(self):
- return self.parentItem().getGroupName() + ":" + self.m_port_name
-
- def getPortWidth(self):
- return self.m_port_width
-
- def getPortHeight(self):
- return self.m_port_height
-
- def setPortMode(self, port_mode):
- self.m_port_mode = port_mode
- self.update()
-
- def setPortType(self, port_type):
- self.m_port_type = port_type
- self.update()
-
- def setPortName(self, port_name):
- if QFontMetrics(self.m_port_font).width(port_name) < QFontMetrics(self.m_port_font).width(self.m_port_name):
- QTimer.singleShot(0, canvas.scene.update)
-
- self.m_port_name = port_name
- self.update()
-
- def setPortWidth(self, port_width):
- if port_width < self.m_port_width:
- QTimer.singleShot(0, canvas.scene.update)
-
- self.m_port_width = port_width
- self.update()
-
- def type(self):
- return CanvasPortType
-
- def hoverEnterEvent(self, event):
- if options.auto_select_items:
- self.setSelected(True)
- QGraphicsItem.hoverEnterEvent(self, event)
-
- def hoverLeaveEvent(self, event):
- if options.auto_select_items:
- self.setSelected(False)
- QGraphicsItem.hoverLeaveEvent(self, event)
-
- def mousePressEvent(self, event):
- self.m_hover_item = None
- self.m_mouse_down = bool(event.button() == Qt.LeftButton)
- self.m_cursor_moving = False
- QGraphicsItem.mousePressEvent(self, event)
-
- def mouseMoveEvent(self, event):
- if self.m_mouse_down:
- if not self.m_cursor_moving:
- self.setCursor(QCursor(Qt.CrossCursor))
- self.m_cursor_moving = True
-
- for connection in canvas.connection_list:
- if ((connection.group_out_id == self.m_group_id and connection.port_out_id == self.m_port_id) or
- (connection.group_in_id == self.m_group_id and connection.port_in_id == self.m_port_id)):
- connection.widget.setLocked(True)
-
- if not self.m_line_mov:
- if options.use_bezier_lines:
- self.m_line_mov = CanvasBezierLineMov(self.m_port_mode, self.m_port_type, self)
- else:
- self.m_line_mov = CanvasLineMov(self.m_port_mode, self.m_port_type, self)
-
- canvas.last_z_value += 1
- self.m_line_mov.setZValue(canvas.last_z_value)
- canvas.last_z_value += 1
- self.parentItem().setZValue(canvas.last_z_value)
-
- item = None
- items = canvas.scene.items(event.scenePos(), Qt.ContainsItemShape, Qt.AscendingOrder)
- for i in range(len(items)):
- if items[i].type() == CanvasPortType:
- if items[i] != self:
- if not item:
- item = items[i]
- elif items[i].parentItem().zValue() > item.parentItem().zValue():
- item = items[i]
-
- if self.m_hover_item and self.m_hover_item != item:
- self.m_hover_item.setSelected(False)
-
- if item:
- if item.getPortMode() != self.m_port_mode and item.getPortType() == self.m_port_type:
- item.setSelected(True)
- self.m_hover_item = item
- else:
- self.m_hover_item = None
- else:
- self.m_hover_item = None
-
- self.m_line_mov.updateLinePos(event.scenePos())
- return event.accept()
-
- QGraphicsItem.mouseMoveEvent(self, event)
-
- def mouseReleaseEvent(self, event):
- if self.m_mouse_down:
- if self.m_line_mov is not None:
- item = self.m_line_mov
- self.m_line_mov = None
- canvas.scene.removeItem(item)
- del item
-
- for connection in canvas.connection_list:
- if ((connection.group_out_id == self.m_group_id and connection.port_out_id == self.m_port_id) or
- (connection.group_in_id == self.m_group_id and connection.port_in_id == self.m_port_id)):
- connection.widget.setLocked(False)
-
- if self.m_hover_item:
- # TODO: a better way to check already existing connection
- for connection in canvas.connection_list:
- hover_group_id = self.m_hover_item.getGroupId()
- hover_port_id = self.m_hover_item.getPortId()
-
- if (
- (connection.group_out_id == self.m_group_id and connection.port_out_id == self.m_port_id and
- connection.group_in_id == hover_group_id and connection.port_in_id == hover_port_id) or
- (connection.group_out_id == hover_group_id and connection.port_out_id == hover_port_id and
- connection.group_in_id == self.m_group_id and connection.port_in_id == self.m_port_id)
- ):
- canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, "")
- break
- else:
- if self.m_port_mode == PORT_MODE_OUTPUT:
- conn = "%i:%i:%i:%i" % (self.m_group_id, self.m_port_id, self.m_hover_item.getGroupId(), self.m_hover_item.getPortId())
- canvas.callback(ACTION_PORTS_CONNECT, 0, 0, conn)
- else:
- conn = "%i:%i:%i:%i" % (self.m_hover_item.getGroupId(), self.m_hover_item.getPortId(), self.m_group_id, self.m_port_id)
- canvas.callback(ACTION_PORTS_CONNECT, 0, 0, conn)
-
- canvas.scene.clearSelection()
-
- if self.m_cursor_moving:
- self.setCursor(QCursor(Qt.ArrowCursor))
-
- self.m_hover_item = None
- self.m_mouse_down = False
- self.m_cursor_moving = False
- QGraphicsItem.mouseReleaseEvent(self, event)
-
- def contextMenuEvent(self, event):
- canvas.scene.clearSelection()
- self.setSelected(True)
-
- menu = QMenu()
- discMenu = QMenu("Disconnect", menu)
-
- conn_list = CanvasGetPortConnectionList(self.m_group_id, self.m_port_id)
-
- if len(conn_list) > 0:
- for conn_id, group_id, port_id in conn_list:
- act_x_disc = discMenu.addAction(CanvasGetFullPortName(group_id, port_id))
- act_x_disc.setData(conn_id)
- act_x_disc.triggered.connect(canvas.qobject.PortContextMenuDisconnect)
- else:
- act_x_disc = discMenu.addAction("No connections")
- act_x_disc.setEnabled(False)
-
- menu.addMenu(discMenu)
- act_x_disc_all = menu.addAction("Disconnect &All")
- act_x_sep_1 = menu.addSeparator()
- act_x_info = menu.addAction("Get &Info")
- act_x_rename = menu.addAction("&Rename")
-
- if not features.port_info:
- act_x_info.setVisible(False)
-
- if not features.port_rename:
- act_x_rename.setVisible(False)
-
- if not (features.port_info and features.port_rename):
- act_x_sep_1.setVisible(False)
-
- act_selected = menu.exec_(event.screenPos())
-
- if act_selected == act_x_disc_all:
- for conn_id, group_id, port_id in conn_list:
- canvas.callback(ACTION_PORTS_DISCONNECT, conn_id, 0, "")
-
- elif act_selected == act_x_info:
- canvas.callback(ACTION_PORT_INFO, self.m_group_id, self.m_port_id, "")
-
- elif act_selected == act_x_rename:
- canvas.callback(ACTION_PORT_RENAME, self.m_group_id, self.m_port_id, "")
-
- event.accept()
-
- def boundingRect(self):
- return QRectF(0, 0, self.m_port_width + 12, self.m_port_height)
-
- def paint(self, painter, option, widget):
- painter.save()
- painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing == ANTIALIASING_FULL))
-
- # FIXME: would be more correct to take line width from Pen, loaded to painter,
- # but this needs some code rearrangement
- lineHinting = canvas.theme.port_audio_jack_pen.widthF() / 2
-
- poly_locx = [0, 0, 0, 0, 0]
-
- if self.m_port_mode == PORT_MODE_INPUT:
- text_pos = QPointF(3, canvas.theme.port_text_ypos)
-
- if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON:
- poly_locx[0] = lineHinting
- poly_locx[1] = self.m_port_width + 5 - lineHinting
- poly_locx[2] = self.m_port_width + 12 - lineHinting
- poly_locx[3] = self.m_port_width + 5 - lineHinting
- poly_locx[4] = lineHinting
- elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE:
- poly_locx[0] = lineHinting
- poly_locx[1] = self.m_port_width + 5 - lineHinting
- poly_locx[2] = self.m_port_width + 5 - lineHinting
- poly_locx[3] = self.m_port_width + 5 - lineHinting
- poly_locx[4] = lineHinting
- else:
- qCritical("PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode)
- return
-
- elif self.m_port_mode == PORT_MODE_OUTPUT:
- text_pos = QPointF(9, canvas.theme.port_text_ypos)
-
- if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON:
- poly_locx[0] = self.m_port_width + 12 - lineHinting
- poly_locx[1] = 7 + lineHinting
- poly_locx[2] = 0 + lineHinting
- poly_locx[3] = 7 + lineHinting
- poly_locx[4] = self.m_port_width + 12 - lineHinting
- elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE:
- poly_locx[0] = self.m_port_width + 12 - lineHinting
- poly_locx[1] = 5 + lineHinting
- poly_locx[2] = 5 + lineHinting
- poly_locx[3] = 5 + lineHinting
- poly_locx[4] = self.m_port_width + 12 - lineHinting
- else:
- qCritical("PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'" % canvas.theme.port_mode)
- return
-
- else:
- qCritical("PatchCanvas::CanvasPort.paint() - invalid port mode '%s'" % port_mode2str(self.m_port_mode))
- return
-
- if self.m_port_type == PORT_TYPE_AUDIO_JACK:
- poly_color = canvas.theme.port_audio_jack_bg_sel if self.isSelected() else canvas.theme.port_audio_jack_bg
- poly_pen = canvas.theme.port_audio_jack_pen_sel if self.isSelected() else canvas.theme.port_audio_jack_pen
- text_pen = canvas.theme.port_audio_jack_text_sel if self.isSelected() else canvas.theme.port_audio_jack_text
- conn_pen = canvas.theme.port_audio_jack_pen_sel
- elif self.m_port_type == PORT_TYPE_MIDI_JACK:
- poly_color = canvas.theme.port_midi_jack_bg_sel if self.isSelected() else canvas.theme.port_midi_jack_bg
- poly_pen = canvas.theme.port_midi_jack_pen_sel if self.isSelected() else canvas.theme.port_midi_jack_pen
- text_pen = canvas.theme.port_midi_jack_text_sel if self.isSelected() else canvas.theme.port_midi_jack_text
- conn_pen = canvas.theme.port_midi_jack_pen_sel
- elif self.m_port_type == PORT_TYPE_MIDI_ALSA:
- poly_color = canvas.theme.port_midi_alsa_bg_sel if self.isSelected() else canvas.theme.port_midi_alsa_bg
- poly_pen = canvas.theme.port_midi_alsa_pen_sel if self.isSelected() else canvas.theme.port_midi_alsa_pen
- text_pen = canvas.theme.port_midi_alsa_text_sel if self.isSelected() else canvas.theme.port_midi_alsa_text
- conn_pen = canvas.theme.port_midi_alsa_pen_sel
- elif self.m_port_type == PORT_TYPE_PARAMETER:
- poly_color = canvas.theme.port_parameter_bg_sel if self.isSelected() else canvas.theme.port_parameter_bg
- poly_pen = canvas.theme.port_parameter_pen_sel if self.isSelected() else canvas.theme.port_parameter_pen
- text_pen = canvas.theme.port_parameter_text_sel if self.isSelected() else canvas.theme.port_parameter_text
- conn_pen = canvas.theme.port_parameter_pen_sel
- else:
- qCritical("PatchCanvas::CanvasPort.paint() - invalid port type '%s'" % port_type2str(self.m_port_type))
- return
-
- if self.m_is_alternate:
- poly_color = poly_color.darker(180)
- #poly_pen.setColor(poly_pen.color().darker(110))
- #text_pen.setColor(text_pen.color()) #.darker(150))
- #conn_pen.setColor(conn_pen.color()) #.darker(150))
-
- polygon = QPolygonF()
- polygon += QPointF(poly_locx[0], lineHinting)
- polygon += QPointF(poly_locx[1], lineHinting)
- polygon += QPointF(poly_locx[2], float(canvas.theme.port_height)/2)
- polygon += QPointF(poly_locx[3], canvas.theme.port_height - lineHinting)
- polygon += QPointF(poly_locx[4], canvas.theme.port_height - lineHinting)
- polygon += QPointF(poly_locx[0], lineHinting)
-
- if canvas.theme.port_bg_pixmap:
- portRect = polygon.boundingRect()
- portPos = portRect.topLeft()
- painter.drawTiledPixmap(portRect, canvas.theme.port_bg_pixmap, portPos)
- else:
- painter.setBrush(poly_color) #.lighter(200))
-
- painter.setPen(poly_pen)
- painter.drawPolygon(polygon)
-
- painter.setPen(text_pen)
- painter.setFont(self.m_port_font)
- painter.drawText(text_pos, self.m_port_name)
-
- if self.isSelected() != self.m_last_selected_state:
- for connection in canvas.connection_list:
- if ((connection.group_out_id == self.m_group_id and connection.port_out_id == self.m_port_id) or
- (connection.group_in_id == self.m_group_id and connection.port_in_id == self.m_port_id)):
- connection.widget.setLineSelected(self.isSelected())
-
- if canvas.theme.idx == Theme.THEME_OOSTUDIO and canvas.theme.port_bg_pixmap:
- painter.setPen(Qt.NoPen)
- painter.setBrush(conn_pen.brush())
-
- if self.m_port_mode == PORT_MODE_INPUT:
- connRect = QRectF(portRect.topLeft(), QSizeF(2, portRect.height()))
- else:
- connRect = QRectF(QPointF(portRect.right()-2, portRect.top()), QSizeF(2, portRect.height()))
-
- painter.drawRect(connRect)
-
- self.m_last_selected_state = self.isSelected()
-
- painter.restore()
-
- # ------------------------------------------------------------------------------
- # canvasbox.cpp
-
- class cb_line_t(object):
- __slots__ = [
- 'line',
- 'connection_id'
- ]
-
- class CanvasBox(QGraphicsItem):
- def __init__(self, group_id, group_name, icon, parent=None):
- QGraphicsItem.__init__(self, parent)
-
- # Save Variables, useful for later
- self.m_group_id = group_id
- self.m_group_name = group_name
-
- # plugin Id, < 0 if invalid
- self.m_plugin_id = -1
- self.m_plugin_ui = False
-
- # Base Variables
- self.p_width = 50
- self.p_height = canvas.theme.box_header_height + canvas.theme.box_header_spacing + 1
-
- self.m_last_pos = QPointF()
- self.m_splitted = False
- self.m_splitted_mode = PORT_MODE_NULL
-
- self.m_cursor_moving = False
- self.m_forced_split = False
- self.m_mouse_down = False
-
- self.m_port_list_ids = []
- self.m_connection_lines = []
-
- # Set Font
- self.m_font_name = QFont()
- self.m_font_name.setFamily(canvas.theme.box_font_name)
- self.m_font_name.setPixelSize(canvas.theme.box_font_size)
- self.m_font_name.setWeight(canvas.theme.box_font_state)
-
- self.m_font_port = QFont()
- self.m_font_port.setFamily(canvas.theme.port_font_name)
- self.m_font_port.setPixelSize(canvas.theme.port_font_size)
- self.m_font_port.setWeight(canvas.theme.port_font_state)
-
- # Icon
- if canvas.theme.box_use_icon:
- self.icon_svg = CanvasIcon(icon, self.m_group_name, self)
- else:
- self.icon_svg = None
-
- # Shadow
- if options.eyecandy:
- self.shadow = CanvasBoxShadow(self.toGraphicsObject())
- self.shadow.setFakeParent(self)
- self.setGraphicsEffect(self.shadow)
- else:
- self.shadow = None
-
- # Final touches
- self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable)
-
- # Wait for at least 1 port
- if options.auto_hide_groups:
- self.setVisible(False)
-
- self.setFlag(QGraphicsItem.ItemIsFocusable, True)
-
- if options.auto_select_items:
- self.setAcceptHoverEvents(True)
-
- self.updatePositions()
-
- canvas.scene.addItem(self)
-
- def getGroupId(self):
- return self.m_group_id
-
- def getGroupName(self):
- return self.m_group_name
-
- def isSplitted(self):
- return self.m_splitted
-
- def getSplittedMode(self):
- return self.m_splitted_mode
-
- def getPortCount(self):
- return len(self.m_port_list_ids)
-
- def getPortList(self):
- return self.m_port_list_ids
-
- def setAsPlugin(self, plugin_id, hasUi):
- self.m_plugin_id = plugin_id
- self.m_plugin_ui = hasUi
-
- def setIcon(self, icon):
- if self.icon_svg is not None:
- self.icon_svg.setIcon(icon, self.m_group_name)
-
- def setSplit(self, split, mode=PORT_MODE_NULL):
- self.m_splitted = split
- self.m_splitted_mode = mode
-
- def setGroupName(self, group_name):
- self.m_group_name = group_name
- self.updatePositions()
-
- def setShadowOpacity(self, opacity):
- if self.shadow:
- self.shadow.setOpacity(opacity)
-
- def addPortFromGroup(self, port_id, port_mode, port_type, port_name, is_alternate):
- if len(self.m_port_list_ids) == 0:
- if options.auto_hide_groups:
- if options.eyecandy == EYECANDY_FULL:
- CanvasItemFX(self, True, False)
- self.setVisible(True)
-
- new_widget = CanvasPort(self.m_group_id, port_id, port_name, port_mode, port_type, is_alternate, self)
-
- port_dict = port_dict_t()
- port_dict.group_id = self.m_group_id
- port_dict.port_id = port_id
- port_dict.port_name = port_name
- port_dict.port_mode = port_mode
- port_dict.port_type = port_type
- port_dict.is_alternate = is_alternate
- port_dict.widget = new_widget
-
- self.m_port_list_ids.append(port_id)
-
- return new_widget
-
- def removePortFromGroup(self, port_id):
- if port_id in self.m_port_list_ids:
- self.m_port_list_ids.remove(port_id)
- else:
- qCritical("PatchCanvas::CanvasBox.removePort(%i) - unable to find port to remove" % port_id)
- return
-
- if len(self.m_port_list_ids) > 0:
- self.updatePositions()
-
- elif self.isVisible():
- if options.auto_hide_groups:
- if options.eyecandy == EYECANDY_FULL:
- CanvasItemFX(self, False, False)
- else:
- self.setVisible(False)
-
- def addLineFromGroup(self, line, connection_id):
- new_cbline = cb_line_t()
- new_cbline.line = line
- new_cbline.connection_id = connection_id
- self.m_connection_lines.append(new_cbline)
-
- def removeLineFromGroup(self, connection_id):
- for connection in self.m_connection_lines:
- if connection.connection_id == connection_id:
- self.m_connection_lines.remove(connection)
- return
- qCritical("PatchCanvas::CanvasBox.removeLineFromGroup(%i) - unable to find line to remove" % connection_id)
-
- def checkItemPos(self):
- if not canvas.size_rect.isNull():
- pos = self.scenePos()
- if not (canvas.size_rect.contains(pos) and canvas.size_rect.contains(pos + QPointF(self.p_width, self.p_height))):
- if pos.x() < canvas.size_rect.x():
- self.setPos(canvas.size_rect.x(), pos.y())
- elif pos.x() + self.p_width > canvas.size_rect.width():
- self.setPos(canvas.size_rect.width() - self.p_width, pos.y())
-
- pos = self.scenePos()
- if pos.y() < canvas.size_rect.y():
- self.setPos(pos.x(), canvas.size_rect.y())
- elif pos.y() + self.p_height > canvas.size_rect.height():
- self.setPos(pos.x(), canvas.size_rect.height() - self.p_height)
-
- def removeIconFromScene(self):
- if self.icon_svg is None:
- return
-
- item = self.icon_svg
- self.icon_svg = None
- canvas.scene.removeItem(item)
- del item
-
- def updatePositions(self):
- self.prepareGeometryChange()
-
- max_in_width = 0
- max_in_height = canvas.theme.box_header_height + canvas.theme.box_header_spacing
- max_out_width = 0
- max_out_height = canvas.theme.box_header_height + canvas.theme.box_header_spacing
- port_spacing = canvas.theme.port_height + canvas.theme.port_spacing
-
- have_audio_jack_in = have_midi_jack_in = have_midi_alsa_in = have_parameter_in = False
- have_audio_jack_out = have_midi_jack_out = have_midi_alsa_out = have_parameter_out = False
-
- # reset box size
- self.p_width = 50
- self.p_height = canvas.theme.box_header_height + canvas.theme.box_header_spacing + 1
-
- # Check Text Name size
- app_name_size = QFontMetrics(self.m_font_name).width(self.m_group_name) + 30
- if app_name_size > self.p_width:
- self.p_width = app_name_size
-
- # Get Port List
- port_list = []
- for port in canvas.port_list:
- if port.group_id == self.m_group_id and port.port_id in self.m_port_list_ids:
- port_list.append(port)
-
- # Get Max Box Width/Height
- for port in port_list:
- if port.port_mode == PORT_MODE_INPUT:
- max_in_height += port_spacing
-
- size = QFontMetrics(self.m_font_port).width(port.port_name)
- if size > max_in_width:
- max_in_width = size
-
- if port.port_type == PORT_TYPE_AUDIO_JACK and not have_audio_jack_in:
- have_audio_jack_in = True
- max_in_height += canvas.theme.port_spacingT
- elif port.port_type == PORT_TYPE_MIDI_JACK and not have_midi_jack_in:
- have_midi_jack_in = True
- max_in_height += canvas.theme.port_spacingT
- elif port.port_type == PORT_TYPE_MIDI_ALSA and not have_midi_alsa_in:
- have_midi_alsa_in = True
- max_in_height += canvas.theme.port_spacingT
- elif port.port_type == PORT_TYPE_PARAMETER and not have_parameter_in:
- have_parameter_in = True
- max_in_height += canvas.theme.port_spacingT
-
- elif port.port_mode == PORT_MODE_OUTPUT:
- max_out_height += port_spacing
-
- size = QFontMetrics(self.m_font_port).width(port.port_name)
- if size > max_out_width:
- max_out_width = size
-
- if port.port_type == PORT_TYPE_AUDIO_JACK and not have_audio_jack_out:
- have_audio_jack_out = True
- max_out_height += canvas.theme.port_spacingT
- elif port.port_type == PORT_TYPE_MIDI_JACK and not have_midi_jack_out:
- have_midi_jack_out = True
- max_out_height += canvas.theme.port_spacingT
- elif port.port_type == PORT_TYPE_MIDI_ALSA and not have_midi_alsa_out:
- have_midi_alsa_out = True
- max_out_height += canvas.theme.port_spacingT
- elif port.port_type == PORT_TYPE_PARAMETER and not have_parameter_out:
- have_parameter_out = True
- max_out_height += canvas.theme.port_spacingT
-
- if canvas.theme.port_spacingT == 0:
- max_in_height += 2
- max_out_height += 2
-
- final_width = 30 + max_in_width + max_out_width
- if final_width > self.p_width:
- self.p_width = final_width
-
- if max_in_height > self.p_height:
- self.p_height = max_in_height
-
- if max_out_height > self.p_height:
- self.p_height = max_out_height
-
- # Remove bottom space
- self.p_height -= canvas.theme.port_spacingT
-
- if canvas.theme.box_header_spacing > 0:
- if len(port_list) == 0:
- self.p_height -= canvas.theme.box_header_spacing
- else:
- self.p_height -= canvas.theme.box_header_spacing/2
-
- last_in_pos = canvas.theme.box_header_height + canvas.theme.box_header_spacing
- last_out_pos = canvas.theme.box_header_height + canvas.theme.box_header_spacing
- last_in_type = PORT_TYPE_NULL
- last_out_type = PORT_TYPE_NULL
-
- # Re-position ports, AUDIO_JACK
- for port in port_list:
- if port.port_type != PORT_TYPE_AUDIO_JACK:
- continue
-
- if port.port_mode == PORT_MODE_INPUT:
- if last_in_type != PORT_TYPE_NULL and port.port_type != last_in_type:
- last_in_pos += canvas.theme.port_spacingT
-
- port.widget.setPos(QPointF(1 + canvas.theme.port_offset, last_in_pos))
- port.widget.setPortWidth(max_in_width)
-
- last_in_pos += port_spacing
- last_in_type = port.port_type
-
- elif port.port_mode == PORT_MODE_OUTPUT:
- if last_out_type != PORT_TYPE_NULL and port.port_type != last_out_type:
- last_out_pos += canvas.theme.port_spacingT
-
- port.widget.setPos(QPointF(self.p_width - max_out_width - canvas.theme.port_offset - 13, last_out_pos))
- port.widget.setPortWidth(max_out_width)
-
- last_out_pos += port_spacing
- last_out_type = port.port_type
-
- # Re-position ports, MIDI_JACK
- for port in port_list:
- if port.port_type != PORT_TYPE_MIDI_JACK:
- continue
-
- if port.port_mode == PORT_MODE_INPUT:
- if last_in_type != PORT_TYPE_NULL and port.port_type != last_in_type:
- last_in_pos += canvas.theme.port_spacingT
-
- port.widget.setPos(QPointF(1 + canvas.theme.port_offset, last_in_pos))
- port.widget.setPortWidth(max_in_width)
-
- last_in_pos += port_spacing
- last_in_type = port.port_type
-
- elif port.port_mode == PORT_MODE_OUTPUT:
- if last_out_type != PORT_TYPE_NULL and port.port_type != last_out_type:
- last_out_pos += canvas.theme.port_spacingT
-
- port.widget.setPos(QPointF(self.p_width - max_out_width - canvas.theme.port_offset - 13, last_out_pos))
- port.widget.setPortWidth(max_out_width)
-
- last_out_pos += port_spacing
- last_out_type = port.port_type
-
- # Re-position ports, MIDI_ALSA
- for port in port_list:
- if port.port_type != PORT_TYPE_MIDI_ALSA:
- continue
-
- if port.port_mode == PORT_MODE_INPUT:
- if last_in_type != PORT_TYPE_NULL and port.port_type != last_in_type:
- last_in_pos += canvas.theme.port_spacingT
-
- port.widget.setPos(QPointF(1 + canvas.theme.port_offset, last_in_pos))
- port.widget.setPortWidth(max_in_width)
-
- last_in_pos += port_spacing
- last_in_type = port.port_type
-
- elif port.port_mode == PORT_MODE_OUTPUT:
- if last_out_type != PORT_TYPE_NULL and port.port_type != last_out_type:
- last_out_pos += canvas.theme.port_spacingT
-
- port.widget.setPos(QPointF(self.p_width - max_out_width - canvas.theme.port_offset - 13, last_out_pos))
- port.widget.setPortWidth(max_out_width)
-
- last_out_pos += port_spacing
- last_out_type = port.port_type
-
- # Re-position ports, PARAMETER
- for port in port_list:
- if port.port_type != PORT_TYPE_PARAMETER:
- continue
-
- if port.port_mode == PORT_MODE_INPUT:
- if last_in_type != PORT_TYPE_NULL and port.port_type != last_in_type:
- last_in_pos += canvas.theme.port_spacingT
-
- port.widget.setPos(QPointF(1 + canvas.theme.port_offset, last_in_pos))
- port.widget.setPortWidth(max_in_width)
-
- last_in_pos += port_spacing
- last_in_type = port.port_type
-
- elif port.port_mode == PORT_MODE_OUTPUT:
- if last_out_type != PORT_TYPE_NULL and port.port_type != last_out_type:
- last_out_pos += canvas.theme.port_spacingT
-
- port.widget.setPos(QPointF(self.p_width - max_out_width - canvas.theme.port_offset - 13, last_out_pos))
- port.widget.setPortWidth(max_out_width)
-
- last_out_pos += port_spacing
- last_out_type = port.port_type
-
- self.repaintLines(True)
- self.update()
-
- def repaintLines(self, forced=False):
- if self.pos() != self.m_last_pos or forced:
- for connection in self.m_connection_lines:
- connection.line.updateLinePos()
-
- self.m_last_pos = self.pos()
-
- def resetLinesZValue(self):
- for connection in canvas.connection_list:
- if connection.port_out_id in self.m_port_list_ids and connection.port_in_id in self.m_port_list_ids:
- z_value = canvas.last_z_value
- else:
- z_value = canvas.last_z_value - 1
-
- connection.widget.setZValue(z_value)
-
- def type(self):
- return CanvasBoxType
-
- def contextMenuEvent(self, event):
- menu = QMenu()
- discMenu = QMenu("Disconnect", menu)
-
- conn_list = []
- conn_list_ids = []
-
- for port_id in self.m_port_list_ids:
- tmp_conn_list = CanvasGetPortConnectionList(self.m_group_id, port_id)
- for conn_id, group_id, port_id in tmp_conn_list:
- if conn_id not in conn_list_ids:
- conn_list.append((conn_id, group_id, port_id))
- conn_list_ids.append(conn_id)
-
- if len(conn_list) > 0:
- for conn_id, group_id, port_id in conn_list:
- act_x_disc = discMenu.addAction(CanvasGetFullPortName(group_id, port_id))
- act_x_disc.setData(conn_id)
- act_x_disc.triggered.connect(canvas.qobject.PortContextMenuDisconnect)
- else:
- act_x_disc = discMenu.addAction("No connections")
- act_x_disc.setEnabled(False)
-
- menu.addMenu(discMenu)
- act_x_disc_all = menu.addAction("Disconnect &All")
- act_x_sep1 = menu.addSeparator()
- act_x_info = menu.addAction("Info")
- act_x_rename = menu.addAction("Rename")
- act_x_sep2 = menu.addSeparator()
- act_x_split_join = menu.addAction("Join" if self.m_splitted else "Split")
-
- if not features.group_info:
- act_x_info.setVisible(False)
-
- if not features.group_rename:
- act_x_rename.setVisible(False)
-
- if not (features.group_info and features.group_rename):
- act_x_sep1.setVisible(False)
-
- if self.m_plugin_id >= 0 and self.m_plugin_id <= MAX_PLUGIN_ID_ALLOWED:
- menu.addSeparator()
- act_p_edit = menu.addAction("Edit")
- act_p_ui = menu.addAction("Show Custom UI")
- menu.addSeparator()
- act_p_clone = menu.addAction("Clone")
- act_p_rename = menu.addAction("Rename...")
- act_p_replace = menu.addAction("Replace...")
- act_p_remove = menu.addAction("Remove")
-
- if not self.m_plugin_ui:
- act_p_ui.setVisible(False)
-
- else:
- act_p_edit = act_p_ui = None
- act_p_clone = act_p_rename = None
- act_p_replace = act_p_remove = None
-
- haveIns = haveOuts = False
- for port in canvas.port_list:
- if port.group_id == self.m_group_id and port.port_id in self.m_port_list_ids:
- if port.port_mode == PORT_MODE_INPUT:
- haveIns = True
- elif port.port_mode == PORT_MODE_OUTPUT:
- haveOuts = True
-
- if not (self.m_splitted or bool(haveIns and haveOuts)):
- act_x_sep2.setVisible(False)
- act_x_split_join.setVisible(False)
-
- act_selected = menu.exec_(event.screenPos())
-
- if act_selected is None:
- pass
-
- elif act_selected == act_x_disc_all:
- for conn_id in conn_list_ids:
- canvas.callback(ACTION_PORTS_DISCONNECT, conn_id, 0, "")
-
- elif act_selected == act_x_info:
- canvas.callback(ACTION_GROUP_INFO, self.m_group_id, 0, "")
-
- elif act_selected == act_x_rename:
- canvas.callback(ACTION_GROUP_RENAME, self.m_group_id, 0, "")
-
- elif act_selected == act_x_split_join:
- if self.m_splitted:
- canvas.callback(ACTION_GROUP_JOIN, self.m_group_id, 0, "")
- else:
- canvas.callback(ACTION_GROUP_SPLIT, self.m_group_id, 0, "")
-
- elif act_selected == act_p_edit:
- canvas.callback(ACTION_PLUGIN_EDIT, self.m_plugin_id, 0, "")
-
- elif act_selected == act_p_ui:
- canvas.callback(ACTION_PLUGIN_SHOW_UI, self.m_plugin_id, 0, "")
-
- elif act_selected == act_p_clone:
- canvas.callback(ACTION_PLUGIN_CLONE, self.m_plugin_id, 0, "")
-
- elif act_selected == act_p_rename:
- canvas.callback(ACTION_PLUGIN_RENAME, self.m_plugin_id, 0, "")
-
- elif act_selected == act_p_replace:
- canvas.callback(ACTION_PLUGIN_REPLACE, self.m_plugin_id, 0, "")
-
- elif act_selected == act_p_remove:
- canvas.callback(ACTION_PLUGIN_REMOVE, self.m_plugin_id, 0, "")
-
- event.accept()
-
- def keyPressEvent(self, event):
- if self.m_plugin_id >= 0 and event.key() == Qt.Key_Delete:
- canvas.callback(ACTION_PLUGIN_REMOVE, self.m_plugin_id, 0, "")
- return event.accept()
- QGraphicsItem.keyPressEvent(self, event)
-
- def hoverEnterEvent(self, event):
- if options.auto_select_items:
- if len(canvas.scene.selectedItems()) > 0:
- canvas.scene.clearSelection()
- self.setSelected(True)
- QGraphicsItem.hoverEnterEvent(self, event)
-
- def mouseDoubleClickEvent(self, event):
- if self.m_plugin_id >= 0:
- canvas.callback(ACTION_PLUGIN_SHOW_UI if self.m_plugin_ui else ACTION_PLUGIN_EDIT, self.m_plugin_id, 0, "")
- return event.accept()
- QGraphicsItem.mouseDoubleClickEvent(self, event)
-
- def mousePressEvent(self, event):
- canvas.last_z_value += 1
- self.setZValue(canvas.last_z_value)
- self.resetLinesZValue()
- self.m_cursor_moving = False
-
- if event.button() == Qt.RightButton:
- canvas.scene.clearSelection()
- self.setSelected(True)
- self.m_mouse_down = False
- return event.accept()
-
- elif event.button() == Qt.LeftButton:
- if self.sceneBoundingRect().contains(event.scenePos()):
- self.m_mouse_down = True
- else:
- # Fix a weird Qt behaviour with right-click mouseMove
- self.m_mouse_down = False
- return event.ignore()
-
- else:
- self.m_mouse_down = False
-
- QGraphicsItem.mousePressEvent(self, event)
-
- def mouseMoveEvent(self, event):
- if self.m_mouse_down:
- if not self.m_cursor_moving:
- self.setCursor(QCursor(Qt.SizeAllCursor))
- self.m_cursor_moving = True
- self.repaintLines()
- QGraphicsItem.mouseMoveEvent(self, event)
-
- def mouseReleaseEvent(self, event):
- if self.m_cursor_moving:
- self.setCursor(QCursor(Qt.ArrowCursor))
- self.setX(round(self.x()))
- self.setY(round(self.y()))
- self.m_mouse_down = False
- self.m_cursor_moving = False
- QGraphicsItem.mouseReleaseEvent(self, event)
-
- def boundingRect(self):
- return QRectF(0, 0, self.p_width, self.p_height)
-
- def paint(self, painter, option, widget):
- painter.save()
- painter.setRenderHint(QPainter.Antialiasing, bool(options.antialiasing == ANTIALIASING_FULL))
-
- # Draw rectangle
- if self.isSelected():
- painter.setPen(canvas.theme.box_pen_sel)
- else:
- painter.setPen(canvas.theme.box_pen)
-
- if canvas.theme.box_bg_type == Theme.THEME_BG_GRADIENT:
- box_gradient = QLinearGradient(0, 0, 0, self.p_height)
- box_gradient.setColorAt(0, canvas.theme.box_bg_1)
- box_gradient.setColorAt(1, canvas.theme.box_bg_2)
- painter.setBrush(box_gradient)
- else:
- painter.setBrush(canvas.theme.box_bg_1)
-
- lineHinting = painter.pen().widthF() / 2
- painter.drawRect(QRectF(lineHinting, lineHinting, self.p_width - lineHinting*2, self.p_height - lineHinting*2))
-
- # Draw pixmap header
- if canvas.theme.box_header_pixmap:
- painter.setPen(Qt.NoPen)
- painter.setBrush(canvas.theme.box_bg_2)
- painter.drawRect(1, 1, self.p_width-2, canvas.theme.box_header_height)
-
- headerPos = QPointF(1, 1)
- headerRect = QRectF(2, 2, self.p_width-4, canvas.theme.box_header_height-3)
- painter.drawTiledPixmap(headerRect, canvas.theme.box_header_pixmap, headerPos)
-
- # Draw text
- painter.setFont(self.m_font_name)
-
- if self.isSelected():
- painter.setPen(canvas.theme.box_text_sel)
- else:
- painter.setPen(canvas.theme.box_text)
-
- if canvas.theme.box_use_icon:
- textPos = QPointF(25, canvas.theme.box_text_ypos)
- else:
- appNameSize = QFontMetrics(self.m_font_name).width(self.m_group_name)
- rem = self.p_width - appNameSize
- textPos = QPointF(rem/2, canvas.theme.box_text_ypos)
-
- painter.drawText(textPos, self.m_group_name)
-
- self.repaintLines()
-
- painter.restore()
-
- # ------------------------------------------------------------------------------
- # canvasicon.cpp
-
- class CanvasIcon(QGraphicsSvgItem):
- def __init__(self, icon, name, parent):
- QGraphicsSvgItem.__init__(self, parent)
-
- self.m_renderer = None
- self.p_size = QRectF(0, 0, 0, 0)
-
- self.m_colorFX = QGraphicsColorizeEffect(self)
- self.m_colorFX.setColor(canvas.theme.box_text.color())
-
- self.setGraphicsEffect(self.m_colorFX)
- self.setIcon(icon, name)
-
- def setIcon(self, icon, name):
- name = name.lower()
- icon_path = ""
-
- if icon == ICON_APPLICATION:
- self.p_size = QRectF(3, 2, 19, 18)
-
- if "audacious" in name:
- icon_path = ":/scalable/pb_audacious.svg"
- self.p_size = QRectF(5, 4, 16, 16)
- elif "clementine" in name:
- icon_path = ":/scalable/pb_clementine.svg"
- self.p_size = QRectF(5, 4, 16, 16)
- elif "distrho" in name:
- icon_path = ":/scalable/pb_distrho.svg"
- self.p_size = QRectF(5, 4, 14, 14)
- elif "jamin" in name:
- icon_path = ":/scalable/pb_jamin.svg"
- self.p_size = QRectF(5, 3, 16, 16)
- elif "mplayer" in name:
- icon_path = ":/scalable/pb_mplayer.svg"
- self.p_size = QRectF(5, 4, 16, 16)
- elif "vlc" in name:
- icon_path = ":/scalable/pb_vlc.svg"
- self.p_size = QRectF(5, 3, 16, 16)
-
- else:
- icon_path = ":/scalable/pb_generic.svg"
- self.p_size = QRectF(4, 3, 16, 16)
-
- elif icon == ICON_HARDWARE:
- icon_path = ":/scalable/pb_hardware.svg"
- self.p_size = QRectF(5, 2, 16, 16)
-
- elif icon == ICON_DISTRHO:
- icon_path = ":/scalable/pb_distrho.svg"
- self.p_size = QRectF(5, 4, 14, 14)
-
- elif icon == ICON_FILE:
- icon_path = ":/scalable/pb_file.svg"
- self.p_size = QRectF(5, 4, 12, 14)
-
- elif icon == ICON_PLUGIN:
- icon_path = ":/scalable/pb_plugin.svg"
- self.p_size = QRectF(5, 4, 14, 14)
-
- elif icon == ICON_LADISH_ROOM:
- # TODO - make a unique ladish-room icon
- icon_path = ":/scalable/pb_hardware.svg"
- self.p_size = QRectF(5, 2, 16, 16)
-
- else:
- self.p_size = QRectF(0, 0, 0, 0)
- qCritical("PatchCanvas::CanvasIcon.setIcon(%s, %s) - unsupported icon requested" % (icon2str(icon), name.encode()))
- return
-
- self.m_renderer = QSvgRenderer(icon_path, canvas.scene)
- self.setSharedRenderer(self.m_renderer)
- self.update()
-
- def type(self):
- return CanvasIconType
-
- def boundingRect(self):
- return self.p_size
-
- def paint(self, painter, option, widget):
- if self.m_renderer:
- painter.save()
- painter.setRenderHint(QPainter.Antialiasing, False)
- painter.setRenderHint(QPainter.TextAntialiasing, False)
- self.m_renderer.render(painter, self.p_size)
- painter.restore()
- else:
- QGraphicsSvgItem.paint(self, painter, option, widget)
-
- # ------------------------------------------------------------------------------
- # canvasportglow.cpp
-
- class CanvasPortGlow(QGraphicsDropShadowEffect):
- def __init__(self, port_type, parent):
- QGraphicsDropShadowEffect.__init__(self, parent)
-
- self.setBlurRadius(12)
- self.setOffset(0, 0)
-
- if port_type == PORT_TYPE_AUDIO_JACK:
- self.setColor(canvas.theme.line_audio_jack_glow)
- elif port_type == PORT_TYPE_MIDI_JACK:
- self.setColor(canvas.theme.line_midi_jack_glow)
- elif port_type == PORT_TYPE_MIDI_ALSA:
- self.setColor(canvas.theme.line_midi_alsa_glow)
- elif port_type == PORT_TYPE_PARAMETER:
- self.setColor(canvas.theme.line_parameter_glow)
-
- # ------------------------------------------------------------------------------
- # canvasboxshadow.cpp
-
- class CanvasBoxShadow(QGraphicsDropShadowEffect):
- def __init__(self, parent):
- QGraphicsDropShadowEffect.__init__(self, parent)
-
- self.m_fakeParent = None
-
- self.setBlurRadius(20)
- self.setColor(canvas.theme.box_shadow)
- self.setOffset(0, 0)
-
- def setFakeParent(self, fakeParent):
- self.m_fakeParent = fakeParent
-
- def setOpacity(self, opacity):
- color = QColor(canvas.theme.box_shadow)
- color.setAlphaF(opacity)
- self.setColor(color)
-
- def draw(self, painter):
- if self.m_fakeParent:
- self.m_fakeParent.repaintLines()
- QGraphicsDropShadowEffect.draw(self, painter)
|