diff --git a/bin/app/data/fonts/MyriadPro-Regular.otf b/bin/app/data/fonts/MyriadPro-Regular.otf new file mode 100755 index 00000000..e7b7f262 Binary files /dev/null and b/bin/app/data/fonts/MyriadPro-Regular.otf differ diff --git a/bin/app/data/fonts/MyriadPro-Semibold.otf b/bin/app/data/fonts/MyriadPro-Semibold.otf new file mode 100755 index 00000000..1178f242 Binary files /dev/null and b/bin/app/data/fonts/MyriadPro-Semibold.otf differ diff --git a/bin/app/data/gui/graph_view/images/arrow.png b/bin/app/data/gui/graph_view/images/arrow.png new file mode 100644 index 00000000..dff2a697 Binary files /dev/null and b/bin/app/data/gui/graph_view/images/arrow.png differ diff --git a/bin/app/data/gui/graph_view/images/pattern.png b/bin/app/data/gui/graph_view/images/pattern.png new file mode 100644 index 00000000..2f424187 Binary files /dev/null and b/bin/app/data/gui/graph_view/images/pattern.png differ diff --git a/bin/app/data/gui/graph_view/images/private.png b/bin/app/data/gui/graph_view/images/private.png new file mode 100644 index 00000000..24160f45 Binary files /dev/null and b/bin/app/data/gui/graph_view/images/private.png differ diff --git a/bin/app/data/gui/graph_view/images/protected.png b/bin/app/data/gui/graph_view/images/protected.png new file mode 100644 index 00000000..8fb00f38 Binary files /dev/null and b/bin/app/data/gui/graph_view/images/protected.png differ diff --git a/bin/app/data/gui/graph_view/images/public.png b/bin/app/data/gui/graph_view/images/public.png new file mode 100644 index 00000000..ddaf769f Binary files /dev/null and b/bin/app/data/gui/graph_view/images/public.png differ diff --git a/bin/app/data/src/header.h b/bin/app/data/src/header.h index 97bb97ab..2e3c4545 100644 --- a/bin/app/data/src/header.h +++ b/bin/app/data/src/header.h @@ -133,3 +133,14 @@ public: private: int m_importantInt; }; + +class AnotherClass + : public A +{ +public: + int publicInt; +protected: + int protectedInt; +private: + int privateInt; +}; diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 3b76f1d3..dfc785d4 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -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 diff --git a/src/app/qt/graphics/QtGraphicsRoundedRectItem.cpp b/src/app/qt/graphics/QtGraphicsRoundedRectItem.cpp new file mode 100644 index 00000000..d093e501 --- /dev/null +++ b/src/app/qt/graphics/QtGraphicsRoundedRectItem.cpp @@ -0,0 +1,39 @@ +#include "qt/graphics/QtGraphicsRoundedRectItem.h" + +#include +#include + +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; +} diff --git a/src/app/qt/graphics/QtGraphicsRoundedRectItem.h b/src/app/qt/graphics/QtGraphicsRoundedRectItem.h new file mode 100644 index 00000000..764274b1 --- /dev/null +++ b/src/app/qt/graphics/QtGraphicsRoundedRectItem.h @@ -0,0 +1,22 @@ +#ifndef QT_GRAPHICS_ROUNDED_RECT_ITEM_H +#define QT_GRAPHICS_ROUNDED_RECT_ITEM_H + +#include + +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 diff --git a/src/app/qt/utility/QtDeviceScaledPixmap.h b/src/app/qt/utility/QtDeviceScaledPixmap.h new file mode 100644 index 00000000..bd20f101 --- /dev/null +++ b/src/app/qt/utility/QtDeviceScaledPixmap.h @@ -0,0 +1,55 @@ +#ifndef QT_DEVICE_SCALED_PIXMAP_H +#define QT_DEVICE_SCALED_PIXMAP_H + +#include +#include + +class QtDeviceScaledPixmap +{ +public: + static qreal devicePixelRatio() + { + QApplication* app = dynamic_cast(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 diff --git a/src/app/qt/view/QtGraphView.cpp b/src/app/qt/view/QtGraphView.cpp index 432ab979..05f4f1ba 100644 --- a/src/app/qt/view/QtGraphView.cpp +++ b/src/app/qt/view/QtGraphView.cpp @@ -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> newNodes; + std::list> newNodes; // create nodes (or find existing nodes for re-use) for (unsigned int i = 0; i < nodes.size(); i++) { - std::shared_ptr newNode = createNodeRecursive(view, NULL, nodes[i]); + std::shared_ptr 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 edge = createEdge(view, edges[i]); + std::shared_ptr 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>::iterator it = m_nodes.begin(); it != m_nodes.end(); it++) + for (const std::shared_ptr& node : m_nodes) { - (*it)->hideContent(); + node->hideContent(); } } else @@ -134,31 +133,40 @@ void QtGraphView::doClear() m_edges.clear(); } -std::shared_ptr QtGraphView::findNodeRecursive(const std::list>& nodes, Id tokenId) +std::shared_ptr QtGraphView::findNodeRecursive(const std::list>& nodes, Id tokenId) { - for (const std::shared_ptr& node : nodes) + for (const std::shared_ptr& node : nodes) { if (node->getTokenId() == tokenId) { return node; } - std::shared_ptr result = findNodeRecursive(node->getSubNodes(), tokenId); + std::shared_ptr result = findNodeRecursive(node->getSubNodes(), tokenId); if (result != NULL) { return result; } } - return std::shared_ptr(); + return std::shared_ptr(); } -std::shared_ptr QtGraphView::createNodeRecursive( +std::shared_ptr QtGraphView::createNodeRecursive( QGraphicsView* view, std::shared_ptr parentNode, const DummyNode& node ){ if (view != NULL) { - std::shared_ptr newNode = std::make_shared(node.data, node.accessType); + std::shared_ptr newNode; + if (node.data) + { + newNode = std::make_shared(node.data); + } + else + { + newNode = std::make_shared(node.accessType); + } + newNode->addComponent(std::make_shared(newNode)); view->scene()->addItem(newNode.get()); @@ -177,18 +185,10 @@ std::shared_ptr QtGraphView::createNodeRecursive( newNode->addComponent(std::make_shared(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(newNode)); - } - - for (unsigned int i = 0; i < node.subNodes.size(); i++) - { - std::shared_ptr subNode = createNodeRecursive(view, newNode, node.subNodes[i]); - newNode->addSubNode(subNode); - } + std::shared_ptr subNode = createNodeRecursive(view, newNode, node.subNodes[i]); + newNode->addSubNode(subNode); } return newNode; @@ -204,8 +204,8 @@ std::shared_ptr QtGraphView::createEdge(QGraphicsView* view, const { if (view != NULL) { - std::shared_ptr owner = findNodeRecursive(m_nodes, edge.ownerId); - std::shared_ptr target = findNodeRecursive(m_nodes, edge.targetId); + std::shared_ptr owner = findNodeRecursive(m_nodes, edge.ownerId); + std::shared_ptr target = findNodeRecursive(m_nodes, edge.targetId); if (owner != NULL && target != NULL) { diff --git a/src/app/qt/view/QtGraphView.h b/src/app/qt/view/QtGraphView.h index f7c62130..b7ed37b8 100644 --- a/src/app/qt/view/QtGraphView.h +++ b/src/app/qt/view/QtGraphView.h @@ -42,9 +42,9 @@ private: const std::vector& edges); void doClear(); - std::shared_ptr findNodeRecursive(const std::list>& nodes, Id tokenId); + std::shared_ptr findNodeRecursive(const std::list>& nodes, Id tokenId); - std::shared_ptr createNodeRecursive( + std::shared_ptr createNodeRecursive( QGraphicsView* view, std::shared_ptr parentNode, const DummyNode& node); std::shared_ptr createEdge(QGraphicsView* view, const DummyEdge& edge); @@ -55,6 +55,12 @@ private: > m_rebuildGraphFunctor; QtThreadedFunctor m_clearFunctor; + + std::shared_ptr m_graph; + std::vector m_activeTokenIds; + + std::list> m_nodes; + std::list> m_edges; }; #endif // QT_GRAPH_VIEW_H diff --git a/src/app/qt/view/graphElements/QtGraphEdge.cpp b/src/app/qt/view/graphElements/QtGraphEdge.cpp index 46fc2e31..fb2c8afd 100644 --- a/src/app/qt/view/graphElements/QtGraphEdge.cpp +++ b/src/app/qt/view/graphElements/QtGraphEdge.cpp @@ -36,14 +36,14 @@ QtGraphEdge::QtGraphEdge(const std::weak_ptr& 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); } diff --git a/src/app/qt/view/graphElements/QtGraphNode.cpp b/src/app/qt/view/graphElements/QtGraphNode.cpp index 2f3d1230..cc30e1ce 100644 --- a/src/app/qt/view/graphElements/QtGraphNode.cpp +++ b/src/app/qt/view/graphElements/QtGraphNode.cpp @@ -1,46 +1,50 @@ #include "qt/view/graphElements/QtGraphNode.h" -#include - +#include #include -#include #include +#include -#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 parentNode) -{ - m_parentNode = parentNode; - - std::shared_ptr parent = parentNode.lock(); - if (parent != NULL) - { - QGraphicsRectItem::setParentItem(parent.get()); - } -} - -void QtGraphNode::addComponent(const std::shared_ptr& component) -{ - m_components.push_back(component); } bool QtGraphNode::addOutEdge(const std::shared_ptr& edge) @@ -173,72 +153,6 @@ void QtGraphNode::removeOutEdge(GraphEdge* edge) } } -std::list> QtGraphNode::getSubNodes() const -{ - return m_subNodes; -} - -void QtGraphNode::addSubNode(const std::shared_ptr& node) -{ - m_subNodes.push_back(node); - - rebuildLayout(); -} - -void QtGraphNode::notifyParentMoved() -{ - notifyEdgesAfterMove(); -} - -void QtGraphNode::hideContent() -{ - for (std::shared_ptr node : m_subNodes) - { - node->hideContent(); - - if (node->getTokenId() && node->getEdgeAndActiveCountRecursive() <= 0) - { - node->hide(); - } - } - - m_contentHidden = true; - - onChildSizeChanged(); -} - -void QtGraphNode::showContent() -{ - for (std::shared_ptr 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 parentNode) +{ + m_parentNode = parentNode; + + std::shared_ptr parent = parentNode.lock(); + if (parent != NULL) + { + QGraphicsRectItem::setParentItem(parent.get()); + } +} + +void QtGraphNode::addComponent(const std::shared_ptr& component) +{ + m_components.push_back(component); +} + +std::list> QtGraphNode::getSubNodes() const +{ + return m_subNodes; +} + +void QtGraphNode::addSubNode(const std::shared_ptr& 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 node : m_subNodes) + for (std::shared_ptr node : m_subNodes) { result += node->getEdgeAndActiveCountRecursive(); } @@ -268,9 +225,24 @@ unsigned int QtGraphNode::getEdgeAndActiveCountRecursive() const return result; } +void QtGraphNode::hideContent() +{ + for (std::shared_ptr 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>::iterator it = m_outEdges.begin(); it != m_outEdges.end(); it++) + for (const std::shared_ptr& edge : m_outEdges) { - (*it)->ownerMoved(); + edge->ownerMoved(); } - std::list>::iterator it2 = m_inEdges.begin(); - while (it2 != m_inEdges.end()) + for (const std::weak_ptr& e : m_inEdges) { - std::shared_ptr edge = it2->lock(); - if (edge.get() != NULL) - { - edge->targetMoved(); - ++it2; - } - else - { - m_inEdges.erase(it2++); - } + std::shared_ptr edge = e.lock(); + if (edge) + { + edge->targetMoved(); + } } - for (std::list>::iterator it3 = m_subNodes.begin(); it3 != m_subNodes.end(); it3++) + for (const std::shared_ptr& node : m_subNodes) { - (*it3)->notifyParentMoved(); + node->notifyEdgesAfterMove(); } } -void QtGraphNode::notifyParentNodeAfterSizeChanged() +void QtGraphNode::onSizeChanged() { + rebuildLayout(); + std::shared_ptr 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& node : m_subNodes) + Vec2i newSize(m_baseSize); + newSize.y = newSize.y - m_padding.w; + + for (const std::shared_ptr& 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; } diff --git a/src/app/qt/view/graphElements/QtGraphNode.h b/src/app/qt/view/graphElements/QtGraphNode.h index 13546ebe..d35ad135 100644 --- a/src/app/qt/view/graphElements/QtGraphNode.h +++ b/src/app/qt/view/graphElements/QtGraphNode.h @@ -4,11 +4,12 @@ #include #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& edge); + virtual bool addInEdge(const std::weak_ptr& 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& component); - virtual bool addOutEdge(const std::shared_ptr& edge); - virtual bool addInEdge(const std::weak_ptr& edge); - - virtual void removeOutEdge(GraphEdge* edge); - - virtual std::list> getSubNodes() const; - virtual void addSubNode(const std::shared_ptr& 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> getSubNodes() const; + void addSubNode(const std::shared_ptr& 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> m_outEdges; std::list> m_inEdges; -private: - void rebuildLayout(); - - QGraphicsTextItem* m_text; - std::weak_ptr m_parentNode; - std::list> m_subNodes; + std::list> m_subNodes; - std::list> 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> m_components; + + bool m_isActive; + bool m_isHovering; }; #endif // QT_GRAPH_NODE_H diff --git a/src/app/qt/view/graphElements/QtGraphNodeAccess.cpp b/src/app/qt/view/graphElements/QtGraphNodeAccess.cpp new file mode 100644 index 00000000..6f6f6f23 --- /dev/null +++ b/src/app/qt/view/graphElements/QtGraphNodeAccess.cpp @@ -0,0 +1,184 @@ +#include "qt/view/graphElements/QtGraphNodeAccess.h" + +#include +#include +#include + +#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 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& 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); +} diff --git a/src/app/qt/view/graphElements/QtGraphNodeAccess.h b/src/app/qt/view/graphElements/QtGraphNodeAccess.h new file mode 100644 index 00000000..9937d18a --- /dev/null +++ b/src/app/qt/view/graphElements/QtGraphNodeAccess.h @@ -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 diff --git a/src/app/qt/view/graphElements/nodeComponents/QtGraphNodeComponentToggleButton.cpp b/src/app/qt/view/graphElements/nodeComponents/QtGraphNodeComponentToggleButton.cpp deleted file mode 100644 index b5f4d651..00000000 --- a/src/app/qt/view/graphElements/nodeComponents/QtGraphNodeComponentToggleButton.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "QtGraphNodeComponentToggleButton.h" - -#include -#include - -#include "qt/view/graphElements/QtGraphNode.h" - -QtGraphNodeComponentToggleButton::QtGraphNodeComponentToggleButton(const std::weak_ptr& graphNode) - : QtGraphNodeComponent(graphNode) -{ - this->setRect(0, 0, 10, 10); - this->setPos(0, 0); - QBrush brush(Qt::darkGray); - this->setBrush(brush); - - std::shared_ptr node = graphNode.lock(); - if(node != NULL) - { - this->setParentItem(node.get()); - } -} - -QtGraphNodeComponentToggleButton::~QtGraphNodeComponentToggleButton() -{ -} - -void QtGraphNodeComponentToggleButton::mousePressEvent(QGraphicsSceneMouseEvent* event) -{ - std::shared_ptr node = m_graphNode.lock(); - if(node != NULL) - { - if(node->contentIsHidden()) - { - node->showContent(); - } - else - { - node->hideContent(); - } - } -} diff --git a/src/app/qt/view/graphElements/nodeComponents/QtGraphNodeComponentToggleButton.h b/src/app/qt/view/graphElements/nodeComponents/QtGraphNodeComponentToggleButton.h deleted file mode 100644 index 234fba9e..00000000 --- a/src/app/qt/view/graphElements/nodeComponents/QtGraphNodeComponentToggleButton.h +++ /dev/null @@ -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& graphNode); - ~QtGraphNodeComponentToggleButton(); - - void mousePressEvent(QGraphicsSceneMouseEvent* event); -}; - -#endif // QT_GRAPH_NODE_COMPONENT_TOGGLE_BUTTON_H diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index e5f0eacd..afd59ebd 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -36,7 +36,7 @@ GraphView* GraphController::getView() void GraphController::createDummyGraphForTokenIds(const std::vector& tokenIds) { - const GraphLayouter::LayoutFunction layoutFunction = &GraphLayouter::layoutSimpleRing; + const GraphLayouter::LayoutFunction layoutFunction = &GraphLayouter::layoutSimpleRaster; GraphView* view = getView(); if (!view) diff --git a/src/lib/component/view/GraphView.h b/src/lib/component/view/GraphView.h index 8f8aa8a4..4bd893e2 100644 --- a/src/lib/component/view/GraphView.h +++ b/src/lib/component/view/GraphView.h @@ -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& edges) = 0; virtual void clear() = 0; - -protected: - std::shared_ptr m_graph; - std::vector m_activeTokenIds; - - std::list > m_nodes; - std::list > m_edges; }; #endif // GRAPH_VIEW_H \ No newline at end of file diff --git a/src/lib/component/view/graphElements/GraphNode.h b/src/lib/component/view/graphElements/GraphNode.h index dba704d7..c9fce680 100644 --- a/src/lib/component/view/graphElements/GraphNode.h +++ b/src/lib/component/view/graphElements/GraphNode.h @@ -34,25 +34,9 @@ public: virtual void removeOutEdge(GraphEdge* edge) = 0; - virtual std::list > getSubNodes() const = 0; - virtual void addSubNode(const std::shared_ptr& 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; };