Commit 4801d256 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[ADD #291] allow disconnects via mouse: double-click on connector or arrow or...

[ADD #291] allow disconnects via mouse: double-click on connector or arrow or drag the connection arrow away.
parent 478e15a7
......@@ -39,6 +39,8 @@
#include "WQtNetworkArrow.h"
const qreal Pi = 3.14;
const QColor owRed( 248, 87, 87 );
const QColor owGreen( 115, 225, 115 );
WQtNetworkArrow::WQtNetworkArrow( WQtNetworkOutputPort *startPort, WQtNetworkInputPort *endPort )
: QGraphicsPathItem()
......@@ -63,12 +65,18 @@ int WQtNetworkArrow::type() const
return Type;
}
void WQtNetworkArrow::updatePosition()
void WQtNetworkArrow::updatePosition( QPointF deviate )
{
QRectF sRect = m_startPort->rect();
QRectF eRect = m_startPort->rect();
updatePosition( mapFromItem( m_endPort, eRect.bottomRight() * 0.5 ), deviate );
}
void WQtNetworkArrow::updatePosition( QPointF targetPoint, QPointF deviate )
{
QRectF sRect = m_startPort->rect();
QLineF tmpLine( mapFromItem( m_startPort, sRect.bottomRight() * 0.5 ),
mapFromItem( m_endPort, eRect.bottomRight() * 0.5 ) );
targetPoint );
m_line = QLineF( tmpLine.x1(), tmpLine.y1()+5, tmpLine.x2(), tmpLine.y2()-5 );
QPainterPath path( m_line.p1() );
......@@ -86,7 +94,7 @@ void WQtNetworkArrow::updatePosition()
QPointF c2( m_line.p2() + QPointF( 0, -dy ) );
// cubic bezier
path.cubicTo( c1, c2, m_line.p2() );
path.cubicTo( c1, c2 + deviate, m_line.p2() );
setPath( path );
}
......@@ -112,12 +120,6 @@ QVariant WQtNetworkArrow::itemChange( GraphicsItemChange change,
void WQtNetworkArrow::paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* w )
{
if( isSelected() &&
m_color != Qt::green )
{
changeColor( Qt::green );
}
QStyleOptionGraphicsItem *o = const_cast<QStyleOptionGraphicsItem*>( option );
o->state &= ~QStyle::State_Selected;
......@@ -157,7 +159,7 @@ void WQtNetworkArrow::hoverEnterEvent( QGraphicsSceneHoverEvent * event )
{
Q_UNUSED( event );
changeColor( Qt::green );
changeColor( Qt::black, 3 );
updatePosition();
}
......@@ -174,3 +176,111 @@ void WQtNetworkArrow::changeColor( QColor color )
setPen( QPen( m_color, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
}
void WQtNetworkArrow::changeColor( QColor color, float penWidth )
{
m_color = color;
setPen( QPen( m_color, penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
}
void WQtNetworkArrow::mouseDoubleClickEvent( QGraphicsSceneMouseEvent* mouseEvent )
{
QGraphicsItem::mouseDoubleClickEvent( mouseEvent );
// ignore all buttons but the left one
if( mouseEvent->button() != Qt::LeftButton )
{
mouseEvent->ignore();
return;
}
QList<QGraphicsItem *> startItem = scene()->items( mouseEvent->scenePos() );
if( !startItem.isEmpty() )
{
mouseEvent->accept();
getStartPort()->getConnector()->disconnect( getEndPort()->getConnector() );
}
else
{
mouseEvent->ignore();
}
}
void WQtNetworkArrow::mousePressEvent( QGraphicsSceneMouseEvent *mouseEvent )
{
if( mouseEvent->button() != Qt::LeftButton )
{
mouseEvent->ignore();
return;
}
mouseEvent->accept();
m_snappedOff = false;
m_connectionDisconnect = false;
// highlight
changeColor( owGreen, 3 );
// clickPoint
m_clickPoint = mouseEvent->pos();
}
void WQtNetworkArrow::mouseMoveEvent( QGraphicsSceneMouseEvent *mouseEvent )
{
mouseEvent->accept();
QPointF currentPoint = mouseEvent->pos();
// deviate according to start pos
QPointF deviate = currentPoint - m_clickPoint;
float l = sqrt( ( deviate.x() * deviate.x() ) + ( deviate.y() * deviate.y() ) );
// if moved far enough, snap to mouse
m_snappedOff = m_snappedOff || ( l > 100.0 ); // when snapped of once, never snap on again
// are we near the original connector?
QPointF diffToConnector = currentPoint - mapFromItem( m_endPort, m_endPort->rect().bottomRight() * 0.5 );
float lDiffToConnector = sqrt( ( diffToConnector.x() * diffToConnector.x() ) + ( diffToConnector.y() * diffToConnector.y() ) );
bool snapBack = ( lDiffToConnector < 50.0 );
if( m_snappedOff && !snapBack )
{
updatePosition( currentPoint, QPointF() );
}
else
{
updatePosition( deviate );
}
if( snapBack )
{
changeColor( owGreen, 3 );
m_connectionDisconnect = false;
}
if( m_snappedOff && !snapBack )
{
changeColor( owRed, 3 );
m_connectionDisconnect = true;
}
}
void WQtNetworkArrow::mouseReleaseEvent( QGraphicsSceneMouseEvent *mouseEvent )
{
if( mouseEvent->button() != Qt::LeftButton )
{
mouseEvent->ignore();
return;
}
mouseEvent->accept();
updatePosition();
changeColor( Qt::black );
// what to do
if( m_connectionDisconnect )
{
m_startPort->getConnector()->disconnect( m_endPort->getConnector() );
}
}
......@@ -78,8 +78,19 @@ public:
/**
* Calculated the new position of the lines endpoints in the scene.
* Is called everytime the parentItem is changed or after construction.
*
* \param deviate pull the line into this direction.
*/
void updatePosition( QPointF deviate = QPointF() );
/**
* Calculated the new position of the lines endpoints in the scene.
* Is called everytime the parentItem is changed or after construction.
*
* \param deviate pull the line into this direction.
* \param targetPoint the point where to point to.
*/
void updatePosition();
void updatePosition( QPointF targetPoint, QPointF deviate );
/**
* Returns the WQtNetworkOutputPort where the arrow starts.
......@@ -142,6 +153,36 @@ protected:
*/
void hoverLeaveEvent( QGraphicsSceneHoverEvent *event );
/**
* Double click on port
*
* \param mouseEvent the event
*/
void mouseDoubleClickEvent( QGraphicsSceneMouseEvent* mouseEvent );
/**
* Start drawing an arrow temporary.
*
* \param mouseEvent the mouse event
*/
void mousePressEvent( QGraphicsSceneMouseEvent *mouseEvent );
/**
* Updates the temporary arrows endpoint.
* Arrow is colored green when connection possible, red if no connection
* is possible, or black when cursor doesent covers an WQtNetworkPort.
*
* \param mouseEvent the mouse event
*/
void mouseMoveEvent( QGraphicsSceneMouseEvent *mouseEvent );
/**
* Send a connect request to kernel when start- and endport are
* connectable
*
* \param mouseEvent the mouse event
*/
void mouseReleaseEvent( QGraphicsSceneMouseEvent *mouseEvent );
private:
/**
* This method changes the color of the arrow.
......@@ -150,6 +191,14 @@ private:
*/
void changeColor( QColor color );
/**
* Change color and width of the arrow
*
* \param color the color
* \param penWidth the new width.
*/
void changeColor( QColor color, float penWidth );
WQtNetworkOutputPort *m_startPort; //!< the start port
WQtNetworkInputPort *m_endPort; //!< the end port
......@@ -159,5 +208,11 @@ private:
QPolygonF m_arrowHead; //!< the arrowhead
QLineF m_line; //!< the line representing the arrow
QPointF m_clickPoint; //!< position where the click event was created.
bool m_snappedOff; //!< gets true once the arrow was pulled far away from original click position.
bool m_connectionDisconnect; //!< disconnect if true.
};
#endif // WQTNETWORKARROW_H
......@@ -94,6 +94,39 @@ void WQtNetworkPort::mousePressEvent( QGraphicsSceneMouseEvent *mouseEvent )
}
}
void WQtNetworkPort::mouseDoubleClickEvent( QGraphicsSceneMouseEvent* mouseEvent )
{
QGraphicsItem::mouseDoubleClickEvent( mouseEvent );
// ignore all buttons but the left one
if( mouseEvent->button() != Qt::LeftButton )
{
mouseEvent->ignore();
return;
}
QList<QGraphicsItem *> startItem = scene()->items( mouseEvent->scenePos() );
if( !startItem.isEmpty() )
{
mouseEvent->accept();
WQtNetworkOutputPort* outP = dynamic_cast< WQtNetworkOutputPort* >( startItem.first() );
WQtNetworkInputPort* inP = dynamic_cast< WQtNetworkInputPort* >( startItem.first() );
// delete all connections
if( inP )
{
inP->getConnector()->disconnectAll();
}
if( outP )
{
outP->getConnector()->disconnectAll();
}
}
else
{
mouseEvent->ignore();
}
}
void WQtNetworkPort::mouseMoveEvent( QGraphicsSceneMouseEvent *mouseEvent )
{
if( m_line )
......
......@@ -154,6 +154,13 @@ protected:
*/
void mousePressEvent( QGraphicsSceneMouseEvent *mouseEvent );
/**
* Double click on port
*
* \param mouseEvent the event
*/
void mouseDoubleClickEvent( QGraphicsSceneMouseEvent* mouseEvent );
/**
* Updates the temporary arrows endpoint.
* Arrow is colored green when connection possible, red if no connection
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment