ui: extented graph view ui features
* fitting boxes to name length * highlighting active edges and nodes * hover for edges and nodes * single click selection for edges and nodes * edges have transparent second line for easier clicking * sub structure class members by public/protected/private
This commit is contained in:
@@ -28,6 +28,8 @@ add_files(
|
||||
|
||||
qt/view/graphElements/nodeComponents/QtGraphNodeComponent.cpp
|
||||
qt/view/graphElements/nodeComponents/QtGraphNodeComponent.h
|
||||
qt/view/graphElements/nodeComponents/QtGraphNodeComponentClickable.cpp
|
||||
qt/view/graphElements/nodeComponents/QtGraphNodeComponentClickable.h
|
||||
qt/view/graphElements/nodeComponents/QtGraphNodeComponentMoveable.cpp
|
||||
qt/view/graphElements/nodeComponents/QtGraphNodeComponentMoveable.h
|
||||
qt/view/graphElements/nodeComponents/QtGraphNodeComponentToggleButton.cpp
|
||||
|
||||
@@ -39,9 +39,25 @@ private:
|
||||
QSemaphore m_freeCallbacks;
|
||||
};
|
||||
|
||||
template <typename T1 = void, typename T2 = void, typename T3 = void>
|
||||
template <typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void>
|
||||
class QtThreadedFunctor
|
||||
{
|
||||
public:
|
||||
QtThreadedFunctor(std::function<void(T1, T2, T3, T4)> callback) : m_callback(callback) {}
|
||||
|
||||
void operator()(T1 p1, T2 p2, T3 p3, T4 p4)
|
||||
{
|
||||
m_helper(std::bind(m_callback, p1, p2, p3, p4));
|
||||
}
|
||||
|
||||
private:
|
||||
QtThreadedFunctorHelper m_helper;
|
||||
std::function<void(T1, T2, T3, T4)> m_callback;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
class QtThreadedFunctor<T1, T2, T3, void>
|
||||
{
|
||||
public:
|
||||
QtThreadedFunctor(std::function<void(T1, T2, T3)> callback) : m_callback(callback) {}
|
||||
|
||||
@@ -56,7 +72,7 @@ private:
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
class QtThreadedFunctor<T1, T2, void>
|
||||
class QtThreadedFunctor<T1, T2, void, void>
|
||||
{
|
||||
public:
|
||||
QtThreadedFunctor(std::function<void(T1, T2)> callback) : m_callback(callback) {}
|
||||
@@ -72,7 +88,7 @@ private:
|
||||
};
|
||||
|
||||
template <typename T1>
|
||||
class QtThreadedFunctor<T1, void, void>
|
||||
class QtThreadedFunctor<T1, void, void, void>
|
||||
{
|
||||
public:
|
||||
QtThreadedFunctor(std::function<void(T1)> callback) : m_callback(callback) {}
|
||||
@@ -88,7 +104,7 @@ private:
|
||||
};
|
||||
|
||||
template <>
|
||||
class QtThreadedFunctor<void, void, void>
|
||||
class QtThreadedFunctor<void, void, void, void>
|
||||
{
|
||||
public:
|
||||
QtThreadedFunctor(std::function<void(void)> callback) : m_callback(callback) {}
|
||||
|
||||
+69
-132
@@ -10,20 +10,19 @@
|
||||
#include "qt/view/QtViewWidgetWrapper.h"
|
||||
#include "qt/view/graphElements/QtGraphEdge.h"
|
||||
#include "qt/view/graphElements/QtGraphNode.h"
|
||||
#include "qt/view/graphElements/nodeComponents/QtGraphNodeComponentClickable.h"
|
||||
#include "qt/view/graphElements/nodeComponents/QtGraphNodeComponentMoveable.h"
|
||||
#include "qt/view/graphElements/nodeComponents/QtGraphNodeComponentToggleButton.h"
|
||||
|
||||
QtGraphView::QtGraphView(ViewLayout* viewLayout)
|
||||
: GraphView(viewLayout)
|
||||
, m_rebuildGraph(std::bind(&QtGraphView::doRebuildGraph, this, std::placeholders::_1, std::placeholders::_2))
|
||||
, m_clear(std::bind(&QtGraphView::doClear, this))
|
||||
, m_rebuildGraphFunctor(
|
||||
std::bind(
|
||||
&QtGraphView::doRebuildGraph, this,
|
||||
std::placeholders::_1, std::placeholders::_2,
|
||||
std::placeholders::_3, std::placeholders::_4))
|
||||
, m_clearFunctor(std::bind(&QtGraphView::doClear, this))
|
||||
{
|
||||
m_edgeColors.push_back(Vec4i(100, 100, 100, 255)); // call
|
||||
m_edgeColors.push_back(Vec4i(66, 230, 103, 255)); // usage
|
||||
m_edgeColors.push_back(Vec4i(73, 155, 222, 255)); // type
|
||||
m_edgeColors.push_back(Vec4i(231, 65, 65, 255)); // return
|
||||
m_edgeColors.push_back(Vec4i(227, 180, 68, 255)); // parameter
|
||||
m_edgeColors.push_back(Vec4i(113, 96, 191, 255)); // inheritance
|
||||
}
|
||||
|
||||
QtGraphView::~QtGraphView()
|
||||
@@ -57,14 +56,18 @@ void QtGraphView::refreshView()
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphView::rebuildGraph(const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges)
|
||||
{
|
||||
m_rebuildGraph(nodes, edges);
|
||||
void QtGraphView::rebuildGraph(
|
||||
std::shared_ptr<Graph> graph,
|
||||
std::vector<Id> activeTokenIds,
|
||||
const std::vector<DummyNode>& nodes,
|
||||
const std::vector<DummyEdge>& edges
|
||||
){
|
||||
m_rebuildGraphFunctor(graph, activeTokenIds, nodes, edges);
|
||||
}
|
||||
|
||||
void QtGraphView::clear()
|
||||
{
|
||||
m_clear();
|
||||
m_clearFunctor();
|
||||
}
|
||||
|
||||
QGraphicsView* QtGraphView::getView()
|
||||
@@ -76,15 +79,17 @@ QGraphicsView* QtGraphView::getView()
|
||||
return widget->findChild<QGraphicsView*>("");
|
||||
}
|
||||
|
||||
void QtGraphView::doRebuildGraph(const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges)
|
||||
{
|
||||
void QtGraphView::doRebuildGraph(
|
||||
std::shared_ptr<Graph> graph,
|
||||
std::vector<Id> activeTokenIds,
|
||||
const std::vector<DummyNode>& nodes,
|
||||
const std::vector<DummyEdge>& edges
|
||||
){
|
||||
m_activeTokenIds = activeTokenIds;
|
||||
QGraphicsView* view = getView();
|
||||
|
||||
if (view != NULL)
|
||||
{
|
||||
// Used when creating the edges.
|
||||
std::map<Id, std::weak_ptr<GraphNode>> weakNodes;
|
||||
|
||||
// Temporary stores all nodes (existing and newly created) needed in the new graph
|
||||
// this is a relatively easy and cheap way to save existing nodes that are still needed
|
||||
std::list<std::shared_ptr<GraphNode>> newNodes;
|
||||
@@ -92,10 +97,9 @@ void QtGraphView::doRebuildGraph(const std::vector<DummyNode>& nodes, const std:
|
||||
// create nodes (or find existing nodes for re-use)
|
||||
for (unsigned int i = 0; i < nodes.size(); i++)
|
||||
{
|
||||
std::shared_ptr<GraphNode> newNode = findOrCreateNode(view, nodes[i]);
|
||||
std::shared_ptr<GraphNode> newNode = createNodeRecursive(view, NULL, nodes[i]);
|
||||
newNode->setPosition(nodes[i].position);
|
||||
newNodes.push_back(newNode);
|
||||
weakNodes[nodes[i].tokenId] = newNode;
|
||||
}
|
||||
|
||||
doClear();
|
||||
@@ -120,6 +124,8 @@ void QtGraphView::doRebuildGraph(const std::vector<DummyNode>& nodes, const std:
|
||||
{
|
||||
LOG_WARNING("Failed to get QGraphicsView");
|
||||
}
|
||||
|
||||
m_graph = graph;
|
||||
}
|
||||
|
||||
void QtGraphView::doClear()
|
||||
@@ -128,113 +134,59 @@ void QtGraphView::doClear()
|
||||
m_edges.clear();
|
||||
}
|
||||
|
||||
std::shared_ptr<GraphNode> QtGraphView::findOrCreateNode(QGraphicsView* view, const DummyNode& node)
|
||||
std::shared_ptr<GraphNode> QtGraphView::findNodeRecursive(const std::list<std::shared_ptr<GraphNode>>& nodes, Id tokenId)
|
||||
{
|
||||
std::shared_ptr<GraphNode> result;
|
||||
|
||||
result = findNode(node.tokenId);
|
||||
|
||||
if (result == NULL)
|
||||
for (const std::shared_ptr<GraphNode>& node : nodes)
|
||||
{
|
||||
result = createNode(view, node);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::shared_ptr<GraphNode> QtGraphView::findNode(const Id id)
|
||||
{
|
||||
for (std::list<std::shared_ptr<GraphNode>>::iterator it = m_nodes.begin(); it != m_nodes.end(); it++)
|
||||
{
|
||||
if ((*it)->getTokenId() == id)
|
||||
if (node->getTokenId() == tokenId)
|
||||
{
|
||||
return *it;
|
||||
return node;
|
||||
}
|
||||
else
|
||||
|
||||
std::shared_ptr<GraphNode> result = findNodeRecursive(node->getSubNodes(), tokenId);
|
||||
if (result != NULL)
|
||||
{
|
||||
std::shared_ptr<GraphNode> result = findSubNode(*it, id);
|
||||
if (result != NULL)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
for (std::list<std::shared_ptr<GraphNode>>::iterator it = subNodes.begin(); it != subNodes.end(); it++)
|
||||
std::shared_ptr<GraphNode> QtGraphView::createNodeRecursive(
|
||||
QGraphicsView* view, std::shared_ptr<QtGraphNode> parentNode, const DummyNode& node
|
||||
){
|
||||
if (view != NULL)
|
||||
{
|
||||
if ((*it)->getTokenId() == id)
|
||||
std::shared_ptr<QtGraphNode> newNode = std::make_shared<QtGraphNode>(node.data, node.accessType);
|
||||
newNode->addComponent(std::make_shared<QtGraphNodeComponentClickable>(newNode));
|
||||
|
||||
view->scene()->addItem(newNode.get());
|
||||
|
||||
if (node.data && isActiveTokenId(node.data->getId()))
|
||||
{
|
||||
return *it;
|
||||
newNode->setIsActive(true);
|
||||
}
|
||||
|
||||
if (parentNode)
|
||||
{
|
||||
newNode->setParent(parentNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::shared_ptr<GraphNode> result = findSubNode(*it, id);
|
||||
if (result != NULL)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
newNode->addComponent(std::make_shared<QtGraphNodeComponentMoveable>(newNode));
|
||||
}
|
||||
}
|
||||
|
||||
return std::shared_ptr<GraphNode>();
|
||||
}
|
||||
|
||||
std::shared_ptr<GraphNode> QtGraphView::createNode(QGraphicsView* view, const DummyNode& node)
|
||||
{
|
||||
if (view != NULL)
|
||||
{
|
||||
std::shared_ptr<QtGraphNode> newNode =
|
||||
std::make_shared<QtGraphNode>(Vec2i(0, 0), Vec2i(100, 30), node.name, node.tokenId);
|
||||
view->scene()->addItem(newNode.get());
|
||||
m_nodes.push_back(newNode);
|
||||
|
||||
newNode->addComponent(std::make_shared<QtGraphNodeComponentMoveable>(newNode));
|
||||
|
||||
if(node.subNodes.size() > 0)
|
||||
if (node.subNodes.size() > 0)
|
||||
{
|
||||
newNode->addComponent(std::make_shared<QtGraphNodeComponentToggleButton>(newNode));
|
||||
if (!node.data || node.subNodes[0].data)
|
||||
{
|
||||
newNode->addComponent(std::make_shared<QtGraphNodeComponentToggleButton>(newNode));
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < node.subNodes.size(); i++)
|
||||
{
|
||||
std::shared_ptr<QtGraphNode> subNode = createSubNode(view, node.subNodes[i]);
|
||||
subNode->setParent(newNode);
|
||||
newNode->addSubNode(subNode);
|
||||
}
|
||||
}
|
||||
|
||||
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), Vec2i(80, 20), node.name, node.tokenId);
|
||||
view->scene()->addItem(newNode.get());
|
||||
|
||||
if(node.subNodes.size() > 0)
|
||||
{
|
||||
newNode->addComponent(std::make_shared<QtGraphNodeComponentToggleButton>(newNode));
|
||||
|
||||
for (unsigned int i = 0; i < node.subNodes.size(); i++)
|
||||
{
|
||||
std::shared_ptr<QtGraphNode> subNode = createSubNode(view, node.subNodes[i]);
|
||||
|
||||
subNode->setParent(newNode);
|
||||
|
||||
std::shared_ptr<GraphNode> subNode = createNodeRecursive(view, newNode, node.subNodes[i]);
|
||||
newNode->addSubNode(subNode);
|
||||
}
|
||||
}
|
||||
@@ -252,41 +204,21 @@ std::shared_ptr<QtGraphEdge> QtGraphView::createEdge(QGraphicsView* view, const
|
||||
{
|
||||
if (view != NULL)
|
||||
{
|
||||
std::shared_ptr<GraphNode> owner = findNode(edge.ownerId);
|
||||
std::shared_ptr<GraphNode> target = findNode(edge.targetId);
|
||||
std::shared_ptr<GraphNode> owner = findNodeRecursive(m_nodes, edge.ownerId);
|
||||
std::shared_ptr<GraphNode> target = findNodeRecursive(m_nodes, edge.targetId);
|
||||
|
||||
if (owner != NULL && target != NULL)
|
||||
{
|
||||
std::shared_ptr<QtGraphEdge> qtEdge = std::make_shared<QtGraphEdge>(owner, target, edge.tokenId);
|
||||
|
||||
switch (edge.edgeType)
|
||||
{
|
||||
case Edge::EDGE_CALL:
|
||||
qtEdge->setColor(m_edgeColors[0]);
|
||||
break;
|
||||
case Edge::EDGE_USAGE:
|
||||
qtEdge->setColor(m_edgeColors[1]);
|
||||
break;
|
||||
case Edge::EDGE_TYPE_OF:
|
||||
qtEdge->setColor(m_edgeColors[2]);
|
||||
break;
|
||||
case Edge::EDGE_RETURN_TYPE_OF:
|
||||
qtEdge->setColor(m_edgeColors[3]);
|
||||
break;
|
||||
case Edge::EDGE_PARAMETER_TYPE_OF:
|
||||
qtEdge->setColor(m_edgeColors[4]);
|
||||
break;
|
||||
case Edge::EDGE_INHERITANCE:
|
||||
qtEdge->setColor(m_edgeColors[5]);
|
||||
break;
|
||||
default:
|
||||
qtEdge->setColor(Vec4i(0, 0, 0, 255));
|
||||
}
|
||||
|
||||
std::shared_ptr<QtGraphEdge> qtEdge = std::make_shared<QtGraphEdge>(owner, target, edge.data);
|
||||
owner->addOutEdge(qtEdge);
|
||||
target->addInEdge(qtEdge);
|
||||
view->scene()->addItem(qtEdge.get());
|
||||
|
||||
if (isActiveTokenId(edge.data->getId()))
|
||||
{
|
||||
qtEdge->setIsActive(true);
|
||||
}
|
||||
|
||||
return qtEdge;
|
||||
}
|
||||
else
|
||||
@@ -301,3 +233,8 @@ std::shared_ptr<QtGraphEdge> QtGraphView::createEdge(QGraphicsView* view, const
|
||||
return std::shared_ptr<QtGraphEdge>();
|
||||
}
|
||||
}
|
||||
|
||||
bool QtGraphView::isActiveTokenId(Id tokenId) const
|
||||
{
|
||||
return find(m_activeTokenIds.begin(), m_activeTokenIds.end(), tokenId) != m_activeTokenIds.end();
|
||||
}
|
||||
|
||||
@@ -24,28 +24,37 @@ public:
|
||||
virtual void initView();
|
||||
virtual void refreshView();
|
||||
|
||||
virtual void rebuildGraph(const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges);
|
||||
virtual void rebuildGraph(
|
||||
std::shared_ptr<Graph> graph,
|
||||
std::vector<Id> activeTokenIds,
|
||||
const std::vector<DummyNode>& nodes,
|
||||
const std::vector<DummyEdge>& edges);
|
||||
|
||||
virtual void clear();
|
||||
|
||||
private:
|
||||
QGraphicsView* getView();
|
||||
|
||||
void doRebuildGraph(const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges);
|
||||
void doRebuildGraph(
|
||||
std::shared_ptr<Graph> graph,
|
||||
std::vector<Id> activeTokenIds,
|
||||
const std::vector<DummyNode>& nodes,
|
||||
const std::vector<DummyEdge>& edges);
|
||||
void doClear();
|
||||
|
||||
std::shared_ptr<GraphNode> findOrCreateNode(QGraphicsView* view, 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<GraphNode> findNodeRecursive(const std::list<std::shared_ptr<GraphNode>>& nodes, Id tokenId);
|
||||
|
||||
std::shared_ptr<GraphNode> createNodeRecursive(
|
||||
QGraphicsView* view, std::shared_ptr<QtGraphNode> parentNode, 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;
|
||||
bool isActiveTokenId(Id tokenId) const;
|
||||
|
||||
std::vector<Vec4i> m_edgeColors;
|
||||
QtThreadedFunctor<
|
||||
std::shared_ptr<Graph>, std::vector<Id>, const std::vector<DummyNode>&, const std::vector<DummyEdge>&
|
||||
> m_rebuildGraphFunctor;
|
||||
|
||||
QtThreadedFunctor<void> m_clearFunctor;
|
||||
};
|
||||
|
||||
#endif // QT_GRAPH_VIEW_H
|
||||
|
||||
@@ -1,34 +1,75 @@
|
||||
#include "qt/view/graphElements/QtGraphEdge.h"
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneEvent>
|
||||
#include <QPen>
|
||||
|
||||
#include "component/view/graphElements/GraphNode.h"
|
||||
|
||||
QtGraphEdge::QtGraphEdge(const std::weak_ptr<GraphNode>& owner, const std::weak_ptr<GraphNode>& target, const Id id)
|
||||
: GraphEdge(id)
|
||||
QtGraphEdge::QtGraphEdge(const std::weak_ptr<GraphNode>& owner, const std::weak_ptr<GraphNode>& target, const Edge* data)
|
||||
: GraphEdge(data)
|
||||
, m_owner(owner)
|
||||
, m_target(target)
|
||||
, m_color(0, 0, 0, 0)
|
||||
, m_isActive(false)
|
||||
, m_mousePos(0.0f, 0.0f)
|
||||
, m_mouseMoved(false)
|
||||
{
|
||||
std::shared_ptr<GraphNode> o = owner.lock();
|
||||
std::shared_ptr<GraphNode> t = target.lock();
|
||||
|
||||
Vec2i ownerPos;
|
||||
Vec2i targetPos;
|
||||
|
||||
if (o != NULL && t != NULL)
|
||||
{
|
||||
Vec2i ownerPos = o->getPosition();
|
||||
this->setLine(ownerPos.x, ownerPos.y,t->getPosition().x, t->getPosition().y);
|
||||
ownerPos = o->getPosition();
|
||||
targetPos = t->getPosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("Either the owner or the target node is null.");
|
||||
}
|
||||
|
||||
QPen blackPen(Qt::black);
|
||||
blackPen.setWidth(2);
|
||||
this->setLine(ownerPos.x, ownerPos.y, targetPos.x, targetPos.y);
|
||||
|
||||
this->setPen(blackPen);
|
||||
this->setAcceptHoverEvents(true);
|
||||
this->setZValue(1); // Used to draw edges always on top of nodes.
|
||||
|
||||
QPen pen(Qt::transparent);
|
||||
pen.setWidth(10);
|
||||
this->setPen(pen);
|
||||
|
||||
m_child = new QGraphicsLineItem(this);
|
||||
m_child->setLine(ownerPos.x, ownerPos.y, targetPos.x, targetPos.y);
|
||||
|
||||
pen.setColor(Qt::black);
|
||||
pen.setWidth(2);
|
||||
|
||||
switch (data->getType())
|
||||
{
|
||||
case Edge::EDGE_CALL:
|
||||
pen.setColor(QColor(100, 100, 100));
|
||||
break;
|
||||
case Edge::EDGE_USAGE:
|
||||
pen.setColor(QColor(66, 230, 103));
|
||||
break;
|
||||
case Edge::EDGE_TYPE_OF:
|
||||
pen.setColor(QColor(73, 155, 222));
|
||||
break;
|
||||
case Edge::EDGE_RETURN_TYPE_OF:
|
||||
pen.setColor(QColor(231, 65, 65));
|
||||
break;
|
||||
case Edge::EDGE_PARAMETER_TYPE_OF:
|
||||
pen.setColor(QColor(227, 180, 68));
|
||||
break;
|
||||
case Edge::EDGE_INHERITANCE:
|
||||
pen.setColor(QColor(113, 96, 191));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_child->setPen(pen);
|
||||
}
|
||||
|
||||
QtGraphEdge::~QtGraphEdge()
|
||||
@@ -41,8 +82,11 @@ void QtGraphEdge::ownerMoved()
|
||||
|
||||
if (node != NULL)
|
||||
{
|
||||
Vec2i pos = node->getPosition();
|
||||
this->setLine(pos.x, pos.y, this->line().x2(), this->line().y2());
|
||||
Vec2i posA = node->getPosition();
|
||||
Vec2i posB(this->line().x2(), this->line().y2());
|
||||
|
||||
this->setLine(posA.x, posA.y, posB.x, posB.y);
|
||||
m_child->setLine(posA.x, posA.y, posB.x, posB.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -56,7 +100,11 @@ void QtGraphEdge::targetMoved()
|
||||
|
||||
if (node != NULL)
|
||||
{
|
||||
this->setLine(this->line().x1(), this->line().y1(), node->getPosition().x, node->getPosition().y);
|
||||
Vec2i posA(this->line().x1(), this->line().y1());
|
||||
Vec2i posB = node->getPosition();
|
||||
|
||||
this->setLine(posA.x, posA.y, posB.x, posB.y);
|
||||
m_child->setLine(posA.x, posA.y, posB.x, posB.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -88,22 +136,64 @@ std::weak_ptr<GraphNode> QtGraphEdge::getTarget()
|
||||
return m_target;
|
||||
}
|
||||
|
||||
void QtGraphEdge::setColor(const Vec4i& color)
|
||||
bool QtGraphEdge::getIsActive() const
|
||||
{
|
||||
m_color = color;
|
||||
|
||||
QPen pen(QColor(color.x, color.y, color.z, color.w));
|
||||
pen.setWidth(2);
|
||||
this->setPen(pen);
|
||||
return m_isActive;
|
||||
}
|
||||
|
||||
Vec4i QtGraphEdge::getColor() const
|
||||
void QtGraphEdge::setIsActive(bool isActive)
|
||||
{
|
||||
return m_color;
|
||||
m_isActive = isActive;
|
||||
|
||||
QPen p = m_child->pen();
|
||||
if (isActive)
|
||||
{
|
||||
p.setWidth(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.setWidth(2);
|
||||
}
|
||||
m_child->setPen(p);
|
||||
}
|
||||
|
||||
void QtGraphEdge::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
|
||||
void QtGraphEdge::onClick()
|
||||
{
|
||||
MessageActivateToken message(m_tokenId);
|
||||
message.dispatch();
|
||||
MessageActivateToken(getTokenId()).dispatch();
|
||||
}
|
||||
|
||||
void QtGraphEdge::mousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
m_mousePos = Vec2i(event->scenePos().x(), event->scenePos().y());
|
||||
m_mouseMoved = false;
|
||||
}
|
||||
|
||||
void QtGraphEdge::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
Vec2i mousePos = Vec2i(event->scenePos().x(), event->scenePos().y());
|
||||
|
||||
if ((mousePos - m_mousePos).getLength() > 1.0f)
|
||||
{
|
||||
m_mouseMoved = true;
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphEdge::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
if (!m_mouseMoved)
|
||||
{
|
||||
this->onClick();
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphEdge::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
|
||||
{
|
||||
bool isActive = m_isActive;
|
||||
this->setIsActive(true);
|
||||
m_isActive = isActive;
|
||||
}
|
||||
|
||||
void QtGraphEdge::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
|
||||
{
|
||||
this->setIsActive(m_isActive);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
#include "utility/math/Vector2.h"
|
||||
#include "utility/messaging/type/MessageActivateToken.h"
|
||||
|
||||
#include "component/view/graphElements/GraphEdge.h"
|
||||
@@ -16,7 +17,7 @@ class QtGraphEdge
|
||||
, public QGraphicsLineItem
|
||||
{
|
||||
public:
|
||||
QtGraphEdge(const std::weak_ptr<GraphNode>& owner, const std::weak_ptr<GraphNode>& target, const Id id);
|
||||
QtGraphEdge(const std::weak_ptr<GraphNode>& owner, const std::weak_ptr<GraphNode>& target, const Edge* data);
|
||||
virtual ~QtGraphEdge();
|
||||
|
||||
virtual void ownerMoved();
|
||||
@@ -27,16 +28,29 @@ public:
|
||||
virtual std::weak_ptr<GraphNode> getOwner();
|
||||
virtual std::weak_ptr<GraphNode> getTarget();
|
||||
|
||||
virtual void setColor(const Vec4i& color);
|
||||
virtual Vec4i getColor() const;
|
||||
bool getIsActive() const;
|
||||
void setIsActive(bool isActive);
|
||||
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
|
||||
void onClick();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
|
||||
|
||||
private:
|
||||
std::weak_ptr<GraphNode> m_owner;
|
||||
std::weak_ptr<GraphNode> m_target;
|
||||
|
||||
Vec4i m_color;
|
||||
bool m_isActive;
|
||||
|
||||
QGraphicsLineItem* m_child;
|
||||
|
||||
Vec2i m_mousePos;
|
||||
bool m_mouseMoved;
|
||||
};
|
||||
|
||||
#endif // QT_GRAPH_EDGE_H
|
||||
|
||||
@@ -2,29 +2,45 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <QFontMetrics>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneEvent>
|
||||
|
||||
#include "qt/view/graphElements/QtGraphEdge.h"
|
||||
#include "qt/view/graphElements/nodeComponents/QtGraphNodeComponent.h"
|
||||
|
||||
QtGraphNode::QtGraphNode(const Vec2i& position, const Vec2i& size, const std::string& name, const Id tokenId)
|
||||
: GraphNode(tokenId)
|
||||
, m_baseSize(size)
|
||||
, m_currentSize(size)
|
||||
QtGraphNode::QtGraphNode(const Node* data, TokenComponentAccess::AccessType accessType)
|
||||
: GraphNode(data)
|
||||
, m_isActive(false)
|
||||
, m_padding(10, 10)
|
||||
, m_contentHidden(false)
|
||||
{
|
||||
this->setRect(0, 0, size.x, size.y);
|
||||
this->setPos(position.x, position.y);
|
||||
QBrush brush(Qt::lightGray);
|
||||
this->setBrush(brush);
|
||||
|
||||
m_text = new QGraphicsTextItem(this);
|
||||
m_text->setPos(0, 0);
|
||||
|
||||
std::stringstream text;
|
||||
text << m_tokenId << " -> " << name;
|
||||
QBrush brush(Qt::white);
|
||||
|
||||
if (data)
|
||||
{
|
||||
text << data->getId() << ": " << data->getName();
|
||||
brush.setColor(Qt::lightGray);
|
||||
}
|
||||
else
|
||||
{
|
||||
text << TokenComponentAccess::getAccessString(accessType);
|
||||
}
|
||||
|
||||
m_text->setPlainText(QString(text.str().c_str()));
|
||||
this->setBrush(brush);
|
||||
|
||||
m_baseSize.x = QFontMetrics(m_text->font()).width(m_text->toPlainText()) + 10;
|
||||
m_baseSize.y = 25;
|
||||
|
||||
m_currentSize = m_baseSize;
|
||||
|
||||
this->setRect(0, 0, m_baseSize.x, m_baseSize.y);
|
||||
this->setAcceptHoverEvents(true);
|
||||
}
|
||||
|
||||
QtGraphNode::~QtGraphNode()
|
||||
@@ -66,12 +82,38 @@ Vec2i QtGraphNode::getSize() const
|
||||
return m_currentSize;
|
||||
}
|
||||
|
||||
bool QtGraphNode::getIsActive() const
|
||||
{
|
||||
return m_isActive;
|
||||
}
|
||||
|
||||
void QtGraphNode::setIsActive(bool isActive)
|
||||
{
|
||||
m_isActive = isActive;
|
||||
|
||||
QPen p = this->pen();
|
||||
if (isActive)
|
||||
{
|
||||
p.setWidth(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
p.setWidth(1);
|
||||
}
|
||||
this->setPen(p);
|
||||
}
|
||||
|
||||
QtGraphNode* QtGraphNode::getParent() const
|
||||
{
|
||||
return m_parentNode.lock().get();
|
||||
}
|
||||
|
||||
void QtGraphNode::setParent(std::weak_ptr<QtGraphNode> parentNode)
|
||||
{
|
||||
m_parentNode = parentNode;
|
||||
|
||||
std::shared_ptr<QtGraphNode> parent = parentNode.lock();
|
||||
if(parent != NULL)
|
||||
if (parent != NULL)
|
||||
{
|
||||
QGraphicsRectItem::setParentItem(parent.get());
|
||||
}
|
||||
@@ -143,33 +185,6 @@ void QtGraphNode::addSubNode(const std::shared_ptr<GraphNode>& node)
|
||||
rebuildLayout();
|
||||
}
|
||||
|
||||
void QtGraphNode::mousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
for (std::list<std::shared_ptr<QtGraphNodeComponent>>::iterator it = m_components.begin(); it != m_components.end(); it++)
|
||||
{
|
||||
(*it)->nodeMousePressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
for (std::list<std::shared_ptr<QtGraphNodeComponent>>::iterator it = m_components.begin(); it != m_components.end(); it++)
|
||||
{
|
||||
(*it)->nodeMouseMoveEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
MessageActivateToken message(m_tokenId);
|
||||
message.dispatch();
|
||||
|
||||
for (std::list<std::shared_ptr<QtGraphNodeComponent>>::iterator it = m_components.begin(); it != m_components.end(); it++)
|
||||
{
|
||||
(*it)->nodeMouseDoubleClickEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::notifyParentMoved()
|
||||
{
|
||||
notifyEdgesAfterMove();
|
||||
@@ -177,35 +192,31 @@ void QtGraphNode::notifyParentMoved()
|
||||
|
||||
void QtGraphNode::hideContent()
|
||||
{
|
||||
for (std::list<std::shared_ptr<GraphNode>>::iterator it = m_subNodes.begin(); it != m_subNodes.end(); it++)
|
||||
for (std::shared_ptr<GraphNode> node : m_subNodes)
|
||||
{
|
||||
(*it)->hideContent();
|
||||
node->hideContent();
|
||||
|
||||
if((*it)->getEdgeCountRecursive() <= 0)
|
||||
if (node->getTokenId() && node->getEdgeAndActiveCountRecursive() <= 0)
|
||||
{
|
||||
(*it)->hide();
|
||||
node->hide();
|
||||
}
|
||||
}
|
||||
|
||||
m_contentHidden = true;
|
||||
|
||||
rebuildLayout();
|
||||
|
||||
notifyParentNodeAfterSizeChanged();
|
||||
onChildSizeChanged();
|
||||
}
|
||||
|
||||
void QtGraphNode::showContent()
|
||||
{
|
||||
for (std::list<std::shared_ptr<GraphNode>>::iterator it = m_subNodes.begin(); it != m_subNodes.end(); it++)
|
||||
for (std::shared_ptr<GraphNode> node : m_subNodes)
|
||||
{
|
||||
(*it)->show();
|
||||
node->show();
|
||||
}
|
||||
|
||||
m_contentHidden = false;
|
||||
|
||||
rebuildLayout();
|
||||
|
||||
notifyParentNodeAfterSizeChanged();
|
||||
onChildSizeChanged();
|
||||
}
|
||||
|
||||
void QtGraphNode::hide()
|
||||
@@ -238,13 +249,18 @@ unsigned int QtGraphNode::getInEdgeCount() const
|
||||
return m_inEdges.size();
|
||||
}
|
||||
|
||||
unsigned int QtGraphNode::getEdgeCountRecursive() const
|
||||
unsigned int QtGraphNode::getEdgeAndActiveCountRecursive() const
|
||||
{
|
||||
unsigned int result = 0;
|
||||
|
||||
for (std::list<std::shared_ptr<GraphNode>>::const_iterator it = m_subNodes.begin(); it != m_subNodes.end(); it++)
|
||||
if (m_isActive)
|
||||
{
|
||||
result += (*it)->getEdgeCountRecursive();
|
||||
result++;
|
||||
}
|
||||
|
||||
for (std::shared_ptr<GraphNode> node : m_subNodes)
|
||||
{
|
||||
result += node->getEdgeAndActiveCountRecursive();
|
||||
}
|
||||
|
||||
result += (getInEdgeCount() + getOutEdgeCount());
|
||||
@@ -252,6 +268,86 @@ unsigned int QtGraphNode::getEdgeCountRecursive() const
|
||||
return result;
|
||||
}
|
||||
|
||||
void QtGraphNode::onClick()
|
||||
{
|
||||
if (m_data)
|
||||
{
|
||||
MessageActivateToken(m_data->getId()).dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::mousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
for (std::shared_ptr<QtGraphNodeComponent> component : m_components)
|
||||
{
|
||||
component->nodeMousePressEvent(event);
|
||||
}
|
||||
|
||||
if (!event->isAccepted())
|
||||
{
|
||||
QtGraphNode* parent = getParent();
|
||||
if (parent)
|
||||
{
|
||||
parent->mousePressEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
for (std::shared_ptr<QtGraphNodeComponent> component : m_components)
|
||||
{
|
||||
component->nodeMouseMoveEvent(event);
|
||||
}
|
||||
|
||||
if (!event->isAccepted())
|
||||
{
|
||||
QtGraphNode* parent = getParent();
|
||||
if (parent)
|
||||
{
|
||||
parent->mouseMoveEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
|
||||
for (std::shared_ptr<QtGraphNodeComponent> component : m_components)
|
||||
{
|
||||
component->nodeMouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
if (!event->isAccepted())
|
||||
{
|
||||
QtGraphNode* parent = getParent();
|
||||
if (parent)
|
||||
{
|
||||
parent->mouseReleaseEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
|
||||
{
|
||||
if (m_data)
|
||||
{
|
||||
bool isActive = m_isActive;
|
||||
this->setIsActive(true);
|
||||
m_isActive = isActive;
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
|
||||
{
|
||||
this->setIsActive(m_isActive);
|
||||
}
|
||||
|
||||
void QtGraphNode::notifyEdgesAfterMove()
|
||||
{
|
||||
for (std::list<std::shared_ptr<GraphEdge>>::iterator it = m_outEdges.begin(); it != m_outEdges.end(); it++)
|
||||
@@ -284,7 +380,7 @@ void QtGraphNode::notifyParentNodeAfterSizeChanged()
|
||||
{
|
||||
std::shared_ptr<QtGraphNode> parentNode = m_parentNode.lock();
|
||||
|
||||
if(parentNode != NULL)
|
||||
if (parentNode != NULL)
|
||||
{
|
||||
parentNode->onChildSizeChanged();
|
||||
}
|
||||
@@ -302,16 +398,16 @@ void QtGraphNode::rebuildLayout()
|
||||
int nextYPos = m_baseSize.y;
|
||||
int newWidth = m_baseSize.x;
|
||||
|
||||
for (std::list<std::shared_ptr<GraphNode>>::iterator it = m_subNodes.begin(); it != m_subNodes.end(); it++)
|
||||
for (const std::shared_ptr<GraphNode>& node : m_subNodes)
|
||||
{
|
||||
if((*it)->isHidden() == false)
|
||||
if (!node->isHidden())
|
||||
{
|
||||
(*it)->setPosition(this->getPosition() + Vec2i(m_padding.x, nextYPos));
|
||||
nextYPos += (*it)->getSize().y + m_padding.y;
|
||||
node->setPosition(this->getPosition() + Vec2i(m_padding.x, nextYPos));
|
||||
nextYPos += node->getSize().y + m_padding.y;
|
||||
|
||||
int tmpWidth = ((*it)->getPosition().x - getPosition().x) + (*it)->getSize().x + m_padding.x;
|
||||
int tmpWidth = (node->getPosition().x - getPosition().x) + node->getSize().x + m_padding.x;
|
||||
|
||||
if(tmpWidth > newWidth)
|
||||
if (tmpWidth > newWidth)
|
||||
{
|
||||
newWidth = tmpWidth;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class QtGraphNode
|
||||
, public QGraphicsRectItem
|
||||
{
|
||||
public:
|
||||
QtGraphNode(const Vec2i& position, const Vec2i& size, const std::string& name, const Id tokenId);
|
||||
QtGraphNode(const Node* data, TokenComponentAccess::AccessType accessType);
|
||||
virtual ~QtGraphNode();
|
||||
|
||||
virtual std::string getName() const;
|
||||
@@ -25,6 +25,10 @@ public:
|
||||
|
||||
virtual Vec2i getSize() const;
|
||||
|
||||
bool getIsActive() const;
|
||||
void setIsActive(bool isActive);
|
||||
|
||||
QtGraphNode* getParent() const;
|
||||
void setParent(std::weak_ptr<QtGraphNode> parentNode);
|
||||
|
||||
void addComponent(const std::shared_ptr<QtGraphNodeComponent>& component);
|
||||
@@ -37,10 +41,6 @@ public:
|
||||
virtual std::list<std::shared_ptr<GraphNode>> getSubNodes() const;
|
||||
virtual void addSubNode(const std::shared_ptr<GraphNode>& node);
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
virtual void notifyParentMoved();
|
||||
|
||||
virtual void hideContent();
|
||||
@@ -56,11 +56,20 @@ public:
|
||||
virtual unsigned int getInEdgeCount() const;
|
||||
|
||||
/**
|
||||
* @brief Returns the count of all connected edges (including edges of sub nodes)
|
||||
* @brief Returns the count of all connected edges and active nodes (including sub nodes)
|
||||
*/
|
||||
virtual unsigned int getEdgeCountRecursive() const;
|
||||
virtual unsigned int getEdgeAndActiveCountRecursive() const;
|
||||
|
||||
void onClick();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
|
||||
|
||||
void notifyEdgesAfterMove();
|
||||
void notifyParentNodeAfterSizeChanged();
|
||||
|
||||
@@ -79,7 +88,9 @@ private:
|
||||
|
||||
std::list<std::shared_ptr<QtGraphNodeComponent>> m_components;
|
||||
|
||||
const Vec2i m_baseSize;
|
||||
bool m_isActive;
|
||||
|
||||
Vec2i m_baseSize;
|
||||
Vec2i m_currentSize;
|
||||
|
||||
Vec2i m_padding;
|
||||
|
||||
@@ -8,3 +8,15 @@ QtGraphNodeComponent::QtGraphNodeComponent(const std::weak_ptr<QtGraphNode>& gra
|
||||
QtGraphNodeComponent::~QtGraphNodeComponent()
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphNodeComponent::nodeMousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphNodeComponent::nodeMouseMoveEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphNodeComponent::nodeMouseReleaseEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ public:
|
||||
QtGraphNodeComponent(const std::weak_ptr<QtGraphNode>& graphNode);
|
||||
virtual ~QtGraphNodeComponent();
|
||||
|
||||
virtual void nodeMousePressEvent(QGraphicsSceneMouseEvent* event) = 0;
|
||||
virtual void nodeMouseMoveEvent(QGraphicsSceneMouseEvent* event) = 0;
|
||||
virtual void nodeMouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) = 0;
|
||||
virtual void nodeMousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
virtual void nodeMouseMoveEvent(QGraphicsSceneMouseEvent* event);
|
||||
virtual void nodeMouseReleaseEvent(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
protected:
|
||||
std::weak_ptr<QtGraphNode> m_graphNode;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "QtGraphNodeComponentClickable.h"
|
||||
|
||||
#include <QGraphicsSceneEvent>
|
||||
|
||||
#include "qt/view/graphElements/QtGraphNode.h"
|
||||
|
||||
QtGraphNodeComponentClickable::QtGraphNodeComponentClickable(const std::weak_ptr<QtGraphNode>& graphNode)
|
||||
: QtGraphNodeComponent(graphNode)
|
||||
, m_mousePos(0.0f, 0.0f)
|
||||
, m_mouseMoved(false)
|
||||
{
|
||||
}
|
||||
|
||||
QtGraphNodeComponentClickable::~QtGraphNodeComponentClickable()
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentClickable::nodeMousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
m_mousePos = Vec2i(event->scenePos().x(), event->scenePos().y());
|
||||
m_mouseMoved = false;
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentClickable::nodeMouseMoveEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
Vec2i mousePos = Vec2i(event->scenePos().x(), event->scenePos().y());
|
||||
|
||||
if ((mousePos - m_mousePos).getLength() > 1.0f)
|
||||
{
|
||||
m_mouseMoved = true;
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentClickable::nodeMouseReleaseEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
if (!m_mouseMoved)
|
||||
{
|
||||
std::shared_ptr<QtGraphNode> node = m_graphNode.lock();
|
||||
if (node != NULL)
|
||||
{
|
||||
node->onClick();
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef QT_GRAPH_NODE_COMPONENT_CLICKABLE
|
||||
#define QT_GRAPH_NODE_COMPONENT_CLICKABLE
|
||||
|
||||
#include "QtGraphNodeComponent.h"
|
||||
|
||||
#include "utility/math/Vector2.h"
|
||||
|
||||
class QtGraphNodeComponentClickable
|
||||
: public QtGraphNodeComponent
|
||||
{
|
||||
public:
|
||||
QtGraphNodeComponentClickable(const std::weak_ptr<QtGraphNode>& graphNode);
|
||||
virtual ~QtGraphNodeComponentClickable();
|
||||
|
||||
virtual void nodeMousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
virtual void nodeMouseMoveEvent(QGraphicsSceneMouseEvent* event);
|
||||
virtual void nodeMouseReleaseEvent(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
private:
|
||||
Vec2i m_mousePos;
|
||||
bool m_mouseMoved;
|
||||
};
|
||||
|
||||
#endif // QT_GRAPH_NODE_COMPONENT_CLICKABLE
|
||||
@@ -16,20 +16,22 @@ QtGraphNodeComponentMoveable::~QtGraphNodeComponentMoveable()
|
||||
|
||||
void QtGraphNodeComponentMoveable::nodeMousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
m_mouseOffset.x = event->pos().x();
|
||||
m_mouseOffset.y = event->pos().y();
|
||||
std::shared_ptr<GraphNode> node = m_graphNode.lock();
|
||||
if (node != NULL)
|
||||
{
|
||||
m_mouseOffset.x = event->scenePos().x() - node->getPosition().x;
|
||||
m_mouseOffset.y = event->scenePos().y() - node->getPosition().y;
|
||||
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentMoveable::nodeMouseMoveEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
std::shared_ptr<GraphNode> node = m_graphNode.lock();
|
||||
|
||||
if(node != NULL)
|
||||
if (node != NULL)
|
||||
{
|
||||
node->setPosition(Vec2i(event->scenePos().x() - m_mouseOffset.x, event->scenePos().y() - m_mouseOffset.y));
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentMoveable::nodeMouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -14,10 +14,9 @@ public:
|
||||
|
||||
virtual void nodeMousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
virtual void nodeMouseMoveEvent(QGraphicsSceneMouseEvent* event);
|
||||
virtual void nodeMouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
private:
|
||||
Vec2i m_mouseOffset;
|
||||
};
|
||||
|
||||
#endif // QT_GRAPH_NODE_COMPONENT_MOVEABLE
|
||||
#endif // QT_GRAPH_NODE_COMPONENT_MOVEABLE
|
||||
|
||||
@@ -24,18 +24,6 @@ QtGraphNodeComponentToggleButton::~QtGraphNodeComponentToggleButton()
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentToggleButton::nodeMousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentToggleButton::nodeMouseMoveEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentToggleButton::nodeMouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentToggleButton::mousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
std::shared_ptr<QtGraphNode> node = m_graphNode.lock();
|
||||
@@ -51,11 +39,3 @@ void QtGraphNodeComponentToggleButton::mousePressEvent(QGraphicsSceneMouseEvent*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentToggleButton::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphNodeComponentToggleButton::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -11,13 +11,7 @@ public:
|
||||
QtGraphNodeComponentToggleButton(const std::weak_ptr<QtGraphNode>& graphNode);
|
||||
~QtGraphNodeComponentToggleButton();
|
||||
|
||||
virtual void nodeMousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
virtual void nodeMouseMoveEvent(QGraphicsSceneMouseEvent* event);
|
||||
virtual void nodeMouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
|
||||
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event);
|
||||
};
|
||||
|
||||
#endif // QT_GRAPH_NODE_COMPONENT_TOGGLE_BUTTON_H
|
||||
|
||||
@@ -20,12 +20,13 @@ GraphController::~GraphController()
|
||||
|
||||
void GraphController::handleMessage(MessageActivateToken* message)
|
||||
{
|
||||
createDummyGraphForTokenId(message->tokenId, &GraphLayouter::layoutSimpleRing);
|
||||
std::vector<Id> activeTokenIds(1, message->tokenId);
|
||||
createDummyGraphForTokenIds(activeTokenIds);
|
||||
}
|
||||
|
||||
void GraphController::handleMessage(MessageActivateTokens* message)
|
||||
{
|
||||
createDummyGraphForTokenId(message->tokenIds[0], &GraphLayouter::layoutSimpleRing);
|
||||
createDummyGraphForTokenIds(message->tokenIds);
|
||||
}
|
||||
|
||||
GraphView* GraphController::getView()
|
||||
@@ -33,8 +34,10 @@ GraphView* GraphController::getView()
|
||||
return Controller::getView<GraphView>();
|
||||
}
|
||||
|
||||
void GraphController::createDummyGraphForTokenId(Id tokenId, const GraphLayouter::LayoutFunction layoutFunction)
|
||||
void GraphController::createDummyGraphForTokenIds(const std::vector<Id>& tokenIds)
|
||||
{
|
||||
const GraphLayouter::LayoutFunction layoutFunction = &GraphLayouter::layoutSimpleRing;
|
||||
|
||||
GraphView* view = getView();
|
||||
if (!view)
|
||||
{
|
||||
@@ -42,9 +45,7 @@ void GraphController::createDummyGraphForTokenId(Id tokenId, const GraphLayouter
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<Id> activeTokenIds;
|
||||
activeTokenIds.push_back(tokenId);
|
||||
std::shared_ptr<Graph> graph = m_graphAccess->getGraphForActiveTokenIds(activeTokenIds);
|
||||
std::shared_ptr<Graph> graph = m_graphAccess->getGraphForActiveTokenIds(tokenIds);
|
||||
|
||||
std::vector<DummyNode> dummyNodes;
|
||||
std::vector<DummyEdge> dummyEdges;
|
||||
@@ -66,20 +67,47 @@ void GraphController::createDummyGraphForTokenId(Id tokenId, const GraphLayouter
|
||||
);
|
||||
|
||||
layoutFunction(dummyNodes);
|
||||
view->rebuildGraph(dummyNodes, dummyEdges);
|
||||
|
||||
view->rebuildGraph(graph, tokenIds, dummyNodes, dummyEdges);
|
||||
}
|
||||
|
||||
DummyNode GraphController::createDummyNodeTopDown(Node* node, std::vector<DummyEdge>* dummyEdges) const
|
||||
{
|
||||
DummyNode result("invalid", 0, Vec2i());
|
||||
|
||||
result.name = node->getName();
|
||||
result.tokenId = node->getId();
|
||||
DummyNode result(node);
|
||||
|
||||
node->forEachChildNode(
|
||||
[&result, dummyEdges, this](Node* child)
|
||||
{
|
||||
result.subNodes.push_back(createDummyNodeTopDown(child, dummyEdges));
|
||||
DummyNode* container = nullptr;
|
||||
|
||||
Edge* edge = child->getMemberEdge();
|
||||
TokenComponentAccess* access = edge->getComponent<TokenComponentAccess>();
|
||||
if (access)
|
||||
{
|
||||
TokenComponentAccess::AccessType accessType = access->getAccess();
|
||||
|
||||
for (DummyNode& dummy : result.subNodes)
|
||||
{
|
||||
if (dummy.accessType == accessType)
|
||||
{
|
||||
container = &dummy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!container)
|
||||
{
|
||||
result.subNodes.push_back(DummyNode(accessType));
|
||||
container = &result.subNodes.back();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
container = &result;
|
||||
}
|
||||
|
||||
container->subNodes.push_back(createDummyNodeTopDown(child, dummyEdges));
|
||||
}
|
||||
);
|
||||
|
||||
@@ -93,14 +121,13 @@ DummyNode GraphController::createDummyNodeTopDown(Node* node, std::vector<DummyE
|
||||
|
||||
for (const DummyEdge& dummy : *dummyEdges)
|
||||
{
|
||||
if (dummy.tokenId == edge->getId())
|
||||
if (dummy.data->getId() == edge->getId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dummyEdges->push_back(
|
||||
DummyEdge(edge->getFrom()->getId(), edge->getTo()->getId(), edge->getId(), edge->getType()));
|
||||
dummyEdges->push_back(DummyEdge(edge->getFrom()->getId(), edge->getTo()->getId(), edge));
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
struct DummyNode;
|
||||
struct DummyEdge;
|
||||
class Graph;
|
||||
class GraphView;
|
||||
class GraphAccess;
|
||||
class Node;
|
||||
@@ -31,7 +32,7 @@ private:
|
||||
|
||||
GraphView* getView();
|
||||
|
||||
void createDummyGraphForTokenId(Id tokenId, const GraphLayouter::LayoutFunction layoutFunction);
|
||||
void createDummyGraphForTokenIds(const std::vector<Id>& tokenIds);
|
||||
DummyNode createDummyNodeTopDown(Node* node, std::vector<DummyEdge>* dummyEdges) const;
|
||||
|
||||
GraphAccess* m_graphAccess;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "component/controller/GraphLayouter.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "component/view/graphElements/GraphNode.h"
|
||||
|
||||
void GraphLayouter::layoutSimpleRaster(std::vector<DummyNode>& nodes)
|
||||
@@ -8,19 +10,19 @@ void GraphLayouter::layoutSimpleRaster(std::vector<DummyNode>& nodes)
|
||||
int y = 0;
|
||||
int offset = 150;
|
||||
|
||||
int w = ceil(sqrt(nodes.size()));
|
||||
|
||||
for (unsigned int i = 0; i < nodes.size(); i++)
|
||||
{
|
||||
nodes[i].position = Vec2i(x, y);
|
||||
|
||||
if (x > 0)
|
||||
if (i > 0 && i % w == 0)
|
||||
{
|
||||
y += offset;
|
||||
x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += offset;
|
||||
}
|
||||
|
||||
nodes[i].position = Vec2i(x, y);
|
||||
|
||||
x += offset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +34,7 @@ void GraphLayouter::layoutSimpleRing(std::vector<DummyNode>& nodes)
|
||||
|
||||
if (nodes.size() > 1)
|
||||
{
|
||||
float offset = 150.0f;
|
||||
float offset = 200.0f;
|
||||
|
||||
for (unsigned int i = 1; i < nodes.size(); i++)
|
||||
{
|
||||
|
||||
@@ -4,10 +4,13 @@
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#include "utility/types.h"
|
||||
|
||||
#include "component/view/View.h"
|
||||
|
||||
struct DummyEdge;
|
||||
struct DummyNode;
|
||||
class Graph;
|
||||
class GraphEdge;
|
||||
class GraphNode;
|
||||
|
||||
@@ -19,11 +22,18 @@ public:
|
||||
|
||||
virtual std::string getName() const;
|
||||
|
||||
virtual void rebuildGraph(const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges) = 0;
|
||||
virtual void rebuildGraph(
|
||||
std::shared_ptr<Graph> graph,
|
||||
std::vector<Id> activeTokenIds,
|
||||
const std::vector<DummyNode>& nodes,
|
||||
const std::vector<DummyEdge>& edges) = 0;
|
||||
|
||||
virtual void clear() = 0;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Graph> m_graph;
|
||||
std::vector<Id> m_activeTokenIds;
|
||||
|
||||
std::list<std::shared_ptr<GraphNode> > m_nodes;
|
||||
std::list<std::weak_ptr<GraphEdge> > m_edges;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "component/view/graphElements/GraphEdge.h"
|
||||
|
||||
GraphEdge::GraphEdge(const Id tokenId)
|
||||
: m_tokenId(tokenId)
|
||||
GraphEdge::GraphEdge(const Edge* data)
|
||||
: m_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -11,5 +11,10 @@ GraphEdge::~GraphEdge()
|
||||
|
||||
Id GraphEdge::getTokenId() const
|
||||
{
|
||||
return m_tokenId;
|
||||
return m_data->getId();
|
||||
}
|
||||
|
||||
const Edge* GraphEdge::getData() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class GraphNode;
|
||||
class GraphEdge
|
||||
{
|
||||
public:
|
||||
GraphEdge(const Id tokenId);
|
||||
GraphEdge(const Edge* data);
|
||||
virtual ~GraphEdge();
|
||||
|
||||
virtual void ownerMoved() = 0;
|
||||
@@ -24,63 +24,26 @@ public:
|
||||
virtual std::weak_ptr<GraphNode> getTarget() = 0;
|
||||
|
||||
Id getTokenId() const;
|
||||
|
||||
virtual void setColor(const Vec4i& color) = 0;
|
||||
virtual Vec4i getColor() const = 0;
|
||||
const Edge* getData() const;
|
||||
|
||||
protected:
|
||||
Id m_tokenId;
|
||||
const Edge* m_data;
|
||||
};
|
||||
|
||||
// temporary data structure for (visual) graph creation process
|
||||
struct DummyEdge
|
||||
{
|
||||
public:
|
||||
DummyEdge(const Id o, const Id t, const Id tknId, Edge::EdgeType type)
|
||||
DummyEdge(const Id o, const Id t, const Edge* data)
|
||||
: ownerId(o)
|
||||
, targetId(t)
|
||||
, tokenId(tknId)
|
||||
, edgeType(type)
|
||||
, data(data)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const DummyEdge& other) const
|
||||
{
|
||||
if (ownerId == other.ownerId && targetId == other.targetId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const DummyEdge& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool operator<(const DummyEdge& other) const
|
||||
{
|
||||
if (ownerId < other.ownerId )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (ownerId == other.ownerId)
|
||||
{
|
||||
return (targetId < other.targetId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator>(const DummyEdge& other) const
|
||||
{
|
||||
return !(*this < other);
|
||||
}
|
||||
|
||||
Id ownerId;
|
||||
Id targetId;
|
||||
Id tokenId;
|
||||
|
||||
Edge::EdgeType edgeType;
|
||||
const Edge* data;
|
||||
};
|
||||
|
||||
#endif // GRAPH_EDGE_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "component/view/graphElements/GraphNode.h"
|
||||
|
||||
GraphNode::GraphNode(const Id tokenId)
|
||||
: m_tokenId(tokenId)
|
||||
GraphNode::GraphNode(const Node* data)
|
||||
: m_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -11,5 +11,19 @@ GraphNode::~GraphNode()
|
||||
|
||||
Id GraphNode::getTokenId() const
|
||||
{
|
||||
return m_tokenId;
|
||||
if (m_data)
|
||||
{
|
||||
return m_data->getId();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Node* GraphNode::getData() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
void GraphNode::setData(const Node* data)
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
@@ -7,16 +7,23 @@
|
||||
#include "utility/math/Vector2.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
#include "data/graph/Node.h"
|
||||
#include "data/graph/token_component/TokenComponentAccess.h"
|
||||
|
||||
class GraphEdge;
|
||||
|
||||
class GraphNode
|
||||
{
|
||||
public:
|
||||
GraphNode(const Id tokenId);
|
||||
GraphNode(const Node* data);
|
||||
virtual ~GraphNode();
|
||||
|
||||
virtual std::string getName() const = 0;
|
||||
Id getTokenId() const;
|
||||
|
||||
const Node* getData() const;
|
||||
void setData(const Node* data);
|
||||
|
||||
virtual Vec2i getPosition() const = 0;
|
||||
virtual void setPosition(const Vec2i& position) = 0;
|
||||
|
||||
@@ -44,71 +51,31 @@ public:
|
||||
virtual unsigned int getOutEdgeCount() const = 0;
|
||||
virtual unsigned int getInEdgeCount() const = 0;
|
||||
|
||||
virtual unsigned int getEdgeCountRecursive() const = 0;
|
||||
virtual unsigned int getEdgeAndActiveCountRecursive() const = 0;
|
||||
|
||||
protected:
|
||||
Id m_tokenId;
|
||||
const Node* m_data;
|
||||
};
|
||||
|
||||
struct DummyNode
|
||||
{
|
||||
public:
|
||||
DummyNode(const std::string& n, const Id tId, const Vec2i& p)
|
||||
: name(n)
|
||||
, tokenId(tId)
|
||||
, position(p)
|
||||
, subNodes()
|
||||
, actualNode()
|
||||
DummyNode(const Node* data)
|
||||
: data(data)
|
||||
, accessType(TokenComponentAccess::ACCESS_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const DummyNode& other) const
|
||||
DummyNode(TokenComponentAccess::AccessType accessType)
|
||||
: data(nullptr)
|
||||
, accessType(accessType)
|
||||
{
|
||||
if (tokenId == other.tokenId
|
||||
&& name == other.name
|
||||
&& position == position)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const DummyNode& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
const Node* data;
|
||||
const TokenComponentAccess::AccessType accessType;
|
||||
|
||||
bool operator<(const DummyNode& other) const
|
||||
{
|
||||
if (tokenId < other.tokenId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator>(const DummyNode& other) const
|
||||
{
|
||||
return !(*this < other);
|
||||
}
|
||||
|
||||
DummyNode& operator=(const DummyNode& other)
|
||||
{
|
||||
name = other.name;
|
||||
tokenId = other.tokenId;
|
||||
position = other.position;
|
||||
subNodes = other.subNodes;
|
||||
actualNode = other.actualNode;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
Id tokenId;
|
||||
Vec2i position;
|
||||
|
||||
std::vector<DummyNode> subNodes;
|
||||
|
||||
std::weak_ptr<GraphNode> actualNode;
|
||||
};
|
||||
|
||||
#endif // GRAPH_NODE_H
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
#include "data/graph/token_component/TokenComponentAccess.h"
|
||||
|
||||
std::string TokenComponentAccess::getAccessString(AccessType access)
|
||||
{
|
||||
switch (access)
|
||||
{
|
||||
case ACCESS_PUBLIC:
|
||||
return "public";
|
||||
case ACCESS_PROTECTED:
|
||||
return "protected";
|
||||
case ACCESS_PRIVATE:
|
||||
return "private";
|
||||
case ACCESS_NONE:
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
TokenComponentAccess::TokenComponentAccess(AccessType access)
|
||||
: m_access(access)
|
||||
{
|
||||
@@ -21,16 +37,5 @@ TokenComponentAccess::AccessType TokenComponentAccess::getAccess() const
|
||||
|
||||
std::string TokenComponentAccess::getAccessString() const
|
||||
{
|
||||
switch (m_access)
|
||||
{
|
||||
case ACCESS_PUBLIC:
|
||||
return "public";
|
||||
case ACCESS_PROTECTED:
|
||||
return "protected";
|
||||
case ACCESS_PRIVATE:
|
||||
return "private";
|
||||
case ACCESS_NONE:
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
return getAccessString(m_access);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ public:
|
||||
ACCESS_NONE
|
||||
};
|
||||
|
||||
static std::string getAccessString(AccessType access);
|
||||
|
||||
TokenComponentAccess(AccessType access);
|
||||
virtual ~TokenComponentAccess();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user