@@ -0,0 +1,398 @@ | |||||
#!/usr/bin/env python3 | |||||
# -*- coding: utf-8 -*- | |||||
# PatchCanvas test application | |||||
# Copyright (C) 2012 Filipe Coelho <falktx@gmail.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 COPYING file | |||||
# Imports (Global) | |||||
from PyQt4.QtCore import pyqtSlot, Qt, QSettings | |||||
from PyQt4.QtGui import QApplication, QDialog, QDialogButtonBox, QPainter, QMainWindow | |||||
# Imports (Custom Stuff) | |||||
import patchcanvas | |||||
import ui_catarina, icons_rc | |||||
import ui_catarina_addgroup, ui_catarina_removegroup, ui_catarina_renamegroup | |||||
import ui_catarina_addport, ui_catarina_removeport, ui_catarina_renameport | |||||
import ui_catarina_connectports, ui_catarina_disconnectports | |||||
from shared import * | |||||
try: | |||||
from PyQt4.QtOpenGL import QGLWidget | |||||
hasGL = True | |||||
except: | |||||
hasGL = False | |||||
iGroupId = 0 | |||||
iGroupName = 1 | |||||
iGroupSplit = 2 | |||||
iGroupIcon = 3 | |||||
iGroupPosId = 0 | |||||
iGroupPosX_o = 1 | |||||
iGroupPosY_o = 2 | |||||
iGroupPosX_i = 3 | |||||
iGroupPosY_i = 4 | |||||
iPortGroup = 0 | |||||
iPortId = 1 | |||||
iPortName = 2 | |||||
iPortMode = 3 | |||||
iPortType = 4 | |||||
iConnId = 0 | |||||
iConnOutput = 1 | |||||
iConnInput = 2 | |||||
# Add Group Dialog | |||||
class CatarinaAddGroupW(QDialog, ui_catarina_addgroup.Ui_CatarinaAddGroupW): | |||||
def __init__(self, parent, group_list): | |||||
QDialog.__init__(self, parent) | |||||
self.setupUi(self) | |||||
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) | |||||
self.m_group_list_names = [] | |||||
for group in group_list: | |||||
self.m_group_list_names.append(group[iGroupName]) | |||||
self.connect(self, SIGNAL("accepted()"), SLOT("slot_setReturn()")) | |||||
self.connect(self.le_group_name, SIGNAL("textChanged(QString)"), SLOT("slot_checkText(QString)")) | |||||
self.ret_group_name = "" | |||||
self.ret_group_split = False | |||||
@pyqtSlot(str) | |||||
def slot_checkText(self, text): | |||||
check = bool(text and text not in self.m_group_list_names) | |||||
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check) | |||||
@pyqtSlot() | |||||
def slot_setReturn(self): | |||||
self.ret_group_name = self.le_group_name.text() | |||||
self.ret_group_split = self.cb_split.isChecked() | |||||
# Remove Group Dialog | |||||
class CatarinaRemoveGroupW(QDialog, ui_catarina_removegroup.Ui_CatarinaRemoveGroupW): | |||||
def __init__(self, parent, group_list): | |||||
QDialog.__init__(self, parent) | |||||
self.setupUi(self) | |||||
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) | |||||
i = 0 | |||||
for group in group_list: | |||||
twi_group_id = QTableWidgetItem(str(group[iGroupId])) | |||||
twi_group_name = QTableWidgetItem(group[iGroupName]) | |||||
twi_group_split = QTableWidgetItem("Yes" if (group[iGroupSplit]) else "No") | |||||
self.tw_group_list.insertRow(i) | |||||
self.tw_group_list.setItem(i, 0, twi_group_id) | |||||
self.tw_group_list.setItem(i, 1, twi_group_name) | |||||
self.tw_group_list.setItem(i, 2, twi_group_split) | |||||
i += 1 | |||||
self.connect(self, SIGNAL("accepted()"), SLOT("slot_setReturn()")) | |||||
self.connect(self.tw_group_list, SIGNAL("cellDoubleClicked(int, int)"), SLOT("accept()")) | |||||
self.connect(self.tw_group_list, SIGNAL("currentCellChanged(int, int, int, int)"), SLOT("slot_checkCell(int)")) | |||||
self.ret_group_id = -1 | |||||
@pyqtSlot(int) | |||||
def slot_checkCell(self, row): | |||||
check = bool(row >= 0) | |||||
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check) | |||||
@pyqtSlot() | |||||
def slot_setReturn(self): | |||||
self.ret_group_id = int(self.tw_group_list.item(self.tw_group_list.currentRow(), 0).text()) | |||||
# Rename Group Dialog | |||||
class CatarinaRenameGroupW(QDialog, ui_catarina_renamegroup.Ui_CatarinaRenameGroupW): | |||||
def __init__(self, parent, group_list): | |||||
QDialog.__init__(self, parent) | |||||
self.setupUi(self) | |||||
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) | |||||
for group in group_list: | |||||
self.cb_group_to_rename.addItem("%i - %s" % (group[iGroupId], group[iGroupName])) | |||||
self.connect(self, SIGNAL("accepted()"), SLOT("slot_setReturn()")) | |||||
self.connect(self.cb_group_to_rename, SIGNAL("currentIndexChanged(int)"), SLOT("slot_checkItem()")) | |||||
self.connect(self.le_new_group_name, SIGNAL("textChanged(QString)"), SLOT("slot_checkText(QString)")) | |||||
self.ret_group_id = -1 | |||||
self.ret_new_group_name = "" | |||||
@pyqtSlot() | |||||
def slot_checkItem(self, index): | |||||
self.checkText(self.le_new_group_name.text()) | |||||
@pyqtSlot(str) | |||||
def slot_checkText(self, text): | |||||
if (self.cb_group_to_rename.count() > 0): | |||||
group_name = self.cb_group_to_rename.currentText().split(" - ", 1)[1] | |||||
check = bool(text and text != group_name) | |||||
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check) | |||||
@pyqtSlot() | |||||
def slot_setReturn(self): | |||||
self.ret_group_id = int(self.cb_group_to_rename.currentText().split(" - ", 1)[0]) | |||||
self.ret_new_group_name = self.le_new_group_name.text() | |||||
# Main Window | |||||
class CatarinaMainW(QMainWindow, ui_catarina.Ui_CatarinaMainW): | |||||
def __init__(self, parent=None): | |||||
QMainWindow.__init__(self, parent) | |||||
self.setupUi(self) | |||||
self.settings = QSettings("Cadence", "Catarina") | |||||
self.loadSettings() | |||||
self.act_project_new.setIcon(getIcon("document-new")) | |||||
self.act_project_open.setIcon(getIcon("document-open")) | |||||
self.act_project_save.setIcon(getIcon("document-save")) | |||||
self.act_project_save_as.setIcon(getIcon("document-save-as")) | |||||
self.b_project_new.setIcon(getIcon("document-new")) | |||||
self.b_project_open.setIcon(getIcon("document-open")) | |||||
self.b_project_save.setIcon(getIcon("document-save")) | |||||
self.b_project_save_as.setIcon(getIcon("document-save-as")) | |||||
self.act_patchbay_add_group.setIcon(getIcon("list-add")) | |||||
self.act_patchbay_remove_group.setIcon(getIcon("edit-delete")) | |||||
self.act_patchbay_rename_group.setIcon(getIcon("edit-rename")) | |||||
self.act_patchbay_add_port.setIcon(getIcon("list-add")) | |||||
self.act_patchbay_remove_port.setIcon(getIcon("list-remove")) | |||||
self.act_patchbay_rename_port.setIcon(getIcon("edit-rename")) | |||||
self.act_patchbay_connect_ports.setIcon(getIcon("network-connect")) | |||||
self.act_patchbay_disconnect_ports.setIcon(getIcon("network-disconnect")) | |||||
self.b_group_add.setIcon(getIcon("list-add")) | |||||
self.b_group_remove.setIcon(getIcon("edit-delete")) | |||||
self.b_group_rename.setIcon(getIcon("edit-rename")) | |||||
self.b_port_add.setIcon(getIcon("list-add")) | |||||
self.b_port_remove.setIcon(getIcon("list-remove")) | |||||
self.b_port_rename.setIcon(getIcon("edit-rename")) | |||||
self.b_ports_connect.setIcon(getIcon("network-connect")) | |||||
self.b_ports_disconnect.setIcon(getIcon("network-disconnect")) | |||||
setIcons(self, ("canvas",)) | |||||
self.scene = patchcanvas.PatchScene(self, self.graphicsView) | |||||
self.graphicsView.setScene(self.scene) | |||||
self.graphicsView.setRenderHint(QPainter.Antialiasing, bool(self.m_savedSettings["Canvas/Antialiasing"] == Qt.Checked)) | |||||
self.graphicsView.setRenderHint(QPainter.TextAntialiasing, self.m_savedSettings["Canvas/TextAntialiasing"]) | |||||
if (self.m_savedSettings["Canvas/UseOpenGL"] and hasGL): | |||||
self.graphicsView.setViewport(QGLWidget(self.graphicsView)) | |||||
self.graphicsView.setRenderHint(QPainter.HighQualityAntialiasing, self.m_savedSettings["Canvas/HighQualityAntialiasing"]) | |||||
p_options = patchcanvas.options_t() | |||||
p_options.theme_name = self.m_savedSettings["Canvas/Theme"] | |||||
p_options.bezier_lines = self.m_savedSettings["Canvas/BezierLines"] | |||||
p_options.antialiasing = self.m_savedSettings["Canvas/Antialiasing"] | |||||
p_options.auto_hide_groups = self.m_savedSettings["Canvas/AutoHideGroups"] | |||||
p_options.fancy_eyecandy = self.m_savedSettings["Canvas/FancyEyeCandy"] | |||||
p_features = patchcanvas.features_t() | |||||
p_features.group_info = False | |||||
p_features.group_rename = True | |||||
p_features.port_info = True | |||||
p_features.port_rename = True | |||||
p_features.handle_group_pos = False | |||||
patchcanvas.set_options(p_options) | |||||
patchcanvas.set_features(p_features) | |||||
patchcanvas.init(self.scene, self.canvasCallback, DEBUG) | |||||
self.connect(self.act_project_new, SIGNAL("triggered()"), SLOT("slot_projectNew()")) | |||||
#self.connect(self.act_project_open, SIGNAL("triggered()"), SLOT("slot_projectOpen()")) | |||||
#self.connect(self.act_project_save, SIGNAL("triggered()"), SLOT("slot_projectSave()")) | |||||
#self.connect(self.act_project_save_as, SIGNAL("triggered()"), SLOT("slot_projectSaveAs()")) | |||||
self.connect(self.b_project_new, SIGNAL("clicked()"), SLOT("slot_projectNew()")) | |||||
#self.connect(self.b_project_open, SIGNAL("clicked()"), SLOT("slot_projectOpen()")) | |||||
#self.connect(self.b_project_save, SIGNAL("clicked()"), SLOT("slot_projectSave()")) | |||||
#self.connect(self.b_project_save_as, SIGNAL("clicked()"), SLOT("slot_projectSaveAs()")) | |||||
self.connect(self.act_patchbay_add_group, SIGNAL("triggered()"), SLOT("slot_groupAdd()")) | |||||
self.connect(self.act_patchbay_remove_group, SIGNAL("triggered()"), SLOT("slot_groupRemove()")) | |||||
self.connect(self.act_patchbay_rename_group, SIGNAL("triggered()"), SLOT("slot_groupRename()")) | |||||
#self.connect(self.act_patchbay_add_port, SIGNAL("triggered()"),SLOT("slot_portAdd()")) | |||||
#self.connect(self.act_patchbay_remove_port, SIGNAL("triggered()"), SLOT("slot_portRemove()")) | |||||
#self.connect(self.act_patchbay_rename_port, SIGNAL("triggered()"), SLOT("slot_portRename()")) | |||||
#self.connect(self.act_patchbay_connect_ports, SIGNAL("triggered()"), SLOT("slot_connectPorts()")) | |||||
#self.connect(self.act_patchbay_disconnect_ports, SIGNAL("triggered()"), SLOT("slot_disconnectPorts()")) | |||||
self.connect(self.b_group_add, SIGNAL("clicked()"), SLOT("slot_groupAdd()")) | |||||
self.connect(self.b_group_remove, SIGNAL("clicked()"), SLOT("slot_groupRemove()")) | |||||
self.connect(self.b_group_rename, SIGNAL("clicked()"), SLOT("slot_groupRename()")) | |||||
#self.connect(self.b_port_add, SIGNAL("clicked()"), SLOT("slot_portAdd()")) | |||||
#self.connect(self.b_port_remove, SIGNAL("clicked()"), SLOT("slot_portRemove()")) | |||||
#self.connect(self.b_port_rename, SIGNAL("clicked()"), SLOT("slot_portRename()")) | |||||
#self.connect(self.b_ports_connect, SIGNAL("clicked()"), SLOT("slot_connectPorts()")) | |||||
#self.connect(self.b_ports_disconnect, SIGNAL("clicked()"), SLOT("slot_disconnectPorts()")) | |||||
#setCanvasConnections(self) | |||||
#self.connect(self.act_settings_configure, SIGNAL("triggered()"), self.configureCatarina) | |||||
self.connect(self.act_help_about, SIGNAL("triggered()"), SLOT("slot_aboutCatarina()")) | |||||
self.connect(self.act_help_about_qt, SIGNAL("triggered()"), app, SLOT("aboutQt()")) | |||||
#self.connect(self, SIGNAL("SIGUSR1()"), SLOT("slot_projectSave()")) | |||||
# Dummy timer to keep events active | |||||
self.m_updateTimer = self.startTimer(500) | |||||
# Start Empty Project | |||||
self.slot_projectNew() | |||||
def canvasCallback(self, action, value1, value2, value_str): | |||||
print(action, value1, value2, value_str) | |||||
@pyqtSlot() | |||||
def slot_projectNew(self): | |||||
self.m_group_list = [] | |||||
self.m_group_list_pos = [] | |||||
self.m_port_list = [] | |||||
self.m_connection_list = [] | |||||
self.m_last_group_id = 1 | |||||
self.m_last_port_id = 1 | |||||
self.m_last_connection_id = 1 | |||||
self.m_save_path = None | |||||
patchcanvas.clear() | |||||
@pyqtSlot() | |||||
def slot_groupAdd(self): | |||||
dialog = CatarinaAddGroupW(self, self.m_group_list) | |||||
if (dialog.exec_()): | |||||
group_id = self.m_last_group_id | |||||
group_name = dialog.ret_group_name | |||||
group_split = dialog.ret_group_split | |||||
group_icon = patchcanvas.ICON_HARDWARE if (group_split) else patchcanvas.ICON_APPLICATION | |||||
patchcanvas.addGroup(group_id, group_name, group_split, group_icon) | |||||
group_obj = [None, None, None, None] | |||||
group_obj[iGroupId] = group_id | |||||
group_obj[iGroupName] = group_name | |||||
group_obj[iGroupSplit] = group_split | |||||
group_obj[iGroupIcon] = group_icon | |||||
self.m_group_list.append(group_obj) | |||||
self.m_last_group_id += 1 | |||||
@pyqtSlot() | |||||
def slot_groupRemove(self): | |||||
dialog = CatarinaRemoveGroupW(self, self.m_group_list) | |||||
if (dialog.exec_()): | |||||
group_id = dialog.ret_group_id | |||||
#for port in self.m_port_list: | |||||
#if (group_id == port[iPortGroup]): | |||||
#port_id = port[iPortId] | |||||
#h = 0 | |||||
#for j in range(len(self.connection_list)): | |||||
#if (self.connection_list[j-h][iConnOutput] == port_id or self.connection_list[j-h][iConnInput] == port_id): | |||||
#patchcanvas.disconnectPorts(self.connection_list[j-h][iConnId]) | |||||
#self.connection_list.pop(j-h) | |||||
#h += 1 | |||||
#h = 0 | |||||
#for i in range(len(self.port_list)): | |||||
#if (self.port_list[i-h][iPortGroup] == group_id): | |||||
#port_id = self.port_list[i-h][iPortId] | |||||
#patchcanvas.removePort(port_id) | |||||
#self.port_list.pop(i-h) | |||||
#h += 1 | |||||
#patchcanvas.removeGroup(group_id) | |||||
#for i in range(len(self.group_list)): | |||||
#if (self.group_list[i][iGroupId] == group_id): | |||||
#self.group_list.pop(i) | |||||
#break | |||||
@pyqtSlot() | |||||
def slot_groupRename(self): | |||||
dialog = CatarinaRenameGroupW(self, self.m_group_list) | |||||
if (dialog.exec_()): | |||||
group_id = dialog.ret_group_id | |||||
new_group_name = dialog.ret_new_group_name | |||||
patchcanvas.renameGroup(group_id, new_group_name) | |||||
for group in self.m_group_list: | |||||
if (group[iGroupId] == group_id): | |||||
group[iGroupName] = new_group_name | |||||
break | |||||
@pyqtSlot() | |||||
def slot_aboutCatarina(self): | |||||
QMessageBox.about(self, self.tr("About Catarina"), self.tr("<h3>Catarina</h3>" | |||||
"<br>Version %s" | |||||
"<br>Catarina is a testing ground for the 'PatchCanvas' module.<br>" | |||||
"<br>Copyright (C) 2010-2012 falkTX") % (VERSION)) | |||||
def saveSettings(self): | |||||
self.settings.setValue("Geometry", self.saveGeometry()) | |||||
self.settings.setValue("ShowToolbar", self.frame_toolbar.isVisible()) | |||||
def loadSettings(self): | |||||
self.restoreGeometry(self.settings.value("Geometry", "")) | |||||
show_toolbar = self.settings.value("ShowToolbar", True, type=bool) | |||||
self.act_settings_show_toolbar.setChecked(show_toolbar) | |||||
self.frame_toolbar.setVisible(show_toolbar) | |||||
self.m_savedSettings = { | |||||
"Canvas/Theme": self.settings.value("Canvas/Theme", patchcanvas.getThemeName(patchcanvas.getDefaultTheme), type=str), | |||||
"Canvas/BezierLines": self.settings.value("Canvas/BezierLines", True, type=bool), | |||||
"Canvas/AutoHideGroups": self.settings.value("Canvas/AutoHideGroups", False, type=bool), | |||||
"Canvas/FancyEyeCandy": self.settings.value("Canvas/FancyEyeCandy", False, type=bool), | |||||
"Canvas/UseOpenGL": self.settings.value("Canvas/UseOpenGL", False, type=bool), | |||||
"Canvas/Antialiasing": self.settings.value("Canvas/Antialiasing", Qt.PartiallyChecked, type=int), | |||||
"Canvas/TextAntialiasing": self.settings.value("Canvas/TextAntialiasing", True, type=bool), | |||||
"Canvas/HighQualityAntialiasing": self.settings.value("Canvas/HighQualityAntialiasing", False, type=bool) | |||||
} | |||||
def timerEvent(self, event): | |||||
if (event.timerId() == self.m_updateTimer): | |||||
self.update() | |||||
QMainWindow.timerEvent(self, event) | |||||
def closeEvent(self, event): | |||||
self.saveSettings() | |||||
QMainWindow.closeEvent(self, event) | |||||
#--------------- main ------------------ | |||||
if __name__ == '__main__': | |||||
# App initialization | |||||
app = QApplication(sys.argv) | |||||
app.setApplicationName("Catarina") | |||||
app.setApplicationVersion(VERSION) | |||||
app.setOrganizationName("falkTX") | |||||
app.setWindowIcon(QIcon(":/scalable/catarina.svg")) | |||||
# Show GUI | |||||
gui = CatarinaMainW() | |||||
# Set-up custom signal handling | |||||
set_up_signals(gui) | |||||
#if (app.arguments().count() > 1): | |||||
#gui.save_path = QStringStr(app.arguments()[1]) | |||||
#gui.prepareToloadFile() | |||||
gui.show() | |||||
# App-Loop | |||||
sys.exit(app.exec_()) |
@@ -0,0 +1,493 @@ | |||||
#!/usr/bin/env python3 | |||||
# -*- coding: utf-8 -*- | |||||
# Patchbay Canvas engine using QGraphicsView/Scene | |||||
# Copyright (C) 2012 Filipe Coelho <falktx@gmail.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 COPYING file | |||||
# Imports (Global) | |||||
from PyQt4.QtCore import pyqtSlot, qDebug, qCritical, qFatal, Qt, QObject, SIGNAL, SLOT | |||||
from PyQt4.QtCore import QPointF, QRectF, QSettings | |||||
from PyQt4.QtGui import QGraphicsScene, QGraphicsItem | |||||
# Imports (Theme) | |||||
from patchcanvas_theme import * | |||||
PATCHCANVAS_ORGANISATION_NAME = "Cadence" | |||||
# ------------------------------------------------------------------------------ | |||||
# patchcanvas-api.h | |||||
# 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_A2J = 3 | |||||
PORT_TYPE_MIDI_ALSA = 4 | |||||
# Callback Action | |||||
ACTION_GROUP_INFO = 0 # group_id, N, N | |||||
ACTION_GROUP_RENAME = 1 # group_id, N, new_name | |||||
ACTION_GROUP_SPLIT = 2 # group_id, N, N | |||||
ACTION_GROUP_JOIN = 3 # group_id, N, N | |||||
ACTION_PORT_INFO = 4 # port_id, N, N | |||||
ACTION_PORT_RENAME = 5 # port_id, N, new_name | |||||
ACTION_PORTS_CONNECT = 6 # out_id, in_id, N | |||||
ACTION_PORTS_DISCONNECT = 7 # conn_id, N, N | |||||
# Icon | |||||
ICON_HARDWARE = 0 | |||||
ICON_APPLICATION = 1 | |||||
ICON_LADISH_ROOM = 2 | |||||
# Split Option | |||||
SPLIT_UNDEF = 0 | |||||
SPLIT_NO = 1 | |||||
SPLIT_YES = 2 | |||||
# Canvas options | |||||
class options_t(object): | |||||
__slots__ = [ | |||||
'theme_name', | |||||
'bezier_lines', | |||||
'antialiasing', | |||||
'auto_hide_groups', | |||||
'fancy_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', | |||||
'widgets' | |||||
] | |||||
class port_dict_t(object): | |||||
__slots__ = [ | |||||
'group_id', | |||||
'port_id', | |||||
'port_name', | |||||
'port_mode', | |||||
'port_type', | |||||
'widget' | |||||
] | |||||
class connection_dict_t(object): | |||||
__slots__ = [ | |||||
'connection_id', | |||||
'port_in_id', | |||||
'port_out_id', | |||||
'widget' | |||||
] | |||||
# Main Canvas object | |||||
class Canvas(object): | |||||
__slots__ = [ | |||||
'scene', | |||||
'callback', | |||||
'debug', | |||||
'last_z_value', | |||||
'last_group_id', | |||||
'last_connection_id', | |||||
'initial_pos', | |||||
'group_list', | |||||
'port_list', | |||||
'connection_list', | |||||
'postponed_groups', | |||||
'qobject', | |||||
'settings', | |||||
'theme', | |||||
'size_rect', | |||||
'initiated' | |||||
] | |||||
# ------------------------------------------------------------------------------ | |||||
# patchcanvas.cpp | |||||
class CanvasObject(QObject): | |||||
def __init__(self, parent): | |||||
QObject.__init__(self, parent) | |||||
@pyqtSlot() | |||||
def CanvasPostponedGroups(self): | |||||
CanvasPostponedGroups() | |||||
@pyqtSlot() | |||||
def PortContextMenuDisconnect(self): | |||||
connection_id_try = self.sender().data().toInt() | |||||
if (connection_id_try[1]): | |||||
CanvasCallback(ACTION_PORTS_DISCONNECT, connection_id_try[0], 0, "") | |||||
# Global objects | |||||
canvas = Canvas() | |||||
canvas.qobject = None | |||||
canvas.settings = None | |||||
canvas.theme = None | |||||
canvas.initiated = False | |||||
options = options_t() | |||||
options.theme_name = getThemeName(getDefaultTheme()) | |||||
options.bezier_lines = True | |||||
options.antialiasing = Qt.PartiallyChecked | |||||
options.auto_hide_groups = True | |||||
options.fancy_eyecandy = False | |||||
features = features_t() | |||||
features.group_info = False | |||||
features.group_rename = True | |||||
features.port_info = False | |||||
features.port_rename = True | |||||
features.handle_group_pos = False | |||||
# Internal functions | |||||
def bool2str(check): | |||||
return "True" if check else "False" | |||||
# PatchCanvas API | |||||
def set_options(new_options): | |||||
if (canvas.initiated): return | |||||
options.theme_name = new_options.theme_name | |||||
options.bezier_lines = new_options.bezier_lines | |||||
options.antialiasing = new_options.antialiasing | |||||
options.auto_hide_groups = new_options.auto_hide_groups | |||||
options.fancy_eyecandy = new_options.fancy_eyecandy | |||||
def set_features(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(scene, callback, debug=False): | |||||
if (debug): | |||||
qDebug("PatchCanvas::init(%s, %s, %s)" % (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_group_id = 0 | |||||
canvas.last_connection_id = 0 | |||||
canvas.initial_pos = QPointF(0, 0) | |||||
canvas.group_list = [] | |||||
canvas.port_list = [] | |||||
canvas.connection_list = [] | |||||
canvas.postponed_groups = [] | |||||
if (not canvas.qobject): canvas.qobject = CanvasObject(None) | |||||
if (not canvas.settings): canvas.settings = QSettings(PATCHCANVAS_ORGANISATION_NAME, "PatchCanvas") | |||||
for i in range(Theme.THEME_MAX): | |||||
this_theme_name = getThemeName(i) | |||||
if (this_theme_name == options.theme_name): | |||||
canvas.theme = Theme(i) | |||||
break | |||||
else: | |||||
canvas.theme = Theme(getDefaultTheme()) | |||||
canvas.size_rect = QRectF() | |||||
canvas.scene.rubberbandByTheme() | |||||
canvas.scene.setBackgroundBrush(canvas.theme.canvas_bg) | |||||
canvas.initiated = True | |||||
def clear(): | |||||
if (canvas.debug): | |||||
qDebug("patchcanvas::clear()") | |||||
group_list_ids = [] | |||||
port_list_ids = [] | |||||
connection_list_ids = [] | |||||
for i in range(len(canvas.group_list)): | |||||
group_list_ids.append(canvas.group_list[i].group_id) | |||||
for i in range(len(canvas.port_list)): | |||||
port_list_ids.append(canvas.port_list[i].port_id) | |||||
for i in range(len(canvas.connection_list)): | |||||
connection_list_ids.append(canvas.connection_list[i].connection_id) | |||||
for idx in connection_list_ids: | |||||
disconnectPorts(idx) | |||||
for idx in port_list_ids: | |||||
removePort(tmp_port_list[i]) | |||||
for idx in group_list_ids: | |||||
removeGroup(idx) | |||||
canvas.last_z_value = 0 | |||||
canvas.last_group_id = 0 | |||||
canvas.last_connection_id = 0 | |||||
canvas.group_list = [] | |||||
canvas.port_list = [] | |||||
canvas.connection_list = [] | |||||
canvas.postponed_groups = [] | |||||
canvas.initiated = False | |||||
def setInitialPos(x, y): | |||||
if (canvas.debug): | |||||
qDebug("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): | |||||
qDebug("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) | |||||
# ------------------------------------------------------------------------------ | |||||
# patchscene.cpp | |||||
class PatchScene(QGraphicsScene): | |||||
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_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) | |||||
self.m_view = view | |||||
if (not self.m_view): | |||||
qFatal("PatchCanvas::PatchScene() - Invalid view") | |||||
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.emit(SIGNAL("scaleChanged(double)"), self.m_view.transform().m11()) | |||||
def rubberbandByTheme(self): | |||||
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 | |||||
items_list = self.items() | |||||
if (len(items_list) > 0): | |||||
for i in range(len(items_list)): | |||||
if (items_list[i].isVisible() and items_list[i].type() == CanvasBoxType): | |||||
pos = items_list[i].scenePos() | |||||
rect = items_list[i].boundingRect() | |||||
if (min_x == None): | |||||
min_x = pos.x() | |||||
elif (pos.x() < min_x): | |||||
min_x = pos.x() | |||||
if (min_y == None): | |||||
min_y = pos.y() | |||||
elif (pos.y() < min_y): | |||||
min_y = pos.y() | |||||
if (max_x == None): | |||||
max_x = pos.x()+rect.width() | |||||
elif (pos.x()+rect.width() > max_x): | |||||
max_x = pos.x()+rect.width() | |||||
if (max_y == None): | |||||
max_y = pos.y()+rect.height() | |||||
elif (pos.y()+rect.height() > max_y): | |||||
max_y = pos.y()+rect.height() | |||||
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.emit(SIGNAL("scaleChanged(double)"), 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.emit(SIGNAL("scaleChanged(double)"), self.m_view.transform().m11()) | |||||
def zoom_reset(self): | |||||
self.m_view.resetTransform() | |||||
self.emit(SIGNAL("scaleChanged(double)"), 1.0) | |||||
def keyPressEvent(self, event): | |||||
if (not self.m_view): | |||||
event.reject() | |||||
if (event.key() == Qt.Key_Control): | |||||
self.m_ctrl_down = True | |||||
if (event.key() == Qt.Key_Home): | |||||
self.zoom_fit() | |||||
event.accept() | |||||
elif (self.m_ctrl_down): | |||||
if (event.key() == Qt.Key_Plus): | |||||
self.zoom_in() | |||||
event.accept() | |||||
elif (event.key() == Qt.Key_Minus): | |||||
self.zoom_out() | |||||
event.accept() | |||||
elif (event.key() == Qt.Key_1): | |||||
self.zoom_reset() | |||||
event.accept() | |||||
else: | |||||
QGraphicsScene.keyPressEvent(self, event) | |||||
else: | |||||
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): | |||||
if (event.button() == Qt.LeftButton): | |||||
self.m_mouse_down_init = True | |||||
else: | |||||
self.m_mouse_down_init = False | |||||
self.m_mouse_rubberband = False | |||||
QGraphicsScene.mousePressEvent(self, event) | |||||
def mouseMoveEvent(self, event): | |||||
if (self.m_mouse_down_init): | |||||
self.m_mouse_rubberband = (len(self.selectedItems()) == 0) | |||||
self.m_mouse_down_init = False | |||||
if (self.m_mouse_rubberband): | |||||
if (self.m_rubberband_selection == False): | |||||
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() | |||||
self.m_rubberband.setRect(x, y, abs(pos.x()-self.m_rubberband_orig_point.x()), abs(pos.y()-self.m_rubberband_orig_point.y())) | |||||
event.accept() | |||||
else: | |||||
QGraphicsScene.mouseMoveEvent(self, event) | |||||
def mouseReleaseEvent(self, event): | |||||
if (self.m_rubberband_selection): | |||||
items_list = self.items() | |||||
if (len(items_list) > 0): | |||||
for item in items_list: | |||||
if (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.isVisible() and item.type() == CanvasBoxType): | |||||
item.checkItemPos() | |||||
self.emit(SIGNAL("sceneGroupMoved(int, int, QPointF)"), item.getGroupId(), item.getSplittedMode(), item.scenePos()) | |||||
self.m_mouse_down_init = False | |||||
self.m_mouse_rubberband = False | |||||
QGraphicsScene.mouseReleaseEvent(self, event) | |||||
def wheelEvent(self, event): | |||||
if (not self.m_view): | |||||
event.reject() | |||||
if (self.m_ctrl_down): | |||||
factor = 1.41 ** (event.delta()/240.0) | |||||
self.m_view.scale(factor, factor) | |||||
self.fixScaleFactor() | |||||
event.accept() | |||||
else: | |||||
QGraphicsScene.wheelEvent(self, event) |
@@ -0,0 +1,167 @@ | |||||
#!/usr/bin/env python3 | |||||
# -*- coding: utf-8 -*- | |||||
# Patchbay Canvas Themes | |||||
# Copyright (C) 2012 Filipe Coelho <falktx@gmail.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 COPYING file | |||||
from PyQt4.QtCore import Qt | |||||
from PyQt4.QtGui import QColor, QFont, QPen | |||||
class Theme(object): | |||||
# enum PortType | |||||
THEME_PORT_SQUARE = 0 | |||||
THEME_PORT_POLYGON = 1 | |||||
# enum List | |||||
THEME_MODERN_DARK = 0 | |||||
THEME_CLASSIC_DARK = 1 | |||||
THEME_MAX = 2 | |||||
def __init__(self, idx): | |||||
super(Theme, self).__init__() | |||||
if (idx == self.THEME_MODERN_DARK): | |||||
# Name this theme | |||||
self.m_name = "Modern Dark" | |||||
# Canvas | |||||
self.canvas_bg = QColor(0,0,0) | |||||
# Boxes | |||||
self.box_pen = QPen(QColor(76,77,78), 1, Qt.SolidLine) | |||||
self.box_pen_sel = QPen(QColor(206,207,208), 1, Qt.DashLine) | |||||
self.box_bg_1 = QColor(32,34,35) | |||||
self.box_bg_2 = QColor(43,47,48) | |||||
self.box_shadow = QColor(89,89,89,180) | |||||
self.box_text = QPen(QColor(240,240,240), 0) | |||||
self.box_font_name = "Deja Vu Sans" | |||||
self.box_font_size = 8 | |||||
self.box_font_state = QFont.Bold | |||||
# Ports | |||||
self.port_audio_jack_pen = QPen(QColor(63,90,126), 1) | |||||
self.port_audio_jack_pen_sel = QPen(QColor(63+30,90+30,126+30), 1) | |||||
self.port_midi_jack_pen = QPen(QColor(159,44,42), 1) | |||||
self.port_midi_jack_pen_sel = QPen(QColor(159+30,44+30,42+30), 1) | |||||
self.port_midi_a2j_pen = QPen(QColor(137,76,43), 1) | |||||
self.port_midi_a2j_pen_sel = QPen(QColor(137+30,76+30,43+30), 1) | |||||
self.port_midi_alsa_pen = QPen(QColor(93,141,46), 1) | |||||
self.port_midi_alsa_pen_sel = QPen(QColor(93+30,141+30,46+30), 1) | |||||
self.port_audio_jack_bg = QColor(35,61,99) | |||||
self.port_audio_jack_bg_sel = QColor(35+50,61+50,99+50) | |||||
self.port_midi_jack_bg = QColor(120,15,16) | |||||
self.port_midi_jack_bg_sel = QColor(120+50,15+50,16+50) | |||||
self.port_midi_a2j_bg = QColor(101,47,16) | |||||
self.port_midi_a2j_bg_sel = QColor(101+50,47+50,16+50) | |||||
self.port_midi_alsa_bg = QColor(64,112,18) | |||||
self.port_midi_alsa_bg_sel = QColor(64+50,112+50,18+50) | |||||
self.port_text = QPen(QColor(250,250,250), 0) | |||||
self.port_font_name = "Deja Vu Sans" | |||||
self.port_font_size = 8 | |||||
self.port_font_state = QFont.Normal | |||||
self.port_mode = self.THEME_PORT_POLYGON | |||||
# Lines | |||||
self.line_audio_jack = QColor(63,90,126) | |||||
self.line_audio_jack_sel = QColor(63+90,90+90,126+90) | |||||
self.line_audio_jack_glow = QColor(100,100,200) | |||||
self.line_midi_jack = QColor(159,44,42) | |||||
self.line_midi_jack_sel = QColor(159+90,44+90,42+90) | |||||
self.line_midi_jack_glow = QColor(200,100,100) | |||||
self.line_midi_a2j = QColor(137,76,43) | |||||
self.line_midi_a2j_sel = QColor(137+90,76+90,43+90) | |||||
self.line_midi_a2j_glow = QColor(166,133,133) | |||||
self.line_midi_alsa = QColor(93,141,46) | |||||
self.line_midi_alsa_sel = QColor(93+90,141+90,46+90) | |||||
self.line_midi_alsa_glow = QColor(100,200,100) | |||||
self.rubberband_pen = QPen(QColor(206,207,208), 1, Qt.SolidLine) | |||||
self.rubberband_brush = QColor(76,77,78,100) | |||||
elif (idx == self.THEME_CLASSIC_DARK): | |||||
# Name this theme | |||||
self.m_name = "Classic Dark" | |||||
# Canvas | |||||
self.canvas_bg = QColor(0,0,0) | |||||
# Boxes | |||||
self.box_pen = QPen(QColor(147-70,151-70,143-70), 2, Qt.SolidLine) | |||||
self.box_pen_sel = QPen(QColor(147,151,143), 2, Qt.DashLine) | |||||
self.box_bg_1 = QColor(30,34,36) | |||||
self.box_bg_2 = QColor(30,34,36) | |||||
self.box_shadow = QColor(89,89,89,180) | |||||
self.box_text = QPen(QColor(255,255,255), 0) | |||||
self.box_font_name = "Sans" | |||||
self.box_font_size = 9 | |||||
self.box_font_state = QFont.Normal | |||||
# Ports | |||||
self.port_audio_jack_pen = QPen(QColor(35,61,99), 0) | |||||
self.port_audio_jack_pen_sel = QPen(QColor(255,0,0), 0) | |||||
self.port_midi_jack_pen = QPen(QColor(120,15,16), 0) | |||||
self.port_midi_jack_pen_sel = QPen(QColor(255,0,0), 0) | |||||
self.port_midi_a2j_pen = QPen(QColor(101,47,17), 0) | |||||
self.port_midi_a2j_pen_sel = QPen(QColor(255,0,0), 0) | |||||
self.port_midi_alsa_pen = QPen(QColor(63,112,19), 0) | |||||
self.port_midi_alsa_pen_sel = QPen(QColor(255,0,0), 0) | |||||
self.port_audio_jack_bg = QColor(35,61,99) | |||||
self.port_audio_jack_bg_sel = QColor(255,0,0) | |||||
self.port_midi_jack_bg = QColor(120,15,16) | |||||
self.port_midi_jack_bg_sel = QColor(255,0,0) | |||||
self.port_midi_a2j_bg = QColor(101,47,17) | |||||
self.port_midi_a2j_bg_sel = QColor(255,0,0) | |||||
self.port_midi_alsa_bg = QColor(63,112,19) | |||||
self.port_midi_alsa_bg_sel = QColor(255,0,0) | |||||
self.port_text = QPen(QColor(250,250,250), 0) | |||||
self.port_font_name = "Sans" | |||||
self.port_font_size = 8 | |||||
self.port_font_state = QFont.Normal | |||||
self.port_mode = self.THEME_PORT_SQUARE | |||||
# Lines | |||||
self.line_audio_jack = QColor(53,78,116) | |||||
self.line_audio_jack_sel = QColor(255,0,0) | |||||
self.line_audio_jack_glow = QColor(255,0,0) | |||||
self.line_midi_jack = QColor(139,32,32) | |||||
self.line_midi_jack_sel = QColor(255,0,0) | |||||
self.line_midi_jack_glow = QColor(255,0,0) | |||||
self.line_midi_a2j = QColor(120,65,33) | |||||
self.line_midi_a2j_sel = QColor(255,0,0) | |||||
self.line_midi_a2j_glow = QColor(255,0,0) | |||||
self.line_midi_alsa = QColor(81,130,36) | |||||
self.line_midi_alsa_sel = QColor(255,0,0) | |||||
self.line_midi_alsa_glow = QColor(255,0,0) | |||||
self.rubberband_pen = QPen(QColor(147,151,143), 2, Qt.SolidLine) | |||||
self.rubberband_brush = QColor(35,61,99,100) | |||||
def getDefaultTheme(): | |||||
return Theme.THEME_MODERN_DARK | |||||
def getThemeName(idx): | |||||
if (idx == Theme.THEME_MODERN_DARK): | |||||
return "Modern Dark" | |||||
elif (idx == Theme.THEME_CLASSIC_DARK): | |||||
return "Classic Dark" | |||||
else: | |||||
return "" |
@@ -210,3 +210,40 @@ def showWindow(self): | |||||
self.showMaximized() | self.showMaximized() | ||||
else: | else: | ||||
self.showNormal() | self.showNormal() | ||||
# Shared Icons | |||||
def setIcons(self, modes): | |||||
if ("canvas" in modes): | |||||
self.act_canvas_arrange.setIcon(getIcon("view-sort-ascending")) | |||||
self.act_canvas_refresh.setIcon(getIcon("view-refresh")) | |||||
self.act_canvas_zoom_fit.setIcon(getIcon("zoom-fit-best")) | |||||
self.act_canvas_zoom_in.setIcon(getIcon("zoom-in")) | |||||
self.act_canvas_zoom_out.setIcon(getIcon("zoom-out")) | |||||
self.act_canvas_zoom_100.setIcon(getIcon("zoom-original")) | |||||
self.act_canvas_print.setIcon(getIcon("document-print")) | |||||
self.b_canvas_zoom_fit.setIcon(getIcon("zoom-fit-best")) | |||||
self.b_canvas_zoom_in.setIcon(getIcon("zoom-in")) | |||||
self.b_canvas_zoom_out.setIcon(getIcon("zoom-out")) | |||||
self.b_canvas_zoom_100.setIcon(getIcon("zoom-original")) | |||||
if ("jack" in modes): | |||||
self.act_jack_clear_xruns.setIcon(getIcon("edit-clear")) | |||||
self.act_jack_configure.setIcon(getIcon("configure")) | |||||
self.act_jack_render.setIcon(getIcon("media-record")) | |||||
self.b_jack_clear_xruns.setIcon(getIcon("edit-clear")) | |||||
self.b_jack_configure.setIcon(getIcon("configure")) | |||||
self.b_jack_render.setIcon(getIcon("media-record")) | |||||
if ("transport" in modes): | |||||
self.act_transport_play.setIcon(getIcon("media-playback-start")) | |||||
self.act_transport_stop.setIcon(getIcon("media-playback-stop")) | |||||
self.act_transport_backwards.setIcon(getIcon("media-seek-backward")) | |||||
self.act_transport_forwards.setIcon(getIcon("media-seek-forward")) | |||||
self.b_transport_play.setIcon(getIcon("media-playback-start")) | |||||
self.b_transport_stop.setIcon(getIcon("media-playback-stop")) | |||||
self.b_transport_backwards.setIcon(getIcon("media-seek-backward")) | |||||
self.b_transport_forwards.setIcon(getIcon("media-seek-forward")) | |||||
if ("misc" in modes): | |||||
self.act_quit.setIcon(getIcon("application-exit")) | |||||
self.act_configure.setIcon(getIcon("configure")) |