@@ -0,0 +1,47 @@ | |||
#------------------------------------------------- | |||
# | |||
# Project created by QtCreator 2011-10-17T21:44:58 | |||
# | |||
#------------------------------------------------- | |||
QT = core gui svg opengl | |||
TEMPLATE = app | |||
CONFIG += debug | |||
TARGET = PatchCanvas | |||
SOURCES = main.cpp canvastestapp.cpp \ | |||
patchcanvas.cpp \ | |||
patchcanvas-theme.cpp \ | |||
patchscene.cpp \ | |||
canvasbox.cpp \ | |||
canvasportglow.cpp \ | |||
canvasboxshadow.cpp \ | |||
canvasicon.cpp \ | |||
canvasfadeanimation.cpp \ | |||
canvasline.cpp \ | |||
canvasport.cpp \ | |||
canvasbezierline.cpp \ | |||
canvaslinemov.cpp \ | |||
canvasbezierlinemov.cpp | |||
HEADERS = canvastestapp.h \ | |||
patchcanvas.h \ | |||
patchcanvas-api.h \ | |||
patchcanvas-theme.h \ | |||
patchscene.h \ | |||
abstractcanvasline.h \ | |||
canvasline.h \ | |||
canvasbezierline.h \ | |||
canvaslinemov.h \ | |||
canvasbezierlinemov.h \ | |||
canvasport.h \ | |||
canvasbox.h \ | |||
canvasicon.h \ | |||
canvasboxshadow.h \ | |||
canvasportglow.h \ | |||
canvasfadeanimation.h | |||
FORMS = canvastestapp.ui | |||
LIBS = -ljack |
@@ -0,0 +1,63 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef ABSTRACTCANVASLINE_H | |||
#define ABSTRACTCANVASLINE_H | |||
#include "patchcanvas.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
class AbstractCanvasLine | |||
{ | |||
public: | |||
AbstractCanvasLine() {} | |||
virtual void deleteFromScene() = 0; | |||
virtual bool isLocked() const = 0; | |||
virtual void setLocked(bool yesno) = 0; | |||
virtual bool isLineSelected() const = 0; | |||
virtual void setLineSelected(bool yesno) = 0; | |||
virtual void updateLinePos() = 0; | |||
virtual int type() const = 0; | |||
// QGraphicsItem generic calls | |||
virtual void setZValue(qreal z) = 0; | |||
}; | |||
class AbstractCanvasLineMov | |||
{ | |||
public: | |||
AbstractCanvasLineMov() {} | |||
virtual void deleteFromScene() = 0; | |||
virtual void updateLinePos(QPointF scenePos) = 0; | |||
virtual int type() const = 0; | |||
// QGraphicsItem generic calls | |||
virtual void setZValue(qreal z) = 0; | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // ABSTRACTCANVASLINE_H |
@@ -0,0 +1,162 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "canvasbezierline.h" | |||
#include <QtGui/QPainter> | |||
#include "canvasport.h" | |||
#include "canvasportglow.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
CanvasBezierLine::CanvasBezierLine(CanvasPort* item1_, CanvasPort* item2_, QGraphicsItem* parent) : | |||
QGraphicsPathItem(parent, canvas.scene) | |||
{ | |||
item1 = item1_; | |||
item2 = item2_; | |||
m_locked = false; | |||
m_lineSelected = false; | |||
setBrush(QColor(0,0,0,0)); | |||
setGraphicsEffect(0); | |||
updateLinePos(); | |||
} | |||
CanvasBezierLine::~CanvasBezierLine() | |||
{ | |||
setGraphicsEffect(0); | |||
} | |||
void CanvasBezierLine::deleteFromScene() | |||
{ | |||
canvas.scene->removeItem(this); | |||
delete this; | |||
} | |||
bool CanvasBezierLine::isLocked() const | |||
{ | |||
return m_locked; | |||
} | |||
void CanvasBezierLine::setLocked(bool yesno) | |||
{ | |||
m_locked = yesno; | |||
} | |||
bool CanvasBezierLine::isLineSelected() const | |||
{ | |||
return m_lineSelected; | |||
} | |||
void CanvasBezierLine::setLineSelected(bool yesno) | |||
{ | |||
if (m_locked) | |||
return; | |||
if (options.eyecandy) | |||
{ | |||
if (yesno) | |||
setGraphicsEffect(new CanvasPortGlow(item1->getPortType(), toGraphicsObject())); | |||
else | |||
setGraphicsEffect(0); | |||
} | |||
m_lineSelected = yesno; | |||
updateLineGradient(); | |||
} | |||
void CanvasBezierLine::updateLinePos() | |||
{ | |||
if (item1->getPortMode() == PORT_MODE_OUTPUT) | |||
{ | |||
int item1_x = item1->scenePos().x() + item1->getPortWidth()+12; | |||
int item1_y = item1->scenePos().y() + 7.5; | |||
int item2_x = item2->scenePos().x(); | |||
int item2_y = item2->scenePos().y()+7.5; | |||
int item1_mid_x = abs(item1_x-item2_x)/2; | |||
int item1_new_x = item1_x+item1_mid_x; | |||
int item2_mid_x = abs(item1_x-item2_x)/2; | |||
int item2_new_x = item2_x-item2_mid_x; | |||
QPainterPath path(QPointF(item1_x, item1_y)); | |||
path.cubicTo(item1_new_x, item1_y, item2_new_x, item2_y, item2_x, item2_y); | |||
setPath(path); | |||
m_lineSelected = false; | |||
updateLineGradient(); | |||
} | |||
} | |||
int CanvasBezierLine::type() const | |||
{ | |||
return CanvasBezierLineType; | |||
} | |||
void CanvasBezierLine::updateLineGradient() | |||
{ | |||
short pos1, pos2; | |||
int pos_top = boundingRect().top(); | |||
int pos_bot = boundingRect().bottom(); | |||
if (item2->scenePos().y() >= item1->scenePos().y()) | |||
{ | |||
pos1 = 0; | |||
pos2 = 1; | |||
} | |||
else | |||
{ | |||
pos1 = 1; | |||
pos2 = 0; | |||
} | |||
PortType port_type1 = item1->getPortType(); | |||
PortType port_type2 = item2->getPortType(); | |||
QLinearGradient port_gradient(0, pos_top, 0, pos_bot); | |||
if (port_type1 == PORT_TYPE_AUDIO_JACK) | |||
port_gradient.setColorAt(pos1, m_lineSelected ? canvas.theme->line_audio_jack_sel : canvas.theme->line_audio_jack); | |||
else if (port_type1 == PORT_TYPE_MIDI_JACK) | |||
port_gradient.setColorAt(pos1, m_lineSelected ? canvas.theme->line_midi_jack_sel : canvas.theme->line_midi_jack); | |||
else if (port_type1 == PORT_TYPE_MIDI_A2J) | |||
port_gradient.setColorAt(pos1, m_lineSelected ? canvas.theme->line_midi_a2j_sel : canvas.theme->line_midi_a2j); | |||
else if (port_type1 == PORT_TYPE_MIDI_ALSA) | |||
port_gradient.setColorAt(pos1, m_lineSelected ? canvas.theme->line_midi_alsa_sel : canvas.theme->line_midi_alsa); | |||
if (port_type2 == PORT_TYPE_AUDIO_JACK) | |||
port_gradient.setColorAt(pos2, m_lineSelected ? canvas.theme->line_audio_jack_sel : canvas.theme->line_audio_jack); | |||
else if (port_type2 == PORT_TYPE_MIDI_JACK) | |||
port_gradient.setColorAt(pos2, m_lineSelected ? canvas.theme->line_midi_jack_sel : canvas.theme->line_midi_jack); | |||
else if (port_type2 == PORT_TYPE_MIDI_A2J) | |||
port_gradient.setColorAt(pos2, m_lineSelected ? canvas.theme->line_midi_a2j_sel : canvas.theme->line_midi_a2j); | |||
else if (port_type2 == PORT_TYPE_MIDI_ALSA) | |||
port_gradient.setColorAt(pos2, m_lineSelected ? canvas.theme->line_midi_alsa_sel : canvas.theme->line_midi_alsa); | |||
setPen(QPen(port_gradient, 2)); | |||
} | |||
void CanvasBezierLine::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) | |||
{ | |||
painter->setRenderHint(QPainter::Antialiasing, bool(options.antialiasing)); | |||
QGraphicsPathItem::paint(painter, option, widget); | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,72 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef CANVASBEZIERLINE_H | |||
#define CANVASBEZIERLINE_H | |||
#include <QtGui/QGraphicsPathItem> | |||
#include "abstractcanvasline.h" | |||
class QPainter; | |||
START_NAMESPACE_PATCHCANVAS | |||
class CanvasPort; | |||
class CanvasPortGlow; | |||
class CanvasBezierLine : | |||
public AbstractCanvasLine, | |||
public QGraphicsPathItem | |||
{ | |||
public: | |||
CanvasBezierLine(CanvasPort* item1, CanvasPort* item2, QGraphicsItem* parent); | |||
~CanvasBezierLine(); | |||
virtual void deleteFromScene(); | |||
virtual bool isLocked() const; | |||
virtual void setLocked(bool yesno); | |||
virtual bool isLineSelected() const; | |||
virtual void setLineSelected(bool yesno); | |||
virtual void updateLinePos(); | |||
virtual int type() const; | |||
// QGraphicsItem generic calls | |||
virtual void setZValue(qreal z) | |||
{ | |||
QGraphicsPathItem::setZValue(z); | |||
} | |||
private: | |||
CanvasPort* item1; | |||
CanvasPort* item2; | |||
CanvasPortGlow* glow; | |||
bool m_locked; | |||
bool m_lineSelected; | |||
void updateLineGradient(); | |||
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget); | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // CANVASBEZIERLINE_H |
@@ -0,0 +1,104 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "canvasbezierlinemov.h" | |||
#include <QtGui/QPainter> | |||
#include "canvasport.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
CanvasBezierLineMov::CanvasBezierLineMov(PortMode port_mode, PortType port_type, QGraphicsItem* parent) : | |||
QGraphicsPathItem(parent, canvas.scene) | |||
{ | |||
m_port_mode = port_mode; | |||
m_port_type = port_type; | |||
// Port position doesn't change while moving around line | |||
p_itemX = scenePos().x(); | |||
p_itemY = scenePos().y(); | |||
p_width = ((CanvasPort*)parentItem())->getPortWidth(); | |||
QPen pen; | |||
if (port_type == PORT_TYPE_AUDIO_JACK) | |||
pen = QPen(canvas.theme->line_audio_jack, 2); | |||
else if (port_type == PORT_TYPE_MIDI_JACK) | |||
pen = QPen(canvas.theme->line_midi_jack, 2); | |||
else if (port_type == PORT_TYPE_MIDI_A2J) | |||
pen = QPen(canvas.theme->line_midi_a2j, 2); | |||
else if (port_type == PORT_TYPE_MIDI_ALSA) | |||
pen = QPen(canvas.theme->line_midi_alsa, 2); | |||
else | |||
{ | |||
qWarning("PatchCanvas::CanvasBezierLineMov(%s, %s, %p) - invalid port type", port_mode2str(port_mode), port_type2str(port_type), parent); | |||
pen = QPen(Qt::black); | |||
} | |||
QColor color(0,0,0,0); | |||
setBrush(color); | |||
setPen(pen); | |||
} | |||
void CanvasBezierLineMov::deleteFromScene() | |||
{ | |||
canvas.scene->removeItem(this); | |||
delete this; | |||
} | |||
void CanvasBezierLineMov::updateLinePos(QPointF scenePos) | |||
{ | |||
int old_x, old_y, mid_x, new_x, final_x, final_y; | |||
if (m_port_mode == PORT_MODE_INPUT) | |||
{ | |||
old_x = 0; | |||
old_y = 7.5; | |||
mid_x = abs(scenePos.x()-p_itemX)/2; | |||
new_x = old_x-mid_x; | |||
} | |||
else if (m_port_mode == PORT_MODE_OUTPUT) | |||
{ | |||
old_x = p_width+12; | |||
old_y = 7.5; | |||
mid_x = abs(scenePos.x()-(p_itemX+old_x))/2; | |||
new_x = old_x+mid_x; | |||
} | |||
else | |||
return; | |||
final_x = scenePos.x()-p_itemX; | |||
final_y = scenePos.y()-p_itemY; | |||
QPainterPath path(QPointF(old_x, old_y)); | |||
path.cubicTo(new_x, old_y, new_x, final_y, final_x, final_y); | |||
setPath(path); | |||
} | |||
int CanvasBezierLineMov::type() const | |||
{ | |||
return CanvasBezierLineMovType; | |||
} | |||
void CanvasBezierLineMov::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) | |||
{ | |||
painter->setRenderHint(QPainter::Antialiasing, bool(options.antialiasing)); | |||
QGraphicsPathItem::paint(painter, option, widget); | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,60 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef CANVASBEZIERLINEMOV_H | |||
#define CANVASBEZIERLINEMOV_H | |||
#include <QtGui/QGraphicsPathItem> | |||
#include "abstractcanvasline.h" | |||
class QPainter; | |||
START_NAMESPACE_PATCHCANVAS | |||
class CanvasBezierLineMov : | |||
public AbstractCanvasLineMov, | |||
public QGraphicsPathItem | |||
{ | |||
public: | |||
CanvasBezierLineMov(PortMode port_mode, PortType port_type, QGraphicsItem* parent); | |||
virtual void deleteFromScene(); | |||
virtual void updateLinePos(QPointF scenePos); | |||
virtual int type() const; | |||
// QGraphicsItem generic calls | |||
virtual void setZValue(qreal z) | |||
{ | |||
QGraphicsPathItem::setZValue(z); | |||
} | |||
private: | |||
PortMode m_port_mode; | |||
PortType m_port_type; | |||
int p_itemX; | |||
int p_itemY; | |||
int p_width; | |||
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget); | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // CANVASBEZIERLINEMOV_H |
@@ -0,0 +1,680 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "canvasbox.h" | |||
#include <QtCore/QTimer> | |||
#include <QtGui/QCursor> | |||
#include <QtGui/QInputDialog> | |||
#include <QtGui/QMenu> | |||
#include <QtGui/QGraphicsSceneContextMenuEvent> | |||
#include <QtGui/QGraphicsSceneMouseEvent> | |||
#include <QtGui/QPainter> | |||
#include "canvasline.h" | |||
#include "canvasbezierline.h" | |||
#include "canvasport.h" | |||
#include "canvasboxshadow.h" | |||
#include "canvasicon.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
CanvasBox::CanvasBox(int group_id, QString group_name, Icon icon, QGraphicsItem* parent) : | |||
QGraphicsItem(parent, canvas.scene) | |||
{ | |||
// Save Variables, useful for later | |||
m_group_id = group_id; | |||
m_group_name = group_name; | |||
// Base Variables | |||
p_width = 50; | |||
p_height = 25; | |||
m_last_pos = QPointF(); | |||
m_splitted = false; | |||
m_splitted_mode = PORT_MODE_NULL; | |||
m_cursor_moving = false; | |||
m_forced_split = false; | |||
m_mouse_down = false; | |||
m_port_list_ids.clear(); | |||
m_connection_lines.clear(); | |||
// Set Font | |||
m_font_name = QFont(canvas.theme->box_font_name, canvas.theme->box_font_size, canvas.theme->box_font_state); | |||
m_font_port = QFont(canvas.theme->port_font_name, canvas.theme->port_font_size, canvas.theme->port_font_state); | |||
// Icon | |||
icon_svg = new CanvasIcon(icon, group_name, this); | |||
// Shadow | |||
if (options.eyecandy) | |||
{ | |||
shadow = new CanvasBoxShadow(toGraphicsObject()); | |||
shadow->setFakeParent(this); | |||
setGraphicsEffect(shadow); | |||
} | |||
else | |||
shadow = 0; | |||
// Final touches | |||
setFlags(QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemIsSelectable); | |||
// Wait for at least 1 port | |||
if (options.auto_hide_groups) | |||
setVisible(false); | |||
updatePositions(); | |||
} | |||
CanvasBox::~CanvasBox() | |||
{ | |||
if (shadow) | |||
delete shadow; | |||
delete icon_svg; | |||
} | |||
int CanvasBox::getGroupId() | |||
{ | |||
return m_group_id; | |||
} | |||
QString CanvasBox::getGroupName() | |||
{ | |||
return m_group_name; | |||
} | |||
bool CanvasBox::isSplitted() | |||
{ | |||
return m_splitted; | |||
} | |||
PortMode CanvasBox::getSplittedMode() | |||
{ | |||
return m_splitted_mode; | |||
} | |||
int CanvasBox::getPortCount() | |||
{ | |||
return m_port_list_ids.count(); | |||
} | |||
QList<int> CanvasBox::getPortList() | |||
{ | |||
return m_port_list_ids; | |||
} | |||
void CanvasBox::setIcon(Icon icon) | |||
{ | |||
icon_svg->setIcon(icon, m_group_name); | |||
} | |||
void CanvasBox::setSplit(bool split, PortMode mode) | |||
{ | |||
m_splitted = split; | |||
m_splitted_mode = mode; | |||
} | |||
void CanvasBox::setGroupName(QString group_name) | |||
{ | |||
m_group_name = group_name; | |||
updatePositions(); | |||
} | |||
CanvasPort* CanvasBox::addPortFromGroup(int port_id, QString port_name, PortMode port_mode, PortType port_type) | |||
{ | |||
if (m_port_list_ids.count() == 0) | |||
{ | |||
if (options.auto_hide_groups) | |||
setVisible(true); | |||
} | |||
CanvasPort* new_widget = new CanvasPort(port_id, port_name, port_mode, port_type, this); | |||
port_dict_t port_dict; | |||
port_dict.group_id = 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.widget = new_widget; | |||
m_port_list_ids.append(port_id); | |||
return new_widget; | |||
} | |||
void CanvasBox::removePortFromGroup(int port_id) | |||
{ | |||
if (m_port_list_ids.contains(port_id)) | |||
{ | |||
m_port_list_ids.removeOne(port_id); | |||
} | |||
else | |||
{ | |||
qCritical("PatchCanvas::CanvasBox->removePort(%i) - unable to find port to remove", port_id); | |||
return; | |||
} | |||
if (m_port_list_ids.count() > 0) | |||
{ | |||
updatePositions(); | |||
} | |||
else if (isVisible()) | |||
{ | |||
if (options.auto_hide_groups) | |||
setVisible(false); | |||
} | |||
} | |||
void CanvasBox::addLineFromGroup(AbstractCanvasLine* line, int connection_id) | |||
{ | |||
cb_line_t new_cbline; | |||
new_cbline.line = line; | |||
new_cbline.connection_id = connection_id; | |||
m_connection_lines.append(new_cbline); | |||
} | |||
void CanvasBox::removeLineFromGroup(int connection_id) | |||
{ | |||
foreach2 (const cb_line_t& connection, m_connection_lines) | |||
if (connection.connection_id == connection_id) | |||
{ | |||
m_connection_lines.takeAt(i); | |||
return; | |||
} | |||
} | |||
qCritical("PatchCanvas::CanvasBox->removeLineFromGroup(%i) - unable to find line to remove", connection_id); | |||
} | |||
void CanvasBox::checkItemPos() | |||
{ | |||
if (canvas.size_rect.isNull() == false) | |||
{ | |||
QPointF pos = scenePos(); | |||
if (canvas.size_rect.contains(pos) == false || canvas.size_rect.contains(pos+QPointF(p_width, p_height)) == false) | |||
{ | |||
if (pos.x() < canvas.size_rect.x()) | |||
setPos(canvas.size_rect.x(), pos.y()); | |||
else if (pos.x()+p_width > canvas.size_rect.width()) | |||
setPos(canvas.size_rect.width()-p_width, pos.y()); | |||
pos = scenePos(); | |||
if (pos.y() < canvas.size_rect.y()) | |||
setPos(pos.x(), canvas.size_rect.y()); | |||
else if (pos.y()+p_height > canvas.size_rect.height()) | |||
setPos(pos.x(), canvas.size_rect.height()-p_height); | |||
} | |||
} | |||
} | |||
void CanvasBox::removeIconFromScene() | |||
{ | |||
canvas.scene->removeItem(icon_svg); | |||
} | |||
void CanvasBox::updatePositions() | |||
{ | |||
prepareGeometryChange(); | |||
int max_in_width = 0; | |||
int max_in_height = 24; | |||
int max_out_width = 0; | |||
int max_out_height = 24; | |||
bool have_audio_jack_in, have_audio_jack_out, have_midi_jack_in, have_midi_jack_out; | |||
bool have_midi_a2j_in, have_midi_a2j_out, have_midi_alsa_in, have_midi_alsa_out; | |||
have_audio_jack_in = have_midi_jack_in = have_midi_a2j_in = have_midi_alsa_in = false; | |||
have_audio_jack_out = have_midi_jack_out = have_midi_a2j_out = have_midi_alsa_out = false; | |||
// reset box size | |||
p_width = 50; | |||
p_height = 25; | |||
// Check Text Name size | |||
int app_name_size = QFontMetrics(m_font_name).width(m_group_name)+30; | |||
if (app_name_size > p_width) | |||
p_width = app_name_size; | |||
// Get Port List | |||
QList<port_dict_t> port_list; | |||
foreach (const port_dict_t& port, canvas.port_list) | |||
{ | |||
if (m_port_list_ids.contains(port.port_id)) | |||
port_list.append(port); | |||
} | |||
// Get Max Box Width/Height | |||
foreach (const port_dict_t& port, port_list) | |||
{ | |||
if (port.port_mode == PORT_MODE_INPUT) | |||
{ | |||
max_in_height += 18; | |||
int size = QFontMetrics(m_font_port).width(port.port_name); | |||
if (size > max_in_width) | |||
max_in_width = size; | |||
if (port.port_type == PORT_TYPE_AUDIO_JACK && have_audio_jack_in == false) | |||
{ | |||
have_audio_jack_in = true; | |||
max_in_height += 2; | |||
} | |||
else if (port.port_type == PORT_TYPE_MIDI_JACK && have_midi_jack_in == false) | |||
{ | |||
have_midi_jack_in = true; | |||
max_in_height += 2; | |||
} | |||
else if (port.port_type == PORT_TYPE_MIDI_A2J && have_midi_a2j_in == false) | |||
{ | |||
have_midi_a2j_in = true; | |||
max_in_height += 2; | |||
} | |||
else if (port.port_type == PORT_TYPE_MIDI_ALSA && have_midi_alsa_in == false) | |||
{ | |||
have_midi_alsa_in = true; | |||
max_in_height += 2; | |||
} | |||
} | |||
else if (port.port_mode == PORT_MODE_OUTPUT) | |||
{ | |||
max_out_height += 18; | |||
int size = QFontMetrics(m_font_port).width(port.port_name); | |||
if (size > max_out_width) | |||
max_out_width = size; | |||
if (port.port_type == PORT_TYPE_AUDIO_JACK && have_audio_jack_out == false) | |||
{ | |||
have_audio_jack_out = true; | |||
max_out_height += 2; | |||
} | |||
else if (port.port_type == PORT_TYPE_MIDI_JACK && have_midi_jack_out == false) | |||
{ | |||
have_midi_jack_out = true; | |||
max_out_height += 2; | |||
} | |||
else if (port.port_type == PORT_TYPE_MIDI_A2J && have_midi_a2j_out == false) | |||
{ | |||
have_midi_a2j_out = true; | |||
max_out_height += 2; | |||
} | |||
else if (port.port_type == PORT_TYPE_MIDI_ALSA && have_midi_alsa_out == false) | |||
{ | |||
have_midi_alsa_out = true; | |||
max_out_height += 2; | |||
} | |||
} | |||
} | |||
int final_width = 30 + max_in_width + max_out_width; | |||
if (final_width > p_width) | |||
p_width = final_width; | |||
if (max_in_height > p_height) | |||
p_height = max_in_height; | |||
if (max_out_height > p_height) | |||
p_height = max_out_height; | |||
// Remove bottom space | |||
p_height -= 2; | |||
int last_in_pos = 24; | |||
int last_out_pos = 24; | |||
PortType last_in_type = PORT_TYPE_NULL; | |||
PortType last_out_type = PORT_TYPE_NULL; | |||
// Re-position ports, AUDIO_JACK | |||
foreach (const port_dict_t& port, port_list) | |||
{ | |||
if (port.port_type == PORT_TYPE_AUDIO_JACK) | |||
{ | |||
if (port.port_mode == PORT_MODE_INPUT) | |||
{ | |||
port.widget->setPos(QPointF(1, last_in_pos)); | |||
port.widget->setPortWidth(max_in_width); | |||
last_in_pos += 18; | |||
last_in_type = port.port_type; | |||
} | |||
else if (port.port_mode == PORT_MODE_OUTPUT) | |||
{ | |||
port.widget->setPos(QPointF(p_width-max_out_width-13, last_out_pos)); | |||
port.widget->setPortWidth(max_out_width); | |||
last_out_pos += 18; | |||
last_out_type = port.port_type; | |||
} | |||
} | |||
} | |||
// Re-position ports, MIDI_JACK | |||
foreach (const port_dict_t& port, port_list) | |||
{ | |||
if (port.port_type == PORT_TYPE_MIDI_JACK) | |||
{ | |||
if (port.port_mode == PORT_MODE_INPUT) | |||
{ | |||
if (last_in_type != PORT_TYPE_NULL && port.port_type != last_in_type) | |||
last_in_pos += 2; | |||
port.widget->setPos(QPointF(1, last_in_pos)); | |||
port.widget->setPortWidth(max_in_width); | |||
last_in_pos += 18; | |||
last_in_type = port.port_type; | |||
} | |||
else if (port.port_mode == PORT_MODE_OUTPUT) | |||
{ | |||
if (last_out_type != PORT_TYPE_NULL && port.port_type != last_out_type) | |||
last_out_pos += 2; | |||
port.widget->setPos(QPointF(p_width-max_out_width-13, last_out_pos)); | |||
port.widget->setPortWidth(max_out_width); | |||
last_out_pos += 18; | |||
last_out_type = port.port_type; | |||
} | |||
} | |||
} | |||
// Re-position ports, MIDI_A2J | |||
foreach (const port_dict_t& port, port_list) | |||
{ | |||
if (port.port_type == PORT_TYPE_MIDI_A2J) | |||
{ | |||
if (port.port_mode == PORT_MODE_INPUT) | |||
{ | |||
if (last_in_type != PORT_TYPE_NULL && port.port_type != last_in_type) | |||
last_in_pos += 2; | |||
port.widget->setPos(QPointF(1, last_in_pos)); | |||
port.widget->setPortWidth(max_in_width); | |||
last_in_pos += 18; | |||
last_in_type = port.port_type; | |||
} | |||
else if (port.port_mode == PORT_MODE_OUTPUT) | |||
{ | |||
if (last_out_type != PORT_TYPE_NULL && port.port_type != last_out_type) | |||
last_out_pos += 2; | |||
port.widget->setPos(QPointF(p_width-max_out_width-13, last_out_pos)); | |||
port.widget->setPortWidth(max_out_width); | |||
last_out_pos += 18; | |||
last_out_type = port.port_type; | |||
} | |||
} | |||
} | |||
// Re-position ports, MIDI_ALSA | |||
foreach (const port_dict_t& port, port_list) | |||
{ | |||
if (port.port_type == PORT_TYPE_MIDI_ALSA) | |||
{ | |||
if (port.port_mode == PORT_MODE_INPUT) | |||
{ | |||
if (last_in_type != PORT_TYPE_NULL && port.port_type != last_in_type) | |||
last_in_pos += 2; | |||
port.widget->setPos(QPointF(1, last_in_pos)); | |||
port.widget->setPortWidth(max_in_width); | |||
last_in_pos += 18; | |||
last_in_type = port.port_type; | |||
} | |||
else if (port.port_mode == PORT_MODE_OUTPUT) | |||
{ | |||
if (last_out_type != PORT_TYPE_NULL && port.port_type != last_out_type) | |||
last_out_pos += 2; | |||
port.widget->setPos(QPointF(p_width-max_out_width-13, last_out_pos)); | |||
port.widget->setPortWidth(max_out_width); | |||
last_out_pos += 18; | |||
last_out_type = port.port_type; | |||
} | |||
} | |||
} | |||
repaintLines(true); | |||
update(); | |||
} | |||
void CanvasBox::repaintLines(bool forced) | |||
{ | |||
if (pos() != m_last_pos || forced) | |||
{ | |||
foreach (const cb_line_t& connection, m_connection_lines) | |||
connection.line->updateLinePos(); | |||
} | |||
m_last_pos = pos(); | |||
} | |||
void CanvasBox::resetLinesZValue() | |||
{ | |||
foreach (const connection_dict_t& connection, canvas.connection_list) | |||
{ | |||
int z_value; | |||
if (m_port_list_ids.contains(connection.port_out_id) && m_port_list_ids.contains(connection.port_in_id)) | |||
z_value = canvas.last_z_value; | |||
else | |||
z_value = canvas.last_z_value-1; | |||
connection.widget->setZValue(z_value); | |||
} | |||
} | |||
int CanvasBox::type() const | |||
{ | |||
return CanvasBoxType; | |||
} | |||
void CanvasBox::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) | |||
{ | |||
QMenu menu; | |||
QMenu discMenu("Disconnect", &menu); | |||
QList<int> port_con_list; | |||
QList<int> port_con_list_ids; | |||
foreach (const int& port_id, m_port_list_ids) | |||
{ | |||
QList<int> tmp_port_con_list = CanvasGetPortConnectionList(port_id); | |||
foreach (const int& port_con_id, tmp_port_con_list) | |||
{ | |||
if (port_con_list.contains(port_con_id) == false) | |||
{ | |||
port_con_list.append(port_con_id); | |||
port_con_list_ids.append(port_id); | |||
} | |||
} | |||
} | |||
if (port_con_list.count() > 0) | |||
{ | |||
for (int i=0; i < port_con_list.count(); i++) | |||
{ | |||
int port_con_id = CanvasGetConnectedPort(port_con_list[i], port_con_list_ids[i]); | |||
QAction* act_x_disc = discMenu.addAction(CanvasGetFullPortName(port_con_id)); | |||
act_x_disc->setData(port_con_list[i]); | |||
QObject::connect(act_x_disc, SIGNAL(triggered()), canvas.qobject, SLOT(PortContextMenuDisconnect())); | |||
} | |||
} | |||
else | |||
{ | |||
QAction* act_x_disc = discMenu.addAction("No connections"); | |||
act_x_disc->setEnabled(false); | |||
} | |||
menu.addMenu(&discMenu); | |||
QAction* act_x_disc_all = menu.addAction("Disconnect &All"); | |||
QAction* act_x_sep1 = menu.addSeparator(); | |||
QAction* act_x_info = menu.addAction("&Info"); | |||
QAction* act_x_rename = menu.addAction("&Rename"); | |||
QAction* act_x_sep2 = menu.addSeparator(); | |||
QAction* act_x_split_join = menu.addAction(m_splitted ? "Join" : "Split"); | |||
if (features.group_info == false) | |||
act_x_info->setVisible(false); | |||
if (features.group_rename == false) | |||
act_x_rename->setVisible(false); | |||
if (features.group_info == false && features.group_rename == false) | |||
act_x_sep1->setVisible(false); | |||
bool haveIns, haveOuts; | |||
haveIns = haveOuts = false; | |||
foreach (const port_dict_t& port, canvas.port_list) | |||
{ | |||
if (m_port_list_ids.contains(port.port_id)) | |||
{ | |||
if (port.port_mode == PORT_MODE_INPUT) | |||
haveIns = true; | |||
else if (port.port_mode == PORT_MODE_OUTPUT) | |||
haveOuts = true; | |||
} | |||
} | |||
if (m_splitted == false && (haveIns && haveOuts) == false) | |||
{ | |||
act_x_sep2->setVisible(false); | |||
act_x_split_join->setVisible(false); | |||
} | |||
QAction* act_selected = menu.exec(event->screenPos()); | |||
if (act_selected == act_x_disc_all) | |||
{ | |||
foreach (const int& port_id, port_con_list) | |||
canvas.callback(ACTION_PORTS_DISCONNECT, port_id, 0, ""); | |||
} | |||
else if (act_selected == act_x_info) | |||
{ | |||
canvas.callback(ACTION_GROUP_INFO, m_group_id, 0, ""); | |||
} | |||
else if (act_selected == act_x_rename) | |||
{ | |||
bool ok_check; | |||
QString new_name = QInputDialog::getText(0, "Rename Group", "New name:", QLineEdit::Normal, m_group_name, &ok_check); | |||
if (ok_check and !new_name.isEmpty()) | |||
{ | |||
canvas.callback(ACTION_GROUP_RENAME, m_group_id, 0, new_name); | |||
} | |||
} | |||
else if (act_selected == act_x_split_join) | |||
{ | |||
if (m_splitted) | |||
canvas.callback(ACTION_GROUP_JOIN, m_group_id, 0, ""); | |||
else | |||
canvas.callback(ACTION_GROUP_SPLIT, m_group_id, 0, ""); | |||
} | |||
event->accept(); | |||
} | |||
void CanvasBox::mousePressEvent(QGraphicsSceneMouseEvent* event) | |||
{ | |||
canvas.last_z_value += 1; | |||
setZValue(canvas.last_z_value); | |||
resetLinesZValue(); | |||
m_cursor_moving = false; | |||
if (event->button() == Qt::RightButton) | |||
{ | |||
canvas.scene->clearSelection(); | |||
setSelected(true); | |||
m_mouse_down = false; | |||
return event->accept(); | |||
} | |||
else if (event->button() == Qt::LeftButton) | |||
{ | |||
if (sceneBoundingRect().contains(event->scenePos())) | |||
m_mouse_down = true; | |||
else | |||
{ | |||
// Fixes a weird Qt behaviour with right-click mouseMove | |||
m_mouse_down = false; | |||
return event->ignore(); | |||
} | |||
} | |||
else | |||
m_mouse_down = false; | |||
QGraphicsItem::mousePressEvent(event); | |||
} | |||
void CanvasBox::mouseMoveEvent(QGraphicsSceneMouseEvent* event) | |||
{ | |||
if (m_mouse_down) | |||
{ | |||
if (m_cursor_moving == false) | |||
{ | |||
setCursor(QCursor(Qt::SizeAllCursor)); | |||
m_cursor_moving = true; | |||
} | |||
repaintLines(); | |||
} | |||
QGraphicsItem::mouseMoveEvent(event); | |||
} | |||
void CanvasBox::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) | |||
{ | |||
if (m_cursor_moving) | |||
setCursor(QCursor(Qt::ArrowCursor)); | |||
m_mouse_down = false; | |||
m_cursor_moving = false; | |||
QGraphicsItem::mouseReleaseEvent(event); | |||
} | |||
QRectF CanvasBox::boundingRect() const | |||
{ | |||
return QRectF(0, 0, p_width, p_height); | |||
} | |||
void CanvasBox::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) | |||
{ | |||
painter->setRenderHint(QPainter::Antialiasing, false); | |||
if (isSelected()) | |||
painter->setPen(canvas.theme->box_pen_sel); | |||
else | |||
painter->setPen(canvas.theme->box_pen); | |||
QLinearGradient box_gradient(0, 0, 0, p_height); | |||
box_gradient.setColorAt(0, canvas.theme->box_bg_1); | |||
box_gradient.setColorAt(1, canvas.theme->box_bg_2); | |||
painter->setBrush(box_gradient); | |||
painter->drawRect(0, 0, p_width, p_height); | |||
QPointF text_pos(25, 16); | |||
painter->setFont(m_font_name); | |||
painter->setPen(canvas.theme->box_text); | |||
painter->drawText(text_pos, m_group_name); | |||
repaintLines(); | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,106 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef CANVASBOX_H | |||
#define CANVASBOX_H | |||
#include "patchcanvas.h" | |||
class QGraphicsSceneContextMenuEvent; | |||
class QGraphicsSceneMouseEvent; | |||
class QPainter; | |||
START_NAMESPACE_PATCHCANVAS | |||
class AbstractCanvasLine; | |||
class CanvasBoxShadow; | |||
class CanvasPort; | |||
class CanvasIcon; | |||
struct cb_line_t { | |||
AbstractCanvasLine* line; | |||
int connection_id; | |||
}; | |||
class CanvasBox : public QGraphicsItem | |||
{ | |||
public: | |||
CanvasBox(int group_id, QString group_name, Icon icon, QGraphicsItem* parent=0); | |||
virtual ~CanvasBox(); | |||
int getGroupId(); | |||
QString getGroupName(); | |||
bool isSplitted(); | |||
PortMode getSplittedMode(); | |||
int getPortCount(); | |||
QList<int> getPortList(); | |||
void setIcon(Icon icon); | |||
void setSplit(bool split, PortMode mode=PORT_MODE_NULL); | |||
void setGroupName(QString group_name); | |||
CanvasPort* addPortFromGroup(int port_id, QString port_name, PortMode port_mode, PortType port_type); | |||
void removePortFromGroup(int port_id); | |||
void addLineFromGroup(AbstractCanvasLine* line, int connection_id); | |||
void removeLineFromGroup(int connection_id); | |||
void checkItemPos(); | |||
void removeIconFromScene(); | |||
void updatePositions(); | |||
void repaintLines(bool forced=false); | |||
void resetLinesZValue(); | |||
virtual int type() const; | |||
private: | |||
int m_group_id; | |||
QString m_group_name; | |||
int p_width; | |||
int p_height; | |||
QList<int> m_port_list_ids; | |||
QList<cb_line_t> m_connection_lines; | |||
QPointF m_last_pos; | |||
bool m_splitted; | |||
PortMode m_splitted_mode; | |||
bool m_forced_split; | |||
bool m_cursor_moving; | |||
bool m_mouse_down; | |||
QFont m_font_name; | |||
QFont m_font_port; | |||
CanvasIcon* icon_svg; | |||
CanvasBoxShadow* shadow; | |||
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent* event); | |||
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); | |||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event); | |||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event); | |||
virtual QRectF boundingRect() const; | |||
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget); | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // CANVASBOX_H |
@@ -0,0 +1,46 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "canvasboxshadow.h" | |||
#include "canvasbox.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
CanvasBoxShadow::CanvasBoxShadow(QObject* parent) : | |||
QGraphicsDropShadowEffect(parent) | |||
{ | |||
m_fakeParent = 0; | |||
setBlurRadius(20); | |||
setColor(canvas.theme->box_shadow); | |||
setOffset(0, 0); | |||
} | |||
void CanvasBoxShadow::setFakeParent(CanvasBox* fakeParent) | |||
{ | |||
m_fakeParent = fakeParent; | |||
} | |||
void CanvasBoxShadow::draw(QPainter* painter) | |||
{ | |||
if (m_fakeParent) | |||
m_fakeParent->repaintLines(); | |||
QGraphicsDropShadowEffect::draw(painter); | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,44 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef CANVASBOXSHADOW_H | |||
#define CANVASBOXSHADOW_H | |||
#include <QGraphicsDropShadowEffect> | |||
#include "patchcanvas.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
class CanvasBox; | |||
class CanvasBoxShadow : public QGraphicsDropShadowEffect | |||
{ | |||
public: | |||
CanvasBoxShadow(QObject* parent); | |||
void setFakeParent(CanvasBox* fakeParent); | |||
protected: | |||
virtual void draw(QPainter* painter); | |||
private: | |||
CanvasBox* m_fakeParent; | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // CANVASBOXSHADOW_H |
@@ -0,0 +1,71 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "canvasfadeanimation.h" | |||
#include <QGraphicsItem> | |||
START_NAMESPACE_PATCHCANVAS | |||
CanvasFadeAnimation::CanvasFadeAnimation(QGraphicsItem* item, bool show, QObject* parent) : | |||
QAbstractAnimation(parent) | |||
{ | |||
m_show = show; | |||
m_duration = 0; | |||
m_item = item; | |||
} | |||
void CanvasFadeAnimation::setDuration(int time) | |||
{ | |||
if (m_show == false && m_item->opacity() == 0.0) | |||
m_duration = 0; | |||
else | |||
{ | |||
m_item->show(); | |||
m_duration = time; | |||
} | |||
} | |||
int CanvasFadeAnimation::duration() const | |||
{ | |||
return m_duration; | |||
} | |||
void CanvasFadeAnimation::updateCurrentTime(int time) | |||
{ | |||
if (m_duration == 0) | |||
return; | |||
float value; | |||
if (m_show) | |||
value = float(time)/m_duration; | |||
else | |||
value = 1.0-(float(time)/m_duration); | |||
m_item->setOpacity(value); | |||
} | |||
void CanvasFadeAnimation::updateState(QAbstractAnimation::State /*newState*/, QAbstractAnimation::State /*oldState*/) | |||
{ | |||
} | |||
void CanvasFadeAnimation::updateDirection(QAbstractAnimation::Direction /*direction*/) | |||
{ | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,51 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef CANVASFADEANIMATION_H | |||
#define CANVASFADEANIMATION_H | |||
#include <QtCore/QAbstractAnimation> | |||
#include "patchcanvas.h" | |||
class QGraphicsItem; | |||
START_NAMESPACE_PATCHCANVAS | |||
class CanvasFadeAnimation : public QAbstractAnimation | |||
{ | |||
public: | |||
CanvasFadeAnimation(QGraphicsItem* item, bool show, QObject* parent=0); | |||
void setDuration(int time); | |||
virtual int duration() const; | |||
protected: | |||
virtual void updateCurrentTime(int time); | |||
virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); | |||
virtual void updateDirection(QAbstractAnimation::Direction direction); | |||
private: | |||
bool m_show; | |||
int m_duration; | |||
QGraphicsItem* m_item; | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // CANVASFADEANIMATION_H |
@@ -0,0 +1,134 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "canvasicon.h" | |||
#include <QtGui/QPainter> | |||
#include <QtGui/QGraphicsColorizeEffect> | |||
#include <QtSvg/QSvgRenderer> | |||
START_NAMESPACE_PATCHCANVAS | |||
CanvasIcon::CanvasIcon(Icon icon, QString name, QGraphicsItem* parent) : | |||
QGraphicsSvgItem(parent) | |||
{ | |||
m_renderer = 0; | |||
p_size = QRectF(0, 0, 0, 0); | |||
m_colorFX = new QGraphicsColorizeEffect(this); | |||
m_colorFX->setColor(canvas.theme->box_text.color()); | |||
setGraphicsEffect(m_colorFX); | |||
setIcon(icon, name); | |||
} | |||
CanvasIcon::~CanvasIcon() | |||
{ | |||
if (m_renderer) | |||
delete m_renderer; | |||
delete m_colorFX; | |||
} | |||
void CanvasIcon::setIcon(Icon icon, QString name) | |||
{ | |||
name = name.toLower(); | |||
QString icon_path; | |||
if (icon == ICON_APPLICATION) | |||
{ | |||
p_size = QRectF(3, 2, 19, 18); | |||
if (name.contains("audacious")) | |||
{ | |||
p_size = QRectF(5, 4, 16, 16); | |||
icon_path = ":/scalable/pb_audacious.svg"; | |||
} | |||
else if (name.contains("clementine")) | |||
{ | |||
p_size = QRectF(5, 4, 16, 16); | |||
icon_path = ":/scalable/pb_clementine.svg"; | |||
} | |||
else if (name.contains("jamin")) | |||
{ | |||
p_size = QRectF(5, 3, 16, 16); | |||
icon_path = ":/scalable/pb_jamin.svg"; | |||
} | |||
else if (name.contains("mplayer")) | |||
{ | |||
p_size = QRectF(5, 4, 16, 16); | |||
icon_path = ":/scalable/pb_mplayer.svg"; | |||
} | |||
else if (name.contains("vlc")) | |||
{ | |||
p_size = QRectF(5, 3, 16, 16); | |||
icon_path = ":/scalable/pb_vlc.svg"; | |||
} | |||
else | |||
{ | |||
p_size = QRectF(5, 3, 16, 16); | |||
icon_path = ":/scalable/pb_generic.svg"; | |||
} | |||
} | |||
else if (icon == ICON_HARDWARE) | |||
{ | |||
p_size = QRectF(5, 2, 16, 16); | |||
icon_path = ":/scalable/pb_hardware.svg"; | |||
} | |||
else if (icon == ICON_LADISH_ROOM) | |||
{ | |||
p_size = QRectF(5, 2, 16, 16); | |||
icon_path = ":/scalable/pb_hardware.svg"; | |||
} | |||
else | |||
{ | |||
p_size = QRectF(0, 0, 0, 0); | |||
qCritical("PatchCanvas::CanvasIcon->setIcon(%s, %s) - unsupported Icon requested", icon2str(icon), name.toUtf8().constData()); | |||
return; | |||
} | |||
if (m_renderer) | |||
delete m_renderer; | |||
m_renderer = new QSvgRenderer(icon_path, canvas.scene); | |||
setSharedRenderer(m_renderer); | |||
update(); | |||
} | |||
int CanvasIcon::type() const | |||
{ | |||
return CanvasIconType; | |||
} | |||
QRectF CanvasIcon::boundingRect() const | |||
{ | |||
return p_size; | |||
} | |||
void CanvasIcon::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) | |||
{ | |||
if (m_renderer) | |||
{ | |||
painter->setRenderHint(QPainter::Antialiasing, false); | |||
painter->setRenderHint(QPainter::TextAntialiasing, false); | |||
m_renderer->render(painter, p_size); | |||
} | |||
else | |||
QGraphicsSvgItem::paint(painter, option, widget); | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,52 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef CANVASICON_H | |||
#define CANVASICON_H | |||
#include <QtSvg/QGraphicsSvgItem> | |||
#include "patchcanvas.h" | |||
class QPainter; | |||
class QGraphicsColorizeEffect; | |||
class QSvgRenderer; | |||
START_NAMESPACE_PATCHCANVAS | |||
class CanvasIcon : public QGraphicsSvgItem | |||
{ | |||
public: | |||
CanvasIcon(Icon icon, QString name, QGraphicsItem* parent); | |||
~CanvasIcon(); | |||
void setIcon(Icon icon, QString name); | |||
virtual int type() const; | |||
private: | |||
QGraphicsColorizeEffect* m_colorFX; | |||
QSvgRenderer* m_renderer; | |||
QRectF p_size; | |||
virtual QRectF boundingRect() const; | |||
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget); | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // CANVASICON_H |
@@ -0,0 +1,148 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "canvasline.h" | |||
#include <QtGui/QPainter> | |||
#include "canvasport.h" | |||
#include "canvasportglow.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
CanvasLine::CanvasLine(CanvasPort* item1_, CanvasPort* item2_, QGraphicsItem* parent) : | |||
QGraphicsLineItem(parent, canvas.scene) | |||
{ | |||
item1 = item1_; | |||
item2 = item2_; | |||
m_locked = false; | |||
m_lineSelected = false; | |||
setGraphicsEffect(0); | |||
updateLinePos(); | |||
} | |||
CanvasLine::~CanvasLine() | |||
{ | |||
setGraphicsEffect(0); | |||
} | |||
void CanvasLine::deleteFromScene() | |||
{ | |||
canvas.scene->removeItem(this); | |||
delete this; | |||
} | |||
bool CanvasLine::isLocked() const | |||
{ | |||
return m_locked; | |||
} | |||
void CanvasLine::setLocked(bool yesno) | |||
{ | |||
m_locked = yesno; | |||
} | |||
bool CanvasLine::isLineSelected() const | |||
{ | |||
return m_lineSelected; | |||
} | |||
void CanvasLine::setLineSelected(bool yesno) | |||
{ | |||
if (m_locked) | |||
return; | |||
if (options.eyecandy) | |||
{ | |||
if (yesno) | |||
setGraphicsEffect(new CanvasPortGlow(item1->getPortType(), toGraphicsObject())); | |||
else | |||
setGraphicsEffect(0); | |||
} | |||
m_lineSelected = yesno; | |||
updateLineGradient(); | |||
} | |||
void CanvasLine::updateLinePos() | |||
{ | |||
if (item1->getPortMode() == PORT_MODE_OUTPUT) | |||
{ | |||
QLineF line(item1->scenePos().x() + item1->getPortWidth()+12, item1->scenePos().y()+7.5, item2->scenePos().x(), item2->scenePos().y()+7.5); | |||
setLine(line); | |||
m_lineSelected = false; | |||
updateLineGradient(); | |||
} | |||
} | |||
int CanvasLine::type() const | |||
{ | |||
return CanvasLineType; | |||
} | |||
void CanvasLine::updateLineGradient() | |||
{ | |||
short pos1, pos2; | |||
int pos_top = boundingRect().top(); | |||
int pos_bot = boundingRect().bottom(); | |||
if (item2->scenePos().y() >= item1->scenePos().y()) | |||
{ | |||
pos1 = 0; | |||
pos2 = 1; | |||
} | |||
else | |||
{ | |||
pos1 = 1; | |||
pos2 = 0; | |||
} | |||
PortType port_type1 = item1->getPortType(); | |||
PortType port_type2 = item2->getPortType(); | |||
QLinearGradient port_gradient(0, pos_top, 0, pos_bot); | |||
if (port_type1 == PORT_TYPE_AUDIO_JACK) | |||
port_gradient.setColorAt(pos1, m_lineSelected ? canvas.theme->line_audio_jack_sel : canvas.theme->line_audio_jack); | |||
else if (port_type1 == PORT_TYPE_MIDI_JACK) | |||
port_gradient.setColorAt(pos1, m_lineSelected ? canvas.theme->line_midi_jack_sel : canvas.theme->line_midi_jack); | |||
else if (port_type1 == PORT_TYPE_MIDI_A2J) | |||
port_gradient.setColorAt(pos1, m_lineSelected ? canvas.theme->line_midi_a2j_sel : canvas.theme->line_midi_a2j); | |||
else if (port_type1 == PORT_TYPE_MIDI_ALSA) | |||
port_gradient.setColorAt(pos1, m_lineSelected ? canvas.theme->line_midi_alsa_sel : canvas.theme->line_midi_alsa); | |||
if (port_type2 == PORT_TYPE_AUDIO_JACK) | |||
port_gradient.setColorAt(pos2, m_lineSelected ? canvas.theme->line_audio_jack_sel : canvas.theme->line_audio_jack); | |||
else if (port_type2 == PORT_TYPE_MIDI_JACK) | |||
port_gradient.setColorAt(pos2, m_lineSelected ? canvas.theme->line_midi_jack_sel : canvas.theme->line_midi_jack); | |||
else if (port_type2 == PORT_TYPE_MIDI_A2J) | |||
port_gradient.setColorAt(pos2, m_lineSelected ? canvas.theme->line_midi_a2j_sel : canvas.theme->line_midi_a2j); | |||
else if (port_type2 == PORT_TYPE_MIDI_ALSA) | |||
port_gradient.setColorAt(pos2, m_lineSelected ? canvas.theme->line_midi_alsa_sel : canvas.theme->line_midi_alsa); | |||
setPen(QPen(port_gradient, 2)); | |||
} | |||
void CanvasLine::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) | |||
{ | |||
painter->setRenderHint(QPainter::Antialiasing, bool(options.antialiasing)); | |||
QGraphicsLineItem::paint(painter, option, widget); | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,72 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef CANVASLINE_H | |||
#define CANVASLINE_H | |||
#include <QtGui/QGraphicsLineItem> | |||
#include "abstractcanvasline.h" | |||
class QPainter; | |||
START_NAMESPACE_PATCHCANVAS | |||
class CanvasPort; | |||
class CanvasPortGlow; | |||
class CanvasLine : | |||
public AbstractCanvasLine, | |||
public QGraphicsLineItem | |||
{ | |||
public: | |||
CanvasLine(CanvasPort* item1, CanvasPort* item2, QGraphicsItem* parent); | |||
~CanvasLine(); | |||
virtual void deleteFromScene(); | |||
virtual bool isLocked() const; | |||
virtual void setLocked(bool yesno); | |||
virtual bool isLineSelected() const; | |||
virtual void setLineSelected(bool yesno); | |||
virtual void updateLinePos(); | |||
virtual int type() const; | |||
// QGraphicsItem generic calls | |||
virtual void setZValue(qreal z) | |||
{ | |||
QGraphicsLineItem::setZValue(z); | |||
} | |||
private: | |||
CanvasPort* item1; | |||
CanvasPort* item2; | |||
CanvasPortGlow* glow; | |||
bool m_locked; | |||
bool m_lineSelected; | |||
void updateLineGradient(); | |||
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget); | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // CANVASLINE_H |
@@ -0,0 +1,94 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "canvaslinemov.h" | |||
#include <QtGui/QPainter> | |||
#include "canvasport.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
CanvasLineMov::CanvasLineMov(PortMode port_mode, PortType port_type, QGraphicsItem* parent) : | |||
QGraphicsLineItem(parent, canvas.scene) | |||
{ | |||
m_port_mode = port_mode; | |||
m_port_type = port_type; | |||
// Port position doesn't change while moving around line | |||
p_lineX = scenePos().x(); | |||
p_lineY = scenePos().y(); | |||
p_width = ((CanvasPort*)parentItem())->getPortWidth(); | |||
QPen pen; | |||
if (port_type == PORT_TYPE_AUDIO_JACK) | |||
pen = QPen(canvas.theme->line_audio_jack, 2); | |||
else if (port_type == PORT_TYPE_MIDI_JACK) | |||
pen = QPen(canvas.theme->line_midi_jack, 2); | |||
else if (port_type == PORT_TYPE_MIDI_A2J) | |||
pen = QPen(canvas.theme->line_midi_a2j, 2); | |||
else if (port_type == PORT_TYPE_MIDI_ALSA) | |||
pen = QPen(canvas.theme->line_midi_alsa, 2); | |||
else | |||
{ | |||
qWarning("PatchCanvas::CanvasLineMov(%s, %s, %p) - invalid port type", port_mode2str(port_mode), port_type2str(port_type), parent); | |||
pen = QPen(Qt::black); | |||
} | |||
setPen(pen); | |||
} | |||
void CanvasLineMov::deleteFromScene() | |||
{ | |||
canvas.scene->removeItem(this); | |||
delete this; | |||
} | |||
void CanvasLineMov::updateLinePos(QPointF scenePos) | |||
{ | |||
int item_pos[2] = { 0, 0 }; | |||
if (m_port_mode == PORT_MODE_INPUT) | |||
{ | |||
item_pos[0] = 0; | |||
item_pos[1] = 7.5; | |||
} | |||
else if (m_port_mode == PORT_MODE_OUTPUT) | |||
{ | |||
item_pos[0] = p_width+12; | |||
item_pos[1] = 7.5; | |||
} | |||
else | |||
return; | |||
QLineF line(item_pos[0], item_pos[1], scenePos.x()-p_lineX, scenePos.y()-p_lineY); | |||
setLine(line); | |||
} | |||
int CanvasLineMov::type() const | |||
{ | |||
return CanvasLineMovType; | |||
} | |||
void CanvasLineMov::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) | |||
{ | |||
painter->setRenderHint(QPainter::Antialiasing, bool(options.antialiasing)); | |||
QGraphicsLineItem::paint(painter, option, widget); | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,60 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef CANVASLINEMOV_H | |||
#define CANVASLINEMOV_H | |||
#include <QGraphicsLineItem> | |||
#include "abstractcanvasline.h" | |||
class QPainter; | |||
START_NAMESPACE_PATCHCANVAS | |||
class CanvasLineMov : | |||
public AbstractCanvasLineMov, | |||
public QGraphicsLineItem | |||
{ | |||
public: | |||
CanvasLineMov(PortMode port_mode, PortType port_type, QGraphicsItem* parent); | |||
virtual void deleteFromScene(); | |||
virtual void updateLinePos(QPointF scenePos); | |||
virtual int type() const; | |||
// QGraphicsItem generic calls | |||
virtual void setZValue(qreal z) | |||
{ | |||
QGraphicsLineItem::setZValue(z); | |||
} | |||
private: | |||
PortMode m_port_mode; | |||
PortType m_port_type; | |||
int p_lineX; | |||
int p_lineY; | |||
int p_width; | |||
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget); | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // CANVASLINEMOV_H |
@@ -0,0 +1,447 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "canvasport.h" | |||
#include <QtCore/QTimer> | |||
#include <QtGui/QCursor> | |||
#include <QtGui/QGraphicsSceneContextMenuEvent> | |||
#include <QtGui/QGraphicsSceneMouseEvent> | |||
#include <QtGui/QInputDialog> | |||
#include <QtGui/QMenu> | |||
#include <QtGui/QPainter> | |||
#include "canvaslinemov.h" | |||
#include "canvasbezierlinemov.h" | |||
#include "canvasbox.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
CanvasPort::CanvasPort(int port_id, QString port_name, PortMode port_mode, PortType port_type, QGraphicsItem* parent) : | |||
QGraphicsItem(parent, canvas.scene) | |||
{ | |||
// Save Variables, useful for later | |||
m_port_id = port_id; | |||
m_port_mode = port_mode; | |||
m_port_type = port_type; | |||
m_port_name = port_name; | |||
// Base Variables | |||
m_port_width = 15; | |||
m_port_height = 15; | |||
m_port_font = QFont(canvas.theme->port_font_name, canvas.theme->port_font_size, canvas.theme->port_font_state); | |||
m_line_mov = 0; | |||
m_hover_item = 0; | |||
m_last_selected_state = false; | |||
m_mouse_down = false; | |||
m_cursor_moving = false; | |||
setFlags(QGraphicsItem::ItemIsSelectable); | |||
} | |||
int CanvasPort::getPortId() | |||
{ | |||
return m_port_id; | |||
} | |||
PortMode CanvasPort::getPortMode() | |||
{ | |||
return m_port_mode; | |||
} | |||
PortType CanvasPort::getPortType() | |||
{ | |||
return m_port_type; | |||
} | |||
QString CanvasPort::getPortName() | |||
{ | |||
return m_port_name; | |||
} | |||
QString CanvasPort::getFullPortName() | |||
{ | |||
return ((CanvasBox*)parentItem())->getGroupName()+":"+m_port_name; | |||
} | |||
int CanvasPort::getPortWidth() | |||
{ | |||
return m_port_width; | |||
} | |||
int CanvasPort::getPortHeight() | |||
{ | |||
return m_port_height; | |||
} | |||
void CanvasPort::setPortMode(PortMode port_mode) | |||
{ | |||
m_port_mode = port_mode; | |||
update(); | |||
} | |||
void CanvasPort::setPortType(PortType port_type) | |||
{ | |||
m_port_type = port_type; | |||
update(); | |||
} | |||
void CanvasPort::setPortName(QString port_name) | |||
{ | |||
if (QFontMetrics(m_port_font).width(port_name) < QFontMetrics(m_port_font).width(m_port_name)) | |||
QTimer::singleShot(0, canvas.scene, SLOT(update())); | |||
m_port_name = port_name; | |||
update(); | |||
} | |||
void CanvasPort::setPortWidth(int port_width) | |||
{ | |||
if (port_width < m_port_width) | |||
QTimer::singleShot(0, canvas.scene, SLOT(update())); | |||
m_port_width = port_width; | |||
update(); | |||
} | |||
int CanvasPort::type() const | |||
{ | |||
return CanvasPortType; | |||
} | |||
void CanvasPort::mousePressEvent(QGraphicsSceneMouseEvent* event) | |||
{ | |||
m_hover_item = 0; | |||
m_mouse_down = (event->button() == Qt::LeftButton); | |||
m_cursor_moving = false; | |||
QGraphicsItem::mousePressEvent(event); | |||
} | |||
void CanvasPort::mouseMoveEvent(QGraphicsSceneMouseEvent* event) | |||
{ | |||
if (m_mouse_down) | |||
{ | |||
if (m_cursor_moving == false) | |||
{ | |||
setCursor(QCursor(Qt::CrossCursor)); | |||
m_cursor_moving = true; | |||
foreach (const connection_dict_t& connection, canvas.connection_list) | |||
{ | |||
if (connection.port_out_id == m_port_id || connection.port_in_id == m_port_id) | |||
connection.widget->setLocked(true); | |||
} | |||
} | |||
if (! m_line_mov) | |||
{ | |||
if (options.use_bezier_lines) | |||
m_line_mov = new CanvasBezierLineMov(m_port_mode, m_port_type, this); | |||
else | |||
m_line_mov = new CanvasLineMov(m_port_mode, m_port_type, this); | |||
canvas.last_z_value += 1; | |||
m_line_mov->setZValue(canvas.last_z_value); | |||
canvas.last_z_value += 1; | |||
parentItem()->setZValue(canvas.last_z_value); | |||
} | |||
CanvasPort* item = 0; | |||
QList<QGraphicsItem*> items = canvas.scene->items(event->scenePos(), Qt::ContainsItemShape, Qt::AscendingOrder); | |||
for (int i=0; i < items.count(); i++) | |||
{ | |||
if (items[i]->type() == CanvasPortType) | |||
{ | |||
if (items[i] != this) | |||
{ | |||
if (! item) | |||
item = (CanvasPort*)items[i]; | |||
else if (items[i]->parentItem()->zValue() > item->parentItem()->zValue()) | |||
item = (CanvasPort*)items[i]; | |||
} | |||
} | |||
} | |||
if (m_hover_item and m_hover_item != item) | |||
m_hover_item->setSelected(false); | |||
if (item) | |||
{ | |||
bool a2j_connection = (item->getPortType() == PORT_TYPE_MIDI_JACK && m_port_type == PORT_TYPE_MIDI_A2J) || (item->getPortType() == PORT_TYPE_MIDI_A2J && m_port_type == PORT_TYPE_MIDI_JACK); | |||
if (item->getPortMode() != m_port_mode && (item->getPortType() == m_port_type || a2j_connection)) | |||
{ | |||
item->setSelected(true); | |||
m_hover_item = item; | |||
} | |||
else | |||
m_hover_item = 0; | |||
} | |||
else | |||
m_hover_item = 0; | |||
m_line_mov->updateLinePos(event->scenePos()); | |||
return event->accept(); | |||
} | |||
QGraphicsItem::mouseMoveEvent(event); | |||
} | |||
void CanvasPort::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) | |||
{ | |||
if (m_mouse_down) | |||
{ | |||
if (m_line_mov) | |||
{ | |||
m_line_mov->deleteFromScene(); | |||
m_line_mov = 0; | |||
} | |||
foreach (const connection_dict_t& connection, canvas.connection_list) | |||
{ | |||
if (connection.port_out_id == m_port_id || connection.port_in_id == m_port_id) | |||
connection.widget->setLocked(false); | |||
} | |||
if (m_hover_item) | |||
{ | |||
bool check = false; | |||
foreach (const connection_dict_t& connection, canvas.connection_list) | |||
{ | |||
if ( (connection.port_out_id == m_port_id && connection.port_in_id == m_hover_item->getPortId()) || | |||
(connection.port_out_id == m_hover_item->getPortId() && connection.port_in_id == m_port_id) ) | |||
{ | |||
canvas.callback(ACTION_PORTS_DISCONNECT, connection.connection_id, 0, ""); | |||
check = true; | |||
break; | |||
} | |||
} | |||
if (check == false) | |||
{ | |||
if (m_port_mode == PORT_MODE_OUTPUT) | |||
canvas.callback(ACTION_PORTS_CONNECT, m_port_id, m_hover_item->getPortId(), ""); | |||
else | |||
canvas.callback(ACTION_PORTS_CONNECT, m_hover_item->getPortId(), m_port_id, ""); | |||
} | |||
canvas.scene->clearSelection(); | |||
} | |||
} | |||
if (m_cursor_moving) | |||
setCursor(QCursor(Qt::ArrowCursor)); | |||
m_hover_item = 0; | |||
m_mouse_down = false; | |||
m_cursor_moving = false; | |||
QGraphicsItem::mouseReleaseEvent(event); | |||
} | |||
void CanvasPort::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) | |||
{ | |||
canvas.scene->clearSelection(); | |||
setSelected(true); | |||
QMenu menu; | |||
QMenu discMenu("Disconnect", &menu); | |||
QList<int> port_con_list = CanvasGetPortConnectionList(m_port_id); | |||
if (port_con_list.count() > 0) | |||
{ | |||
foreach (int port_id, port_con_list) | |||
{ | |||
int port_con_id = CanvasGetConnectedPort(port_id, m_port_id); | |||
QAction* act_x_disc = discMenu.addAction(CanvasGetFullPortName(port_con_id)); | |||
act_x_disc->setData(port_id); | |||
QObject::connect(act_x_disc, SIGNAL(triggered()), canvas.qobject, SLOT(PortContextMenuDisconnect())); | |||
} | |||
} | |||
else | |||
{ | |||
QAction* act_x_disc = discMenu.addAction("No connections"); | |||
act_x_disc->setEnabled(false); | |||
} | |||
menu.addMenu(&discMenu); | |||
QAction* act_x_disc_all = menu.addAction("Disconnect &All"); | |||
QAction* act_x_sep_1 = menu.addSeparator(); | |||
QAction* act_x_info = menu.addAction("Get &Info"); | |||
QAction* act_x_rename = menu.addAction("&Rename"); | |||
if (features.port_info == false) | |||
act_x_info->setVisible(false); | |||
if (features.port_rename == false) | |||
act_x_rename->setVisible(false); | |||
if (features.port_info == false && features.port_rename == false) | |||
act_x_sep_1->setVisible(false); | |||
QAction* act_selected = menu.exec(event->screenPos()); | |||
if (act_selected == act_x_disc_all) | |||
{ | |||
foreach (int port_id, port_con_list) | |||
canvas.callback(ACTION_PORTS_DISCONNECT, port_id, 0, ""); | |||
} | |||
else if (act_selected == act_x_info) | |||
{ | |||
canvas.callback(ACTION_PORT_INFO, m_port_id, 0, ""); | |||
} | |||
else if (act_selected == act_x_rename) | |||
{ | |||
bool ok_check; | |||
QString new_name = QInputDialog::getText(0, "Rename Port", "New name:", QLineEdit::Normal, m_port_name, &ok_check); | |||
if (ok_check and new_name.isEmpty() == false) | |||
{ | |||
canvas.callback(ACTION_PORT_RENAME, m_port_id, 0, new_name); | |||
} | |||
} | |||
event->accept(); | |||
} | |||
QRectF CanvasPort::boundingRect() const | |||
{ | |||
return QRectF(0, 0, m_port_width+12, m_port_height); | |||
} | |||
void CanvasPort::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) | |||
{ | |||
painter->setRenderHint(QPainter::Antialiasing, (options.antialiasing == ANTIALIASING_FULL)); | |||
QPointF text_pos; | |||
int poly_locx[5] = { 0 }; | |||
if (m_port_mode == PORT_MODE_INPUT) | |||
{ | |||
text_pos = QPointF(3, 12); | |||
if (canvas.theme->port_mode == Theme::THEME_PORT_POLYGON) | |||
{ | |||
poly_locx[0] = 0; | |||
poly_locx[1] = m_port_width+5; | |||
poly_locx[2] = m_port_width+12; | |||
poly_locx[3] = m_port_width+5; | |||
poly_locx[4] = 0; | |||
} | |||
else if (canvas.theme->port_mode == Theme::THEME_PORT_SQUARE) | |||
{ | |||
poly_locx[0] = 0; | |||
poly_locx[1] = m_port_width+5; | |||
poly_locx[2] = m_port_width+5; | |||
poly_locx[3] = m_port_width+5; | |||
poly_locx[4] = 0; | |||
} | |||
else | |||
{ | |||
qCritical("PatchCanvas::CanvasPort->paint() - invalid theme port mode '%i'", canvas.theme->port_mode); | |||
return; | |||
} | |||
} | |||
else if (m_port_mode == PORT_MODE_OUTPUT) | |||
{ | |||
text_pos = QPointF(9, 12); | |||
if (canvas.theme->port_mode == Theme::THEME_PORT_POLYGON) | |||
{ | |||
poly_locx[0] = m_port_width+12; | |||
poly_locx[1] = 7; | |||
poly_locx[2] = 0; | |||
poly_locx[3] = 7; | |||
poly_locx[4] = m_port_width+12; | |||
} | |||
else if (canvas.theme->port_mode == Theme::THEME_PORT_SQUARE) | |||
{ | |||
poly_locx[0] = m_port_width+12; | |||
poly_locx[1] = 5; | |||
poly_locx[2] = 5; | |||
poly_locx[3] = 5; | |||
poly_locx[4] = m_port_width+12; | |||
} | |||
else | |||
{ | |||
qCritical("PatchCanvas::CanvasPort->paint() - invalid theme port mode '%i'", canvas.theme->port_mode); | |||
return; | |||
} | |||
} | |||
else | |||
{ | |||
qCritical("PatchCanvas::CanvasPort->paint() - invalid port mode '%s'", port_mode2str(m_port_mode)); | |||
return; | |||
} | |||
QColor poly_color; | |||
QPen poly_pen; | |||
if (m_port_type == PORT_TYPE_AUDIO_JACK) | |||
{ | |||
poly_color = isSelected() ? canvas.theme->port_audio_jack_bg_sel : canvas.theme->port_audio_jack_bg; | |||
poly_pen = isSelected() ? canvas.theme->port_audio_jack_pen_sel : canvas.theme->port_audio_jack_pen; | |||
} | |||
else if (m_port_type == PORT_TYPE_MIDI_JACK) | |||
{ | |||
poly_color = isSelected() ? canvas.theme->port_midi_jack_bg_sel : canvas.theme->port_midi_jack_bg; | |||
poly_pen = isSelected() ? canvas.theme->port_midi_jack_pen_sel : canvas.theme->port_midi_jack_pen; | |||
} | |||
else if (m_port_type == PORT_TYPE_MIDI_A2J) | |||
{ | |||
poly_color = isSelected() ? canvas.theme->port_midi_a2j_bg_sel : canvas.theme->port_midi_a2j_bg; | |||
poly_pen = isSelected() ? canvas.theme->port_midi_a2j_pen_sel : canvas.theme->port_midi_a2j_pen; | |||
} | |||
else if (m_port_type == PORT_TYPE_MIDI_ALSA) | |||
{ | |||
poly_color = isSelected() ? canvas.theme->port_midi_alsa_bg_sel : canvas.theme->port_midi_alsa_bg; | |||
poly_pen = isSelected() ? canvas.theme->port_midi_alsa_pen_sel : canvas.theme->port_midi_alsa_pen; | |||
} | |||
else | |||
{ | |||
qCritical("PatchCanvas::CanvasPort->paint() - invalid port type '%s'", port_type2str(m_port_type)); | |||
return; | |||
} | |||
QPolygonF polygon; | |||
polygon += QPointF(poly_locx[0], 0); | |||
polygon += QPointF(poly_locx[1], 0); | |||
polygon += QPointF(poly_locx[2], 7.5); | |||
polygon += QPointF(poly_locx[3], 15); | |||
polygon += QPointF(poly_locx[4], 15); | |||
painter->setBrush(poly_color); | |||
painter->setPen(poly_pen); | |||
painter->drawPolygon(polygon); | |||
painter->setPen(canvas.theme->port_text); | |||
painter->setFont(m_port_font); | |||
painter->drawText(text_pos, m_port_name); | |||
if (isSelected() != m_last_selected_state) | |||
{ | |||
foreach (const connection_dict_t& connection, canvas.connection_list) | |||
{ | |||
if (connection.port_out_id == m_port_id || connection.port_in_id == m_port_id) | |||
connection.widget->setLineSelected(isSelected()); | |||
} | |||
} | |||
m_last_selected_state = isSelected(); | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,79 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef CANVASPORT_H | |||
#define CANVASPORT_H | |||
#include "patchcanvas.h" | |||
class QGraphicsSceneContextMenuEvent; | |||
class QGraphicsSceneMouseEvent; | |||
class QPainter; | |||
START_NAMESPACE_PATCHCANVAS | |||
class AbstractCanvasLineMov; | |||
class CanvasPort : public QGraphicsItem | |||
{ | |||
public: | |||
CanvasPort(int port_id, QString port_name, PortMode port_mode, PortType port_type, QGraphicsItem* parent); | |||
int getPortId(); | |||
PortMode getPortMode(); | |||
PortType getPortType(); | |||
QString getPortName(); | |||
QString getFullPortName(); | |||
int getPortWidth(); | |||
int getPortHeight(); | |||
void setPortMode(PortMode port_mode); | |||
void setPortType(PortType port_type); | |||
void setPortName(QString port_name); | |||
void setPortWidth(int port_width); | |||
virtual int type() const; | |||
private: | |||
int m_port_id; | |||
PortMode m_port_mode; | |||
PortType m_port_type; | |||
QString m_port_name; | |||
int m_port_width; | |||
int m_port_height; | |||
QFont m_port_font; | |||
AbstractCanvasLineMov* m_line_mov; | |||
CanvasPort* m_hover_item; | |||
bool m_last_selected_state; | |||
bool m_mouse_down; | |||
bool m_cursor_moving; | |||
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); | |||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event); | |||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event); | |||
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent* event); | |||
virtual QRectF boundingRect() const; | |||
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget); | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // CANVASPORT_H |
@@ -0,0 +1,38 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "canvasportglow.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
CanvasPortGlow::CanvasPortGlow(PortType port_type, QObject* parent) : | |||
QGraphicsDropShadowEffect(parent) | |||
{ | |||
setBlurRadius(12); | |||
setOffset(0, 0); | |||
if (port_type == PORT_TYPE_AUDIO_JACK) | |||
setColor(canvas.theme->line_audio_jack_glow); | |||
else if (port_type == PORT_TYPE_MIDI_JACK) | |||
setColor(canvas.theme->line_midi_jack_glow); | |||
else if (port_type == PORT_TYPE_MIDI_A2J) | |||
setColor(canvas.theme->line_midi_a2j_glow); | |||
else if (port_type == PORT_TYPE_MIDI_ALSA) | |||
setColor(canvas.theme->line_midi_alsa_glow); | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,35 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef CANVASPORTGLOW_H | |||
#define CANVASPORTGLOW_H | |||
#include <QGraphicsDropShadowEffect> | |||
#include "patchcanvas.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
class CanvasPortGlow : public QGraphicsDropShadowEffect | |||
{ | |||
public: | |||
CanvasPortGlow(PortType port_type, QObject* parent); | |||
}; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // CANVASPORTGLOW_H |
@@ -0,0 +1,405 @@ | |||
#include "canvastestapp.h" | |||
#include "ui_canvastestapp.h" | |||
#include <QMessageBox> | |||
#include <QSettings> | |||
#include <QVariant> | |||
#include <QGLWidget> | |||
struct group_name_to_id_t { | |||
int id; | |||
QString name; | |||
}; | |||
struct port_name_to_id_t { | |||
int group_id; | |||
int port_id; | |||
QString name; | |||
}; | |||
struct connection_to_id_t { | |||
int id; | |||
int port_out; | |||
int port_in; | |||
}; | |||
static int last_group_id = 0; | |||
static int last_port_id = 0; | |||
static int last_connection_id = 0; | |||
static CanvasTestApp* main_gui = 0; | |||
static jack_client_t* jack_client = 0; | |||
static QList<group_name_to_id_t> used_group_names; | |||
static QList<port_name_to_id_t> used_port_names; | |||
static QList<connection_to_id_t> used_connections; | |||
int get_group_id(QString group_name) | |||
{ | |||
for (int i=0; i < used_group_names.count(); i++) | |||
{ | |||
if (used_group_names[i].name == group_name) | |||
{ | |||
return used_group_names[i].id; | |||
} | |||
} | |||
return -1; | |||
} | |||
int get_port_id(QString full_port_name) | |||
{ | |||
QString group_name = full_port_name.split(":").at(0); | |||
QString port_name = full_port_name.replace(group_name+":", ""); | |||
int group_id = get_group_id(group_name); | |||
for (int i=0; i < used_port_names.count(); i++) | |||
{ | |||
if (used_port_names[i].group_id == group_id && used_port_names[i].name == port_name) | |||
{ | |||
return used_port_names[i].port_id; | |||
} | |||
} | |||
return -1; | |||
} | |||
QString get_full_port_name(int port_id) | |||
{ | |||
int group_id = -1; | |||
QString group_name; | |||
QString port_name; | |||
for (int i=0; i < used_port_names.count(); i++) | |||
{ | |||
if (used_port_names[i].port_id == port_id) | |||
{ | |||
group_id = used_port_names[i].group_id; | |||
port_name = used_port_names[i].name; | |||
} | |||
} | |||
for (int i=0; i < used_group_names.count(); i++) | |||
{ | |||
if (used_group_names[i].id == group_id) | |||
{ | |||
group_name = used_group_names[i].name; | |||
} | |||
} | |||
return group_name+":"+port_name; | |||
} | |||
void canvas_callback(PatchCanvas::CallbackAction action, int value1, int value2, QString value_str) | |||
{ | |||
qDebug("--------------------------- Callback called %i|%i|%i|%s", action, value1, value2, value_str.toStdString().data()); | |||
switch (action) | |||
{ | |||
case PatchCanvas::ACTION_PORT_INFO: | |||
QMessageBox::information(main_gui, "port info dialog", "dummy text here"); | |||
break; | |||
case PatchCanvas::ACTION_PORT_RENAME: | |||
// Unused | |||
break; | |||
case PatchCanvas::ACTION_PORTS_CONNECT: | |||
jack_connect(jack_client, get_full_port_name(value1).toStdString().data(), get_full_port_name(value2).toStdString().data()); | |||
break; | |||
case PatchCanvas::ACTION_PORTS_DISCONNECT: | |||
for (int i=0; i < used_connections.count(); i++) | |||
{ | |||
if (used_connections[i].id == value1) | |||
{ | |||
jack_disconnect(jack_client, get_full_port_name(used_connections[i].port_out).toStdString().data(), get_full_port_name(used_connections[i].port_in).toStdString().data()); | |||
break; | |||
} | |||
} | |||
break; | |||
case PatchCanvas::ACTION_GROUP_INFO: | |||
QMessageBox::information(main_gui, "group info dialog", "dummy text here"); | |||
break; | |||
case PatchCanvas::ACTION_GROUP_RENAME: | |||
// Unused | |||
break; | |||
case PatchCanvas::ACTION_GROUP_SPLIT: | |||
PatchCanvas::splitGroup(value1); | |||
break; | |||
case PatchCanvas::ACTION_GROUP_JOIN: | |||
PatchCanvas::joinGroup(value1); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
CanvasTestApp::CanvasTestApp(QWidget *parent) : | |||
QMainWindow(parent), | |||
ui(new Ui::CanvasTestApp) | |||
{ | |||
ui->setupUi(this); | |||
settings = new QSettings("PatchCanvas", "Canvas-test-app"); | |||
restoreGeometry(settings->value("Geometry").toByteArray()); | |||
main_gui = this; | |||
used_group_names.clear(); | |||
used_port_names.clear(); | |||
used_connections.clear(); | |||
scene = new PatchScene(this, ui->graphicsView); | |||
ui->graphicsView->setScene(scene); | |||
ui->graphicsView->setRenderHint(QPainter::Antialiasing, true); | |||
ui->graphicsView->setRenderHint(QPainter::TextAntialiasing, true); | |||
//ui->graphicsView->setRenderHint(QPainter::HighQualityAntialiasing, true); | |||
//ui->graphicsView->setViewport(new QGLWidget(ui->graphicsView)); | |||
PatchCanvas::options_t options; | |||
options.auto_hide_groups = false; | |||
options.use_bezier_lines = true; | |||
options.antialiasing = PatchCanvas::ANTIALIASING_SMALL; | |||
options.eyecandy = PatchCanvas::EYECANDY_FULL; | |||
options.theme_name = PatchCanvas::getDefaultThemeName(); | |||
PatchCanvas::features_t features; | |||
features.group_info = false; | |||
features.group_rename = false; | |||
features.port_info = false; | |||
features.port_rename = false; | |||
features.handle_group_pos = true; | |||
PatchCanvas::setOptions(&options); | |||
PatchCanvas::setFeatures(&features); | |||
PatchCanvas::init(scene, canvas_callback, true); | |||
connect(this, SIGNAL(clientRegisterCallback(QString,bool)), SLOT(handle_clientRegisterCallback(QString,bool))); | |||
connect(this, SIGNAL(portRegisterCallback(int,bool)), SLOT(handle_portRegisterCallback(int,bool))); | |||
connect(this, SIGNAL(connectionCallback(int,int,bool)), SLOT(handle_connectionCallback(int,int,bool))); | |||
jack_client = jack_client_open("canvas-test-app", JackNullOption, 0); | |||
jack_set_client_registration_callback(jack_client, client_register_callback, 0); | |||
jack_set_port_registration_callback(jack_client, port_register_callback, 0); | |||
jack_set_port_connect_callback(jack_client, port_connect_callback, 0); | |||
jack_activate(jack_client); | |||
// query initial jack ports | |||
QList<QString> parsed_groups; | |||
const char** ports = jack_get_ports(jack_client, 0, 0, 0); | |||
if (ports) { | |||
for (int i=0; ports[i]; i++) { | |||
QString full_name(ports[i]); | |||
QString group_name = full_name.split(":").at(0); | |||
QString port_name = full_name.replace(group_name+":", ""); | |||
int group_id = -1; | |||
if (parsed_groups.contains(group_name)) | |||
{ | |||
group_id = get_group_id(group_name); | |||
} | |||
else | |||
{ | |||
group_id = last_group_id; | |||
group_name_to_id_t group_name_to_id; | |||
group_name_to_id.id = group_id; | |||
group_name_to_id.name = group_name; | |||
used_group_names.append(group_name_to_id); | |||
parsed_groups.append(group_name); | |||
PatchCanvas::addGroup(group_id, group_name); | |||
last_group_id++; | |||
} | |||
PatchCanvas::PortMode port_mode; | |||
PatchCanvas::PortType port_type; | |||
jack_port_t* jack_port = jack_port_by_name(jack_client, ports[i]); | |||
if (jack_port_flags(jack_port) & JackPortIsInput) | |||
port_mode = PatchCanvas::PORT_MODE_INPUT; | |||
else | |||
port_mode = PatchCanvas::PORT_MODE_OUTPUT; | |||
if (strcmp(jack_port_type(jack_port), JACK_DEFAULT_AUDIO_TYPE) == 0) | |||
port_type = PatchCanvas::PORT_TYPE_AUDIO_JACK; | |||
else | |||
port_type = PatchCanvas::PORT_TYPE_MIDI_JACK; | |||
port_name_to_id_t port_name_to_id; | |||
port_name_to_id.group_id = group_id; | |||
port_name_to_id.port_id = last_port_id; | |||
port_name_to_id.name = port_name; | |||
used_port_names.append(port_name_to_id); | |||
PatchCanvas::addPort(group_id, last_port_id, port_name, port_mode, port_type); | |||
last_port_id++; | |||
} | |||
jack_free(ports); | |||
} | |||
// query connections, after all ports are in place | |||
ports = jack_get_ports(jack_client, 0, 0, JackPortIsOutput); | |||
if (ports) { | |||
for (int i=0; ports[i]; i++) { | |||
QString this_full_name(ports[i]); | |||
int this_port_id = get_port_id(this_full_name); | |||
jack_port_t* jack_port = jack_port_by_name(jack_client, ports[i]); | |||
const char** connections = jack_port_get_connections(jack_port); | |||
if (connections) { | |||
for (int j=0; connections[j]; j++) { | |||
QString target_full_name(connections[j]); | |||
int target_port_id = get_port_id(target_full_name); | |||
connection_to_id_t connection; | |||
connection.id = last_connection_id; | |||
connection.port_out = this_port_id; | |||
connection.port_in = target_port_id; | |||
used_connections.append(connection); | |||
PatchCanvas::connectPorts(last_connection_id, this_port_id, target_port_id); | |||
last_connection_id++; | |||
} | |||
jack_free(connections); | |||
} | |||
} | |||
jack_free(ports); | |||
} | |||
} | |||
CanvasTestApp::~CanvasTestApp() | |||
{ | |||
delete settings; | |||
delete scene; | |||
delete ui; | |||
} | |||
void CanvasTestApp::client_register_callback(const char* name, int register_, void*) | |||
{ | |||
main_gui->emit clientRegisterCallback(QString(name), bool(register_)); | |||
} | |||
void CanvasTestApp::port_register_callback(jack_port_id_t port_id_jack, int register_, void*) | |||
{ | |||
main_gui->emit portRegisterCallback(port_id_jack, bool(register_)); | |||
} | |||
void CanvasTestApp::port_connect_callback(jack_port_id_t port_a, jack_port_id_t port_b, int connect, void*) | |||
{ | |||
main_gui->emit connectionCallback(port_a, port_b, bool(connect)); | |||
} | |||
void CanvasTestApp::handle_clientRegisterCallback(QString name, bool yesno) | |||
{ | |||
QString qname(name); | |||
if (yesno) | |||
{ | |||
group_name_to_id_t group_name_to_id; | |||
group_name_to_id.id = last_group_id; | |||
group_name_to_id.name = qname; | |||
used_group_names.append(group_name_to_id); | |||
PatchCanvas::addGroup(last_group_id, qname); | |||
last_group_id++; | |||
} | |||
else | |||
{ | |||
for (int i=0; i < used_group_names.count(); i++) | |||
{ | |||
if (used_group_names[i].name == qname) | |||
{ | |||
PatchCanvas::removeGroup(used_group_names[i].id); | |||
used_group_names.takeAt(i); | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
void CanvasTestApp::handle_portRegisterCallback(int port, bool yesno) | |||
{ | |||
jack_port_t* jack_port = jack_port_by_id(jack_client, port); | |||
QString full_name(jack_port_name(jack_port)); | |||
QString group_name = full_name.split(":").at(0); | |||
QString port_name = full_name.replace(group_name+":", ""); | |||
int group_id = get_group_id(group_name); | |||
if (yesno) | |||
{ | |||
PatchCanvas::PortMode port_mode; | |||
PatchCanvas::PortType port_type; | |||
if (jack_port_flags(jack_port) & JackPortIsInput) | |||
port_mode = PatchCanvas::PORT_MODE_INPUT; | |||
else | |||
port_mode = PatchCanvas::PORT_MODE_OUTPUT; | |||
if (strcmp(jack_port_type(jack_port), JACK_DEFAULT_AUDIO_TYPE) == 0) | |||
port_type = PatchCanvas::PORT_TYPE_AUDIO_JACK; | |||
else | |||
port_type = PatchCanvas::PORT_TYPE_MIDI_JACK; | |||
port_name_to_id_t port_name_to_id; | |||
port_name_to_id.group_id = group_id; | |||
port_name_to_id.port_id = last_port_id; | |||
port_name_to_id.name = port_name; | |||
used_port_names.append(port_name_to_id); | |||
PatchCanvas::addPort(group_id, last_port_id, port_name, port_mode, port_type); | |||
last_port_id++; | |||
} | |||
else | |||
{ | |||
for (int i=0; i < used_port_names.count(); i++) | |||
{ | |||
if (used_port_names[i].group_id == group_id && used_port_names[i].name == port_name) | |||
{ | |||
PatchCanvas::removePort(used_port_names[i].port_id); | |||
used_port_names.takeAt(i); | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
void CanvasTestApp::handle_connectionCallback(int port_a, int port_b, bool yesno) | |||
{ | |||
jack_port_t* jack_port_a = jack_port_by_id(jack_client, port_a); | |||
jack_port_t* jack_port_b = jack_port_by_id(jack_client, port_b); | |||
int port_id_a = get_port_id(QString(jack_port_name(jack_port_a))); | |||
int port_id_b = get_port_id(QString(jack_port_name(jack_port_b))); | |||
if (yesno) | |||
{ | |||
connection_to_id_t connection; | |||
connection.id = last_connection_id; | |||
connection.port_out = port_id_a; | |||
connection.port_in = port_id_b; | |||
used_connections.append(connection); | |||
PatchCanvas::connectPorts(last_connection_id, port_id_a, port_id_b); | |||
last_connection_id++; | |||
} | |||
else | |||
{ | |||
for (int i=0; i < used_connections.count(); i++) | |||
{ | |||
if (used_connections[i].port_out == port_id_a && used_connections[i].port_in == port_id_b) | |||
{ | |||
PatchCanvas::disconnectPorts(used_connections[i].id); | |||
used_connections.takeAt(i); | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
void CanvasTestApp::closeEvent(QCloseEvent* event) | |||
{ | |||
jack_deactivate(jack_client); | |||
jack_client_close(jack_client); | |||
PatchCanvas::clear(); | |||
settings->setValue("Geometry", QVariant(saveGeometry())); | |||
QMainWindow::closeEvent(event); | |||
} |
@@ -0,0 +1,50 @@ | |||
/* | |||
* PatchCanvas test app | |||
*/ | |||
#ifndef CANVASTESTAPP_H | |||
#define CANVASTESTAPP_H | |||
#include <QMainWindow> | |||
#include <jack/jack.h> | |||
#include "patchcanvas-api.h" | |||
namespace Ui { | |||
class CanvasTestApp; | |||
} | |||
class QSettings; | |||
class CanvasTestApp : public QMainWindow | |||
{ | |||
Q_OBJECT | |||
public: | |||
explicit CanvasTestApp(QWidget *parent = 0); | |||
~CanvasTestApp(); | |||
static void client_register_callback(const char* name, int register_, void *arg); | |||
static void port_register_callback(jack_port_id_t port_id_jack, int register_, void *arg); | |||
static void port_connect_callback(jack_port_id_t port_a, jack_port_id_t port_b, int connect, void* arg); | |||
signals: | |||
void clientRegisterCallback(QString name, bool yesno); | |||
void portRegisterCallback(int port, bool yesno); | |||
void connectionCallback(int port_a, int port_b, bool yesno); | |||
private slots: | |||
void handle_clientRegisterCallback(QString name, bool yesno); | |||
void handle_portRegisterCallback(int port, bool yesno); | |||
void handle_connectionCallback(int port_a, int port_b, bool yesno); | |||
private: | |||
Ui::CanvasTestApp* ui; | |||
PatchScene* scene; | |||
QSettings* settings; | |||
virtual void closeEvent(QCloseEvent* event); | |||
}; | |||
#endif // CANVASTESTAPP_H |
@@ -0,0 +1,95 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<ui version="4.0"> | |||
<class>CanvasTestApp</class> | |||
<widget class="QMainWindow" name="CanvasTestApp"> | |||
<property name="geometry"> | |||
<rect> | |||
<x>0</x> | |||
<y>0</y> | |||
<width>811</width> | |||
<height>646</height> | |||
</rect> | |||
</property> | |||
<property name="windowTitle"> | |||
<string>CanvasTestApp</string> | |||
</property> | |||
<widget class="QWidget" name="centralWidget"> | |||
<layout class="QVBoxLayout" name="verticalLayout"> | |||
<property name="spacing"> | |||
<number>0</number> | |||
</property> | |||
<property name="margin"> | |||
<number>0</number> | |||
</property> | |||
<item> | |||
<widget class="QGraphicsView" name="graphicsView"/> | |||
</item> | |||
</layout> | |||
</widget> | |||
<action name="action_Quit"> | |||
<property name="text"> | |||
<string>&Quit</string> | |||
</property> | |||
</action> | |||
<action name="action_Arrange"> | |||
<property name="text"> | |||
<string>&Arrange</string> | |||
</property> | |||
</action> | |||
<action name="action_Refresh"> | |||
<property name="text"> | |||
<string>&Refresh</string> | |||
</property> | |||
</action> | |||
<action name="actionZoom_Fit"> | |||
<property name="text"> | |||
<string>Zoom Fit</string> | |||
</property> | |||
</action> | |||
<action name="actionZoom_In"> | |||
<property name="text"> | |||
<string>Zoom In</string> | |||
</property> | |||
</action> | |||
<action name="actionZoom_Out"> | |||
<property name="text"> | |||
<string>Zoom Out</string> | |||
</property> | |||
</action> | |||
<action name="actionZoom_100"> | |||
<property name="text"> | |||
<string>Zoom 100%</string> | |||
</property> | |||
</action> | |||
<action name="action_Print"> | |||
<property name="text"> | |||
<string>&Print...</string> | |||
</property> | |||
</action> | |||
<action name="action_Save_Image"> | |||
<property name="text"> | |||
<string>&Save Image...</string> | |||
</property> | |||
</action> | |||
</widget> | |||
<layoutdefault spacing="6" margin="11"/> | |||
<resources/> | |||
<connections> | |||
<connection> | |||
<sender>action_Quit</sender> | |||
<signal>triggered()</signal> | |||
<receiver>CanvasTestApp</receiver> | |||
<slot>close()</slot> | |||
<hints> | |||
<hint type="sourcelabel"> | |||
<x>-1</x> | |||
<y>-1</y> | |||
</hint> | |||
<hint type="destinationlabel"> | |||
<x>198</x> | |||
<y>148</y> | |||
</hint> | |||
</hints> | |||
</connection> | |||
</connections> | |||
</ui> |
@@ -0,0 +1,11 @@ | |||
#include <QtGui/QApplication> | |||
#include "canvastestapp.h" | |||
int main(int argc, char *argv[]) | |||
{ | |||
QApplication a(argc, argv); | |||
CanvasTestApp w; | |||
w.show(); | |||
return a.exec(); | |||
} |
@@ -0,0 +1,134 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef PATCHCANVAS_API_H | |||
#define PATCHCANVAS_API_H | |||
#define START_NAMESPACE_PATCHCANVAS namespace PatchCanvas { | |||
#define END_NAMESPACE_PATCHCANVAS } | |||
#ifndef PATCHCANVAS_ORGANISATION_NAME | |||
#define PATCHCANVAS_ORGANISATION_NAME "PatchCanvas" | |||
#endif | |||
#include <QtCore/QString> | |||
#include "patchcanvas-theme.h" | |||
#include "patchscene.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
enum PortMode { | |||
PORT_MODE_NULL = 0, | |||
PORT_MODE_INPUT = 1, | |||
PORT_MODE_OUTPUT = 2 | |||
}; | |||
enum PortType { | |||
PORT_TYPE_NULL = 0, | |||
PORT_TYPE_AUDIO_JACK = 1, | |||
PORT_TYPE_MIDI_JACK = 2, | |||
PORT_TYPE_MIDI_A2J = 3, | |||
PORT_TYPE_MIDI_ALSA = 4 | |||
}; | |||
enum CallbackAction { | |||
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 | |||
}; | |||
enum Icon { | |||
ICON_HARDWARE = 0, | |||
ICON_APPLICATION = 1, | |||
ICON_LADISH_ROOM = 2 | |||
}; | |||
enum SplitOption { | |||
SPLIT_UNDEF = 0, | |||
SPLIT_NO = 1, | |||
SPLIT_YES = 2 | |||
}; | |||
enum AntialiasingOption { | |||
ANTIALIASING_NONE = 0, | |||
ANTIALIASING_SMALL = 1, | |||
ANTIALIASING_FULL = 2 | |||
}; | |||
enum EyeCandyOption { | |||
EYECANDY_NONE = 0, | |||
EYECANDY_SMALL = 1, | |||
EYECANDY_FULL = 2 | |||
}; | |||
// Canvas options | |||
struct options_t { | |||
QString theme_name; | |||
bool auto_hide_groups; | |||
bool use_bezier_lines; | |||
AntialiasingOption antialiasing; | |||
EyeCandyOption eyecandy; | |||
}; | |||
// Canvas features | |||
struct features_t { | |||
bool group_info; | |||
bool group_rename; | |||
bool port_info; | |||
bool port_rename; | |||
bool handle_group_pos; | |||
}; | |||
typedef void (*Callback) (CallbackAction action, int value1, int value2, QString value_str); | |||
// API starts here | |||
void setOptions(options_t* options); | |||
void setFeatures(features_t* features); | |||
void init(PatchScene* scene, Callback callback, bool debug=false); | |||
void clear(); | |||
void setInitialPos(int x, int y); | |||
void setCanvasSize(int x, int y, int width, int height); | |||
void addGroup(int group_id, QString group_name, SplitOption split=SPLIT_UNDEF, Icon icon=ICON_APPLICATION); | |||
void removeGroup(int group_id); | |||
void renameGroup(int group_id, QString new_group_name); | |||
void splitGroup(int group_id); | |||
void joinGroup(int group_id); | |||
QPointF getGroupPos(int group_id, PortMode port_mode=PORT_MODE_OUTPUT); | |||
void setGroupPos(int group_id, int group_pos_x, int group_pos_y); | |||
void setGroupPos(int group_id, int group_pos_x, int group_pos_y, int group_pos_xs, int group_pos_ys); | |||
void setGroupIcon(int group_id, Icon icon); | |||
void addPort(int group_id, int port_id, QString port_name, PortMode port_mode, PortType port_type); | |||
void removePort(int port_id); | |||
void renamePort(int port_id, QString new_port_name); | |||
void connectPorts(int connection_id, int port_out_id, int port_in_id); | |||
void disconnectPorts(int connection_id); | |||
void Arrange(); | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // PATCHCANVAS_API_H |
@@ -0,0 +1,178 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "patchcanvas-theme.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
Theme::Theme(List id) | |||
{ | |||
switch (id) | |||
{ | |||
case THEME_MODERN_DARK: | |||
// Name this theme | |||
name = "Modern Dark"; | |||
// Canvas | |||
canvas_bg = QColor(0, 0, 0); | |||
// Boxes | |||
box_pen = QPen(QColor(76,77,78), 1, Qt::SolidLine); | |||
box_pen_sel = QPen(QColor(206,207,208), 1, Qt::DashLine); | |||
box_bg_1 = QColor(32,34,35); | |||
box_bg_2 = QColor(43,47,48); | |||
box_shadow = QColor(89,89,89,180); | |||
box_text = QPen(QColor(240,240,240), 0); | |||
box_font_name = "Deja Vu Sans"; | |||
box_font_size = 8; | |||
box_font_state = QFont::Bold; | |||
// Ports | |||
port_audio_jack_pen = QPen(QColor(63,90,126), 1); | |||
port_audio_jack_pen_sel = QPen(QColor(63+30,90+30,126+30), 1); | |||
port_midi_jack_pen = QPen(QColor(159,44,42), 1); | |||
port_midi_jack_pen_sel = QPen(QColor(159+30,44+30,42+30), 1); | |||
port_midi_a2j_pen = QPen(QColor(137,76,43), 1); | |||
port_midi_a2j_pen_sel = QPen(QColor(137+30,76+30,43+30), 1); | |||
port_midi_alsa_pen = QPen(QColor(93,141,46), 1); | |||
port_midi_alsa_pen_sel = QPen(QColor(93+30,141+30,46+30), 1); | |||
port_audio_jack_bg = QColor(35,61,99); | |||
port_audio_jack_bg_sel = QColor(35+50,61+50,99+50); | |||
port_midi_jack_bg = QColor(120,15,16); | |||
port_midi_jack_bg_sel = QColor(120+50,15+50,16+50); | |||
port_midi_a2j_bg = QColor(101,47,16); | |||
port_midi_a2j_bg_sel = QColor(101+50,47+50,16+50); | |||
port_midi_alsa_bg = QColor(64,112,18); | |||
port_midi_alsa_bg_sel = QColor(64+50,112+50,18+50); | |||
port_text = QPen(QColor(250,250,250), 0); | |||
port_font_name = "Deja Vu Sans"; | |||
port_font_size = 8; | |||
port_font_state = QFont::Normal; | |||
port_mode = THEME_PORT_POLYGON; | |||
// Lines | |||
line_audio_jack = QColor(63,90,126); | |||
line_audio_jack_sel = QColor(63+90,90+90,126+90); | |||
line_audio_jack_glow = QColor(100,100,200); | |||
line_midi_jack = QColor(159,44,42); | |||
line_midi_jack_sel = QColor(159+90,44+90,42+90); | |||
line_midi_jack_glow = QColor(200,100,100); | |||
line_midi_a2j = QColor(137,76,43); | |||
line_midi_a2j_sel = QColor(137+90,76+90,43+90); | |||
line_midi_a2j_glow = QColor(166,133,133); | |||
line_midi_alsa = QColor(93,141,46); | |||
line_midi_alsa_sel = QColor(93+90,141+90,46+90); | |||
line_midi_alsa_glow = QColor(100,200,100); | |||
rubberband_pen = QPen(QColor(206,207,208), 1, Qt::SolidLine); | |||
rubberband_brush = QColor(76,77,78,100); | |||
break; | |||
case THEME_CLASSIC_DARK: | |||
// Name this theme | |||
name = "Classic Dark"; | |||
// Canvas | |||
canvas_bg = QColor(0,0,0); | |||
// Boxes | |||
box_pen = QPen(QColor(147-70,151-70,143-70), 2, Qt::SolidLine); | |||
box_pen_sel = QPen(QColor(147,151,143), 2, Qt::DashLine); | |||
box_bg_1 = QColor(30,34,36); | |||
box_bg_2 = QColor(30,34,36); | |||
box_shadow = QColor(89,89,89,180); | |||
box_text = QPen(QColor(255,255,255), 0); | |||
box_font_name = "Sans"; | |||
box_font_size = 9; | |||
box_font_state = QFont::Normal; | |||
// Ports | |||
port_audio_jack_pen = QPen(QColor(35,61,99), 0); | |||
port_audio_jack_pen_sel = QPen(QColor(255,0,0), 0); | |||
port_midi_jack_pen = QPen(QColor(120,15,16), 0); | |||
port_midi_jack_pen_sel = QPen(QColor(255,0,0), 0); | |||
port_midi_a2j_pen = QPen(QColor(101,47,17), 0); | |||
port_midi_a2j_pen_sel = QPen(QColor(255,0,0), 0); | |||
port_midi_alsa_pen = QPen(QColor(63,112,19), 0); | |||
port_midi_alsa_pen_sel = QPen(QColor(255,0,0), 0); | |||
port_audio_jack_bg = QColor(35,61,99); | |||
port_audio_jack_bg_sel = QColor(255,0,0); | |||
port_midi_jack_bg = QColor(120,15,16); | |||
port_midi_jack_bg_sel = QColor(255,0,0); | |||
port_midi_a2j_bg = QColor(101,47,17); | |||
port_midi_a2j_bg_sel = QColor(255,0,0); | |||
port_midi_alsa_bg = QColor(63,112,19); | |||
port_midi_alsa_bg_sel = QColor(255,0,0); | |||
port_text = QPen(QColor(250,250,250), 0); | |||
port_font_name = "Sans"; | |||
port_font_size = 8; | |||
port_font_state = QFont::Normal; | |||
port_mode = THEME_PORT_SQUARE; | |||
// Lines | |||
line_audio_jack = QColor(53,78,116); | |||
line_audio_jack_sel = QColor(255,0,0); | |||
line_audio_jack_glow = QColor(255,0,0); | |||
line_midi_jack = QColor(139,32,32); | |||
line_midi_jack_sel = QColor(255,0,0); | |||
line_midi_jack_glow = QColor(255,0,0); | |||
line_midi_a2j = QColor(120,65,33); | |||
line_midi_a2j_sel = QColor(255,0,0); | |||
line_midi_a2j_glow = QColor(255,0,0); | |||
line_midi_alsa = QColor(81,130,36); | |||
line_midi_alsa_sel = QColor(255,0,0); | |||
line_midi_alsa_glow = QColor(255,0,0); | |||
rubberband_pen = QPen(QColor(147,151,143), 2, Qt::SolidLine); | |||
rubberband_brush = QColor(35,61,99,100); | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
Theme::List getDefaultTheme() | |||
{ | |||
return Theme::THEME_MODERN_DARK; | |||
} | |||
QString getThemeName(Theme::List id) | |||
{ | |||
switch (id) | |||
{ | |||
case Theme::THEME_MODERN_DARK: | |||
return "Modern Dark"; | |||
case Theme::THEME_CLASSIC_DARK: | |||
return "Classic Dark"; | |||
default: | |||
return ""; | |||
} | |||
} | |||
QString getDefaultThemeName() | |||
{ | |||
return "Modern Dark"; | |||
} | |||
END_NAMESPACE_PATCHCANVAS |
@@ -0,0 +1,106 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef PATCHCANVAS_THEME_H | |||
#define PATCHCANVAS_THEME_H | |||
#include <QtGui/QColor> | |||
#include <QtGui/QFont> | |||
#include <QtGui/QPen> | |||
#include "patchcanvas-api.h" | |||
START_NAMESPACE_PATCHCANVAS | |||
class Theme | |||
{ | |||
public: | |||
enum PortType { | |||
THEME_PORT_SQUARE = 0, | |||
THEME_PORT_POLYGON = 1 | |||
}; | |||
enum List { | |||
THEME_MODERN_DARK = 0, | |||
THEME_CLASSIC_DARK = 1, | |||
THEME_MAX = 2 | |||
}; | |||
Theme(List id); | |||
// Canvas | |||
QString name; | |||
// Boxes | |||
QColor canvas_bg; | |||
QPen box_pen; | |||
QPen box_pen_sel; | |||
QColor box_bg_1; | |||
QColor box_bg_2; | |||
QColor box_shadow; | |||
QPen box_text; | |||
QString box_font_name; | |||
int box_font_size; | |||
QFont::Weight box_font_state; | |||
// Ports | |||
QPen port_audio_jack_pen; | |||
QPen port_audio_jack_pen_sel; | |||
QPen port_midi_jack_pen; | |||
QPen port_midi_jack_pen_sel; | |||
QPen port_midi_a2j_pen; | |||
QPen port_midi_a2j_pen_sel; | |||
QPen port_midi_alsa_pen; | |||
QPen port_midi_alsa_pen_sel; | |||
QColor port_audio_jack_bg; | |||
QColor port_audio_jack_bg_sel; | |||
QColor port_midi_jack_bg; | |||
QColor port_midi_jack_bg_sel; | |||
QColor port_midi_a2j_bg; | |||
QColor port_midi_a2j_bg_sel; | |||
QColor port_midi_alsa_bg; | |||
QColor port_midi_alsa_bg_sel; | |||
QPen port_text; | |||
QString port_font_name; | |||
int port_font_size; | |||
QFont::Weight port_font_state; | |||
PortType port_mode; | |||
// Lines | |||
QColor line_audio_jack; | |||
QColor line_audio_jack_sel; | |||
QColor line_audio_jack_glow; | |||
QColor line_midi_jack; | |||
QColor line_midi_jack_sel; | |||
QColor line_midi_jack_glow; | |||
QColor line_midi_a2j; | |||
QColor line_midi_a2j_sel; | |||
QColor line_midi_a2j_glow; | |||
QColor line_midi_alsa; | |||
QColor line_midi_alsa_sel; | |||
QColor line_midi_alsa_glow; | |||
QPen rubberband_pen; | |||
QColor rubberband_brush; | |||
}; | |||
Theme::List getDefaultTheme(); | |||
QString getThemeName(Theme::List id); | |||
QString getDefaultThemeName(); | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // PATCHCANVAS_THEME_H |
@@ -0,0 +1,129 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef PATCHCANVAS_H | |||
#define PATCHCANVAS_H | |||
#include <QtGui/QGraphicsItem> | |||
#include "patchcanvas-api.h" | |||
#define foreach2(var, list) \ | |||
for (int i=0; i < list.count(); i++) { var = list[i]; | |||
class QSettings; | |||
class QTimer; | |||
class CanvasObject : public QObject { | |||
Q_OBJECT | |||
public: | |||
CanvasObject(QObject* parent=0); | |||
public slots: | |||
void CanvasPostponedGroups(); | |||
void PortContextMenuDisconnect(); | |||
}; | |||
START_NAMESPACE_PATCHCANVAS | |||
class AbstractCanvasLine; | |||
class CanvasBox; | |||
class CanvasPort; | |||
class Theme; | |||
// object types | |||
enum CanvasType { | |||
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 | |||
struct group_dict_t { | |||
int group_id; | |||
QString group_name; | |||
bool split; | |||
Icon icon; | |||
CanvasBox* widgets[2]; | |||
}; | |||
struct port_dict_t { | |||
int group_id; | |||
int port_id; | |||
QString port_name; | |||
PortMode port_mode; | |||
PortType port_type; | |||
CanvasPort* widget; | |||
}; | |||
struct connection_dict_t { | |||
int connection_id; | |||
int port_in_id; | |||
int port_out_id; | |||
AbstractCanvasLine* widget; | |||
}; | |||
// Main Canvas object | |||
class Canvas { | |||
public: | |||
Canvas(); | |||
~Canvas(); | |||
PatchScene* scene; | |||
Callback callback; | |||
bool debug; | |||
unsigned long last_z_value; | |||
int last_connection_id; | |||
QPointF initial_pos; | |||
QRectF size_rect; | |||
QList<group_dict_t> group_list; | |||
QList<port_dict_t> port_list; | |||
QList<connection_dict_t> connection_list; | |||
CanvasObject* qobject; | |||
QSettings* settings; | |||
Theme* theme; | |||
bool initiated; | |||
}; | |||
const char* bool2str(bool check); | |||
const char* port_mode2str(PortMode port_mode); | |||
const char* port_type2str(PortType port_type); | |||
const char* icon2str(Icon icon); | |||
const char* split2str(SplitOption split); | |||
QString CanvasGetGroupName(int group_id); | |||
int CanvasGetGroupPortCount(int group_id); | |||
QPointF CanvasGetNewGroupPos(bool horizontal=false); | |||
QString CanvasGetFullPortName(int port_id); | |||
QList<int> CanvasGetPortConnectionList(int port_id); | |||
int CanvasGetConnectedPort(int connection_id, int port_id); | |||
void CanvasPostponedGroups(); | |||
void CanvasCallback(CallbackAction action, int value1, int value2, QString value_str); | |||
// global objects | |||
extern Canvas canvas; | |||
extern options_t options; | |||
extern features_t features; | |||
END_NAMESPACE_PATCHCANVAS | |||
#endif // PATCHCANVAS_H |
@@ -0,0 +1,287 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#include "patchscene.h" | |||
#include <cmath> | |||
#include <QtGui/QKeyEvent> | |||
#include <QtGui/QGraphicsRectItem> | |||
#include <QtGui/QGraphicsSceneMouseEvent> | |||
#include <QtGui/QGraphicsSceneWheelEvent> | |||
#include <QtGui/QGraphicsView> | |||
#include "patchcanvas.h" | |||
#include "canvasbox.h" | |||
using namespace PatchCanvas; | |||
PatchScene::PatchScene(QObject* parent, QGraphicsView* view) : | |||
QGraphicsScene(parent) | |||
{ | |||
m_ctrl_down = false; | |||
m_mouse_down_init = false; | |||
m_mouse_rubberband = false; | |||
m_rubberband = addRect(QRectF(0, 0, 0, 0)); | |||
m_rubberband->setZValue(-1); | |||
m_rubberband->hide(); | |||
m_rubberband_selection = false; | |||
m_rubberband_orig_point = QPointF(0, 0); | |||
m_view = view; | |||
if (! m_view) | |||
qFatal("PatchCanvas::PatchScene() - invalid view"); | |||
} | |||
void PatchScene::fixScaleFactor() | |||
{ | |||
qreal scale = m_view->transform().m11(); | |||
if (scale > 3.0) | |||
{ | |||
m_view->resetTransform(); | |||
m_view->scale(3.0, 3.0); | |||
} | |||
else if (scale < 0.2) | |||
{ | |||
m_view->resetTransform(); | |||
m_view->scale(0.2, 0.2); | |||
} | |||
emit scaleChanged(m_view->transform().m11()); | |||
} | |||
void PatchScene::updateTheme() | |||
{ | |||
setBackgroundBrush(canvas.theme->canvas_bg); | |||
m_rubberband->setPen(canvas.theme->rubberband_pen); | |||
m_rubberband->setBrush(canvas.theme->rubberband_brush); | |||
} | |||
void PatchScene::zoom_fit() | |||
{ | |||
qreal min_x, min_y, max_x, max_y; | |||
bool first_value = true; | |||
QList<QGraphicsItem*> items_list = items(); | |||
if (items_list.count() > 0) | |||
{ | |||
foreach (const QGraphicsItem* item, items_list) | |||
{ | |||
if (item && item->isVisible() and item->type() == CanvasBoxType) | |||
{ | |||
QPointF pos = item->scenePos(); | |||
QRectF rect = item->boundingRect(); | |||
if (first_value) | |||
min_x = pos.x(); | |||
else if (pos.x() < min_x) | |||
min_x = pos.x(); | |||
if (first_value) | |||
min_y = pos.y(); | |||
else if (pos.y() < min_y) | |||
min_y = pos.y(); | |||
if (first_value) | |||
max_x = pos.x()+rect.width(); | |||
else if (pos.x()+rect.width() > max_x) | |||
max_x = pos.x()+rect.width(); | |||
if (first_value) | |||
max_y = pos.y()+rect.height(); | |||
else if (pos.y()+rect.height() > max_y) | |||
max_y = pos.y()+rect.height(); | |||
first_value = false; | |||
} | |||
} | |||
m_view->fitInView(min_x, min_y, abs(max_x-min_x), abs(max_y-min_y), Qt::KeepAspectRatio); | |||
fixScaleFactor(); | |||
} | |||
} | |||
void PatchScene::zoom_in() | |||
{ | |||
if (m_view->transform().m11() < 3.0) | |||
m_view->scale(1.2, 1.2); | |||
emit scaleChanged(m_view->transform().m11()); | |||
} | |||
void PatchScene::zoom_out() | |||
{ | |||
if (m_view->transform().m11() > 0.2) | |||
m_view->scale(0.8, 0.8); | |||
emit scaleChanged(m_view->transform().m11()); | |||
} | |||
void PatchScene::zoom_reset() | |||
{ | |||
m_view->resetTransform(); | |||
emit scaleChanged(1.0); | |||
} | |||
void PatchScene::keyPressEvent(QKeyEvent* event) | |||
{ | |||
if (! m_view) | |||
return event->ignore(); | |||
if (event->key() == Qt::Key_Control) | |||
{ | |||
m_ctrl_down = true; | |||
} | |||
else if (event->key() == Qt::Key_Home) | |||
{ | |||
zoom_fit(); | |||
return event->accept(); | |||
} | |||
else if (m_ctrl_down) | |||
{ | |||
if (event->key() == Qt::Key_Plus) | |||
{ | |||
zoom_in(); | |||
return event->accept(); | |||
} | |||
else if (event->key() == Qt::Key_Minus) | |||
{ | |||
zoom_out(); | |||
return event->accept(); | |||
} | |||
else if (event->key() == Qt::Key_1) | |||
{ | |||
zoom_reset(); | |||
return event->accept(); | |||
} | |||
} | |||
QGraphicsScene::keyPressEvent(event); | |||
} | |||
void PatchScene::keyReleaseEvent(QKeyEvent* event) | |||
{ | |||
if (event->key() == Qt::Key_Control) | |||
m_ctrl_down = false; | |||
QGraphicsScene::keyReleaseEvent(event); | |||
} | |||
void PatchScene::mousePressEvent(QGraphicsSceneMouseEvent* event) | |||
{ | |||
m_mouse_down_init = (event->button() == Qt::LeftButton); | |||
m_mouse_rubberband = false; | |||
QGraphicsScene::mousePressEvent(event); | |||
} | |||
void PatchScene::mouseMoveEvent(QGraphicsSceneMouseEvent* event) | |||
{ | |||
if (m_mouse_down_init) | |||
{ | |||
m_mouse_down_init = false; | |||
m_mouse_rubberband = (selectedItems().count() == 0); | |||
} | |||
if (m_mouse_rubberband) | |||
{ | |||
if (m_rubberband_selection == false) | |||
{ | |||
m_rubberband->show(); | |||
m_rubberband_selection = true; | |||
m_rubberband_orig_point = event->scenePos(); | |||
} | |||
int x, y; | |||
QPointF pos = event->scenePos(); | |||
if (pos.x() > m_rubberband_orig_point.x()) | |||
x = m_rubberband_orig_point.x(); | |||
else | |||
x = pos.x(); | |||
if (pos.y() > m_rubberband_orig_point.y()) | |||
y = m_rubberband_orig_point.y(); | |||
else | |||
y = pos.y(); | |||
m_rubberband->setRect(x, y, abs(pos.x()-m_rubberband_orig_point.x()), abs(pos.y()-m_rubberband_orig_point.y())); | |||
return event->accept(); | |||
} | |||
QGraphicsScene::mouseMoveEvent(event); | |||
} | |||
void PatchScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) | |||
{ | |||
if (m_rubberband_selection) | |||
{ | |||
QList<QGraphicsItem*> items_list = items(); | |||
if (items_list.count() > 0) | |||
{ | |||
foreach (QGraphicsItem* item, items_list) | |||
{ | |||
if (item && item->isVisible() && item->type() == CanvasBoxType) | |||
{ | |||
QRectF item_rect = item->sceneBoundingRect(); | |||
QPointF item_top_left = QPointF(item_rect.x(), item_rect.y()); | |||
QPointF item_bottom_right = QPointF(item_rect.x()+item_rect.width(), item_rect.y()+item_rect.height()); | |||
if (m_rubberband->contains(item_top_left) && m_rubberband->contains(item_bottom_right)) | |||
item->setSelected(true); | |||
} | |||
} | |||
m_rubberband->hide(); | |||
m_rubberband->setRect(0, 0, 0, 0); | |||
m_rubberband_selection = false; | |||
} | |||
} | |||
else | |||
{ | |||
QList<QGraphicsItem*> items_list = selectedItems(); | |||
foreach (QGraphicsItem* item, items_list) | |||
{ | |||
if (item && item->isVisible() && item->type() == CanvasBoxType) | |||
{ | |||
CanvasBox* citem = (CanvasBox*)item; | |||
citem->checkItemPos(); | |||
emit sceneGroupMoved(citem->getGroupId(), citem->getSplittedMode(), citem->scenePos()); | |||
} | |||
} | |||
if (items_list.count() > 1) | |||
canvas.scene->update(); | |||
} | |||
m_mouse_down_init = false; | |||
m_mouse_rubberband = false; | |||
QGraphicsScene::mouseReleaseEvent(event); | |||
} | |||
void PatchScene::wheelEvent(QGraphicsSceneWheelEvent* event) | |||
{ | |||
if (! m_view) | |||
return event->ignore(); | |||
if (m_ctrl_down) | |||
{ | |||
double factor = std::pow(1.41, (event->delta()/240.0)); | |||
m_view->scale(factor, factor); | |||
fixScaleFactor(); | |||
return event->accept(); | |||
} | |||
QGraphicsScene::wheelEvent(event); | |||
} |
@@ -0,0 +1,67 @@ | |||
/* | |||
* Patchbay Canvas engine using QGraphicsView/Scene | |||
* Copyright (C) 2010-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 | |||
*/ | |||
#ifndef PATCHSCENE_H | |||
#define PATCHSCENE_H | |||
#include <QtGui/QGraphicsScene> | |||
class QKeyEvent; | |||
class QGraphicsRectItem; | |||
class QGraphicsSceneMouseEvent; | |||
class QGraphicsSceneWheelEvent; | |||
class QGraphicsView; | |||
class PatchScene : public QGraphicsScene | |||
{ | |||
Q_OBJECT | |||
public: | |||
PatchScene(QObject* parent, QGraphicsView* view); | |||
void fixScaleFactor(); | |||
void updateTheme(); | |||
void zoom_fit(); | |||
void zoom_in(); | |||
void zoom_out(); | |||
void zoom_reset(); | |||
signals: | |||
void scaleChanged(double); | |||
void sceneGroupMoved(int, int, QPointF); | |||
private: | |||
bool m_ctrl_down; | |||
bool m_mouse_down_init; | |||
bool m_mouse_rubberband; | |||
QGraphicsRectItem* m_rubberband; | |||
bool m_rubberband_selection; | |||
QPointF m_rubberband_orig_point; | |||
QGraphicsView* m_view; | |||
virtual void keyPressEvent(QKeyEvent* event); | |||
virtual void keyReleaseEvent(QKeyEvent* event); | |||
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event); | |||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event); | |||
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event); | |||
virtual void wheelEvent(QGraphicsSceneWheelEvent* event); | |||
}; | |||
#endif // PATCHSCENE_H |