diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index f57347c3..a50a17fd 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -127,7 +127,6 @@ add_files( data/graph/token_component/TokenComponentAggregation.h data/graph/token_component/TokenComponentConst.cpp data/graph/token_component/TokenComponentConst.h - data/graph/token_component/TokenComponentEdgeIds.h data/graph/token_component/TokenComponentFilePath.cpp data/graph/token_component/TokenComponentFilePath.h data/graph/token_component/TokenComponentInheritanceChain.h diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index d26cbdf9..0ad77694 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -17,7 +17,6 @@ #include "component/view/GraphViewStyle.h" #include "data/access/StorageAccess.h" #include "data/graph/token_component/TokenComponentAccess.h" -#include "data/graph/token_component/TokenComponentEdgeIds.h" #include "data/graph/Graph.h" #include "data/parser/AccessKind.h" #include "settings/ApplicationSettings.h" @@ -245,18 +244,44 @@ void GraphController::handleMessage(MessageGraphNodeBundleSplit* message) for (size_t i = 0; i < m_dummyNodes.size(); i++) { DummyNode* node = m_dummyNodes[i].get(); - if (node->isBundleNode() && node->tokenId == message->bundleId) + if ((node->isBundleNode() || node->isGroupNode()) && node->tokenId == message->bundleId) { + std::vector> nodes; + if (node->isBundleNode()) + { + nodes = std::vector>(node->bundledNodes.begin(), node->bundledNodes.end()); + } + else if (node->isGroupNode()) + { + nodes = node->subNodes; + std::set hiddenEdgeIds(node->hiddenEdgeIds.begin(), node->hiddenEdgeIds.end()); + + for (std::shared_ptr& edge : m_dummyEdges) + { + if (edge->ownerId == node->tokenId || edge->targetId == node->tokenId || + (edge->data && hiddenEdgeIds.find(edge->data->getId()) != hiddenEdgeIds.end())) + { + edge->hidden = false; + } + } + + m_topLevelAncestorIds.erase(node->tokenId); + for (const std::shared_ptr& subNode : nodes) + { + m_topLevelAncestorIds[subNode->tokenId] = subNode->tokenId; + } + } + if (message->removeOtherNodes) { - std::vector> nodes(node->bundledNodes.begin(), node->bundledNodes.end()); m_dummyNodes = nodes; } else { - m_dummyNodes.insert(m_dummyNodes.begin() + i + 1, node->bundledNodes.begin(), node->bundledNodes.end()); + m_dummyNodes.insert(m_dummyNodes.begin() + i + 1, nodes.begin(), nodes.end()); m_dummyNodes.erase(m_dummyNodes.begin() + i); } + break; } } @@ -271,22 +296,7 @@ void GraphController::handleMessage(MessageGraphNodeBundleSplit* message) } } - std::vector tokenIds = utility::concat(m_activeNodeIds, m_activeEdgeIds); - setActiveAndVisibility(tokenIds); - - if (message->layoutToList) - { - addCharacterIndex(); - layoutNesting(); - layoutList(); - } - else - { - layoutNesting(); - layoutGraph(); - } - - buildGraph(message, false, true, message->layoutToList); + relayoutGraph(message, false, true, message->layoutToList, message->layoutToList); } void GraphController::handleMessage(MessageGraphNodeExpand* message) @@ -423,31 +433,7 @@ void GraphController::handleMessage(MessageGraphNodeHide* message) if (node || edge) { - bool showsTrail = m_graph->getTrailMode() != Graph::TRAIL_NONE; - - setVisibility(setActive(utility::concat(m_activeNodeIds, m_activeEdgeIds), showsTrail)); - - if (hasCharacterIndex()) - { - addCharacterIndex(); - layoutNesting(); - layoutList(); - } - else - { - layoutNesting(); - - if (showsTrail) - { - layoutTrail(m_graph->getTrailMode() == Graph::TRAIL_HORIZONTAL, m_graph->hasTrailOrigin()); - } - else - { - layoutGraph(); - } - } - - buildGraph(message, false, true, false); + relayoutGraph(message, false, true, false, false); } } @@ -764,6 +750,10 @@ bool GraphController::setActive(const std::vector& activeTokenIds, bool show from->connected = true; to->connected = true; } + else + { + edge->visible = false; + } } return noActive; @@ -1458,6 +1448,7 @@ void GraphController::groupTrailNodes(NodeType::GroupType groupType) // Use token Id of first node and make first 2 bits 1 groupNode->tokenId = ~(~size_t(0) >> 2) + node.nodeId; + m_topLevelAncestorIds[groupNode->tokenId] = groupNode->tokenId; std::shared_ptr targetEdge = std::make_shared(); targetEdge->ownerId = groupNode->tokenId; @@ -1465,8 +1456,7 @@ void GraphController::groupTrailNodes(NodeType::GroupType groupType) std::shared_ptr originEdge = std::make_shared(); originEdge->targetId = groupNode->tokenId; - std::vector targetEdgeIds; - std::vector originEdgeIds; + std::vector hiddenEdgeIds; for (TrailNode& node : group) { @@ -1483,48 +1473,48 @@ void GraphController::groupTrailNodes(NodeType::GroupType groupType) for (DummyEdge* edge : node.targetEdges) { - targetEdge->visible = true; - targetEdge->targetId = edge->targetId; - targetEdge->data = edge->data; + if (!targetEdge->visible) + { + targetEdge->visible = true; + targetEdge->targetId = edge->targetId; + targetEdge->data = edge->data; + } + edge->visible = false; edge->hidden = true; if (edge->data) { - targetEdgeIds.push_back(edge->data->getId()); + groupNode->hiddenEdgeIds.push_back(edge->data->getId()); } } for (DummyEdge* edge : node.originEdges) { - originEdge->visible = true; - originEdge->ownerId = edge->ownerId; - originEdge->data = edge->data; + if (!originEdge->visible) + { + originEdge->visible = true; + originEdge->ownerId = edge->ownerId; + originEdge->data = edge->data; + } + edge->visible = false; edge->hidden = true; if (edge->data) { - originEdgeIds.push_back(edge->data->getId()); + groupNode->hiddenEdgeIds.push_back(edge->data->getId()); } } } if (targetEdge->visible) { - if (targetEdge->data && targetEdgeIds.size()) - { - const_cast(targetEdge->data)->addComponent(std::make_shared(targetEdgeIds)); - } m_dummyEdges.push_back(targetEdge); } if (originEdge->visible) { - if (originEdge->data && originEdgeIds.size()) - { - const_cast(targetEdge->data)->addComponent(std::make_shared(originEdgeIds)); - } m_dummyEdges.push_back(originEdge); } @@ -1890,6 +1880,36 @@ DummyEdge* GraphController::getDummyGraphEdgeById(Id tokenId) const return nullptr; } +void GraphController::relayoutGraph( + MessageBase* message, bool centerActiveNode, bool animatedTransition, bool scrollToTop, bool withCharacterIndex) +{ + bool showsTrail = m_graph->getTrailMode() != Graph::TRAIL_NONE; + + setVisibility(setActive(utility::concat(m_activeNodeIds, m_activeEdgeIds), showsTrail)); + + if (hasCharacterIndex() || withCharacterIndex) + { + addCharacterIndex(); + layoutNesting(); + layoutList(); + } + else + { + layoutNesting(); + + if (showsTrail) + { + layoutTrail(m_graph->getTrailMode() == Graph::TRAIL_HORIZONTAL, m_graph->hasTrailOrigin()); + } + else + { + layoutGraph(); + } + } + + buildGraph(message, centerActiveNode, animatedTransition, scrollToTop); +} + void GraphController::buildGraph( MessageBase* message, bool centerActiveNode, bool animatedTransition, bool scrollToTop) { diff --git a/src/lib/component/controller/GraphController.h b/src/lib/component/controller/GraphController.h index 4c668d69..820b8a7c 100644 --- a/src/lib/component/controller/GraphController.h +++ b/src/lib/component/controller/GraphController.h @@ -125,6 +125,8 @@ private: std::shared_ptr getDummyGraphNodeById(Id tokenId) const; DummyEdge* getDummyGraphEdgeById(Id tokenId) const; + void relayoutGraph( + MessageBase* message, bool centerActiveNode, bool animatedTransition, bool scrollToTop, bool withCharacterIndex); void buildGraph(MessageBase* message, bool centerActiveNode, bool animatedTransition, bool scrollToTop); void forEachDummyNodeRecursive(std::function func); diff --git a/src/lib/component/controller/helper/DummyNode.h b/src/lib/component/controller/helper/DummyNode.h index 660fe902..8e5cc558 100644 --- a/src/lib/component/controller/helper/DummyNode.h +++ b/src/lib/component/controller/helper/DummyNode.h @@ -412,6 +412,7 @@ public: // GroupNode NodeType::GroupType groupType; + std::vector hiddenEdgeIds; }; #endif // DUMMY_NODE_H diff --git a/src/lib/component/controller/helper/TrailLayouter.cpp b/src/lib/component/controller/helper/TrailLayouter.cpp index e69e0717..13feca05 100644 --- a/src/lib/component/controller/helper/TrailLayouter.cpp +++ b/src/lib/component/controller/helper/TrailLayouter.cpp @@ -44,14 +44,20 @@ void TrailLayouter::buildGraph( { for (const std::shared_ptr& dummyNode : dummyNodes) { - addNode(dummyNode); + if (dummyNode->visible) + { + addNode(dummyNode); + } } for (const std::shared_ptr& dummyEdge : dummyEdges) { dummyEdge->path.clear(); - addEdge(dummyEdge, topLevelAncestorIds); + if (dummyEdge->visible) + { + addEdge(dummyEdge, topLevelAncestorIds); + } } } diff --git a/src/lib/data/graph/token_component/TokenComponentEdgeIds.h b/src/lib/data/graph/token_component/TokenComponentEdgeIds.h deleted file mode 100644 index 79388261..00000000 --- a/src/lib/data/graph/token_component/TokenComponentEdgeIds.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef TOKEN_COMPONENT_EDGE_IDS_H -#define TOKEN_COMPONENT_EDGE_IDS_H - -#include "data/graph/token_component/TokenComponent.h" - -class TokenComponentEdgeIds - : public TokenComponent -{ -public: - TokenComponentEdgeIds(const std::vector& edgeIds) - : edgeIds(edgeIds) - { - } - - virtual std::shared_ptr copy() const - { - return std::make_shared(*this); - } - - const std::vector edgeIds; -}; - -#endif // TOKEN_COMPONENT_EDGE_IDS_H diff --git a/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp b/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp index 83dbacc0..63c72df4 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp @@ -6,7 +6,6 @@ #include "component/view/GraphViewStyle.h" #include "data/graph/Edge.h" #include "data/graph/token_component/TokenComponentAggregation.h" -#include "data/graph/token_component/TokenComponentEdgeIds.h" #include "data/graph/token_component/TokenComponentInheritanceChain.h" #include "qt/graphics/QtLineItemAngled.h" #include "qt/graphics/QtLineItemBezier.h" @@ -250,24 +249,23 @@ void QtGraphEdge::setIsFocused(bool isFocused) void QtGraphEdge::onClick() { - if (isTrailEdge()) - { - TokenComponentEdgeIds* componentEdgeIds = getData()->getComponent(); - std::vector ids = { getData()->getId() }; + Edge::EdgeType type = (getData() ? getData()->getType() : Edge::EDGE_AGGREGATION); + if (!getData() || m_owner->isGroupNode() || m_target->isGroupNode()) + { + QtGraphNode* node = + ((m_direction == TokenComponentAggregation::DIRECTION_BACKWARD) == (type != Edge::EDGE_INHERITANCE)) + ? m_owner : m_target; + MessageGraphNodeBundleSplit(node->getTokenId()).dispatch(); + } + else if (isTrailEdge()) + { MessageActivateTrailEdge( - componentEdgeIds ? componentEdgeIds->edgeIds : ids, + { getData()->getId() }, getData()->getType(), getData()->getFrom()->getNameHierarchy(), getData()->getTo()->getNameHierarchy() ).dispatch(); - return; - } - - if (!getData()) - { - QtGraphNode* node = (m_direction == TokenComponentAggregation::DIRECTION_BACKWARD ? m_owner : m_target); - MessageGraphNodeBundleSplit(node->getTokenId()).dispatch(); } else { diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.cpp b/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.cpp index b89e68d8..442dc00b 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.cpp @@ -4,12 +4,16 @@ #include #include +#include "utility/messaging/type/MessageGraphNodeBundleSplit.h" + #include "qt/graphics/QtRoundedRectItem.h" QtGraphNodeGroup::QtGraphNodeGroup(Id tokenId, const std::wstring& name, NodeType::GroupType type) : m_tokenId(tokenId) , m_type(type) { + setAcceptHoverEvents(true); + setName(name); setZValue(-10.0f); m_rect->setZValue(-10.0f); @@ -60,6 +64,11 @@ Id QtGraphNodeGroup::getTokenId() const return m_tokenId; } +void QtGraphNodeGroup::onClick() +{ + MessageGraphNodeBundleSplit(m_tokenId).dispatch(); +} + void QtGraphNodeGroup::updateStyle() { GraphViewStyle::NodeStyle style = GraphViewStyle::getStyleOfGroupNode(m_type, false); diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.h b/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.h index b0765a04..477a1af1 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.h +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeGroup.h @@ -19,6 +19,7 @@ public: virtual bool isGroupNode() const; virtual Id getTokenId() const; + virtual void onClick(); virtual void updateStyle(); private: