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:
@@ -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