ui: graph view layouting and member rendering

Added simple layouting functions (implementations for simple grid and circle layout).
Also the graph displays class members and connections (edges) to or from them "correctly" now.

fortune cookie message = Your exotic ideas will lead you to many exciting new adventures.
This commit is contained in:
Manuel Dobusch
2014-07-15 16:40:52 +02:00
parent 61cb4afd91
commit ec42ef708d
24 changed files with 839 additions and 165 deletions
+2 -2
View File
@@ -22,8 +22,8 @@ add_files(
qt/view/graphElements/QtGraphEdge.h
qt/view/graphElements/QtGraphNode.cpp
qt/view/graphElements/QtGraphNode.h
qt/view/graphElements/QtGraphNodeMovable.cpp
qt/view/graphElements/QtGraphNodeMovable.h
qt/view/graphElements/QtGraphNodeMouseMovable.cpp
qt/view/graphElements/QtGraphNodeMouseMovable.h
qt/view/QtCodeView.cpp
qt/view/QtCodeView.h
+114 -14
View File
@@ -12,7 +12,7 @@
#include "qt/QtWidgetWrapper.h"
#include "qt/view/graphElements/QtGraphEdge.h"
#include "qt/view/graphElements/QtGraphNode.h"
#include "qt/view/graphElements/QtGraphNodeMovable.h"
#include "qt/view/graphElements/QtGraphNodeMouseMovable.h"
QtGraphView::QtGraphView(ViewLayout* viewLayout)
: GraphView(viewLayout)
@@ -83,6 +83,7 @@ void QtGraphView::doRebuildGraph(const std::vector<DummyNode>& nodes, const std:
for(unsigned int i = 0; i < nodes.size(); i++)
{
std::shared_ptr<GraphNode> newNode = findOrCreateNode(view, nodes[i]);
newNode->setPosition(nodes[i].position);
newNodes.push_back(newNode);
weakNodes[nodes[i].tokenId] = newNode;
}
@@ -90,8 +91,17 @@ void QtGraphView::doRebuildGraph(const std::vector<DummyNode>& nodes, const std:
doClear();
m_nodes = newNodes;
// create edges
for(unsigned int i = 0; i < edges.size(); i++)
{
std::shared_ptr<GraphEdge> edge = createEdge(view, edges[i]);
if(edge != NULL)
{
m_edges.push_back(edge);
}
}
// create edges
/*for(unsigned int i = 0; i < edges.size(); i++)
{
if (weakNodes.find(edges[i].ownerId) != weakNodes.end() && weakNodes.find(edges[i].targetId) != weakNodes.end())
{
@@ -106,7 +116,7 @@ void QtGraphView::doRebuildGraph(const std::vector<DummyNode>& nodes, const std:
}
}
}
}
}*/
}
else
{
@@ -124,7 +134,7 @@ std::shared_ptr<GraphNode> QtGraphView::findOrCreateNode(QGraphicsView* view, co
{
std::shared_ptr<GraphNode> result;
result = findNode(node);
result = findNode(node.tokenId);
if(result == NULL)
{
@@ -134,41 +144,131 @@ std::shared_ptr<GraphNode> QtGraphView::findOrCreateNode(QGraphicsView* view, co
return result;
}
std::shared_ptr<GraphNode> QtGraphView::findNode(const DummyNode& node)
std::shared_ptr<GraphNode> QtGraphView::findNode(const Id id)
{
std::list<std::shared_ptr<GraphNode>>::iterator it = m_nodes.begin();
for(it; it != m_nodes.end(); it++)
{
if((*it)->getTokenId() == node.tokenId)
if((*it)->getTokenId() == id)
{
return *it;
}
else
{
std::shared_ptr<GraphNode> result = findSubNode(*it, id);
if(result != NULL)
{
return result;
}
}
}
return NULL;
return std::shared_ptr<GraphNode>();
}
std::shared_ptr<GraphNode> QtGraphView::findSubNode(const std::shared_ptr<GraphNode> node, const Id id)
{
std::list<std::shared_ptr<GraphNode>> subNodes = node->getSubNodes();
std::list<std::shared_ptr<GraphNode>>::iterator it = subNodes.begin();
for(it; it != subNodes.end(); it++)
{
if((*it)->getTokenId() == id)
{
return *it;
}
else
{
std::shared_ptr<GraphNode> result = findSubNode(*it, id);
if(result != NULL)
{
return result;
}
}
}
return std::shared_ptr<GraphNode>();
}
std::shared_ptr<GraphNode> QtGraphView::createNode(QGraphicsView* view, const DummyNode& node)
{
if(view != NULL)
{
std::shared_ptr<QtGraphNodeMovable> newNode = std::make_shared<QtGraphNodeMovable>(node.position, node.name, node.tokenId);
std::shared_ptr<QtGraphNodeMouseMovable> newNode = std::make_shared<QtGraphNodeMouseMovable>(Vec2i(0, 0), node.name, node.tokenId);
view->scene()->addItem(newNode.get());
m_nodes.push_back(newNode);
// create debug sub node
std::shared_ptr<QtGraphNode> subNode = std::make_shared<QtGraphNode>(Vec2i(10, 30), node.name + " member", 666);
subNode->setParentItem(newNode.get());
view->scene()->addItem(subNode.get());
newNode->addSubNode(subNode);
for(unsigned int i = 0; i < node.subNodes.size(); i++)
{
std::shared_ptr<QtGraphNode> subNode = createSubNode(view, node.subNodes[i]);
subNode->setParentItem(newNode.get());
newNode->addSubNode(subNode);
subNode->setRect(0, 0, 80, 20);
subNode->moveBy(10, (i+1)*30);
}
subNode->setRect(0, 0, 80, 20);
newNode->setRect(0, 0, 100, 40 + (node.subNodes.size() * 30));
return newNode;
}
else
{
LOG_WARNING("Received pointer to QGraphicsView was NULL. No node created.");
return std::shared_ptr<QtGraphNode>();
}
}
std::shared_ptr<QtGraphNode> QtGraphView::createSubNode(QGraphicsView* view, const DummyNode& node)
{
if(view != NULL)
{
std::shared_ptr<QtGraphNode> newNode = std::make_shared<QtGraphNode>(Vec2i(0, 0), node.name, node.tokenId);
view->scene()->addItem(newNode.get());
for(unsigned int i = 0; i < node.subNodes.size(); i++)
{
std::shared_ptr<QtGraphNode> subNode = createSubNode(view, node.subNodes[i]);
subNode->setParentItem(newNode.get());
newNode->addSubNode(subNode);
subNode->setRect(0, 0, 80, 20);
subNode->moveBy(10, (i+1)*30);
}
return newNode;
}
else
{
LOG_WARNING("Received pointer to QGraphicsView was NULL. No node created.");
return std::shared_ptr<QtGraphNode>();
}
}
std::shared_ptr<QtGraphEdge> QtGraphView::createEdge(QGraphicsView* view, const DummyEdge& edge)
{
if(view != NULL)
{
std::shared_ptr<GraphNode> owner = findNode(edge.ownerId);
std::shared_ptr<GraphNode> target = findNode(edge.targetId);
if(owner != NULL && target != NULL)
{
std::shared_ptr<QtGraphEdge> edge = std::make_shared<QtGraphEdge>(owner, target);
owner->addOutEdge(edge);
target->addInEdge(edge);
view->scene()->addItem(edge.get());
return edge;
}
else
{
LOG_WARNING("Couldn't find owner or target node.");
return std::shared_ptr<QtGraphEdge>();
}
}
else
{
LOG_WARNING("Received pointer to QGraphicsView was NULL. No node created.");
return std::shared_ptr<QtGraphEdge>();
}
}
+9 -1
View File
@@ -3,11 +3,15 @@
#include "qt/utility/QtThreadedFunctor.h"
#include "utility/types.h"
#include "component/view/GraphView.h"
struct DummyEdge;
struct DummyNode;
class QGraphicsView;
class QtGraphEdge;
class QtGraphNode;
class QtGraphView : public GraphView
{
@@ -30,8 +34,12 @@ private:
void doClear();
std::shared_ptr<GraphNode> findOrCreateNode(QGraphicsView* view, const DummyNode& node);
std::shared_ptr<GraphNode> findNode(const DummyNode& node);
std::shared_ptr<GraphNode> findNode(const Id id);
std::shared_ptr<GraphNode> findSubNode(const std::shared_ptr<GraphNode> node, const Id id);
std::shared_ptr<GraphNode> createNode(QGraphicsView* view, const DummyNode& node);
std::shared_ptr<QtGraphNode> createSubNode(QGraphicsView* view, const DummyNode& node);
std::shared_ptr<QtGraphEdge> createEdge(QGraphicsView* view, const DummyEdge& edge);
QtThreadedFunctor<const std::vector<DummyNode>&, const std::vector<DummyEdge>&> m_rebuildGraph;
QtThreadedFunctor<void> m_clear;
+59 -3
View File
@@ -1,5 +1,7 @@
#include "qt/view/graphElements/QtGraphNode.h"
#include <sstream>
#include "qgraphicsscene.h"
#include "qgraphicssceneevent.h"
@@ -15,7 +17,9 @@ QtGraphNode::QtGraphNode(const Vec2i& position, const std::string& name, const I
m_text = new QGraphicsTextItem(this);
m_text->setPos(0, 0);
m_text->setPlainText(QString(name.c_str()));
std::stringstream text;
text << m_tokenId << " -> " << name;
m_text->setPlainText(QString(text.str().c_str()));
}
QtGraphNode::~QtGraphNode()
@@ -31,16 +35,28 @@ QtGraphNode::~QtGraphNode()
}
}
std::string QtGraphNode::getName()
std::string QtGraphNode::getName() const
{
return m_text->toPlainText().toStdString();
}
Vec2i QtGraphNode::getPosition()
Vec2i QtGraphNode::getPosition() const
{
return Vec2i(this->scenePos().x(), this->scenePos().y());
}
void QtGraphNode::setPosition(const Vec2i& position)
{
Vec2i currentPosition = getPosition();
Vec2i offset = position - currentPosition;
if(offset.getLength() > 0.0f)
{
this->moveBy(offset.x, offset.y);
notifyEdgesAfterMove();
}
}
bool QtGraphNode::addOutEdge(const std::shared_ptr<GraphEdge>& edge)
{
std::list<std::shared_ptr<GraphEdge> >::iterator it = m_outEdges.begin();
@@ -91,6 +107,11 @@ void QtGraphNode::removeOutEdge(GraphEdge* edge)
}
}
std::list<std::shared_ptr<GraphNode> > QtGraphNode::getSubNodes() const
{
return m_subNodes;
}
void QtGraphNode::addSubNode(const std::shared_ptr<GraphNode>& node)
{
m_subNodes.push_back(node);
@@ -101,3 +122,38 @@ void QtGraphNode::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
MessageActivateToken message(m_tokenId);
message.dispatch();
}
void QtGraphNode::notifyParentMoved()
{
notifyEdgesAfterMove();
}
void QtGraphNode::notifyEdgesAfterMove()
{
std::list<std::shared_ptr<GraphEdge> >::iterator it = m_outEdges.begin();
for(it; it != m_outEdges.end(); it++)
{
(*it)->ownerMoved();
}
std::list<std::weak_ptr<GraphEdge> >::iterator it2 = m_inEdges.begin();
while(it2 != m_inEdges.end())
{
std::shared_ptr<GraphEdge> edge = it2->lock();
if(edge.get() != NULL)
{
edge->targetMoved();
++it2;
}
else
{
m_inEdges.erase(it2++);
}
}
std::list<std::shared_ptr<GraphNode> >::iterator it3 = m_subNodes.begin();
for(it3; it3 != m_subNodes.end(); it3++)
{
(*it3)->notifyParentMoved();
}
}
+8 -2
View File
@@ -18,19 +18,25 @@ public:
QtGraphNode(const Vec2i& position, const std::string& name, const Id tokenId);
virtual ~QtGraphNode();
virtual std::string getName();
virtual Vec2i getPosition();
virtual std::string getName() const;
virtual Vec2i getPosition() const;
virtual void setPosition(const Vec2i& position);
virtual bool addOutEdge(const std::shared_ptr<GraphEdge>& edge);
virtual bool addInEdge(const std::weak_ptr<GraphEdge>& edge);
virtual void removeOutEdge(GraphEdge* edge);
virtual std::list<std::shared_ptr<GraphNode> > getSubNodes() const;
virtual void addSubNode(const std::shared_ptr<GraphNode>& node);
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
virtual void notifyParentMoved();
protected:
void notifyEdgesAfterMove();
std::list<std::shared_ptr<GraphEdge> > m_outEdges;
std::list<std::weak_ptr<GraphEdge> > m_inEdges;
@@ -0,0 +1,29 @@
#include "qt/view/graphElements/QtGraphNodeMouseMovable.h"
#include "qgraphicssceneevent.h"
#include "qt/view/graphElements/QtGraphEdge.h"
QtGraphNodeMouseMovable::QtGraphNodeMouseMovable(const Vec2i& position, const std::string& name, const Id tokenId)
: QtGraphNode(position, name, tokenId)
{
}
QtGraphNodeMouseMovable::~QtGraphNodeMouseMovable()
{
}
void QtGraphNodeMouseMovable::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
m_mouseOffset.x = event->pos().x();
m_mouseOffset.y = event->pos().y();
}
void QtGraphNodeMouseMovable::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
this->setPos(event->scenePos().x() - m_mouseOffset.x, event->scenePos().y() - m_mouseOffset.y);
Vec2i p(event->scenePos().x(), event->scenePos().y());
notifyEdgesAfterMove();
}
@@ -0,0 +1,19 @@
#ifndef QT_GRAPH_NODE_MOUSE_MOVABLE_H
#define QT_GRAPH_NODE_MOUSE_MOVABLE_H
#include "qt/view/graphElements/QtGraphNode.h"
class QtGraphNodeMouseMovable : public QtGraphNode
{
public:
QtGraphNodeMouseMovable(const Vec2i& position, const std::string& name, const Id tokenId);
virtual ~QtGraphNodeMouseMovable();
void mousePressEvent(QGraphicsSceneMouseEvent* event);
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
private:
Vec2i m_mouseOffset;
};
#endif // QT_GRAPH_NODE_MOUSE_MOVABLE_H
@@ -1,48 +0,0 @@
#include "qt/view/graphElements/QtGraphNodeMovable.h"
#include "qgraphicssceneevent.h"
#include "qt/view/graphElements/QtGraphEdge.h"
QtGraphNodeMovable::QtGraphNodeMovable(const Vec2i& position, const std::string& name, const Id tokenId)
: QtGraphNode(position, name, tokenId)
{
}
QtGraphNodeMovable::~QtGraphNodeMovable()
{
}
void QtGraphNodeMovable::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
m_mouseOffset.x = event->pos().x();
m_mouseOffset.y = event->pos().y();
}
void QtGraphNodeMovable::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
this->setPos(event->scenePos().x() - m_mouseOffset.x, event->scenePos().y() - m_mouseOffset.y);
Vec2i p(event->scenePos().x(), event->scenePos().y());
std::list<std::shared_ptr<GraphEdge> >::iterator it = m_outEdges.begin();
for(it; it != m_outEdges.end(); it++)
{
(*it)->ownerMoved();
}
std::list<std::weak_ptr<GraphEdge> >::iterator it2 = m_inEdges.begin();
while(it2 != m_inEdges.end())
{
std::shared_ptr<GraphEdge> edge = it2->lock();
if(edge.get() != NULL)
{
edge->targetMoved();
++it2;
}
else
{
m_inEdges.erase(it2++);
}
}
}
@@ -1,19 +0,0 @@
#ifndef QT_GRAPH_NODE_MOVABLE_H
#define QT_GRAPH_NODE_MOVABLE_H
#include "qt/view/graphElements/QtGraphNode.h"
class QtGraphNodeMovable : public QtGraphNode
{
public:
QtGraphNodeMovable(const Vec2i& position, const std::string& name, const Id tokenId);
virtual ~QtGraphNodeMovable();
void mousePressEvent(QGraphicsSceneMouseEvent* event);
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
private:
Vec2i m_mouseOffset;
};
#endif // QT_GRAPH_NODE_MOVABLE_H