more comments, no arrow is drawn at the end of an Edge if the Nodes are too close

master
Denes Matetelki 14 years ago
parent 497bda949e
commit bec530fd18

@ -9,8 +9,16 @@ class ArgumentParser : public QObject
public: 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 parseCmdLineArgs(bool &successful);
bool isSystemTray() { return m_isSystemTray; } bool isSystemTray() { return m_isSystemTray; }
@ -20,6 +28,7 @@ public:
private: private:
// print --help text
void printUsage(); void printUsage();
bool m_isSystemTray; bool m_isSystemTray;

@ -5,6 +5,7 @@
class Node; class Node;
// directed arrow
class Edge : public QGraphicsItem class Edge : public QGraphicsItem
{ {
public: public:
@ -12,10 +13,11 @@ public:
Edge(Node *sourceNode, Node *destNode); Edge(Node *sourceNode, Node *destNode);
~Edge(); ~Edge();
Node *sourceNode() const; Node *sourceNode() const { return m_sourceNode; }
Node *destNode() const; Node *destNode() const { return m_destNode; }
double getAngle() const; double angle() const { return m_angle; }
// set/get color/width/secondary
QColor color() const { return m_color; } QColor color() const { return m_color; }
void setColor(const QColor &color); void setColor(const QColor &color);
qreal width() const { return m_width; } qreal width() const { return m_width; }
@ -23,6 +25,8 @@ public:
bool secondary() const { return m_secondary; } bool secondary() const { return m_secondary; }
void setSecondary(const bool &sec = true ); void setSecondary(const bool &sec = true );
// re-calculates the source and endpoint.
// called when the source/dest node changed (size,pos)
void adjust(); void adjust();
protected: protected:
@ -42,6 +46,9 @@ private:
double m_angle; double m_angle;
QColor m_color; QColor m_color;
qreal m_width; qreal m_width;
// just a logical connection between two nodes,
// does not counts at subtree calculation
bool m_secondary; bool m_secondary;
static const qreal m_arrowSize; static const qreal m_arrowSize;

@ -39,7 +39,7 @@ public:
// changing visibility from prot to pub // changing visibility from prot to pub
void keyPressEvent(QKeyEvent *event); void keyPressEvent(QKeyEvent *event);
bool isConnected(const Node *node) const; 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<Edge *> edgesFrom(const bool &excludeSecondaries = true) const; QList<Edge *> edgesFrom(const bool &excludeSecondaries = true) const;
QList<Edge *> edgesToThis(const bool &excludeSecondaries = true) const; QList<Edge *> edgesToThis(const bool &excludeSecondaries = true) const;

@ -6,15 +6,6 @@
#include <iostream> #include <iostream>
ArgumentParser::ArgumentParser(QObject *parent) :
QObject(parent),
m_isSystemTray(false),
m_isShowMinimized(false),
m_filePath()
{
}
void ArgumentParser::printUsage() void ArgumentParser::printUsage()
{ {
std::cout << tr("Usage: ").toStdString() << "qtmindmap " std::cout << tr("Usage: ").toStdString() << "qtmindmap "

@ -17,6 +17,7 @@ Edge::Edge(Node *sourceNode, Node *destNode)
, m_width(1) , m_width(1)
, m_secondary(false) , m_secondary(false)
{ {
// does not interact with user
setAcceptedMouseButtons(0); setAcceptedMouseButtons(0);
setZValue(1); setZValue(1);
@ -33,21 +34,6 @@ Edge::~Edge()
m_destNode->removeEdgeFromList(this); 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) void Edge::setColor(const QColor &color)
{ {
m_color = color; m_color = color;
@ -71,24 +57,14 @@ void Edge::setSecondary(const bool &sec)
void Edge::adjust() void Edge::adjust()
{ {
if (!m_sourceNode || !m_destNode)
return;
prepareGeometryChange(); prepareGeometryChange();
QLineF line(m_sourceNode->sceneBoundingRect().center(), QLineF line(m_sourceNode->sceneBoundingRect().center(),
m_destNode->sceneBoundingRect().center()); m_destNode->sceneBoundingRect().center());
if (line.length() > qreal(20.)) m_destPoint = m_destNode->intersection(line, true);
{
m_destPoint = m_destNode->intersect(line,true);
m_sourcePoint = m_sourceNode->sceneBoundingRect().center(); m_sourcePoint = m_sourceNode->sceneBoundingRect().center();
} }
else
{
m_sourcePoint = m_destPoint = line.p1();
}
}
QRectF Edge::boundingRect() const QRectF Edge::boundingRect() const
{ {
@ -98,9 +74,11 @@ QRectF Edge::boundingRect() const
qreal penWidth = 1; qreal penWidth = 1;
qreal extra = (penWidth + m_arrowSize + m_width) / 2.0; qreal extra = (penWidth + m_arrowSize + m_width) / 2.0;
return QRectF(m_sourcePoint, QSizeF(m_destPoint.x() - m_sourcePoint.x(), return QRectF(m_sourcePoint,
QSizeF(m_destPoint.x() - m_sourcePoint.x(),
m_destPoint.y() - m_sourcePoint.y())) m_destPoint.y() - m_sourcePoint.y()))
.normalized().adjusted(-extra, -extra, extra, extra); .normalized().adjusted(-extra, -extra,
extra, extra);
} }
void Edge::paint(QPainter *painter, void Edge::paint(QPainter *painter,
@ -109,19 +87,18 @@ void Edge::paint(QPainter *painter,
{ {
Q_UNUSED(w); Q_UNUSED(w);
if (!m_sourceNode || !m_destNode) // calculate angle
return;
QLineF line(m_sourcePoint, m_destPoint); QLineF line(m_sourcePoint, m_destPoint);
m_angle = ::acos(line.dx() / line.length()); m_angle = ::acos(line.dx() / line.length());
if (line.dy() >= 0) if (line.dy() >= 0)
m_angle = Edge::m_twoPi - m_angle; m_angle = Edge::m_twoPi - m_angle;
// no need to draw when the nodes overlap
if (sourceNode()->collidesWithItem(destNode())) if (sourceNode()->collidesWithItem(destNode()))
return; return;
// Draw the line itself // Draw the line itself - if secondary then dashline
painter->setPen(QPen(m_color, painter->setPen(QPen(m_color,
m_width, m_width,
m_secondary ? m_secondary ?
@ -141,15 +118,24 @@ void Edge::paint(QPainter *painter,
Qt::RoundCap, Qt::RoundCap,
Qt::RoundJoin)); Qt::RoundJoin));
painter->setBrush(m_color);
qreal arrowSize = m_arrowSize + m_width; 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 destArrowP1 = m_destPoint +
QPointF(sin(m_angle - Edge::m_pi / 3) * arrowSize, QPointF(sin(m_angle - Edge::m_pi / 3) * arrowSize,
cos(m_angle - Edge::m_pi / 3) * arrowSize); cos(m_angle - Edge::m_pi / 3) * arrowSize);
QPointF destArrowP2 = m_destPoint + QPointF destArrowP2 = m_destPoint +
QPointF(sin(m_angle - Edge::m_pi + Edge::m_pi / 3) * arrowSize, QPointF(sin(m_angle - Edge::m_pi + Edge::m_pi / 3) * arrowSize,
cos(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() painter->drawPolygon(QPolygonF() << line.p2()
<< destArrowP1 << destArrowP1
<< destArrowP2); << destArrowP2);

@ -175,16 +175,16 @@ double Node::calculateBiggestAngle()
if (m_edgeList.size()==1) if (m_edgeList.size()==1)
return m_edgeList.first().startsFromThisNode ? return m_edgeList.first().startsFromThisNode ?
Node::m_pi - m_edgeList.first().edge->getAngle() : Node::m_pi - m_edgeList.first().edge->angle() :
Node::m_twoPi - m_edgeList.first().edge->getAngle(); Node::m_twoPi - m_edgeList.first().edge->angle();
QList<double> tmp; QList<double> tmp;
for(QList<EdgeElement>::iterator it = m_edgeList.begin(); for(QList<EdgeElement>::iterator it = m_edgeList.begin();
it != m_edgeList.end(); it++) it != m_edgeList.end(); it++)
{ {
tmp.push_back(it->startsFromThisNode ? tmp.push_back(it->startsFromThisNode ?
it->edge->getAngle() : it->edge->angle() :
doubleModulo(Node::m_pi + it->edge->getAngle(), Node::m_twoPi)); doubleModulo(Node::m_pi + it->edge->angle(), Node::m_twoPi));
} }
qSort(tmp.begin(), tmp.end()); qSort(tmp.begin(), tmp.end());
@ -266,8 +266,12 @@ bool Node::isConnected(const Node *node) const
return false; return false;
} }
QPointF Node::intersect(const QLineF &line, const bool &reverse) const QPointF Node::intersection(const QLineF &line, const bool &reverse) const
{ {
/// @note What a shame, the following does not work,
/// doing it with brute (unaccurate) force
// QPainterPath shape; // QPainterPath shape;
// shape.addRoundedRect(sceneBoundingRect(), 20.0, 15.0); // shape.addRoundedRect(sceneBoundingRect(), 20.0, 15.0);
@ -278,23 +282,20 @@ QPointF Node::intersect(const QLineF &line, const bool &reverse) const
// return shape.intersected(l).pointAtPercent(0.5); // return shape.intersected(l).pointAtPercent(0.5);
/// @but this just does not work, doing it with brute force
QPainterPath path; QPainterPath path;
path.addRoundedRect(sceneBoundingRect(), 28.0, 28.0); path.addRoundedRect(sceneBoundingRect(), 28.0, 28.0);
if (reverse) if (reverse)
{ {
for (qreal t = 1; t!=0; t-=0.01) for (qreal t = 1; t!=0; t-=0.01)
{ if (!path.contains(line.pointAt(t)))
if (!path.contains(line.pointAt(t))) return line.pointAt(t); return line.pointAt(t);
}
} }
else else
{ {
for (qreal t = 0; t!=1; t+=0.01) for (qreal t = 0; t!=1; t+=0.01)
{ if (!path.contains(line.pointAt(t)))
if (!path.contains(line.pointAt(t))) return line.pointAt(t); return line.pointAt(t);
}
} }
return QPointF(0,0); return QPointF(0,0);

Loading…
Cancel
Save