Secondary edges

master
Denes Matetelki 14 years ago
parent eb97252d33
commit 144ed860a6

@ -15,6 +15,7 @@ Edge::Edge(Node *sourceNode, Node *destNode)
: m_angle(-1) : m_angle(-1)
, m_color(0,0,0) , m_color(0,0,0)
, m_width(1) , m_width(1)
, m_secondary(false)
{ {
setAcceptedMouseButtons(0); setAcceptedMouseButtons(0);
setZValue(1); setZValue(1);
@ -62,6 +63,12 @@ void Edge::setWidth(const qreal &width)
update(); update();
} }
void Edge::setSecondary(const bool &sec)
{
m_secondary = sec;
update();
}
void Edge::adjust() void Edge::adjust()
{ {
if (!m_sourceNode || !m_destNode) if (!m_sourceNode || !m_destNode)
@ -75,22 +82,25 @@ void Edge::adjust()
if (line.length() > qreal(20.)) if (line.length() > qreal(20.))
{ {
// m_sourcePoint = m_sourceNode->intersect(line); // m_sourcePoint = m_sourceNode->intersect(line);
// m_destPoint = m_destNode->intersect(line,true); m_destPoint = m_destNode->intersect(line,true);
/// @bug seems not to be updated
m_sourcePoint = m_sourceNode->sceneBoundingRect().center(); m_sourcePoint = m_sourceNode->sceneBoundingRect().center();
m_destPoint = m_destNode->sceneBoundingRect().center(); // m_destPoint = m_destNode->sceneBoundingRect().center();
} else { } else {
m_sourcePoint = m_destPoint = line.p1(); m_sourcePoint = m_destPoint = line.p1();
} }
} }
/// @bug not ok yet
QRectF Edge::boundingRect() const QRectF Edge::boundingRect() const
{ {
if (!m_sourceNode || !m_destNode) if (!m_sourceNode || !m_destNode)
return QRectF(); return QRectF();
qreal penWidth = 1; qreal penWidth = 1;
qreal extra = (penWidth + m_arrowSize) / 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()))
@ -118,6 +128,8 @@ void Edge::paint(QPainter *painter,
// Draw the line itself // Draw the line itself
painter->setPen(QPen(m_color, painter->setPen(QPen(m_color,
m_width, m_width,
m_secondary ?
Qt::DashLine :
Qt::SolidLine, Qt::SolidLine,
Qt::RoundCap, Qt::RoundCap,
Qt::RoundJoin)); Qt::RoundJoin));
@ -127,13 +139,20 @@ void Edge::paint(QPainter *painter,
return; return;
// Draw the arrow // Draw the arrow
// QPointF destArrowP1 = m_destPoint + painter->setPen(QPen(m_color,
// QPointF(sin(m_angle - Edge::m_pi / 3) * m_arrowSize, m_width,
// cos(m_angle - Edge::m_pi / 3) * m_arrowSize); Qt::SolidLine,
// QPointF destArrowP2 = m_destPoint + Qt::RoundCap,
// QPointF(sin(m_angle - Edge::m_pi + Edge::m_pi / 3) * m_arrowSize, Qt::RoundJoin));
// cos(m_angle - Edge::m_pi + Edge::m_pi / 3) * m_arrowSize);
qreal arrowSize = m_arrowSize + m_width;
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->setBrush(m_color);
painter->drawPolygon(QPolygonF() << line.p2() painter->drawPolygon(QPolygonF() << line.p2()
<< destArrowP1 << destArrowP1

@ -16,10 +16,12 @@ public:
Node *destNode() const; Node *destNode() const;
double getAngle() const; double getAngle() const;
void setColor(const QColor &color);
QColor color() const { return m_color; } QColor color() const { return m_color; }
void setWidth(const qreal &width); void setColor(const QColor &color);
qreal width() const { return m_width; } qreal width() const { return m_width; }
void setWidth(const qreal &width);
bool secondary() const { return m_secondary; }
void setSecondary(const bool &sec = true );
void adjust(); void adjust();
@ -40,6 +42,7 @@ private:
double m_angle; double m_angle;
QColor m_color; QColor m_color;
qreal m_width; qreal m_width;
bool m_secondary;
static const qreal m_arrowSize; static const qreal m_arrowSize;
static const double m_pi; static const double m_pi;

@ -95,6 +95,7 @@ void GraphWidget::readContentFromXmlFile(const QString &fileName)
e.attribute("text_green").toFloat(), e.attribute("text_green").toFloat(),
e.attribute("text_blue").toFloat()/*, e.attribute("text_blue").toFloat()/*,
e.attribute("text_alpha").toFloat()*/)); e.attribute("text_alpha").toFloat()*/));
m_nodeList.append(node); m_nodeList.append(node);
} }
} }
@ -113,6 +114,7 @@ void GraphWidget::readContentFromXmlFile(const QString &fileName)
e.attribute("blue").toFloat()/*, e.attribute("blue").toFloat()/*,
e.attribute("alpha").toFloat()*/)); e.attribute("alpha").toFloat()*/));
edge->setWidth(e.attribute("width").toFloat()); edge->setWidth(e.attribute("width").toFloat());
edge->setSecondary(e.attribute("secondary").toInt() );
m_scene->addItem(edge); m_scene->addItem(edge);
} }
@ -144,7 +146,7 @@ void GraphWidget::writeContentToXmlFile(const QString &fileName)
cn.setAttribute( "x", QString::number(node->pos().x())); cn.setAttribute( "x", QString::number(node->pos().x()));
cn.setAttribute( "y", QString::number(node->pos().y())); cn.setAttribute( "y", QString::number(node->pos().y()));
cn.setAttribute( "htmlContent", node->toHtml()); cn.setAttribute( "htmlContent", node->toHtml());
cn.setAttribute( "scale", QString::number(((QGraphicsTextItem*)node)->scale())); cn.setAttribute( "scale", QString::number(dynamic_cast<QGraphicsTextItem*>(node)->scale()));
cn.setAttribute( "bg_red", QString::number(node->color().red())); cn.setAttribute( "bg_red", QString::number(node->color().red()));
cn.setAttribute( "bg_green", QString::number(node->color().green())); cn.setAttribute( "bg_green", QString::number(node->color().green()));
cn.setAttribute( "bg_blue", QString::number(node->color().blue())); cn.setAttribute( "bg_blue", QString::number(node->color().blue()));
@ -171,6 +173,7 @@ void GraphWidget::writeContentToXmlFile(const QString &fileName)
cn.setAttribute( "blue", QString::number(edge->color().blue())); cn.setAttribute( "blue", QString::number(edge->color().blue()));
// cn.setAttribute( "alpha", QString::number(edge->color().alpha())); // cn.setAttribute( "alpha", QString::number(edge->color().alpha()));
cn.setAttribute( "width", QString::number(edge->width())); cn.setAttribute( "width", QString::number(edge->width()));
cn.setAttribute( "secondary", QString::number(edge->secondary()));
edges_root.appendChild(cn); edges_root.appendChild(cn);
} }
@ -431,7 +434,8 @@ void GraphWidget::keyPressEvent(QKeyEvent *event)
{ {
QColor color = dialog.selectedColor(); QColor color = dialog.selectedColor();
m_activeNode->setColor(color); m_activeNode->setColor(color);
m_activeNode->edgeTo()->setColor(color); foreach (Edge * edge, m_activeNode->edgesToThis(false))
edge->setColor(color);
} }
break; break;
@ -615,6 +619,13 @@ void GraphWidget::nodeSelected(Node *node)
void GraphWidget::addEdge(Node *source, Node *destination) void GraphWidget::addEdge(Node *source, Node *destination)
{ {
if (destination == m_nodeList.first())
{
m_parent->statusBarMsg(
tr("Root element cannot be an edge target."));
return;
}
if (source->isConnected(destination)) if (source->isConnected(destination))
{ {
m_parent->statusBarMsg( m_parent->statusBarMsg(
@ -622,8 +633,18 @@ void GraphWidget::addEdge(Node *source, Node *destination)
} }
else else
{ {
bool sec(false);
if (!destination->edgesToThis().empty())
{
m_parent->statusBarMsg(
tr("The graph is acyclic, edge added as secondary edge."));
sec = true;
}
Edge *edge = new Edge(source, destination); Edge *edge = new Edge(source, destination);
edge->setColor(destination->color()); edge->setColor(destination->color());
edge->setWidth(dynamic_cast<QGraphicsTextItem *>(destination)->scale()*2 + 1);
edge->setSecondary(sec);
m_scene->addItem(edge); m_scene->addItem(edge);
contentChanged(); contentChanged();
} }

@ -70,10 +70,10 @@ void Node::removeEdgeFromList(Edge *edge)
} }
} }
void Node::adjustEdges() //void Node::adjustEdges()
{ //{
foreach (EdgeElement element, m_edgeList) element.edge->adjust(); // foreach (EdgeElement element, m_edgeList) element.edge->adjust();
} //}
void Node::setBorder(const bool &hasBorder) void Node::setBorder(const bool &hasBorder)
{ {
@ -113,20 +113,21 @@ void Node::setTextColor(const QColor &color)
void Node::scale(const qreal &factor) void Node::scale(const qreal &factor)
{ {
if (factor * QGraphicsTextItem::scale() < 0.2 || if (factor * QGraphicsTextItem::scale() < 0.4 ||
factor * QGraphicsTextItem::scale() > 10 ) factor * QGraphicsTextItem::scale() > 4 )
return; return;
// it would make stuff difficult, like limiting the pos. inside scene // it would make stuff difficult, like limiting the pos. inside scene
// setTransformOriginPoint(boundingRect().center()); // setTransformOriginPoint(boundingRect().center());
QGraphicsTextItem::setScale(factor * QGraphicsTextItem::scale()); QGraphicsTextItem::setScale(factor * QGraphicsTextItem::scale());
foreach(EdgeElement element, m_edgeList) foreach(EdgeElement element, m_edgeList)
if (!element.startsFromThisNode) if (!element.startsFromThisNode)
element.edge->setWidth(element.edge->width() + {
(factor>1 ? 2 : -2) ); element.edge->setWidth(element.edge->width() * factor );
/// @bug seems not working
adjustEdges(); element.edge->adjust();
}
} }
void Node::showNumber(const int &number, void Node::showNumber(const int &number,
@ -270,29 +271,35 @@ QPointF Node::intersect(const QLineF &line, const bool &reverse) const
return QPointF(0,0); return QPointF(0,0);
} }
QList<Edge *> Node::edgesFrom() const QList<Edge *> Node::edgesFrom(const bool &excludeSecondaries) const
{ {
QList<Edge *> list; QList<Edge *> list;
foreach(EdgeElement element, m_edgeList) foreach(EdgeElement element, m_edgeList)
if (element.startsFromThisNode) if (element.startsFromThisNode &&
(!element.edge->secondary() || !excludeSecondaries))
list.push_back(element.edge); list.push_back(element.edge);
return list; return list;
} }
Edge * Node::edgeTo(const Node *node) const QList<Edge *> Node::edgesToThis(const bool &excludeSecondaries) const
{ {
if (!node) QList<Edge *> list;
{
foreach(EdgeElement element, m_edgeList) foreach(EdgeElement element, m_edgeList)
if (!element.startsFromThisNode) if (!element.startsFromThisNode &&
return element.edge; (!element.edge->secondary() || !excludeSecondaries))
} list.push_back(element.edge);
return list;
}
Edge * Node::edgeTo(const Node *node) const
{
foreach(EdgeElement element, m_edgeList) foreach(EdgeElement element, m_edgeList)
if (element.edge->sourceNode() == node || if ((element.edge->sourceNode() == node ||
element.edge->destNode() == node) element.edge->destNode() == node))
return element.edge; return element.edge;
return 0; return 0;

@ -19,7 +19,7 @@ public:
void addEdge(Edge *edge, bool startsFromThisNode); void addEdge(Edge *edge, bool startsFromThisNode);
void deleteEdge(Node *otherEnd); void deleteEdge(Node *otherEnd);
void removeEdgeFromList(Edge *edge); void removeEdgeFromList(Edge *edge);
void adjustEdges(); // void adjustEdges();
void setBorder(const bool &hasBorder); void setBorder(const bool &hasBorder);
void setActive(const bool &active = true); void setActive(const bool &active = true);
@ -39,8 +39,9 @@ public:
bool isConnected(const Node *node) const; bool isConnected(const Node *node) const;
QPointF intersect(const QLineF &line, const bool &reverse = false) const; QPointF intersect(const QLineF &line, const bool &reverse = false) const;
QList<Edge *> edgesFrom() const; QList<Edge *> edgesFrom(const bool &excludeSecondaries = true) const;
Edge * edgeTo(const Node* node = 0) const; QList<Edge *> edgesToThis(const bool &excludeSecondaries = true) const;
Edge * edgeTo(const Node* node) const;
protected: protected:

Loading…
Cancel
Save