/**************************************************************************** ** ** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved. ** ** This file is part of the example classes of the Qt Toolkit. ** ** This file may be used under the terms of the GNU General Public ** License version 2.0 as published by the Free Software Foundation ** and appearing in the file LICENSE.GPL included in the packaging of ** this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** http://trolltech.com/products/qt/licenses/licensing/opensource/ ** ** If you are unsure which license is appropriate for your use, please ** review the following information: ** http://trolltech.com/products/qt/licenses/licensing/licensingoverview ** or contact the sales department at sales@trolltech.com. ** ** In addition, as a special exception, Trolltech gives you certain ** additional rights. These rights are described in the Trolltech GPL ** Exception version 1.0, which can be found at ** http://www.trolltech.com/products/qt/gplexception/ and in the file ** GPL_EXCEPTION.txt in this package. ** ** In addition, as a special exception, Trolltech, as the sole copyright ** holder for Qt Designer, grants users of the Qt/Eclipse Integration ** plug-in the right for the Qt/Eclipse Integration to link to ** functionality provided by Qt Designer and its related libraries. ** ** Trolltech reserves all rights not expressly granted herein. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #include "graphwidget.h" #include "edge.h" #include "arrow.h" #include "node.h" #include #include #include #include GraphWidget::GraphWidget(QWidget *parent) :QGraphicsView(parent), timerId(0) { #if 0 QGraphicsScene *scene = new QGraphicsScene(this); scene->setItemIndexMethod(QGraphicsScene::NoIndex); //scene->setSceneRect(-200, -200, 400, 400); scene->setSceneRect(-200, -200, 1000, 1000); setScene(scene); centerNode = new Node(this, 1, "You"); scene->addItem(centerNode); centerNode->setPos(0, 0); #endif centerNode = NULL; setCacheMode(CacheBackground); setRenderHint(QPainter::Antialiasing); setTransformationAnchor(AnchorUnderMouse); setResizeAnchor(AnchorViewCenter); scale(0.8, 0.8); //setMinimumSize(400, 400); //setMinimumSize(1000, 1000); setWindowTitle(tr("Elastic Nodes")); clearGraph(); clearGraph(); } bool GraphWidget::clearGraph() { QGraphicsScene *oldscene = scene(); Node *oldcenterNode = centerNode; QGraphicsScene *scene = new QGraphicsScene(this); scene->setItemIndexMethod(QGraphicsScene::NoIndex); //scene->setSceneRect(-200, -200, 400, 400); scene->setSceneRect(-200, -200, 1000, 1000); setScene(scene); centerNode = new Node(this, 1, "OwnId", "You"); scene->addItem(centerNode); centerNode->setPos(0, 0); if (oldscene) { delete oldscene; } nodeMap.clear(); edgeList.clear(); return true; } void GraphWidget::addNode(uint32_t type, std::string id, std::string name) { Node *node = new Node(this, type, id, name); /* store node */ nodeMap[id] = node; scene()->addItem(node); node->setPos(-50 + qrand() % 100 , -50 + qrand() % 100); } void GraphWidget::addEdge(std::string id1, std::string id2) { std::map::iterator it; Node *n1 = NULL; Node *n2 = NULL; if (id1 == "") { n1 = centerNode; } else { it = nodeMap.find(id1); if (it != nodeMap.end()) { n1 = it->second; } } it = nodeMap.find(id2); if (it != nodeMap.end()) { n2 = it->second; } if ((n1) && (n2)) { Edge *edge = new Edge(n1, n2); scene()->addItem(edge); edgeList.push_back(edge); } } void GraphWidget::addArrow(std::string id1, std::string id2) { std::map::iterator it; Node *n1 = NULL; Node *n2 = NULL; if (id1 == "") { n1 = centerNode; } else { it = nodeMap.find(id1); if (it != nodeMap.end()) { n1 = it->second; } } it = nodeMap.find(id2); if (it != nodeMap.end()) { n2 = it->second; } if ((n1) && (n2)) { Arrow *arrow = new Arrow(n1, n2); scene()->addItem(arrow); arrowList.push_back(arrow); } } void GraphWidget::itemMoved() { if (!timerId) timerId = startTimer(1000 / 10); } void GraphWidget::keyPressEvent(QKeyEvent *event) { switch (event->key()) { case Qt::Key_Up: centerNode->moveBy(0, -20); break; case Qt::Key_Down: centerNode->moveBy(0, 20); break; case Qt::Key_Left: centerNode->moveBy(-20, 0); break; case Qt::Key_Right: centerNode->moveBy(20, 0); break; case Qt::Key_Plus: scaleView(1.2); break; case Qt::Key_Minus: scaleView(1 / 1.2); break; case Qt::Key_Space: case Qt::Key_Enter: foreach (QGraphicsItem *item, scene()->items()) { if (qgraphicsitem_cast(item)) item->setPos(-150 + qrand() % 300, -150 + qrand() % 300); } break; default: QGraphicsView::keyPressEvent(event); } } void GraphWidget::timerEvent(QTimerEvent *event) { Q_UNUSED(event); QList nodes; foreach (QGraphicsItem *item, scene()->items()) { if (Node *node = qgraphicsitem_cast(item)) nodes << node; } foreach (Node *node, nodes) node->calculateForces(); bool itemsMoved = false; foreach (Node *node, nodes) { if (node->advance()) itemsMoved = true; } if (!itemsMoved) { killTimer(timerId); timerId = 0; } } void GraphWidget::wheelEvent(QWheelEvent *event) { scaleView(pow((double)2, -event->delta() / 240.0)); } void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect) { Q_UNUSED(rect); // Shadow QRectF sceneRect = this->sceneRect(); QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height()); QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5); if (rightShadow.intersects(rect) || rightShadow.contains(rect)) painter->fillRect(rightShadow, Qt::darkGray); if (bottomShadow.intersects(rect) || bottomShadow.contains(rect)) painter->fillRect(bottomShadow, Qt::darkGray); // Fill QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight()); gradient.setColorAt(0, Qt::white); gradient.setColorAt(1, Qt::lightGray); painter->fillRect(rect.intersect(sceneRect), gradient); painter->setBrush(Qt::NoBrush); painter->drawRect(sceneRect); // Text // QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4, // sceneRect.width() - 4, sceneRect.height() - 4); // QString message(tr("Click and drag the nodes around, and zoom with the mouse " // "wheel or the '+' and '-' keys")); // // QFont font = painter->font(); // font.setBold(true); // font.setPointSize(14); // painter->setFont(font); // painter->setPen(Qt::lightGray); // painter->drawText(textRect.translated(2, 2), message); // painter->setPen(Qt::black); // painter->drawText(textRect, message); } void GraphWidget::scaleView(qreal scaleFactor) { qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); if (factor < 0.07 || factor > 100) return; scale(scaleFactor, scaleFactor); }