diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index 411f7a10..1964bbc1 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -1846,11 +1846,11 @@ void GraphController::layoutNestingRecursive(DummyNode* node) const break; case GroupLayout::BUCKET: - if (node->hasActiveSubNode()) + if (node->hasActiveSubNode() || !m_activeNodeIds.size() /* aggregations */) { BucketLayouter grid(viewSize); grid.createBuckets(node->subNodes, m_dummyEdges); - grid.layoutBuckets(true); + grid.layoutBuckets(m_activeNodeIds.size()); node->subNodes = grid.getSortedNodes(); } else diff --git a/src/lib/component/controller/helper/BucketLayouter.cpp b/src/lib/component/controller/helper/BucketLayouter.cpp index 02262c72..4d2ce9d0 100644 --- a/src/lib/component/controller/helper/BucketLayouter.cpp +++ b/src/lib/component/controller/helper/BucketLayouter.cpp @@ -55,7 +55,7 @@ const DummyNode::BundledNodesSet& Bucket::getNodes() const return m_nodes; } -void Bucket::preLayout(Vec2i viewSize, bool addVerticalOffset) +void Bucket::preLayout(Vec2i viewSize, bool addVerticalSplit, bool forceVerticalSplit) { int cols = (viewSize.y > 0 ? (m_height / viewSize.y) : 0) + 1; @@ -111,7 +111,8 @@ void Bucket::preLayout(Vec2i viewSize, bool addVerticalOffset) } } - if (!addVerticalOffset || nodesInCol.size() < 2) + addVerticalSplit &= nodesInCol.size() > 1 || forceVerticalSplit; + if (!addVerticalSplit) { return; } @@ -296,7 +297,7 @@ void BucketLayouter::createBuckets( } } -void BucketLayouter::layoutBuckets(bool addVerticalOffset) +void BucketLayouter::layoutBuckets(bool addVerticalSplit) { std::map widths; std::map heights; @@ -307,7 +308,7 @@ void BucketLayouter::layoutBuckets(bool addVerticalOffset) { Bucket* bucket = &m_buckets[j][i]; - bucket->preLayout(m_viewSize, i != 0); + bucket->preLayout(m_viewSize, i != 0, addVerticalSplit); std::map::iterator wt = widths.find(i); if (wt == widths.end() || wt->second < bucket->getWidth()) @@ -345,11 +346,6 @@ void BucketLayouter::layoutBuckets(bool addVerticalOffset) Bucket* midBucket = &m_buckets[0][0]; yOff = (heights[0] - midBucket->getHeight()) / 2 * -j; } - // move every second bucket in a row slighly lower to avoid edges over nodes - else if (addVerticalOffset && std::abs(i) % 2 == 1) - { - yOff = GraphViewStyle::toGridGap(10); - } // align buckets left and right of center to be vertically centered next to the active node else if (j == 0 && i != 0 && verticalOffset != 0) { diff --git a/src/lib/component/controller/helper/BucketLayouter.h b/src/lib/component/controller/helper/BucketLayouter.h index b1ad7538..47b1351c 100644 --- a/src/lib/component/controller/helper/BucketLayouter.h +++ b/src/lib/component/controller/helper/BucketLayouter.h @@ -23,7 +23,7 @@ public: void addNode(std::shared_ptr node); const DummyNode::BundledNodesSet& getNodes() const; - void preLayout(Vec2i viewSize, bool addVerticalOffset); + void preLayout(Vec2i viewSize, bool addVerticalSplit, bool forceVerticalSplit); void layout(int x, int y, int width, int height); int i; @@ -44,7 +44,7 @@ public: void createBuckets( std::vector>& nodes, const std::vector>& edges); - void layoutBuckets(bool addVerticalOffset); + void layoutBuckets(bool addVerticalSplit); std::vector> getSortedNodes(); diff --git a/src/lib/component/view/GraphViewStyle.cpp b/src/lib/component/view/GraphViewStyle.cpp index 6e8d6440..484596a9 100644 --- a/src/lib/component/view/GraphViewStyle.cpp +++ b/src/lib/component/view/GraphViewStyle.cpp @@ -347,7 +347,7 @@ GraphViewStyle::NodeMargins GraphViewStyle::getMarginsOfGroupNode(GroupType type margins.spacingA = (hasName ? 14 : 0); - margins.left = margins.right = 20; + margins.left = margins.right = 26; margins.top = (hasName ? 12 : 20); margins.bottom = 20; diff --git a/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp b/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp index 8e1a7544..5db1db31 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp @@ -100,18 +100,21 @@ void QtGraphEdge::updateLine() Vec4i ownerParentRect; Vec4i targetParentRect; + const QtGraphNode* ownerParent = owner->getLastParent(); + const QtGraphNode* targetParent = target->getLastParent(); + const QtGraphNode* ownerNonGroupParent = owner->getLastNonGroupParent(); const QtGraphNode* targetNonGroupParent = target->getLastNonGroupParent(); - if (owner->getLastParent() == target->getLastParent() && owner->getLastParent()->isGroupNode()) + if (ownerParent == targetParent && ownerParent->isGroupNode()) { ownerParentRect = ownerNonGroupParent->getBoundingRect(); targetParentRect = targetNonGroupParent->getBoundingRect(); } else { - ownerParentRect = owner->getLastParent()->getBoundingRect(); - targetParentRect = target->getLastParent()->getBoundingRect(); + ownerParentRect = ownerParent->getBoundingRect(); + targetParentRect = targetParent->getBoundingRect(); } if (m_useBezier) @@ -168,10 +171,22 @@ void QtGraphEdge::updateLine() } else { - const Vec2i& ownerColumnSize = m_owner->getLastParent()->getColumnSize(); - const Vec2i& targetColumnSize = m_target->getLastParent()->getColumnSize(); - ownerParentRect.z = std::max(ownerParentRect.x + ownerColumnSize.x, ownerParentRect.z()); - targetParentRect.z = std::max(targetParentRect.x + targetColumnSize.x, targetParentRect.z()); + const Vec2i* ownerColumnSize; + const Vec2i* targetColumnSize; + + if (ownerParent != targetParent) + { + ownerColumnSize = &ownerParent->getColumnSize(); + targetColumnSize = &targetParent->getColumnSize(); + } + else + { + ownerColumnSize = &ownerNonGroupParent->getColumnSize(); + targetColumnSize = &targetNonGroupParent->getColumnSize(); + } + + ownerParentRect.z = std::max(ownerParentRect.x + ownerColumnSize->x, ownerParentRect.z()); + targetParentRect.z = std::max(targetParentRect.x + targetColumnSize->x, targetParentRect.z()); if (!m_child) { @@ -202,7 +217,7 @@ void QtGraphEdge::updateLine() } if (type == Edge::EDGE_INHERITANCE || (type == Edge::EDGE_TEMPLATE_SPECIALIZATION && - owner == owner->getLastNonGroupParent() && target == target->getLastNonGroupParent())) + owner == ownerNonGroupParent && target == targetNonGroupParent)) { child->setRoute(QtLineItemBase::ROUTE_VERTICAL); @@ -212,7 +227,7 @@ void QtGraphEdge::updateLine() } } else if (type != Edge::EDGE_AGGREGATION || - owner != owner->getLastNonGroupParent() || target != target->getLastNonGroupParent()) + owner != ownerNonGroupParent || target != targetNonGroupParent) { child->setRoute(QtLineItemBase::ROUTE_HORIZONTAL); } diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp b/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp index 6259cd9c..1e53d41e 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp @@ -12,6 +12,7 @@ #include "qt/view/graphElements/nodeComponents/QtGraphNodeComponent.h" #include "qt/view/graphElements/QtGraphEdge.h" #include "utility/messaging/type/MessageGraphNodeHide.h" +#include "utility/messaging/type/MessageGraphNodeMove.h" #include "utility/ResourcePaths.h" #include "utility/utilityString.h" @@ -374,6 +375,11 @@ void QtGraphNode::addSubNode(QtGraphNode* node) void QtGraphNode::moved(const Vec2i& oldPosition) { setPosition(GraphViewStyle::alignOnRaster(getPosition())); + + if (isDataNode() || isGroupNode() || isBundleNode()) + { + MessageGraphNodeMove(getTokenId(), getPosition() - oldPosition).dispatch(); + } } void QtGraphNode::onClick() diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeBundle.cpp b/src/lib_gui/qt/view/graphElements/QtGraphNodeBundle.cpp index 1884f409..c73dacdc 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeBundle.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeBundle.cpp @@ -4,7 +4,6 @@ #include #include "utility/messaging/type/MessageGraphNodeBundleSplit.h" -#include "utility/messaging/type/MessageGraphNodeMove.h" #include "component/view/GraphViewStyle.h" #include "qt/graphics/QtCountCircleItem.h" @@ -47,13 +46,6 @@ void QtGraphNodeBundle::onClick() ).dispatch(); } -void QtGraphNodeBundle::moved(const Vec2i& oldPosition) -{ - QtGraphNode::moved(oldPosition); - - MessageGraphNodeMove(m_tokenId, getPosition() - oldPosition).dispatch(); -} - void QtGraphNodeBundle::updateStyle() { GraphViewStyle::NodeStyle style; diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeBundle.h b/src/lib_gui/qt/view/graphElements/QtGraphNodeBundle.h index 76c5509a..c88097aa 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeBundle.h +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeBundle.h @@ -19,7 +19,6 @@ public: virtual Id getTokenId() const; virtual void onClick(); - virtual void moved(const Vec2i& oldPosition); virtual void updateStyle(); protected: diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp b/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp index abac6b99..9fff6af8 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp @@ -5,7 +5,6 @@ #include "utility/messaging/type/MessageDeactivateEdge.h" #include "utility/messaging/type/MessageFocusIn.h" #include "utility/messaging/type/MessageFocusOut.h" -#include "utility/messaging/type/MessageGraphNodeMove.h" #include "data/graph/token_component/TokenComponentFilePath.h" @@ -58,13 +57,6 @@ void QtGraphNodeData::onClick() MessageActivateNodes(m_data->getId()).dispatch(); } -void QtGraphNodeData::moved(const Vec2i& oldPosition) -{ - QtGraphNode::moved(oldPosition); - - MessageGraphNodeMove(m_data->getId(), getPosition() - oldPosition).dispatch(); -} - void QtGraphNodeData::updateStyle() { GraphViewStyle::NodeStyle style = GraphViewStyle::getStyleForNodeType( diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeData.h b/src/lib_gui/qt/view/graphElements/QtGraphNodeData.h index 7b30ac0b..8aa85e48 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeData.h +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeData.h @@ -22,7 +22,6 @@ public: virtual Id getTokenId() const; virtual void onClick(); - virtual void moved(const Vec2i& oldPosition); virtual void updateStyle(); protected: diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.cpp b/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.cpp index 8bac3e10..8a72ec46 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.cpp @@ -25,8 +25,6 @@ QtGraphNodeGroup::QtGraphNodeGroup( setAcceptHoverEvents(true); } - setName(name); - if (type == GroupType::FRAMELESS) { m_rect->hide(); @@ -38,6 +36,8 @@ QtGraphNodeGroup::QtGraphNodeGroup( return; } + setName(name); + m_background = new QGraphicsPolygonItem(this); m_background->setZValue(-3.f); @@ -56,6 +56,7 @@ QtGraphNodeGroup::QtGraphNodeGroup( path.lineTo(width - radius, height); path.arcTo(width - 2 * radius, height - 2 * radius, 2 * radius, 2 * radius, 270, 90); path.closeSubpath(); + m_path = path; m_background->setPolygon(path.toFillPolygon()); } @@ -104,6 +105,16 @@ void QtGraphNodeGroup::updateStyle() setStyle(style); } +QPainterPath QtGraphNodeGroup::shape() const +{ + if (m_path.isEmpty()) + { + m_path.addRect(boundingRect()); + } + + return m_path; +} + void QtGraphNodeGroup::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) { if (m_type == GroupType::FILE || m_type == GroupType::NAMESPACE) diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.h b/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.h index 356fe03e..a7570ce1 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.h +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.h @@ -5,6 +5,7 @@ #include "qt/view/graphElements/QtGraphNode.h" class QGraphicsPolygonItem; +class QPainterPath; class QtGraphNodeGroup : public QtGraphNode @@ -21,6 +22,8 @@ public: virtual void onClick(); virtual void updateStyle(); + virtual QPainterPath shape() const; + protected: virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* event); @@ -31,6 +34,7 @@ private: const bool m_interactive; QGraphicsPolygonItem* m_background = nullptr; + mutable QPainterPath m_path; }; #endif // QT_GRAPH_NODE_GROUP_H