From bec530fd189f1631f65ee504ab61d8c22c620b09 Mon Sep 17 00:00:00 2001 From: Denes Matetelki Date: Sat, 25 Jun 2011 19:32:17 +0200 Subject: [PATCH] more comments, no arrow is drawn at the end of an Edge if the Nodes are too close --- include/argumentparser.h | 13 ++++++++-- include/edge.h | 13 +++++++--- include/node.h | 2 +- src/argumentparser.cpp | 9 ------- src/edge.cpp | 56 +++++++++++++++------------------------- src/node.cpp | 37 +++++++++++++------------- 6 files changed, 62 insertions(+), 68 deletions(-) diff --git a/include/argumentparser.h b/include/argumentparser.h index d93754d..d2d4718 100644 --- a/include/argumentparser.h +++ b/include/argumentparser.h @@ -9,8 +9,16 @@ class ArgumentParser : public QObject public: - explicit ArgumentParser(QObject *parent = 0); - + explicit ArgumentParser(QObject *parent = 0) + : QObject(parent) + , m_isSystemTray(false) + , m_isShowMinimized(false) + , m_filePath() {} + + /** parse QCoreApplication::arguments and put data to priv. members + * @param successful true if cannot continue but it is not an error + * @return true if the program can continue + */ bool parseCmdLineArgs(bool &successful); bool isSystemTray() { return m_isSystemTray; } @@ -20,6 +28,7 @@ public: private: + // print --help text void printUsage(); bool m_isSystemTray; diff --git a/include/edge.h b/include/edge.h index a29d2ec..e3efcf4 100644 --- a/include/edge.h +++ b/include/edge.h @@ -5,6 +5,7 @@ class Node; +// directed arrow class Edge : public QGraphicsItem { public: @@ -12,10 +13,11 @@ public: Edge(Node *sourceNode, Node *destNode); ~Edge(); - Node *sourceNode() const; - Node *destNode() const; - double getAngle() const; + Node *sourceNode() const { return m_sourceNode; } + Node *destNode() const { return m_destNode; } + double angle() const { return m_angle; } + // set/get color/width/secondary QColor color() const { return m_color; } void setColor(const QColor &color); qreal width() const { return m_width; } @@ -23,6 +25,8 @@ public: bool secondary() const { return m_secondary; } void setSecondary(const bool &sec = true ); + // re-calculates the source and endpoint. + // called when the source/dest node changed (size,pos) void adjust(); protected: @@ -42,6 +46,9 @@ private: double m_angle; QColor m_color; qreal m_width; + + // just a logical connection between two nodes, + // does not counts at subtree calculation bool m_secondary; static const qreal m_arrowSize; diff --git a/include/node.h b/include/node.h index 41e6860..348c46d 100644 --- a/include/node.h +++ b/include/node.h @@ -39,7 +39,7 @@ public: // changing visibility from prot to pub void keyPressEvent(QKeyEvent *event); bool isConnected(const Node *node) const; - QPointF intersect(const QLineF &line, const bool &reverse = false) const; + QPointF intersection(const QLineF &line, const bool &reverse = false) const; QList edgesFrom(const bool &excludeSecondaries = true) const; QList edgesToThis(const bool &excludeSecondaries = true) const; diff --git a/src/argumentparser.cpp b/src/argumentparser.cpp index 52a37fd..a81cf8d 100644 --- a/src/argumentparser.cpp +++ b/src/argumentparser.cpp @@ -6,15 +6,6 @@ #include -ArgumentParser::ArgumentParser(QObject *parent) : - QObject(parent), - m_isSystemTray(false), - m_isShowMinimized(false), - m_filePath() -{ -} - - void ArgumentParser::printUsage() { std::cout << tr("Usage: ").toStdString() << "qtmindmap " diff --git a/src/edge.cpp b/src/edge.cpp index 4e3b139..b9d1782 100644 --- a/src/edge.cpp +++ b/src/edge.cpp @@ -17,6 +17,7 @@ Edge::Edge(Node *sourceNode, Node *destNode) , m_width(1) , m_secondary(false) { + // does not interact with user setAcceptedMouseButtons(0); setZValue(1); @@ -33,21 +34,6 @@ Edge::~Edge() m_destNode->removeEdgeFromList(this); } -Node *Edge::sourceNode() const -{ - return m_sourceNode; -} - -Node *Edge::destNode() const -{ - return m_destNode; -} - -double Edge::getAngle() const -{ - return m_angle; -} - void Edge::setColor(const QColor &color) { m_color = color; @@ -71,23 +57,13 @@ void Edge::setSecondary(const bool &sec) void Edge::adjust() { - if (!m_sourceNode || !m_destNode) - return; - prepareGeometryChange(); QLineF line(m_sourceNode->sceneBoundingRect().center(), m_destNode->sceneBoundingRect().center()); - if (line.length() > qreal(20.)) - { - m_destPoint = m_destNode->intersect(line,true); - m_sourcePoint = m_sourceNode->sceneBoundingRect().center(); - } - else - { - m_sourcePoint = m_destPoint = line.p1(); - } + m_destPoint = m_destNode->intersection(line, true); + m_sourcePoint = m_sourceNode->sceneBoundingRect().center(); } QRectF Edge::boundingRect() const @@ -98,9 +74,11 @@ QRectF Edge::boundingRect() const qreal penWidth = 1; qreal extra = (penWidth + m_arrowSize + m_width) / 2.0; - return QRectF(m_sourcePoint, QSizeF(m_destPoint.x() - m_sourcePoint.x(), - m_destPoint.y() - m_sourcePoint.y())) - .normalized().adjusted(-extra, -extra, extra, extra); + return QRectF(m_sourcePoint, + QSizeF(m_destPoint.x() - m_sourcePoint.x(), + m_destPoint.y() - m_sourcePoint.y())) + .normalized().adjusted(-extra, -extra, + extra, extra); } void Edge::paint(QPainter *painter, @@ -109,19 +87,18 @@ void Edge::paint(QPainter *painter, { Q_UNUSED(w); - if (!m_sourceNode || !m_destNode) - return; - + // calculate angle QLineF line(m_sourcePoint, m_destPoint); m_angle = ::acos(line.dx() / line.length()); if (line.dy() >= 0) m_angle = Edge::m_twoPi - m_angle; + // no need to draw when the nodes overlap if (sourceNode()->collidesWithItem(destNode())) return; - // Draw the line itself + // Draw the line itself - if secondary then dashline painter->setPen(QPen(m_color, m_width, m_secondary ? @@ -141,15 +118,24 @@ void Edge::paint(QPainter *painter, Qt::RoundCap, Qt::RoundJoin)); + painter->setBrush(m_color); qreal arrowSize = m_arrowSize + m_width; + // no need to draw the arrow if the nodes are too close + if (line.length() < arrowSize) + { + painter->drawLine(m_sourcePoint, m_destPoint); + return; + } + QPointF destArrowP1 = m_destPoint + QPointF(sin(m_angle - Edge::m_pi / 3) * arrowSize, cos(m_angle - Edge::m_pi / 3) * arrowSize); QPointF destArrowP2 = m_destPoint + QPointF(sin(m_angle - Edge::m_pi + Edge::m_pi / 3) * arrowSize, cos(m_angle - Edge::m_pi + Edge::m_pi / 3) * arrowSize); - painter->setBrush(m_color); + + painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2); diff --git a/src/node.cpp b/src/node.cpp index 9d93d54..a0dbf60 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -175,16 +175,16 @@ double Node::calculateBiggestAngle() if (m_edgeList.size()==1) return m_edgeList.first().startsFromThisNode ? - Node::m_pi - m_edgeList.first().edge->getAngle() : - Node::m_twoPi - m_edgeList.first().edge->getAngle(); + Node::m_pi - m_edgeList.first().edge->angle() : + Node::m_twoPi - m_edgeList.first().edge->angle(); QList tmp; for(QList::iterator it = m_edgeList.begin(); it != m_edgeList.end(); it++) { tmp.push_back(it->startsFromThisNode ? - it->edge->getAngle() : - doubleModulo(Node::m_pi + it->edge->getAngle(), Node::m_twoPi)); + it->edge->angle() : + doubleModulo(Node::m_pi + it->edge->angle(), Node::m_twoPi)); } qSort(tmp.begin(), tmp.end()); @@ -266,35 +266,36 @@ bool Node::isConnected(const Node *node) const return false; } -QPointF Node::intersect(const QLineF &line, const bool &reverse) const +QPointF Node::intersection(const QLineF &line, const bool &reverse) const { -// QPainterPath shape; -// shape.addRoundedRect(sceneBoundingRect(), 20.0, 15.0); -// QPainterPath l; -// l.moveTo(sceneBoundingRect().center()); -// l.lineTo(line.p2()); + /// @note What a shame, the following does not work, + /// doing it with brute (unaccurate) force -// return shape.intersected(l).pointAtPercent(0.5); + // QPainterPath shape; + // shape.addRoundedRect(sceneBoundingRect(), 20.0, 15.0); + + // QPainterPath l; + // l.moveTo(sceneBoundingRect().center()); + // l.lineTo(line.p2()); + + // return shape.intersected(l).pointAtPercent(0.5); - /// @but this just does not work, doing it with brute force QPainterPath path; path.addRoundedRect(sceneBoundingRect(), 28.0, 28.0); if (reverse) { for (qreal t = 1; t!=0; t-=0.01) - { - if (!path.contains(line.pointAt(t))) return line.pointAt(t); - } + if (!path.contains(line.pointAt(t))) + return line.pointAt(t); } else { for (qreal t = 0; t!=1; t+=0.01) - { - if (!path.contains(line.pointAt(t))) return line.pointAt(t); - } + if (!path.contains(line.pointAt(t))) + return line.pointAt(t); } return QPointF(0,0);