2 Qanava - Graph drawing library for QT
3 Copyright (C) 2006 Benoit AUTHEMAN
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //-----------------------------------------------------------------------------
21 // This file is a part of the Qanava software.
23 // \file qanEdgeItem.cpp
24 // \author Benoit Autheman (benoit@libqanava.org)
25 // \date 2007 February 08
26 //-----------------------------------------------------------------------------
30 #include "./qanNodeItem.h"
31 #include "./qanEdgeItem.h"
35 #include <QGraphicsScene>
39 namespace qan
{ // ::qan
42 /* Arrow Constructor/Destructor *///-------------------------------------------
43 EdgeItem::EdgeItem( Style::Manager
& styleManager
, Style
* style
, QGraphicsItem
* parent
, QGraphicsScene
* scene
,
44 Edge
& edge
, NodeItem
* src
, NodeItem
* dst
) :
45 GraphItem( styleManager
, style
),
46 QGraphicsItem( parent
, scene
),
52 _lineType( Qt::SolidLine
),
57 if ( src
!= 0 && dst
!= 0 )
67 EdgeItem::~EdgeItem( )
69 // FIXME: segfault with node dtor
71 _src->removeEdge( this );
73 _dst->removeEdge( this );*/
76 QRectF
EdgeItem::boundingRect( ) const
78 if ( _src
== 0 || _dst
== 0 )
81 QPointF src
= _src
->mapToScene( _src
->boundingRect( ).center( ) );
82 QPointF dst
= _dst
->mapToScene( _dst
->boundingRect( ).center( ) );
84 QPointF
topLeft( qMin( src
.x( ), dst
.x( ) ), // tl=(minx, miny)
85 qMin( src
.y( ), dst
.y( ) ) );
86 QPointF
bottomRight( qMax( src
.x( ), dst
.x( ) ), // br=(maxx, maxy)
87 qMax( src
.y( ), dst
.y( ) ) );
89 QRectF
br( 0., 0., qAbs( bottomRight
.x( ) - topLeft
.x( ) ), qAbs( bottomRight
.y( ) - topLeft
.y( ) ) );
91 // Take the text label into account
92 br
= br
.unite( _labelRect
);
94 // Take the arrow into account
95 br
.adjust( -_arrowSize
, -_arrowSize
, _arrowSize
, _arrowSize
);
100 void EdgeItem::updateItem( )
102 if ( _src
== 0 || _dst
== 0 )
105 QPointF srcF
= _src
->mapToScene( _src
->boundingRect( ).center( ) );
106 QPointF dstF
= _dst
->mapToScene( _dst
->boundingRect( ).center( ) );
107 QPointF
topLeft( qMin( srcF
.x( ), dstF
.x( ) ), // tl=(minx, miny)
108 qMin( srcF
.y( ), dstF
.y( ) ) );
110 setPos( topLeft
); // setPos should have been called update on the old garbage area ?
112 if ( getStyle( ) != 0 && getStyle( )->has( "linetype" ) )
114 _lineType
= Qt::SolidLine
;
115 const QVariant
& value
= getStyle( )->get( "linetype" );
116 if ( value
.isValid( ) )
117 _lineType
= value
.value
< int >( );
119 if ( getStyle( ) != 0 && getStyle( )->has( "lineweight" ) )
122 const QVariant
& value
= getStyle( )->get( "lineweight" );
123 if ( value
.isValid( ) )
124 _lineWeight
= value
.value
< int >( );
126 if ( getStyle( ) != 0 && getStyle( )->has( "arrowsize" ) )
129 const QVariant
& value
= getStyle( )->get( "arrowsize" );
130 if ( value
.isValid( ) )
131 _arrowSize
= value
.value
< int >( );
134 QGraphicsItem::update( );
137 void EdgeItem::paint( QPainter
* painter
, const QStyleOptionGraphicsItem
* option
, QWidget
* widget
)
139 if ( _src
== 0 || _dst
== 0 )
142 QPointF srcF
= _src
->mapToScene( _src
->boundingRect( ).center( ) );
143 QPointF dstF
= _dst
->mapToScene( _dst
->boundingRect( ).center( ) );
144 QLineF
line( mapFromScene( srcF
), mapFromScene( dstF
) );
146 QPen
arrowPen( Qt::black
, _lineWeight
, ( Qt::PenStyle
)_lineType
, Qt::RoundCap
, Qt::RoundJoin
);
148 if ( _edge
.getLabel( ).length( ) > 0 )
150 QPointF middleF
= QPointF( 15., 5. ) + srcF
+ ( dstF
- srcF
) / 2;
151 middleF
= mapFromScene( middleF
);
152 painter
->setPen( QPen( Qt::black
, 1, Qt::SolidLine
, Qt::RoundCap
, Qt::RoundJoin
) );
153 _labelRect
= painter
->boundingRect( QRectF( ), Qt::AlignLeft
| Qt::AlignVCenter
, _edge
.getLabel( ) );
154 _labelRect
.translate( middleF
); // Keep the label rect to compute the edge bbox
155 painter
->drawText( middleF
, _edge
.getLabel( ) );
160 const double Pi
= 3.141592653;
161 double TwoPi
= 2.0 * Pi
;
162 double angle
= ::acos( line
.dx( ) / line
.length( ) );
163 if ( line
.dy( ) >= 0 )
164 angle
= TwoPi
- angle
;
166 // Get the intersection between arrow and dst node
167 QRectF br
= mapFromItem( _dst
, _dst
->boundingRect( ) ).boundingRect( );
169 // Test intersection with all borders
170 QLineF
top( br
.topLeft( ), br
.topRight( ) );
171 QLineF
right( br
.topRight( ), br
.bottomRight( ) );
172 QLineF
bottom( br
.bottomLeft( ), br
.bottomRight( ) );
173 QLineF
left( br
.topLeft( ), br
.bottomLeft( ) );
176 if ( line
.intersect( top
, &i
) == QLineF::BoundedIntersection
||
177 line
.intersect( right
, &i
) == QLineF::BoundedIntersection
||
178 line
.intersect( bottom
, &i
) == QLineF::BoundedIntersection
||
179 line
.intersect( left
, &i
) == QLineF::BoundedIntersection
)
181 QLineF
shortLine( mapFromScene( srcF
), i
);
182 painter
->setPen( arrowPen
);
183 painter
->drawLine( shortLine
);
185 painter
->setRenderHint( QPainter::Antialiasing
);
186 painter
->setPen( QPen( Qt::black
, 1, Qt::SolidLine
, Qt::RoundCap
, Qt::RoundJoin
) );
187 painter
->setBrush( QBrush( QColor( 0, 0, 0 ) ) );
189 double angle
= ::acos( line
.dx( ) / line
.length( ) );
190 if ( line
.dy( ) <= 0 )
191 angle
= TwoPi
- angle
;
193 painter
->translate( i
);
194 painter
->rotate( angle
* 180. / Pi
);
196 double arrowSize
= _arrowSize
;
197 double arrowLength
= _arrowSize
* 2.;
198 i
= QPointF( -arrowLength
- 1., 0. );
200 poly
<< QPointF( i
.x( ), i
.y( ) - arrowSize
)
201 << QPointF( i
.x( ) + arrowLength
, i
.y( ) )
202 << QPointF( i
.x( ), i
.y( ) + arrowSize
) << QPointF( i
.x( ), i
.y( ) - arrowSize
);
203 painter
->drawPolygon( poly
);
209 painter
->setPen( arrowPen
);
210 painter
->drawLine( line
);
214 void EdgeItem::disconnectEdge( )
220 void EdgeItem::nodeDestroyed( )
224 //-----------------------------------------------------------------------------