ui: styled nodes in graph view

This change styles the nodes in the QtGraphView. Since Stylesheets can't be applied to QGraphicsItems, the style
implementation was done in the source files. The containers for public/protected/private nodes are now subclassed from
QtGraphNode as QtGraphNodeAccess, including a helper class QtAccessArrow for indicating the opened/colapsed state.
This commit is contained in:
Eberhard Graether
2014-11-12 01:42:49 +01:00
parent 5b230cefa0
commit 72c5847d75
24 changed files with 731 additions and 344 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

+11
View File
@@ -133,3 +133,14 @@ public:
private:
int m_importantInt;
};
class AnotherClass
: public A
{
public:
int publicInt;
protected:
int protectedInt;
private:
int privateInt;
};
+6 -2
View File
@@ -20,6 +20,10 @@ add_files(
qt/element/QtSmartSearchBox.cpp
qt/element/QtSmartSearchBox.h
qt/graphics/QtGraphicsRoundedRectItem.cpp
qt/graphics/QtGraphicsRoundedRectItem.h
qt/utility/QtDeviceScaledPixmap.h
qt/utility/QtHighlighter.cpp
qt/utility/QtHighlighter.h
qt/utility/QtThreadedFunctor.h
@@ -32,13 +36,13 @@ add_files(
qt/view/graphElements/nodeComponents/QtGraphNodeComponentClickable.h
qt/view/graphElements/nodeComponents/QtGraphNodeComponentMoveable.cpp
qt/view/graphElements/nodeComponents/QtGraphNodeComponentMoveable.h
qt/view/graphElements/nodeComponents/QtGraphNodeComponentToggleButton.cpp
qt/view/graphElements/nodeComponents/QtGraphNodeComponentToggleButton.h
qt/view/graphElements/QtGraphEdge.cpp
qt/view/graphElements/QtGraphEdge.h
qt/view/graphElements/QtGraphNode.cpp
qt/view/graphElements/QtGraphNode.h
qt/view/graphElements/QtGraphNodeAccess.cpp
qt/view/graphElements/QtGraphNodeAccess.h
qt/view/QtCodeView.cpp
qt/view/QtCodeView.h
@@ -0,0 +1,39 @@
#include "qt/graphics/QtGraphicsRoundedRectItem.h"
#include <QGraphicsDropShadowEffect>
#include <QPainter>
QtGraphicsRoundedRectItem::QtGraphicsRoundedRectItem(QGraphicsItem* parent)
: QGraphicsRectItem(parent)
, m_radius(0.0f)
{
this->setZValue(-1.0f);
}
QtGraphicsRoundedRectItem::~QtGraphicsRoundedRectItem()
{
}
void QtGraphicsRoundedRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem* options, QWidget* widget)
{
painter->setPen(pen());
painter->setBrush(brush());
painter->setRenderHint(QPainter::Antialiasing);
painter->drawRoundedRect(this->rect(), m_radius, m_radius);
}
void QtGraphicsRoundedRectItem::setShadow(QColor color, int blurRadius)
{
QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect();
effect->setColor(color);
effect->setBlurRadius(5);
effect->setOffset(0, 0);
this->setGraphicsEffect(effect);
}
void QtGraphicsRoundedRectItem::setRadius(qreal radius)
{
m_radius = radius;
}
@@ -0,0 +1,22 @@
#ifndef QT_GRAPHICS_ROUNDED_RECT_ITEM_H
#define QT_GRAPHICS_ROUNDED_RECT_ITEM_H
#include <QGraphicsRectItem>
class QtGraphicsRoundedRectItem
: public QGraphicsRectItem
{
public:
QtGraphicsRoundedRectItem(QGraphicsItem* parent);
virtual ~QtGraphicsRoundedRectItem();
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem* options, QWidget* widget);
void setShadow(QColor color, int blurRadius);
void setRadius(qreal radius);
private:
qreal m_radius;
};
#endif // QT_GRAPHICS_ROUNDED_RECT_ITEM_H
+55
View File
@@ -0,0 +1,55 @@
#ifndef QT_DEVICE_SCALED_PIXMAP_H
#define QT_DEVICE_SCALED_PIXMAP_H
#include <QApplication>
#include <QPixmap>
class QtDeviceScaledPixmap
{
public:
static qreal devicePixelRatio()
{
QApplication* app = dynamic_cast<QApplication*>(QCoreApplication::instance());
return app->devicePixelRatio();
}
explicit QtDeviceScaledPixmap(QString filePath)
: m_pixmap(filePath)
{
m_pixmap.setDevicePixelRatio(devicePixelRatio());
}
virtual ~QtDeviceScaledPixmap() {}
const QPixmap& pixmap() const
{
return m_pixmap;
}
qreal width() const
{
return m_pixmap.width() / devicePixelRatio();
}
qreal height() const
{
return m_pixmap.height() / devicePixelRatio();
}
void scaleToHeight(int height)
{
m_pixmap = m_pixmap.scaledToHeight(height * devicePixelRatio(), Qt::SmoothTransformation);
m_pixmap.setDevicePixelRatio(devicePixelRatio());
}
void mirror(bool horizontal = false, bool vertical = true)
{
m_pixmap = QPixmap::fromImage(m_pixmap.toImage().mirrored(horizontal, vertical));
m_pixmap.setDevicePixelRatio(devicePixelRatio());
}
private:
QPixmap m_pixmap;
};
#endif // QT_DEVICE_SCALED_PIXMAP_H
+29 -29
View File
@@ -10,9 +10,9 @@
#include "qt/view/QtViewWidgetWrapper.h"
#include "qt/view/graphElements/QtGraphEdge.h"
#include "qt/view/graphElements/QtGraphNode.h"
#include "qt/view/graphElements/QtGraphNodeAccess.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)
@@ -37,15 +37,14 @@ void QtGraphView::createWidgetWrapper()
void QtGraphView::initView()
{
QWidget* widget = QtViewWidgetWrapper::getWidgetOfView(this);
utility::setWidgetBackgroundColor(widget, Colori(100, 20, 200, 255));
utility::setWidgetBackgroundColor(widget, Colori(255, 255, 255, 255));
QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom);
layout->setSpacing(3);
layout->setContentsMargins(3, 3, 3, 3);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
widget->setLayout(layout);
QGraphicsScene* scene = new QGraphicsScene(widget);
QGraphicsView* view = new QGraphicsView(widget);
view->setScene(scene);
@@ -92,12 +91,12 @@ void QtGraphView::doRebuildGraph(
{
// 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;
std::list<std::shared_ptr<QtGraphNode>> newNodes;
// create nodes (or find existing nodes for re-use)
for (unsigned int i = 0; i < nodes.size(); i++)
{
std::shared_ptr<GraphNode> newNode = createNodeRecursive(view, NULL, nodes[i]);
std::shared_ptr<QtGraphNode> newNode = createNodeRecursive(view, NULL, nodes[i]);
newNode->setPosition(nodes[i].position);
newNodes.push_back(newNode);
}
@@ -107,7 +106,7 @@ void QtGraphView::doRebuildGraph(
for (unsigned int i = 0; i < edges.size(); i++)
{
std::shared_ptr<GraphEdge> edge = createEdge(view, edges[i]);
std::shared_ptr<QtGraphEdge> edge = createEdge(view, edges[i]);
if (edge != NULL)
{
m_edges.push_back(edge);
@@ -115,9 +114,9 @@ void QtGraphView::doRebuildGraph(
}
// hide node content by default, must be done after all edges are created to keep subnodes with connections visible
for(std::list<std::shared_ptr<GraphNode>>::iterator it = m_nodes.begin(); it != m_nodes.end(); it++)
for (const std::shared_ptr<QtGraphNode>& node : m_nodes)
{
(*it)->hideContent();
node->hideContent();
}
}
else
@@ -134,31 +133,40 @@ void QtGraphView::doClear()
m_edges.clear();
}
std::shared_ptr<GraphNode> QtGraphView::findNodeRecursive(const std::list<std::shared_ptr<GraphNode>>& nodes, Id tokenId)
std::shared_ptr<QtGraphNode> QtGraphView::findNodeRecursive(const std::list<std::shared_ptr<QtGraphNode>>& nodes, Id tokenId)
{
for (const std::shared_ptr<GraphNode>& node : nodes)
for (const std::shared_ptr<QtGraphNode>& node : nodes)
{
if (node->getTokenId() == tokenId)
{
return node;
}
std::shared_ptr<GraphNode> result = findNodeRecursive(node->getSubNodes(), tokenId);
std::shared_ptr<QtGraphNode> result = findNodeRecursive(node->getSubNodes(), tokenId);
if (result != NULL)
{
return result;
}
}
return std::shared_ptr<GraphNode>();
return std::shared_ptr<QtGraphNode>();
}
std::shared_ptr<GraphNode> QtGraphView::createNodeRecursive(
std::shared_ptr<QtGraphNode> QtGraphView::createNodeRecursive(
QGraphicsView* view, std::shared_ptr<QtGraphNode> parentNode, const DummyNode& node
){
if (view != NULL)
{
std::shared_ptr<QtGraphNode> newNode = std::make_shared<QtGraphNode>(node.data, node.accessType);
std::shared_ptr<QtGraphNode> newNode;
if (node.data)
{
newNode = std::make_shared<QtGraphNode>(node.data);
}
else
{
newNode = std::make_shared<QtGraphNodeAccess>(node.accessType);
}
newNode->addComponent(std::make_shared<QtGraphNodeComponentClickable>(newNode));
view->scene()->addItem(newNode.get());
@@ -177,18 +185,10 @@ std::shared_ptr<GraphNode> QtGraphView::createNodeRecursive(
newNode->addComponent(std::make_shared<QtGraphNodeComponentMoveable>(newNode));
}
if (node.subNodes.size() > 0)
for (unsigned int i = 0; i < node.subNodes.size(); i++)
{
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<GraphNode> subNode = createNodeRecursive(view, newNode, node.subNodes[i]);
newNode->addSubNode(subNode);
}
std::shared_ptr<QtGraphNode> subNode = createNodeRecursive(view, newNode, node.subNodes[i]);
newNode->addSubNode(subNode);
}
return newNode;
@@ -204,8 +204,8 @@ std::shared_ptr<QtGraphEdge> QtGraphView::createEdge(QGraphicsView* view, const
{
if (view != NULL)
{
std::shared_ptr<GraphNode> owner = findNodeRecursive(m_nodes, edge.ownerId);
std::shared_ptr<GraphNode> target = findNodeRecursive(m_nodes, edge.targetId);
std::shared_ptr<QtGraphNode> owner = findNodeRecursive(m_nodes, edge.ownerId);
std::shared_ptr<QtGraphNode> target = findNodeRecursive(m_nodes, edge.targetId);
if (owner != NULL && target != NULL)
{
+8 -2
View File
@@ -42,9 +42,9 @@ private:
const std::vector<DummyEdge>& edges);
void doClear();
std::shared_ptr<GraphNode> findNodeRecursive(const std::list<std::shared_ptr<GraphNode>>& nodes, Id tokenId);
std::shared_ptr<QtGraphNode> findNodeRecursive(const std::list<std::shared_ptr<QtGraphNode>>& nodes, Id tokenId);
std::shared_ptr<GraphNode> createNodeRecursive(
std::shared_ptr<QtGraphNode> createNodeRecursive(
QGraphicsView* view, std::shared_ptr<QtGraphNode> parentNode, const DummyNode& node);
std::shared_ptr<QtGraphEdge> createEdge(QGraphicsView* view, const DummyEdge& edge);
@@ -55,6 +55,12 @@ private:
> m_rebuildGraphFunctor;
QtThreadedFunctor<void> m_clearFunctor;
std::shared_ptr<Graph> m_graph;
std::vector<Id> m_activeTokenIds;
std::list<std::shared_ptr<QtGraphNode>> m_nodes;
std::list<std::weak_ptr<QtGraphEdge>> m_edges;
};
#endif // QT_GRAPH_VIEW_H
@@ -36,14 +36,14 @@ QtGraphEdge::QtGraphEdge(const std::weak_ptr<GraphNode>& owner, const std::weak_
this->setZValue(1); // Used to draw edges always on top of nodes.
QPen pen(Qt::transparent);
pen.setWidth(10);
this->setPen(pen);
pen.setWidth(10);
this->setPen(pen);
m_child = new QGraphicsLineItem(this);
m_child->setLine(ownerPos.x, ownerPos.y, targetPos.x, targetPos.y);
m_child = new QGraphicsLineItem(this);
m_child->setLine(ownerPos.x, ownerPos.y, targetPos.x, targetPos.y);
pen.setColor(Qt::black);
pen.setWidth(2);
pen.setWidth(1);
switch (data->getType())
{
@@ -148,11 +148,11 @@ void QtGraphEdge::setIsActive(bool isActive)
QPen p = m_child->pen();
if (isActive)
{
p.setWidth(4);
p.setWidth(2);
}
else
{
p.setWidth(2);
p.setWidth(1);
}
m_child->setPen(p);
}
+283 -177
View File
@@ -1,46 +1,50 @@
#include "qt/view/graphElements/QtGraphNode.h"
#include <sstream>
#include <QBrush>
#include <QFontMetrics>
#include <QGraphicsScene>
#include <QGraphicsSceneEvent>
#include <QPen>
#include "qt/view/graphElements/QtGraphEdge.h"
#include "utility/messaging/type/MessageActivateToken.h"
#include "qt/graphics/QtGraphicsRoundedRectItem.h"
#include "qt/utility/QtDeviceScaledPixmap.h"
#include "qt/view/graphElements/nodeComponents/QtGraphNodeComponent.h"
#include "qt/view/graphElements/QtGraphEdge.h"
QtGraphNode::QtGraphNode(const Node* data, TokenComponentAccess::AccessType accessType)
: GraphNode(data)
QtGraphNode::QtGraphNode()
: GraphNode(nullptr)
, m_undefinedRect(nullptr)
, m_padding(0, 0, 0, 0)
, m_spacing(8)
, m_isActive(false)
, m_padding(10, 10)
, m_contentHidden(false)
, m_isHovering(false)
{
m_text = new QGraphicsTextItem(this);
m_text->setPos(0, 0);
this->setPen(QPen(Qt::transparent));
std::stringstream text;
QBrush brush(Qt::white);
m_rect = new QtGraphicsRoundedRectItem(this);
m_text = new QGraphicsSimpleTextItem(this);
}
if (data)
{
text << data->getId() << ": " << data->getName();
brush.setColor(Qt::lightGray);
}
else
{
text << TokenComponentAccess::getAccessString(accessType);
}
QtGraphNode::QtGraphNode(const Node* data)
: GraphNode(data)
, m_undefinedRect(nullptr)
, m_padding(0, 0, 0, 0)
, m_spacing(8)
, m_isActive(false)
, m_isHovering(false)
{
this->setPen(QPen(Qt::transparent));
m_text->setPlainText(QString(text.str().c_str()));
this->setBrush(brush);
m_rect = new QtGraphicsRoundedRectItem(this);
m_text = new QGraphicsSimpleTextItem(this);
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);
this->setName(data->getName());
this->setStyle();
this->setSize(m_baseSize);
}
QtGraphNode::~QtGraphNode()
@@ -57,7 +61,12 @@ QtGraphNode::~QtGraphNode()
std::string QtGraphNode::getName() const
{
return m_text->toPlainText().toStdString();
return m_text->text().toStdString();
}
void QtGraphNode::setName(const std::string& name)
{
m_text->setText(QString::fromStdString(name));
}
Vec2i QtGraphNode::getPosition() const
@@ -82,46 +91,17 @@ Vec2i QtGraphNode::getSize() const
return m_currentSize;
}
bool QtGraphNode::getIsActive() const
void QtGraphNode::setSize(Vec2i size)
{
return m_isActive;
}
m_currentSize = size;
void QtGraphNode::setIsActive(bool isActive)
{
m_isActive = isActive;
this->setRect(0, 0, size.x, size.y);
m_rect->setRect(0, 0, size.x, size.y);
QPen p = this->pen();
if (isActive)
if (m_undefinedRect)
{
p.setWidth(2);
m_undefinedRect->setRect(1, 1, size.x - 2, size.y - 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)
{
QGraphicsRectItem::setParentItem(parent.get());
}
}
void QtGraphNode::addComponent(const std::shared_ptr<QtGraphNodeComponent>& component)
{
m_components.push_back(component);
}
bool QtGraphNode::addOutEdge(const std::shared_ptr<GraphEdge>& edge)
@@ -173,72 +153,6 @@ 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);
rebuildLayout();
}
void QtGraphNode::notifyParentMoved()
{
notifyEdgesAfterMove();
}
void QtGraphNode::hideContent()
{
for (std::shared_ptr<GraphNode> node : m_subNodes)
{
node->hideContent();
if (node->getTokenId() && node->getEdgeAndActiveCountRecursive() <= 0)
{
node->hide();
}
}
m_contentHidden = true;
onChildSizeChanged();
}
void QtGraphNode::showContent()
{
for (std::shared_ptr<GraphNode> node : m_subNodes)
{
node->show();
}
m_contentHidden = false;
onChildSizeChanged();
}
void QtGraphNode::hide()
{
QGraphicsRectItem::hide();
}
void QtGraphNode::show()
{
QGraphicsRectItem::show();
}
bool QtGraphNode::isHidden()
{
return !QGraphicsRectItem::isVisible();
}
bool QtGraphNode::contentIsHidden()
{
return m_contentHidden;
}
unsigned int QtGraphNode::getOutEdgeCount() const
{
return m_outEdges.size();
@@ -249,6 +163,49 @@ unsigned int QtGraphNode::getInEdgeCount() const
return m_inEdges.size();
}
bool QtGraphNode::getIsActive() const
{
return m_isActive;
}
void QtGraphNode::setIsActive(bool isActive)
{
m_isActive = isActive;
setStyle();
}
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)
{
QGraphicsRectItem::setParentItem(parent.get());
}
}
void QtGraphNode::addComponent(const std::shared_ptr<QtGraphNodeComponent>& component)
{
m_components.push_back(component);
}
std::list<std::shared_ptr<QtGraphNode>> QtGraphNode::getSubNodes() const
{
return m_subNodes;
}
void QtGraphNode::addSubNode(const std::shared_ptr<QtGraphNode>& node)
{
m_subNodes.push_back(node);
}
unsigned int QtGraphNode::getEdgeAndActiveCountRecursive() const
{
unsigned int result = 0;
@@ -258,7 +215,7 @@ unsigned int QtGraphNode::getEdgeAndActiveCountRecursive() const
result++;
}
for (std::shared_ptr<GraphNode> node : m_subNodes)
for (std::shared_ptr<QtGraphNode> node : m_subNodes)
{
result += node->getEdgeAndActiveCountRecursive();
}
@@ -268,9 +225,24 @@ unsigned int QtGraphNode::getEdgeAndActiveCountRecursive() const
return result;
}
void QtGraphNode::hideContent()
{
for (std::shared_ptr<QtGraphNode> node : m_subNodes)
{
node->hideContent();
if (node->getTokenId() && node->getEdgeAndActiveCountRecursive() <= 0)
{
node->hide();
}
}
rebuildLayout();
}
void QtGraphNode::onClick()
{
if (m_data)
if (m_data && !m_data->isType(Node::NODE_UNDEFINED | Node::NODE_NAMESPACE))
{
MessageActivateToken(m_data->getId()).dispatch();
}
@@ -335,87 +307,221 @@ void QtGraphNode::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
void QtGraphNode::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
{
if (m_data)
{
bool isActive = m_isActive;
this->setIsActive(true);
m_isActive = isActive;
}
m_isHovering = true;
setStyle();
}
void QtGraphNode::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
{
this->setIsActive(m_isActive);
m_isHovering = false;
setStyle();
}
void QtGraphNode::notifyEdgesAfterMove()
{
for (std::list<std::shared_ptr<GraphEdge>>::iterator it = m_outEdges.begin(); it != m_outEdges.end(); it++)
for (const std::shared_ptr<GraphEdge>& edge : m_outEdges)
{
(*it)->ownerMoved();
edge->ownerMoved();
}
std::list<std::weak_ptr<GraphEdge>>::iterator it2 = m_inEdges.begin();
while (it2 != m_inEdges.end())
for (const std::weak_ptr<GraphEdge>& e : m_inEdges)
{
std::shared_ptr<GraphEdge> edge = it2->lock();
if (edge.get() != NULL)
{
edge->targetMoved();
++it2;
}
else
{
m_inEdges.erase(it2++);
}
std::shared_ptr<GraphEdge> edge = e.lock();
if (edge)
{
edge->targetMoved();
}
}
for (std::list<std::shared_ptr<GraphNode>>::iterator it3 = m_subNodes.begin(); it3 != m_subNodes.end(); it3++)
for (const std::shared_ptr<QtGraphNode>& node : m_subNodes)
{
(*it3)->notifyParentMoved();
node->notifyEdgesAfterMove();
}
}
void QtGraphNode::notifyParentNodeAfterSizeChanged()
void QtGraphNode::onSizeChanged()
{
rebuildLayout();
std::shared_ptr<QtGraphNode> parentNode = m_parentNode.lock();
if (parentNode != NULL)
{
parentNode->onChildSizeChanged();
parentNode->onSizeChanged();
}
}
void QtGraphNode::onChildSizeChanged()
{
rebuildLayout();
notifyParentNodeAfterSizeChanged();
}
void QtGraphNode::rebuildLayout()
{
int nextYPos = m_baseSize.y;
int newWidth = m_baseSize.x;
setStyle();
for (const std::shared_ptr<GraphNode>& node : m_subNodes)
Vec2i newSize(m_baseSize);
newSize.y = newSize.y - m_padding.w;
for (const std::shared_ptr<QtGraphNode>& node : m_subNodes)
{
if (!node->isHidden())
if (node->isVisible())
{
node->setPosition(this->getPosition() + Vec2i(m_padding.x, nextYPos));
nextYPos += node->getSize().y + m_padding.y;
node->setPosition(this->getPosition() + Vec2i(m_padding.x, m_spacing + newSize.y));
newSize.y = newSize.y + m_spacing + node->getSize().y;
int tmpWidth = (node->getPosition().x - getPosition().x) + node->getSize().x + m_padding.x;
int tmpWidth = node->getSize().x + m_padding.x + m_padding.z;
if (tmpWidth > newWidth)
if (tmpWidth > newSize.x)
{
newWidth = tmpWidth;
newSize.x = tmpWidth;
}
}
}
m_currentSize.x = newWidth;
m_currentSize.y = nextYPos;
newSize.y = newSize.y + m_padding.w;
setSize(newSize);
}
this->setRect(0, 0, m_currentSize.x, m_currentSize.y);
void QtGraphNode::setStyle()
{
if (!m_data)
{
return;
}
QColor color = Qt::lightGray;
qreal radius = 0.0f;
QFont font("Source Code Pro");
QPen p(Qt::transparent);
bool undefined = false;
bool useUndefinedColor = false;
switch (m_data->getType())
{
case Node::NODE_UNDEFINED:
undefined = true;
case Node::NODE_NAMESPACE:
color = Qt::white;
p.setColor("#cc8d91");
p.setWidth(1);
font.setPointSize(12);
radius = 20.0f;
m_padding.x = m_padding.z = 15;
m_padding.y = 6;
m_padding.w = 15;
break;
case Node::NODE_UNDEFINED_TYPE:
undefined = true;
case Node::NODE_STRUCT:
case Node::NODE_CLASS:
case Node::NODE_ENUM:
case Node::NODE_TYPEDEF:
if (m_isHovering)
{
m_rect->setShadow(QColor(0, 0, 0, 255), 5);
}
else
{
m_rect->setShadow(QColor(0, 0, 0, 128), 5);
}
font.setPointSize(14);
color = "#ededed";
if (m_subNodes.size())
{
radius = 20.0f;
m_padding.x = m_padding.z = 15;
m_padding.y = m_padding.w = 10;
}
else
{
radius = 10.0f;
m_padding.x = m_padding.z = 8;
m_padding.y = m_padding.w = 5;
}
break;
case Node::NODE_UNDEFINED_FUNCTION:
undefined = true;
useUndefinedColor = true;
case Node::NODE_FUNCTION:
case Node::NODE_METHOD:
if (m_isActive || m_isHovering)
{
color = "#ffcc00";
font.setWeight(QFont::Bold);
}
else
{
color = "#ffe47a";
}
font.setPointSize(11);
radius = 8.0f;
m_padding.x = m_padding.z = 5;
m_padding.y = m_padding.w = 3;
break;
case Node::NODE_UNDEFINED_VARIABLE:
undefined = true;
useUndefinedColor = true;
case Node::NODE_GLOBAL_VARIABLE:
case Node::NODE_FIELD:
if (m_isActive || m_isHovering)
{
color = "#62b29d";
font.setWeight(QFont::Bold);
}
else
{
color = "#9ab4ad";
}
font.setPointSize(11);
radius = 8.0f;
m_padding.x = m_padding.z = 5;
m_padding.y = m_padding.w = 3;
break;
}
if (m_isActive)
{
p.setWidthF(1.5f);
p.setColor("#3c3c3c");
}
m_rect->setPen(p);
m_rect->setBrush(QBrush(color));
m_rect->setRadius(radius);
if (undefined)
{
QtDeviceScaledPixmap pixmap("data/gui/graph_view/images/pattern.png");
pixmap.scaleToHeight(10);
if (!m_undefinedRect)
{
m_undefinedRect = new QtGraphicsRoundedRectItem(this);
}
p.setWidth(1);
p.setColor(Qt::transparent);
if (useUndefinedColor && !m_isActive)
{
p.setColor(color);
}
m_undefinedRect->setPen(p);
m_undefinedRect->setBrush(QBrush(pixmap.pixmap()));
m_undefinedRect->setRadius(radius);
}
m_text->setFont(font);
m_text->setPos(m_padding.x, m_padding.y);
m_baseSize.x = QFontMetrics(m_text->font()).width(m_text->text()) + m_padding.x + m_padding.z;
m_baseSize.y = QFontMetrics(m_text->font()).height() + m_padding.y + m_padding.w;
}
+41 -43
View File
@@ -4,11 +4,12 @@
#include <QGraphicsItem>
#include "utility/math/Vector2.h"
#include "utility/messaging/type/MessageActivateToken.h"
#include "utility/math/Vector4.h"
#include "component/view/graphElements/GraphNode.h"
class QtGraphEdge;
class QtGraphicsRoundedRectItem;
class QtGraphNodeComponent;
class QtGraphNode
@@ -16,14 +17,26 @@ class QtGraphNode
, public QGraphicsRectItem
{
public:
QtGraphNode(const Node* data, TokenComponentAccess::AccessType accessType);
QtGraphNode();
QtGraphNode(const Node* data);
virtual ~QtGraphNode();
virtual std::string getName() const;
void setName(const std::string& name);
virtual Vec2i getPosition() const;
virtual void setPosition(const Vec2i& position);
virtual Vec2i getSize() const;
virtual void setSize(Vec2i size);
virtual bool addOutEdge(const std::shared_ptr<GraphEdge>& edge);
virtual bool addInEdge(const std::weak_ptr<GraphEdge>& edge);
virtual void removeOutEdge(GraphEdge* edge);
virtual unsigned int getOutEdgeCount() const;
virtual unsigned int getInEdgeCount() const;
bool getIsActive() const;
void setIsActive(bool isActive);
@@ -33,69 +46,54 @@ public:
void addComponent(const std::shared_ptr<QtGraphNodeComponent>& component);
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);
virtual void notifyParentMoved();
virtual void hideContent();
virtual void showContent();
virtual void hide();
virtual void show();
virtual bool isHidden();
virtual bool contentIsHidden();
virtual unsigned int getOutEdgeCount() const;
virtual unsigned int getInEdgeCount() const;
std::list<std::shared_ptr<QtGraphNode>> getSubNodes() const;
void addSubNode(const std::shared_ptr<QtGraphNode>& node);
/**
* @brief Returns the count of all connected edges and active nodes (including sub nodes)
*/
virtual unsigned int getEdgeAndActiveCountRecursive() const;
unsigned int getEdgeAndActiveCountRecursive() const;
void onClick();
virtual void hideContent();
virtual void onClick();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent* event);
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
void notifyEdgesAfterMove();
void notifyParentNodeAfterSizeChanged();
void onSizeChanged();
void onChildSizeChanged();
virtual void rebuildLayout();
std::list<std::shared_ptr<GraphEdge>> m_outEdges;
std::list<std::weak_ptr<GraphEdge>> m_inEdges;
private:
void rebuildLayout();
QGraphicsTextItem* m_text;
std::weak_ptr<QtGraphNode> m_parentNode;
std::list<std::shared_ptr<GraphNode>> m_subNodes;
std::list<std::shared_ptr<QtGraphNode>> m_subNodes;
std::list<std::shared_ptr<QtGraphNodeComponent>> m_components;
bool m_isActive;
QGraphicsSimpleTextItem* m_text;
QtGraphicsRoundedRectItem* m_rect;
QtGraphicsRoundedRectItem* m_undefinedRect;
Vec2i m_baseSize;
Vec2i m_currentSize;
Vec2i m_padding;
Vec4i m_padding;
int m_spacing;
bool m_contentHidden;
private:
void setStyle();
std::list<std::shared_ptr<QtGraphNodeComponent>> m_components;
bool m_isActive;
bool m_isHovering;
};
#endif // QT_GRAPH_NODE_H
@@ -0,0 +1,184 @@
#include "qt/view/graphElements/QtGraphNodeAccess.h"
#include <QBrush>
#include <QFontMetrics>
#include <QPen>
#include "qt/graphics/QtGraphicsRoundedRectItem.h"
#include "qt/utility/QtDeviceScaledPixmap.h"
QtGraphNodeAccess::QtAccessArrow::QtAccessArrow(QGraphicsItem* parent)
: QGraphicsRectItem(parent)
{
m_icon = new QGraphicsPixmapItem(this);
QFont font;
font.setFamily("Myriad Pro");
font.setWeight(QFont::Normal);
font.setPointSize(9);
m_number = new QGraphicsSimpleTextItem(this);
m_number->setFont(font);
}
QtGraphNodeAccess::QtAccessArrow::~QtAccessArrow()
{
}
int QtGraphNodeAccess::QtAccessArrow::update(bool visible, int number)
{
const int iconHeight = 4;
int spacing = 0;
if (!visible)
{
m_icon->hide();
m_number->hide();
return spacing;
}
m_icon->show();
QtDeviceScaledPixmap pixmap("data/gui/graph_view/images/arrow.png");
pixmap.scaleToHeight(iconHeight);
if (number)
{
m_number->show();
spacing = 13;
QString numberStr = QString::number(number);
m_number->setText(numberStr);
m_number->setPos(
-QFontMetrics(m_number->font()).width(numberStr) / 2,
-iconHeight - QFontMetrics(m_number->font()).height()
);
}
else
{
m_number->hide();
spacing = 5;
pixmap.mirror();
}
m_icon->setPixmap(pixmap.pixmap());
m_icon->setPos(-pixmap.width() / 2, -iconHeight);
return spacing;
}
QtGraphNodeAccess::QtGraphNodeAccess(TokenComponentAccess::AccessType accessType)
: QtGraphNode()
, m_contentHidden(false)
, m_accessIconSize(20)
{
m_padding = Vec4i(10, 10, 10, 10);
m_spacing = 8;
QFont font;
font.setFamily("Myriad Pro");
font.setWeight(QFont::Bold);
font.setPointSize(11);
font.setCapitalization(QFont::AllUppercase);
m_text->setFont(font);
m_text->setPos(m_padding.x + m_accessIconSize + 3, m_padding.y + m_accessIconSize / 2 - 1);
m_rect->setPen(QPen(Qt::transparent));
m_rect->setBrush(QBrush(Qt::white));
m_rect->setRadius(12.0f);
std::string accessString = TokenComponentAccess::getAccessString(accessType);
this->setName(accessString);
QtDeviceScaledPixmap pixmap(QString::fromStdString("data/gui/graph_view/images/" + accessString + ".png"));
pixmap.scaleToHeight(m_accessIconSize);
m_accessIcon = new QGraphicsPixmapItem(pixmap.pixmap(), this);
m_accessIcon->setPos(m_padding.x, m_padding.y);
m_arrow = new QtAccessArrow(this);
}
QtGraphNodeAccess::~QtGraphNodeAccess()
{
}
void QtGraphNodeAccess::hideContent()
{
m_contentHidden = true;
QtGraphNode::hideContent();
}
void QtGraphNodeAccess::showContent()
{
for (std::shared_ptr<QtGraphNode> node : m_subNodes)
{
node->show();
}
m_contentHidden = false;
}
void QtGraphNodeAccess::onClick()
{
if (m_contentHidden)
{
showContent();
}
else
{
hideContent();
}
onSizeChanged();
}
void QtGraphNodeAccess::rebuildLayout()
{
bool allActive = true;
int visibleSubNodes = 0;
for (const std::shared_ptr<QtGraphNode>& node : m_subNodes)
{
if (!node->getEdgeAndActiveCountRecursive())
{
allActive = false;
}
if (node->isVisible())
{
visibleSubNodes++;
}
}
int width = m_padding.x + m_accessIconSize;
int height = m_padding.y + m_accessIconSize;
int arrowSpace = m_arrow->update(!allActive, m_subNodes.size() - visibleSubNodes);
if (visibleSubNodes)
{
m_text->show();
width += QFontMetrics(m_text->font()).width(m_text->text()) + 3;
}
else
{
m_text->hide();
arrowSpace -= 3;
}
m_padding.w = 10 + arrowSpace;
width += m_padding.z;
height += m_padding.w;
m_baseSize.x = width;
m_baseSize.y = height;
QtGraphNode::rebuildLayout();
m_arrow->setPos(m_currentSize.x / 2, m_currentSize.y - 5);
}
@@ -0,0 +1,45 @@
#ifndef QT_GRAPH_NODE_ACCESS_H
#define QT_GRAPH_NODE_ACCESS_H
#include "data/graph/token_component/TokenComponentAccess.h"
#include "qt/view/graphElements/QtGraphNode.h"
class QtGraphNodeAccess
: public QtGraphNode
{
public:
class QtAccessArrow
: public QGraphicsRectItem
{
public:
QtAccessArrow(QGraphicsItem* parent);
virtual ~QtAccessArrow();
int update(bool visible, int number);
private:
QGraphicsPixmapItem* m_icon;
QGraphicsSimpleTextItem* m_number;
};
QtGraphNodeAccess(TokenComponentAccess::AccessType accessType);
virtual ~QtGraphNodeAccess();
virtual void hideContent();
virtual void showContent();
virtual void onClick();
virtual void rebuildLayout();
private:
bool m_contentHidden;
QGraphicsPixmapItem* m_accessIcon;
int m_accessIconSize;
QtAccessArrow* m_arrow;
};
#endif // QT_GRAPH_NODE_ACCESS_H
@@ -1,41 +0,0 @@
#include "QtGraphNodeComponentToggleButton.h"
#include <QGraphicsScene>
#include <QGraphicsSceneEvent>
#include "qt/view/graphElements/QtGraphNode.h"
QtGraphNodeComponentToggleButton::QtGraphNodeComponentToggleButton(const std::weak_ptr<QtGraphNode>& graphNode)
: QtGraphNodeComponent(graphNode)
{
this->setRect(0, 0, 10, 10);
this->setPos(0, 0);
QBrush brush(Qt::darkGray);
this->setBrush(brush);
std::shared_ptr<QtGraphNode> node = graphNode.lock();
if(node != NULL)
{
this->setParentItem(node.get());
}
}
QtGraphNodeComponentToggleButton::~QtGraphNodeComponentToggleButton()
{
}
void QtGraphNodeComponentToggleButton::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
std::shared_ptr<QtGraphNode> node = m_graphNode.lock();
if(node != NULL)
{
if(node->contentIsHidden())
{
node->showContent();
}
else
{
node->hideContent();
}
}
}
@@ -1,17 +0,0 @@
#ifndef QT_GRAPH_NODE_COMPONENT_TOGGLE_BUTTON_H
#define QT_GRAPH_NODE_COMPONENT_TOGGLE_BUTTON_H
#include "QtGraphNodeComponent.h"
class QtGraphNodeComponentToggleButton
: public QtGraphNodeComponent
, public QGraphicsRectItem
{
public:
QtGraphNodeComponentToggleButton(const std::weak_ptr<QtGraphNode>& graphNode);
~QtGraphNodeComponentToggleButton();
void mousePressEvent(QGraphicsSceneMouseEvent* event);
};
#endif // QT_GRAPH_NODE_COMPONENT_TOGGLE_BUTTON_H
@@ -36,7 +36,7 @@ GraphView* GraphController::getView()
void GraphController::createDummyGraphForTokenIds(const std::vector<Id>& tokenIds)
{
const GraphLayouter::LayoutFunction layoutFunction = &GraphLayouter::layoutSimpleRing;
const GraphLayouter::LayoutFunction layoutFunction = &GraphLayouter::layoutSimpleRaster;
GraphView* view = getView();
if (!view)
-9
View File
@@ -11,8 +11,6 @@
struct DummyEdge;
struct DummyNode;
class Graph;
class GraphEdge;
class GraphNode;
class GraphView : public View
{
@@ -29,13 +27,6 @@ public:
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;
};
#endif // GRAPH_VIEW_H
@@ -34,25 +34,9 @@ public:
virtual void removeOutEdge(GraphEdge* edge) = 0;
virtual std::list<std::shared_ptr<GraphNode> > getSubNodes() const = 0;
virtual void addSubNode(const std::shared_ptr<GraphNode>& node) = 0;
virtual void notifyParentMoved() = 0;
virtual void hideContent() = 0;
virtual void showContent() = 0;
virtual void hide() = 0;
virtual void show() = 0;
virtual bool isHidden() = 0;
virtual bool contentIsHidden() = 0;
virtual unsigned int getOutEdgeCount() const = 0;
virtual unsigned int getInEdgeCount() const = 0;
virtual unsigned int getEdgeAndActiveCountRecursive() const = 0;
protected:
const Node* m_data;
};