#include <Graphics/ConnectionBox.h> #include <utility> #include <QtGui/QDrag> #include <QtWidgets/QApplication> #include <Graphics/GraphicsBox.h> #include <Graphics/GraphicsScene.h> const QColor ConnectionBox::defaultColor = Qt::white; ConnectionBox::ConnectionBox(GraphicsBox* parent, Type type) : QGraphicsRectItem(-8, -8, 16, 16, parent) , _type(type) { this->setBrush(ConnectionBox::defaultColor); this->setAcceptedMouseButtons(Qt::LeftButton); } void ConnectionBox::mousePressEvent(QGraphicsSceneMouseEvent* event) { this->setCursor(Qt::UpArrowCursor); Q_ASSERT(!this->tempLine); this->tempLine = this->scene()->addLine({this->scenePos(), this->scenePos()}); this->tempLine->setZValue(2); } void ConnectionBox::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { Q_ASSERT(this->tempLine); QLineF line = this->tempLine->line(); line.setP2(event->scenePos()); this->tempLine->setLine(line); static ConnectionBox* other = nullptr; if (other) { other->setColor(ConnectionBox::defaultColor); } other = nullptr; for (auto* item: this->scene()->items(event->scenePos())) { if (auto* cb = dynamic_cast<ConnectionBox*>(item)) { other = cb; break; } } if (other && other->getType() != this->getType()) { other->setColor(Qt::yellow); } } void ConnectionBox::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { this->setCursor(Qt::ArrowCursor); Q_ASSERT(this->tempLine); delete this->tempLine; this->tempLine = nullptr; auto* other = dynamic_cast<ConnectionBox*>(this->scene()->itemAt(event->scenePos(), {})); if (other && other->getType() != this->getType()) { this->setColor(ConnectionBox::defaultColor); other->setColor(ConnectionBox::defaultColor); ConnectionBox::connect(this, other); } } void ConnectionBox::connect(ConnectionBox* a, ConnectionBox* b) { Q_ASSERT(a->getType() != b->getType()); auto* origin = a; auto* target = b; if (origin->getType() == ConnectionBox::Type::Input) std::swap(origin, target); origin->connection = target->connection = std::make_shared<Connection>(origin, target); } void ConnectionBox::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) { QMenu menu; QAction* a = menu.addAction("&Disconnect"); QObject::connect(a, SIGNAL(triggered()), this, SLOT(on_Disconnect())); menu.exec(event->screenPos()); event->accept(); } void ConnectionBox::on_Disconnect() { auto* origin = this->connection->getOriginConnectionBox(); auto* target = this->connection->getTargetConnectionBox(); origin->getWrapperBox()->removeOutput(); target->getWrapperBox()->removeInput(origin->getWrapperBox(), nullptr); origin->connection.reset(); target->connection.reset(); } void ConnectionBox::setColor(QColor color) { QBrush brush = this->brush(); brush.setColor(color); this->setBrush(brush); } WrapperBox* ConnectionBox::getWrapperBox() const { return dynamic_cast<GraphicsBox*>(this->parentObject())->getWrapperBox(); }