nodes are scalable with ctrl + plus/minus

master
Denes Matetelki 14 years ago
parent 565c45ce6a
commit 0f21ae4faa

@ -38,30 +38,6 @@ Node *Edge::destNode() const
return m_destNode;
}
/** @note This is brute force. Isn't there a simple fv for this?
* The precision is not the best either
*/
QPointF firstNotContainedPoint(const QLineF &line,
const QRectF &rect,
bool reverse = false)
{
if (reverse)
{
for (qreal t = 1; t!=0; t-=0.01)
{
if (!rect.contains(line.pointAt(t))) return line.pointAt(t);
}
}
else
{
for (qreal t = 0; t!=1; t+=0.01)
{
if (!rect.contains(line.pointAt(t))) return line.pointAt(t);
}
}
return QPoint(0,0);
}
double Edge::getAngle() const
{
return m_angle;
@ -74,16 +50,14 @@ void Edge::adjust()
prepareGeometryChange();
QLineF line(mapFromItem(m_sourceNode, 0, 0) +
m_sourceNode->boundingRect().center(),
mapFromItem(m_destNode, 0, 0) +
m_destNode->boundingRect().center());
QLineF line(m_sourceNode->sceneBoundingRect().center(),
m_destNode->sceneBoundingRect().center());
if (line.length() > qreal(20.))
{
m_sourcePoint = m_sourceNode->intersect(line);
m_destPoint = m_destNode->intersect(line,true);
if (line.length() > qreal(20.)) {
m_sourcePoint = firstNotContainedPoint(line,
m_sourceNode->sceneBoundingRect());
m_destPoint = firstNotContainedPoint(line,
m_destNode->sceneBoundingRect(),true);
} else {
m_sourcePoint = m_destPoint = line.p1();
}

@ -5,6 +5,7 @@
#include <QMessageBox>
#include <QFileDialog>
#include <QtXml>
#include <QColorDialog>
#include "node.h"
#include "edge.h"
@ -84,6 +85,8 @@ void GraphWidget::readContentFromXmlFile(const QString &fileName)
m_scene->addItem(node);
node->setPos(e.attribute("x").toFloat(),
e.attribute("y").toFloat());
node->setScale(e.attribute("scale").toFloat());
m_nodeList.append(node);
}
}
@ -120,10 +123,13 @@ void GraphWidget::writeContentToXmlFile(const QString &fileName)
foreach(Node *node, m_nodeList)
{
QDomElement cn = doc.createElement("nodes");
// cn.setAttribute( "id", QString::number(m_nodeList.indexOf(node)));
// no need to store ID: parsing order is preorder.
// cn.setAttribute( "id", QString::number(m_nodeList.indexOf(node)));
cn.setAttribute( "x", QString::number(node->pos().x()));
cn.setAttribute( "y", QString::number(node->pos().y()));
cn.setAttribute( "htmlContent", node->toHtml());
cn.setAttribute("scale", QString::number(((QGraphicsTextItem*)node)->scale()));
nodes_root.appendChild(cn);
}
@ -176,8 +182,6 @@ void GraphWidget::writeContentToPngFile(const QString &fileName)
void GraphWidget::keyPressEvent(QKeyEvent *event)
{
qDebug() << __PRETTY_FUNCTION__;
// esc leaves node editing mode
if (event->key() == Qt::Key_Escape && m_editingNode)
{
@ -199,11 +203,13 @@ void GraphWidget::keyPressEvent(QKeyEvent *event)
event->key() == Qt::Key_Delete || // delete node
event->key() == Qt::Key_A || // add edge
event->key() == Qt::Key_D || // remove edge
( event->modifiers() == Qt::ControlModifier && // moving node
( event->modifiers() & Qt::ControlModifier && // moving node
( event->key() == Qt::Key_Up ||
event->key() == Qt::Key_Down ||
event->key() == Qt::Key_Left ||
event->key() == Qt::Key_Right))))
event->key() == Qt::Key_Right ||
event->key() == Qt::Key_Plus ||
event->key() == Qt::Key_Minus ))))
{
m_parent->statusBarMsg(tr("No active node."));
return;
@ -254,10 +260,24 @@ void GraphWidget::keyPressEvent(QKeyEvent *event)
// zoom in/out
case Qt::Key_Plus:
if (event->modifiers() & Qt::ControlModifier)
{
m_activeNode->scale(qreal(1.2));
}
else
{
scaleView(qreal(1.2));
}
break;
case Qt::Key_Minus:
if (event->modifiers() & Qt::ControlModifier)
{
m_activeNode->scale(qreal(1 / 1.2));
}
else
{
scaleView(1 / qreal(1.2));
}
break;
// Hint mode: select a node vimperator style
@ -359,6 +379,14 @@ void GraphWidget::keyPressEvent(QKeyEvent *event)
m_edgeDeleting = true;
break;
case Qt::Key_C:
{
QColorDialog dialog(this);
if (dialog.exec())
QColor color = dialog.selectedColor();
break;
}
default:
QGraphicsView::keyPressEvent(event);
}
@ -554,6 +582,7 @@ void GraphWidget::addFirstNode()
m_scene->addItem(node);
node->setPos(-25, -25);
node->setBorder(false);
m_nodeList.append(node);
m_activeNode = m_nodeList.first();

@ -35,12 +35,11 @@ protected:
void keyPressEvent(QKeyEvent *event);
void wheelEvent(QWheelEvent *event);
void scaleView(qreal scaleFactor);
void drawBackground(QPainter *painter, const QRectF &rect);
private:
void scaleView(qreal scaleFactor);
void showNodeNumbers();
void showingAllNodeNumbers(const bool &show = true);
void showingNodeNumbersBeginWithNumber(const int &number,

@ -16,7 +16,7 @@ Node::Node(GraphWidget *parent) :
m_graph(parent),
m_isActive(false),
m_number(-1),
m_hasBorder(false),
m_hasBorder(true),
m_numberIsSpecial(false)
{
setFlag(ItemIsMovable);
@ -66,6 +66,11 @@ void Node::removeEdgeFromList(Edge *edge)
}
}
void Node::adjustEdges()
{
foreach (EdgeElement element, m_edgeList) element.edge->adjust();
}
void Node::setBorder(const bool &hasBorder)
{
m_hasBorder = hasBorder;
@ -90,6 +95,21 @@ void Node::setEditable(const bool &editable)
setTextCursor(c);
}
void Node::scale(const qreal &factor)
{
qDebug() << factor * QGraphicsTextItem::scale();
if (factor * QGraphicsTextItem::scale() < 0.3 ||
factor * QGraphicsTextItem::scale() > 5 )
return;
// it would make stuff difficult, like limiting the pos. inside scene
// setTransformOriginPoint(boundingRect().center());
QGraphicsTextItem::setScale(factor * QGraphicsTextItem::scale());
adjustEdges();
}
void Node::showNumber(const int &number,
const bool& show,
const bool &numberIsSpecial)
@ -197,6 +217,40 @@ bool Node::isConnected(const Node *node) const
return false;
}
QPointF Node::intersect(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());
// 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);
}
}
else
{
for (qreal t = 0; t!=1; t+=0.01)
{
if (!path.contains(line.pointAt(t))) return line.pointAt(t);
}
}
return QPointF(0,0);
}
QList<Edge *> Node::edgesFrom() const
{
QList<Edge *> list;
@ -219,29 +273,25 @@ void Node::paint(QPainter *painter,
painter->setPen(Qt::transparent);
painter->setBrush(m_numberIsSpecial ? Qt::green : Qt::yellow);
painter->drawRoundedRect(QRect(boundingRect().topLeft().toPoint(),
boundingRect().bottomRight().toPoint()), 20.0, 15.0);
painter->setBrush(Qt::NoBrush);
painter->drawRoundedRect(boundingRect(), 20.0, 15.0);
}
else if (m_isActive) // draw background for active node
else
{
m_hasBorder ?
painter->setPen(m_isActive ? Qt::red : Qt::blue) :
painter->setPen(Qt::transparent);
if (m_isActive)
painter->setBrush(Node::m_orange);
painter->drawRoundedRect(QRect(boundingRect().topLeft().toPoint(),
boundingRect().bottomRight().toPoint()), 20.0, 15.0);
painter->setBrush(Qt::NoBrush);
painter->drawRoundedRect(boundingRect(), 20.0, 15.0);
}
painter->setBrush(Qt::NoBrush);
// the text itself
QGraphicsTextItem::paint(painter, option, w);
if (m_hasBorder)
{
painter->setPen(m_isActive ? Qt::red : Qt::blue);
painter->drawRect(QRect(boundingRect().topLeft().toPoint(),
boundingRect().bottomRight().toPoint() -
QPoint(1,1)));
}
// print num to topleft corner in hint mode.
if (m_number != -1)
@ -268,7 +318,7 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
// the fence is reduced with the size of the node
QRectF rect (scene()->sceneRect().topLeft(),
scene()->sceneRect().bottomRight() -
boundingRect().bottomRight());
boundingRect().bottomRight() * QGraphicsTextItem::scale() );
if (!rect.contains(newPos))
{
@ -316,6 +366,14 @@ void Node::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
QGraphicsItem::mouseMoveEvent(event);
}
/// @bug it seems sceneBoundingRect().contains doesn't care about path retval...
QPainterPath Node::shape () const
{
QPainterPath path;
path.addRoundedRect(boundingRect(), 20.0, 15.0);
return path;
}
double Node::doubleModulo(const double &devided, const double &devisor)
{
return devided - static_cast<double>(devisor * static_cast<int>(devided

@ -19,10 +19,12 @@ public:
void addEdge(Edge *edge, bool startsFromThisNode);
void deleteEdge(Node *otherEnd);
void removeEdgeFromList(Edge *edge);
void adjustEdges();
void setBorder(const bool &hasBorder);
void setActive(const bool &active = true);
void setEditable(const bool &editable = true);
void scale(const qreal &factor);
void showNumber(const int &number, const bool& show = true,
const bool &numberIsSpecial = false);
@ -31,6 +33,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;
QList<Edge *> edgesFrom() const;
@ -43,6 +46,7 @@ protected:
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
QPainterPath shape () const;
private:

Loading…
Cancel
Save