@@ -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 |