c50b5b6db16e78224553d465041bcd997c233b37
[occt.git] / samples / qt / FuncDemo / src / edge.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.
4 **
5 ** This file is part of the example classes of the Qt Toolkit.
6 **
7 ** Licensees holding a valid Qt License Agreement may use this file in
8 ** accordance with the rights, responsibilities and obligations
9 ** contained therein.  Please consult your licensing agreement or
10 ** contact sales@trolltech.com if any conditions of this licensing
11 ** agreement are not clear to you.
12 **
13 ** Further information about Qt licensing is available at:
14 ** http://www.trolltech.com/products/qt/licensing.html or by
15 ** contacting info@trolltech.com.
16 **
17 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 **
20 ****************************************************************************/
21
22 #include <QPainter>
23
24 #include "edge.h"
25 #include "node.h"
26
27 #include <math.h>
28
29 static const double Pi = 3.14159265358979323846264338327950288419717;
30 static double TwoPi = 2.0 * Pi;
31
32 Edge::Edge(Node *sourceNode, Node *destNode)
33     : arrowSize(10)
34 {
35     setAcceptedMouseButtons(0);
36     source = sourceNode;
37     dest = destNode;
38     source->addEdge(this);
39     dest->addEdge(this);
40     adjust();
41 }
42
43 Edge::~Edge()
44 {
45 }
46
47 Node *Edge::sourceNode() const
48 {
49     return source;
50 }
51
52 void Edge::setSourceNode(Node *node)
53 {
54     source = node;
55     adjust();
56 }
57
58 Node *Edge::destNode() const
59 {
60     return dest;
61 }
62
63 void Edge::setDestNode(Node *node)
64 {
65     dest = node;
66     adjust();
67 }
68
69 void Edge::adjust()
70 {
71     if (!source || !dest)
72         return;
73
74     QLineF line(mapFromItem(source, 0, 0), mapFromItem(dest, 0, 0));
75     qreal length = line.length();
76     QPointF edgeOffset((line.dx() * 15) / length, (line.dy() * 15) / length);
77
78     prepareGeometryChange();
79     sourcePoint = line.p1() + edgeOffset;
80     destPoint = line.p2() - edgeOffset;
81 }
82
83 QRectF Edge::boundingRect() const
84 {
85     if (!source || !dest)
86         return QRectF();
87
88     qreal penWidth = 1;
89     qreal extra = (penWidth + arrowSize) / 2.0;
90
91     return QRectF(sourcePoint, QSizeF(destPoint.x() - sourcePoint.x(),
92                                       destPoint.y() - sourcePoint.y()))
93         .normalized()
94         .adjusted(-extra, -extra, extra, extra);
95 }
96
97 void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
98 {
99     if (!source || !dest)
100         return;
101
102     adjust();
103
104     // Draw the line itself
105     QLineF line(sourcePoint, destPoint);
106     painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
107     painter->drawLine(line);
108
109     // Draw the arrows if there's enough room
110     double angle = ::acos(line.dx() / line.length());
111     if (line.dy() >= 0)
112         angle = TwoPi - angle;
113
114     QPointF destArrowP1 = destPoint + QPointF(sin(angle - Pi / 3) * arrowSize,
115                                               cos(angle - Pi / 3) * arrowSize);
116     QPointF destArrowP2 = destPoint + QPointF(sin(angle - Pi + Pi / 3) * arrowSize,
117                                               cos(angle - Pi + Pi / 3) * arrowSize);
118
119     painter->setBrush(Qt::black);
120     painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2);        
121 }