diff --git a/bin/app/data/gui/graph_view/graph_view.css b/bin/app/data/gui/graph_view/graph_view.css index 7cb5bf64..0ecfd046 100644 --- a/bin/app/data/gui/graph_view/graph_view.css +++ b/bin/app/data/gui/graph_view/graph_view.css @@ -101,3 +101,8 @@ QPushButton:pressed { max-height: 26px; padding-right: 2px; } + +#legend_button +{ + border-radius: 9px; +} diff --git a/bin/app/data/gui/graph_view/images/legend.png b/bin/app/data/gui/graph_view/images/legend.png new file mode 100644 index 00000000..98937e44 Binary files /dev/null and b/bin/app/data/gui/graph_view/images/legend.png differ diff --git a/bin/app/user/projects/tutorial/src/graph_tutorial_1.h b/bin/app/user/projects/tutorial/src/graph_tutorial_1.h index 950a59f1..3fb30756 100644 --- a/bin/app/user/projects/tutorial/src/graph_tutorial_1.h +++ b/bin/app/user/projects/tutorial/src/graph_tutorial_1.h @@ -12,11 +12,13 @@ // code. It displays the structure of your project where all named symbols are // nodes and all relations are edges. Like the code view it shows only the // currently active symbol and all the incoming and outgoing dependencies. +// If you want to see which node and edge types exist, then click the '?'-icon in the +// lower right corner of the graph view to show the graph legend. // // 2 - HOW DO I NAVIGATE THE GRAPH -// You can activate a new symbol by left-clicking on the node you are -// interested in. For example: to find out where the function -// "where_am_i_called()" is called get over to the graph and click that +// You can activate a new symbol by left-clicking on the node you are +// interested in. For example: to find out where the function +// "where_am_i_called()" is called get over to the graph and click that // function's node. // //------------------------------------------------------------------------------ diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 68f3408f..3d946350 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -206,6 +206,13 @@ void Application::handleMessage(MessageEnteredLicense* message) m_licenseType = message->type; updateTitle(); + loadSettings(); + + if (m_hasGUI) + { + m_mainView->refreshView(); + m_componentManager->refreshViews(); + } } void Application::handleMessage(MessageIndexingFinished* message) diff --git a/src/lib/component/controller/ActivationController.cpp b/src/lib/component/controller/ActivationController.cpp index 30e05d4f..fa6cc9e8 100644 --- a/src/lib/component/controller/ActivationController.cpp +++ b/src/lib/component/controller/ActivationController.cpp @@ -3,6 +3,7 @@ #include "data/access/StorageAccess.h" #include "settings/ApplicationSettings.h" +#include "utility/messaging/type/activation/MessageActivateLegend.h" #include "utility/messaging/type/error/MessageErrorsAll.h" #include "utility/messaging/type/MessageActivateAll.h" #include "utility/messaging/type/MessageActivateTokens.h" @@ -149,6 +150,12 @@ void ActivationController::handleMessage(MessageSearch* message) MessageErrorsAll().dispatch(); return; } + + case SearchMatch::COMMAND_LEGEND: + { + MessageActivateLegend().dispatch(); + return; + } } } diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 6c1b66d0..289220f8 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -152,6 +152,11 @@ void CodeController::handleMessage(MessageActivateFullTextSearch* message) showCodeSnippets(getSnippetsForCollection(m_collection), params); } +void CodeController::handleMessage(MessageActivateLegend* message) +{ + clear(); +} + void CodeController::handleMessage(MessageActivateLocalSymbols* message) { CodeView* view = getView(); diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index e0edc284..d9057204 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -6,6 +6,7 @@ #include "utility/file/FilePath.h" #include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/activation/MessageActivateLegend.h" #include "utility/messaging/type/code/MessageCodeShowDefinition.h" #include "utility/messaging/type/error/MessageActivateErrors.h" #include "utility/messaging/type/error/MessageErrorCountClear.h" @@ -39,6 +40,7 @@ class CodeController , public MessageListener , public MessageListener , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -64,6 +66,7 @@ private: virtual void handleMessage(MessageActivateAll* message); virtual void handleMessage(MessageActivateErrors* message); virtual void handleMessage(MessageActivateFullTextSearch* message); + virtual void handleMessage(MessageActivateLegend* message); virtual void handleMessage(MessageActivateLocalSymbols* message); virtual void handleMessage(MessageActivateTokens* message); virtual void handleMessage(MessageActivateTrailEdge* message); diff --git a/src/lib/component/controller/GraphController.cpp b/src/lib/component/controller/GraphController.cpp index 3a7b5c53..38952719 100644 --- a/src/lib/component/controller/GraphController.cpp +++ b/src/lib/component/controller/GraphController.cpp @@ -17,6 +17,7 @@ #include "component/view/GraphViewStyle.h" #include "data/access/StorageAccess.h" #include "data/graph/token_component/TokenComponentAccess.h" +#include "data/graph/token_component/TokenComponentFilePath.h" #include "data/graph/Graph.h" #include "data/parser/AccessKind.h" #include "settings/ApplicationSettings.h" @@ -61,7 +62,9 @@ void GraphController::handleMessage(MessageActivateAll* message) layoutGraph(); } - buildGraph(message, false, true, message->acceptedNodeTypes != NodeTypeSet::all()); + GraphView::GraphParams params; + params.scrollToTop = message->acceptedNodeTypes != NodeTypeSet::all(); + buildGraph(message, params); } void GraphController::handleMessage(MessageActivateErrors* message) @@ -74,6 +77,21 @@ void GraphController::handleMessage(MessageActivateFullTextSearch* message) clear(); } +void GraphController::handleMessage(MessageActivateLegend* message) +{ + clear(); + + createLegendGraph(); + + layoutNesting(); + + m_showsLegend = true; + + GraphView::GraphParams params; + params.scrollToTop = true; + buildGraph(message, params); +} + void GraphController::handleMessage(MessageActivateTokens* message) { TRACE("graph activate"); @@ -168,7 +186,10 @@ void GraphController::handleMessage(MessageActivateTokens* message) assignBundleIds(); } - buildGraph(message, !isNamespace, true, isNamespace); + GraphView::GraphParams params; + params.centerActiveNode = !isNamespace; + params.scrollToTop = isNamespace; + buildGraph(message, params); } void GraphController::handleMessage(MessageActivateTrail* message) @@ -241,7 +262,9 @@ void GraphController::handleMessage(MessageActivateTrail* message) MessageStatus(L"Displaying depth graph", false, true).dispatch(); - buildGraph(message, message->isLast(), true, false); + GraphView::GraphParams params; + params.centerActiveNode = message->isLast(); + buildGraph(message, params); } void GraphController::handleMessage(MessageActivateTrailEdge* message) @@ -253,7 +276,10 @@ void GraphController::handleMessage(MessageActivateTrailEdge* message) void GraphController::handleMessage(MessageFlushUpdates* message) { - buildGraph(message, true, !message->keepContent(), false); + GraphView::GraphParams params; + params.centerActiveNode = true; + params.animatedTransition = !message->keepContent(); + buildGraph(message, params); } void GraphController::handleMessage(MessageScrollGraph* message) @@ -344,7 +370,9 @@ void GraphController::handleMessage(MessageGraphNodeBundleSplit* message) } } - relayoutGraph(message, false, true, message->layoutToList, message->layoutToList, name); + GraphView::GraphParams params; + params.scrollToTop = message->layoutToList; + relayoutGraph(message, params, message->layoutToList, name); } void GraphController::handleMessage(MessageGraphNodeExpand* message) @@ -436,7 +464,7 @@ void GraphController::handleMessage(MessageGraphNodeExpand* message) layoutNesting(); layoutGraph(); - buildGraph(message, false, true, false); + buildGraph(message, GraphView::GraphParams()); } } @@ -479,7 +507,7 @@ void GraphController::handleMessage(MessageGraphNodeHide* message) if (node || edge) { - relayoutGraph(message, false, true, false, false, L""); + relayoutGraph(message, GraphView::GraphParams(), false, L""); } } @@ -492,7 +520,7 @@ void GraphController::handleMessage(MessageGraphNodeMove* message) if (message->isReplayed()) { - buildGraph(message, false, true, false); + buildGraph(message, GraphView::GraphParams()); } else { @@ -510,7 +538,10 @@ void GraphController::handleMessage(MessageShowReference* message) m_activeEdgeIds = std::vector(1, message->tokenId); setActiveAndVisibility(utility::concat(m_activeNodeIds, m_activeEdgeIds)); - buildGraph(message, false, false, false); + + GraphView::GraphParams params; + params.animatedTransition = false; + buildGraph(message, params); } GraphView* GraphController::getView() const @@ -531,6 +562,7 @@ void GraphController::clear() m_graph.reset(); m_useBezierEdges = false; + m_showsLegend = false; getView()->clear(); } @@ -1831,7 +1863,7 @@ void GraphController::layoutNestingRecursive(DummyNode* node) const } else if (node->isTextNode()) { - margins = GraphViewStyle::getMarginsOfTextNode(); + margins = GraphViewStyle::getMarginsOfTextNode(node->fontSizeDiff); } else if (node->isGroupNode()) { @@ -1855,7 +1887,7 @@ void GraphController::layoutNestingRecursive(DummyNode* node) const addExpandToggleNode(node); } } - else if (node->isBundleNode()) + else if (node->isBundleNode() || node->isTextNode()) { width = margins.charWidth * node->name.size(); } @@ -2153,8 +2185,7 @@ DummyEdge* GraphController::getDummyGraphEdgeById(Id tokenId) const } void GraphController::relayoutGraph( - MessageBase* message, bool centerActiveNode, bool animatedTransition, bool scrollToTop, bool withCharacterIndex, - const std::wstring& groupName) + MessageBase* message, GraphView::GraphParams params, bool withCharacterIndex, const std::wstring& groupName) { bool showsTrail = m_graph->getTrailMode() != Graph::TRAIL_NONE; @@ -2197,20 +2228,17 @@ void GraphController::relayoutGraph( } } - buildGraph(message, centerActiveNode, animatedTransition, scrollToTop); + buildGraph(message, params); } void GraphController::buildGraph( - MessageBase* message, bool centerActiveNode, bool animatedTransition, bool scrollToTop) + MessageBase* message, GraphView::GraphParams params) { if (!message->isReplayed()) { - GraphView::GraphParams params; - params.centerActiveNode = centerActiveNode; - params.animatedTransition = animatedTransition; - params.scrollToTop = scrollToTop; - params.isIndexedList = scrollToTop; + params.isIndexedList = params.scrollToTop; params.bezierEdges = m_useBezierEdges; + params.disableInteraction = m_showsLegend; getView()->rebuildGraph(m_graph, m_dummyNodes, m_dummyEdges, params); } @@ -2231,3 +2259,332 @@ void GraphController::forEachDummyEdge(std::function func) func(edge.get()); } } + +void GraphController::createLegendGraph() +{ + Id id = ~Id(0) >> 1; + std::map nodePositions; + std::shared_ptr graph = std::make_shared(); + + auto addText = [this](std::wstring text, int fontSizeDiff, Vec2i position) + { + std::shared_ptr node = std::make_shared(DummyNode::DUMMY_TEXT); + node->name = text; + node->visible = true; + node->fontSizeDiff = fontSizeDiff; + node->position = position; + m_dummyNodes.push_back(node); + return node; + }; + + auto addNode = [&id, &graph, &nodePositions]( + NodeType::Type type, const std::wstring& name, Vec2i position, DefinitionKind defKind = DEFINITION_EXPLICIT) + { + nodePositions.emplace(++id, position); + return graph->createNode(id, type, NameHierarchy(name, NAME_DELIMITER_UNKNOWN), defKind); + }; + + auto addEdge = [&id, &graph](Edge::EdgeType type, Node* from, Node* to) + { + return graph->createEdge(++id, type, from, to); + }; + + auto addMember = [&id, &graph](Node* from, Node* to, AccessKind access = ACCESS_NONE) + { + if (access != ACCESS_NONE) + { + to->addComponent(std::make_shared(access)); + } + return graph->createEdge(++id, Edge::EDGE_MEMBER, from, to); + }; + + addText(L"Legend", 6, Vec2i(0, 0)); + + size_t y = 50; + size_t x = 0; + + // Layout + { + addText(L"Layout", 3, Vec2i(x, y)); + + x = 50; + y = 40; + + Node* base = addNode(NodeType::NODE_CLASS, L"Base Class", Vec2i(x + 220, y + 50)); + Node* main = addNode(NodeType::NODE_CLASS, L"Class", Vec2i(x + 200, y + 130)); + Node* derived = addNode(NodeType::NODE_CLASS, L"Derived Class", Vec2i(x + 210, y + 380)); + Node* user = addNode(NodeType::NODE_TYPE, L"Referencing Type", Vec2i(x, y + 220)); + Node* usee = addNode(NodeType::NODE_TYPE, L"Referenced Type", Vec2i(x + 400, y + 220)); + + addEdge(Edge::EDGE_INHERITANCE, main, base); + addEdge(Edge::EDGE_INHERITANCE, derived, main); + + { + Edge* edge = addEdge(Edge::EDGE_AGGREGATION, user, main); + std::shared_ptr aggregationComp = std::make_shared(); + for (size_t i = 0; i < 10; i++) + { + aggregationComp->addAggregationId(++id, true); + } + edge->addComponent(aggregationComp); + } + + { + Edge* edge = addEdge(Edge::EDGE_AGGREGATION, main, usee); + std::shared_ptr aggregationComp = std::make_shared(); + for (size_t i = 0; i < 10; i++) + { + aggregationComp->addAggregationId(++id, true); + } + edge->addComponent(aggregationComp); + } + + Node* publicMethod = addNode(NodeType::NODE_METHOD, L"public method", Vec2i()); + Node* privateField = addNode(NodeType::NODE_FIELD, L"private field", Vec2i()); + + addMember(main, publicMethod, ACCESS_PUBLIC); + addMember(main, privateField, ACCESS_PRIVATE); + + y += 480; + x += 10; + + Node* func = addNode(NodeType::NODE_FUNCTION, L"function", Vec2i(x + 220, y)); + Node* caller = addNode(NodeType::NODE_FUNCTION, L"calling function", Vec2i(x, y)); + Node* var = addNode(NodeType::NODE_GLOBAL_VARIABLE, L"accessed variable", Vec2i(x + 400, y - 50)); + Node* called = addNode(NodeType::NODE_FUNCTION, L"called function", Vec2i(x + 400, y - 10)); + Node* type = addNode(NodeType::NODE_TYPE, L"Referenced Type", Vec2i(x + 400, y + 30)); + + addEdge(Edge::EDGE_CALL, func, called); + addEdge(Edge::EDGE_CALL, caller, func); + addEdge(Edge::EDGE_USAGE, func, var); + addEdge(Edge::EDGE_TYPE_USAGE, func, type); + } + + x = 0; + y = 610; + size_t dx = 200; + size_t dy = 50; + + // Nodes + { + size_t i = 0; + addText(L"Nodes", 3, Vec2i(x, y)); + + addNode(NodeType::NODE_FILE, L"File", Vec2i(x, y + dy * ++i)); + addNode(NodeType::NODE_FILE, L"Non-Indexed File", Vec2i(x, y + dy * ++i), DEFINITION_NONE); + Node* incompleteFile = addNode(NodeType::NODE_FILE, L"Incomplete File", Vec2i(x, y + dy * ++i)); + incompleteFile->addComponent(std::make_shared(FilePath(), false)); + + addNode(NodeType::NODE_MACRO, L"Macro", Vec2i(x, y + dy * ++i)); + + addNode(NodeType::NODE_NAMESPACE, L"namespace", Vec2i(x, y + dy * ++i)); + y -= 15; + addNode(NodeType::NODE_PACKAGE, L"package", Vec2i(x, y + dy * ++i)); + y -= 15; + + addNode(NodeType::NODE_TYPE, L"Type", Vec2i(x, y + dy * ++i)); + addNode(NodeType::NODE_TYPE, L"Non-indexed Type", Vec2i(x, y + dy * ++i), DEFINITION_NONE); + + addNode(NodeType::NODE_GLOBAL_VARIABLE, L"variable", Vec2i(x, y + dy * ++i)); + y -= 15; + addNode(NodeType::NODE_GLOBAL_VARIABLE, L"non-indexed variable", Vec2i(x, y + dy * ++i), DEFINITION_NONE); + y -= 15; + + addNode(NodeType::NODE_FUNCTION, L"function", Vec2i(x, y + dy * ++i)); + y -= 15; + addNode(NodeType::NODE_FUNCTION, L"non-indexed function", Vec2i(x, y + dy * ++i), DEFINITION_NONE); + y -= 15; + + Node* typeNode = addNode(NodeType::NODE_TYPE, L"Type with Members", Vec2i(x, y + dy * ++i)); + Node* publicMethod = addNode(NodeType::NODE_METHOD, L"public method", Vec2i()); + Node* protectedMethod = addNode(NodeType::NODE_METHOD, L"protected method", Vec2i()); + Node* privateMethod = addNode(NodeType::NODE_METHOD, L"private method", Vec2i()); + Node* defaultMethod = addNode(NodeType::NODE_METHOD, L"default method", Vec2i()); + Node* publicField = addNode(NodeType::NODE_FIELD, L"public field", Vec2i()); + Node* protectedField = addNode(NodeType::NODE_FIELD, L"protected field", Vec2i()); + Node* privateField = addNode(NodeType::NODE_FIELD, L"private field", Vec2i()); + Node* defaultField = addNode(NodeType::NODE_FIELD, L"default field", Vec2i()); + + addMember(typeNode, publicMethod, ACCESS_PUBLIC); + addMember(typeNode, publicField, ACCESS_PUBLIC); + addMember(typeNode, protectedMethod, ACCESS_PROTECTED); + addMember(typeNode, protectedField, ACCESS_PROTECTED); + addMember(typeNode, privateMethod, ACCESS_PRIVATE); + addMember(typeNode, privateField, ACCESS_PRIVATE); + addMember(typeNode, defaultMethod, ACCESS_DEFAULT); + addMember(typeNode, defaultField, ACCESS_DEFAULT); + + y -= 15; + i += 9; + + addNode(NodeType::NODE_CLASS, L"Class", Vec2i(x, y + dy * ++i)); + addNode(NodeType::NODE_INTERFACE, L"Interface", Vec2i(x, y + dy * ++i)); + + addNode(NodeType::NODE_STRUCT, L"Struct", Vec2i(x, y + dy * ++i)); + addNode(NodeType::NODE_UNION, L"Union", Vec2i(x, y + dy * ++i)); + + addNode(NodeType::NODE_TYPEDEF, L"TypeDef", Vec2i(x, y + dy * ++i)); + Node* enumNode = addNode(NodeType::NODE_ENUM, L"Enum", Vec2i(x, y + dy * ++i)); + Node* enumConstantNode = addNode(NodeType::NODE_ENUM_CONSTANT, L"ENUM_CONSTANT", Vec2i()); + addMember(enumNode, enumConstantNode); + y += 10; + i += 1; + + Node* templateNode = addNode(NodeType::NODE_TYPE, L"TemplateType", Vec2i(x, y + dy * ++i)); + Node* templateParameterNode = addNode(NodeType::NODE_TEMPLATE_PARAMETER_TYPE, L"ParameterType", Vec2i()); + addMember(templateNode, templateParameterNode, ACCESS_TEMPLATE_PARAMETER); + y += 5; + i += 2; + + Node* genericNode = addNode(NodeType::NODE_TYPE, L"GenericType", Vec2i(x, y + dy * ++i)); + Node* genericParameterNode = addNode(NodeType::NODE_TYPE_PARAMETER, L"ParameterType", Vec2i()); + addMember(genericNode, genericParameterNode, ACCESS_TYPE_PARAMETER); + i += 2; + + y += 10; + + std::shared_ptr groupNode = std::make_shared(DummyNode::DUMMY_GROUP); + groupNode->name = L"Group Node"; + groupNode->visible = true; + groupNode->groupType = GroupType::DEFAULT; + groupNode->position = Vec2i(x, y + dy * ++i); + m_dummyNodes.push_back(groupNode); + y += 25; + + std::shared_ptr bundleNode = std::make_shared(DummyNode::DUMMY_BUNDLE); + bundleNode->name = L"Bundle Node"; + bundleNode->visible = true; + bundleNode->position = Vec2i(x, y + dy * ++i); + m_dummyNodes.push_back(bundleNode); + } + + y = 610; + x = 380; + + // Edges + { + addText(L"Edges", 3, Vec2i(x, y)); + size_t i = 0; + + { + addText(L"file include", 0, Vec2i(x, y + dy * ++i)); + Node* file = addNode(NodeType::NODE_FILE, L"File", Vec2i(x, y + dy * ++i)); + Node* fileB = addNode(NodeType::NODE_FILE, L"File", Vec2i(x + dx, y + dy * i)); + addEdge(Edge::EDGE_INCLUDE, file, fileB); + } + + { + addText(L"class import", 0, Vec2i(x, y + dy * ++i)); + Node* file = addNode(NodeType::NODE_FILE, L"File", Vec2i(x, y + dy * ++i)); + Node* type = addNode(NodeType::NODE_TYPE, L"Class", Vec2i(x + dx, y + dy * i)); + addEdge(Edge::EDGE_IMPORT, file, type); + } + + { + addText(L"macro use", 0, Vec2i(x, y + dy * ++i)); + Node* file = addNode(NodeType::NODE_FILE, L"File", Vec2i(x, y + dy * ++i)); + Node* macro = addNode(NodeType::NODE_MACRO, L"Macro", Vec2i(x + dx, y + dy * i)); + addEdge(Edge::EDGE_MACRO_USAGE, file, macro); + } + + { + addText(L"aggregation", 0, Vec2i(x, y + dy * ++i)); + Node* typeA = addNode(NodeType::NODE_TYPE, L"Type A", Vec2i(x, y + dy * ++i)); + Node* typeB = addNode(NodeType::NODE_TYPE, L"Type B", Vec2i(x + dx, y + dy * i)); + Edge* edge = addEdge(Edge::EDGE_AGGREGATION, typeA, typeB); + std::shared_ptr aggregationComp = std::make_shared(); + for (size_t i = 0; i < 10; i++) + { + aggregationComp->addAggregationId(++id, true); + } + edge->addComponent(aggregationComp); + } + + { + addText(L"type use", 0, Vec2i(x, y + dy * ++i)); + Node* function = addNode(NodeType::NODE_FUNCTION, L"function", Vec2i(x, y + dy * ++i)); + Node* type = addNode(NodeType::NODE_TYPE, L"Type", Vec2i(x + dx, y + dy * i)); + addEdge(Edge::EDGE_TYPE_USAGE, function, type); + } + + { + addText(L"function call", 0, Vec2i(x, y + dy * ++i)); + Node* function = addNode(NodeType::NODE_FUNCTION, L"function", Vec2i(x, y + dy * ++i)); + Node* functionB = addNode(NodeType::NODE_FUNCTION, L"function", Vec2i(x + dx, y + dy * i)); + addEdge(Edge::EDGE_CALL, function, functionB); + } + + { + addText(L"variable access", 0, Vec2i(x, y + dy * ++i)); + Node* function = addNode(NodeType::NODE_FUNCTION, L"function", Vec2i(x, y + dy * ++i)); + Node* variable = addNode(NodeType::NODE_GLOBAL_VARIABLE, L"variable", Vec2i(x + dx, y + dy * i)); + addEdge(Edge::EDGE_USAGE, function, variable); + } + + { + addText(L"class inheritance", 0, Vec2i(x, y + dy * ++i)); + Node* base = addNode(NodeType::NODE_CLASS, L"Base Class", Vec2i(x, y + dy * ++i)); + i += 2; + Node* derived = addNode(NodeType::NODE_CLASS, L"Derived Class", Vec2i(x, y + dy * i)); + addEdge(Edge::EDGE_INHERITANCE, derived, base); + } + + { + addText(L"method override", 0, Vec2i(x , y + dy * ++i)); + Node* base = addNode(NodeType::NODE_CLASS, L"Base Class", Vec2i(x, y + dy * ++i)); + i += 3; + Node* derived = addNode(NodeType::NODE_CLASS, L"Derived Class", Vec2i(x, y + dy * i)); + Node* baseMethod = addNode(NodeType::NODE_METHOD, L"method", Vec2i()); + Node* derivedMethod = addNode(NodeType::NODE_METHOD, L"method", Vec2i()); + addMember(base, baseMethod, ACCESS_PUBLIC); + addMember(derived, derivedMethod, ACCESS_PUBLIC); + addEdge(Edge::EDGE_OVERRIDE, derivedMethod, baseMethod); + i += 2; + } + + { + addText(L"template specialization", 0, Vec2i(x, y + dy * ++i)); + Node* templateFunctionNode = addNode(NodeType::NODE_FUNCTION, L"template_function", Vec2i(x, y + dy * ++i)); + y += 20; + Node* templateFunctionSpecializationNode = addNode(NodeType::NODE_FUNCTION, L"template_function", Vec2i(x, y + dy * ++i), DEFINITION_IMPLICIT); + addEdge(Edge::EDGE_TEMPLATE_SPECIALIZATION, templateFunctionSpecializationNode, templateFunctionNode); + + Node* templateNode = addNode(NodeType::NODE_TYPE, L"TemplateType", Vec2i(x , y + dy * ++i)); + y += 30; + Node* templateSpecializationNode = addNode(NodeType::NODE_TYPE, L"TemplateType", Vec2i(x, y + dy * ++i), DEFINITION_IMPLICIT); + Node* argumentNode = addNode(NodeType::NODE_TYPE, L"ArgumentType", Vec2i(x + 270, y + dy * i)); + addEdge(Edge::EDGE_TEMPLATE_SPECIALIZATION, templateSpecializationNode, templateNode); + addEdge(Edge::EDGE_TEMPLATE_ARGUMENT, templateSpecializationNode, argumentNode); + } + + { + addText(L"template member specialization", 0, Vec2i(x, y + dy * ++i)); + Node* templateNode = addNode(NodeType::NODE_TYPE, L"TemplateType", Vec2i(x, y + dy * ++i)); + Node* templateMethodNode = addNode(NodeType::NODE_METHOD, L"method", Vec2i()); + addMember(templateNode, templateMethodNode); + + i += 1; + + Node* templateSpecializationNode = addNode(NodeType::NODE_TYPE, L"TemplateType", Vec2i(x, y + dy * ++i + 20), DEFINITION_IMPLICIT); + Node* templateSpecializationMethodNode = addNode(NodeType::NODE_METHOD, L"method", Vec2i(), DEFINITION_IMPLICIT); + addMember(templateSpecializationNode, templateSpecializationMethodNode); + addEdge(Edge::EDGE_TEMPLATE_MEMBER_SPECIALIZATION, templateSpecializationMethodNode, templateMethodNode); + } + } + + std::vector> nodes = m_dummyNodes; + createDummyGraphAndSetActiveAndVisibility({}, graph, false); + m_dummyNodes = utility::concat(nodes, m_dummyNodes); + + for (std::shared_ptr node : m_dummyNodes) + { + if (node->tokenId) + { + auto it = nodePositions.find(node->tokenId); + if (it != nodePositions.end()) + { + node->position = it->second; + } + } + } +} diff --git a/src/lib/component/controller/GraphController.h b/src/lib/component/controller/GraphController.h index dfd5d104..11c5298d 100644 --- a/src/lib/component/controller/GraphController.h +++ b/src/lib/component/controller/GraphController.h @@ -5,6 +5,7 @@ #include #include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/activation/MessageActivateLegend.h" #include "utility/messaging/type/error/MessageActivateErrors.h" #include "utility/messaging/type/MessageActivateAll.h" #include "utility/messaging/type/MessageActivateFullTextSearch.h" @@ -35,6 +36,7 @@ class GraphController , public MessageListener , public MessageListener , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -56,6 +58,7 @@ private: virtual void handleMessage(MessageActivateAll* message); virtual void handleMessage(MessageActivateErrors* message); virtual void handleMessage(MessageActivateFullTextSearch* message); + virtual void handleMessage(MessageActivateLegend* message); virtual void handleMessage(MessageActivateTokens* message); virtual void handleMessage(MessageActivateTrail* message); virtual void handleMessage(MessageActivateTrailEdge* message); @@ -129,13 +132,14 @@ private: DummyEdge* getDummyGraphEdgeById(Id tokenId) const; void relayoutGraph( - MessageBase* message, bool centerActiveNode, bool animatedTransition, bool scrollToTop, bool withCharacterIndex, - const std::wstring& groupName); - void buildGraph(MessageBase* message, bool centerActiveNode, bool animatedTransition, bool scrollToTop); + MessageBase* message, GraphView::GraphParams params, bool withCharacterIndex, const std::wstring& groupName); + void buildGraph(MessageBase* message, GraphView::GraphParams params); void forEachDummyNodeRecursive(std::function func); void forEachDummyEdge(std::function func); + void createLegendGraph(); + StorageAccess* m_storageAccess; std::vector> m_dummyNodes; @@ -150,7 +154,8 @@ private: std::map m_topLevelAncestorIds; - bool m_useBezierEdges; + bool m_useBezierEdges = false; + bool m_showsLegend = false; }; #endif // GRAPH_CONTROLLER_H diff --git a/src/lib/component/controller/SearchController.cpp b/src/lib/component/controller/SearchController.cpp index 7c1d5f11..3ccdabd0 100644 --- a/src/lib/component/controller/SearchController.cpp +++ b/src/lib/component/controller/SearchController.cpp @@ -29,6 +29,11 @@ void SearchController::handleMessage(MessageActivateFullTextSearch* message) getView()->setMatches(message->getSearchMatches()); } +void SearchController::handleMessage(MessageActivateLegend* message) +{ + getView()->setMatches(message->getSearchMatches()); +} + void SearchController::handleMessage(MessageActivateTokens* message) { if (message->keepContent()) diff --git a/src/lib/component/controller/SearchController.h b/src/lib/component/controller/SearchController.h index 39016393..7b9748ad 100644 --- a/src/lib/component/controller/SearchController.h +++ b/src/lib/component/controller/SearchController.h @@ -3,6 +3,7 @@ #include "component/controller/Controller.h" #include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/activation/MessageActivateLegend.h" #include "utility/messaging/type/error/MessageActivateErrors.h" #include "utility/messaging/type/MessageActivateAll.h" #include "utility/messaging/type/MessageActivateFullTextSearch.h" @@ -18,6 +19,7 @@ class SearchController , public MessageListener , public MessageListener , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -30,6 +32,7 @@ private: virtual void handleMessage(MessageActivateAll* message); virtual void handleMessage(MessageActivateErrors* message); virtual void handleMessage(MessageActivateFullTextSearch* message); + virtual void handleMessage(MessageActivateLegend* message); virtual void handleMessage(MessageActivateTokens* message); virtual void handleMessage(MessageFind* message); virtual void handleMessage(MessageSearchAutocomplete* message); diff --git a/src/lib/component/controller/UndoRedoController.cpp b/src/lib/component/controller/UndoRedoController.cpp index fc8ac05f..e7178a75 100644 --- a/src/lib/component/controller/UndoRedoController.cpp +++ b/src/lib/component/controller/UndoRedoController.cpp @@ -80,6 +80,17 @@ void UndoRedoController::handleMessage(MessageActivateFullTextSearch* message) processCommand(command); } +void UndoRedoController::handleMessage(MessageActivateLegend* message) +{ + if (sameMessageTypeAsLast(message)) + { + return; + } + + Command command(std::make_shared(*message), Command::ORDER_ACTIVATE); + processCommand(command); +} + void UndoRedoController::handleMessage(MessageActivateLocalSymbols* message) { if (sameMessageTypeAsLast(message)) diff --git a/src/lib/component/controller/UndoRedoController.h b/src/lib/component/controller/UndoRedoController.h index dd3a8735..d576b852 100644 --- a/src/lib/component/controller/UndoRedoController.h +++ b/src/lib/component/controller/UndoRedoController.h @@ -5,6 +5,7 @@ #include "utility/messaging/MessageBase.h" #include "utility/messaging/MessageListener.h" +#include "utility/messaging/type/activation/MessageActivateLegend.h" #include "utility/messaging/type/code/MessageCodeShowDefinition.h" #include "utility/messaging/type/error/MessageActivateErrors.h" #include "utility/messaging/type/error/MessageShowError.h" @@ -40,6 +41,7 @@ class UndoRedoController , public MessageListener , public MessageListener , public MessageListener + , public MessageListener , public MessageListener , public MessageListener , public MessageListener @@ -90,6 +92,7 @@ private: virtual void handleMessage(MessageActivateAll* message); virtual void handleMessage(MessageActivateErrors* message); virtual void handleMessage(MessageActivateFullTextSearch* message); + virtual void handleMessage(MessageActivateLegend* message); virtual void handleMessage(MessageActivateLocalSymbols* message); virtual void handleMessage(MessageActivateTokens* message); virtual void handleMessage(MessageActivateTrail* message); diff --git a/src/lib/component/controller/helper/DummyNode.h b/src/lib/component/controller/helper/DummyNode.h index 2a7de877..33f1976c 100644 --- a/src/lib/component/controller/helper/DummyNode.h +++ b/src/lib/component/controller/helper/DummyNode.h @@ -110,6 +110,7 @@ public: , groupType(GroupType::DEFAULT) , groupLayout(GroupLayout::LIST) , interactive(true) + , fontSizeDiff(5) { } @@ -490,6 +491,9 @@ public: GroupLayout groupLayout; std::vector hiddenEdgeIds; bool interactive; + + // TextNode + int fontSizeDiff; }; #endif // DUMMY_NODE_H diff --git a/src/lib/component/view/GraphView.h b/src/lib/component/view/GraphView.h index dae5e791..28fec7d6 100644 --- a/src/lib/component/view/GraphView.h +++ b/src/lib/component/view/GraphView.h @@ -23,11 +23,12 @@ public: struct GraphParams { - bool animatedTransition; - bool centerActiveNode; - bool scrollToTop; - bool isIndexedList; - bool bezierEdges; + bool animatedTransition = true; + bool centerActiveNode = false; + bool scrollToTop = false; + bool isIndexedList = false; + bool bezierEdges = false; + bool disableInteraction = false; }; GraphView(ViewLayout* viewLayout); diff --git a/src/lib/component/view/GraphViewStyle.cpp b/src/lib/component/view/GraphViewStyle.cpp index 72607cc7..529df328 100644 --- a/src/lib/component/view/GraphViewStyle.cpp +++ b/src/lib/component/view/GraphViewStyle.cpp @@ -144,7 +144,7 @@ void GraphViewStyle::loadStyleSettings() s_edgeColors.clear(); s_screenMatchColors.clear(); - s_gridCellPadding = getImpl()->getCharHeight(NodeType::STYLE_BIG_NODE) - 8; + s_gridCellPadding = getCharHeight(NodeType::STYLE_BIG_NODE) - 8; s_gridCellSize = s_gridCellPadding / 2; } @@ -184,9 +184,9 @@ size_t GraphViewStyle::getFontSizeOfQualifier() return s_fontSize - 3; } -size_t GraphViewStyle::getFontSizeOfTextNode() +size_t GraphViewStyle::getFontSizeOfTextNode(int fontSizeDiff) { - return s_fontSize + 5; + return s_fontSize + fontSizeDiff; } size_t GraphViewStyle::getFontSizeOfGroupNode() @@ -324,13 +324,15 @@ GraphViewStyle::NodeMargins GraphViewStyle::getMarginsOfBundleNode() return getMarginsForDataNode(NodeType::STYLE_BIG_NODE, true, false); } -GraphViewStyle::NodeMargins GraphViewStyle::getMarginsOfTextNode() +GraphViewStyle::NodeMargins GraphViewStyle::getMarginsOfTextNode(int fontSizeDiff) { NodeMargins margins; margins.left = margins.right = 0; margins.top = margins.bottom = 6; - margins.minWidth = margins.charHeight = getFontSizeOfTextNode(); + margins.minWidth = margins.charHeight = getFontSizeOfTextNode(fontSizeDiff); + + margins.charWidth = getCharWidth(getFontNameOfTextNode(), getFontSizeOfTextNode(fontSizeDiff)); return margins; } @@ -545,14 +547,14 @@ GraphViewStyle::NodeStyle GraphViewStyle::getStyleOfQualifier() return style; } -GraphViewStyle::NodeStyle GraphViewStyle::getStyleOfTextNode() +GraphViewStyle::NodeStyle GraphViewStyle::getStyleOfTextNode(int fontSizeDiff) { NodeStyle style; style.color = getNodeColor("text", false); style.fontName = getFontNameOfTextNode(); - style.fontSize = getFontSizeOfTextNode(); + style.fontSize = getFontSizeOfTextNode(fontSizeDiff); style.fontBold = true; style.textOffset.y = 10; @@ -803,13 +805,12 @@ const GraphViewStyle::NodeColor& GraphViewStyle::getScreenMatchColor(bool focus) float GraphViewStyle::getCharWidth(NodeType::StyleType type) { std::map::const_iterator it = s_charWidths.find(type); - if (it != s_charWidths.end()) { return it->second; } - float charWidth = getImpl()->getCharWidth(type); + float charWidth = getCharWidth(getFontNameForDataNode(), getFontSizeForStyleType(type)); s_charWidths.emplace(type, charWidth); return charWidth; } @@ -817,13 +818,22 @@ float GraphViewStyle::getCharWidth(NodeType::StyleType type) float GraphViewStyle::getCharHeight(NodeType::StyleType type) { std::map::const_iterator it = s_charHeights.find(type); - if (it != s_charHeights.end()) { return it->second; } - float charHeight = getImpl()->getCharHeight(type); + float charHeight = getCharHeight(getFontNameForDataNode(), getFontSizeForStyleType(type)); s_charHeights.emplace(type, charHeight); return charHeight; } + +float GraphViewStyle::getCharWidth(const std::string& fontName, size_t fontSize) +{ + return getImpl()->getCharWidth(fontName, fontSize); +} + +float GraphViewStyle::getCharHeight(const std::string& fontName, size_t fontSize) +{ + return getImpl()->getCharHeight(fontName, fontSize); +} diff --git a/src/lib/component/view/GraphViewStyle.h b/src/lib/component/view/GraphViewStyle.h index c160fdcb..a0ca7699 100644 --- a/src/lib/component/view/GraphViewStyle.h +++ b/src/lib/component/view/GraphViewStyle.h @@ -104,7 +104,7 @@ public: static size_t getFontSizeOfExpandToggleNode(); static size_t getFontSizeOfCountCircle(); static size_t getFontSizeOfQualifier(); - static size_t getFontSizeOfTextNode(); + static size_t getFontSizeOfTextNode(int fontSizeDiff); static size_t getFontSizeOfGroupNode(); static std::string getFontNameForDataNode(); @@ -117,7 +117,7 @@ public: static NodeMargins getMarginsOfAccessNode(AccessKind access); static NodeMargins getMarginsOfExpandToggleNode(); static NodeMargins getMarginsOfBundleNode(); - static NodeMargins getMarginsOfTextNode(); + static NodeMargins getMarginsOfTextNode(int fontSizeDiff); static NodeMargins getMarginsOfGroupNode(GroupType type, bool hasName); static NodeStyle getStyleForNodeType( @@ -127,7 +127,7 @@ public: static NodeStyle getStyleOfCountCircle(); static NodeStyle getStyleOfBundleNode(bool isFocused); static NodeStyle getStyleOfQualifier(); - static NodeStyle getStyleOfTextNode(); + static NodeStyle getStyleOfTextNode(int fontSizeDiff); static NodeStyle getStyleOfGroupNode(GroupType type, bool isFocused); static EdgeStyle getStyleForEdgeType(Edge::EdgeType type, bool isActive, bool isFocused, bool isTrailEdge); @@ -154,6 +154,9 @@ private: static float getCharWidth(NodeType::StyleType type); static float getCharHeight(NodeType::StyleType type); + static float getCharWidth(const std::string& fontName, size_t fontSize); + static float getCharHeight(const std::string& fontName, size_t fontSize); + static std::map s_charWidths; static std::map s_charHeights; diff --git a/src/lib/component/view/GraphViewStyleImpl.h b/src/lib/component/view/GraphViewStyleImpl.h index 1e0219e0..6bde9a5c 100644 --- a/src/lib/component/view/GraphViewStyleImpl.h +++ b/src/lib/component/view/GraphViewStyleImpl.h @@ -7,8 +7,8 @@ class GraphViewStyleImpl { public: virtual ~GraphViewStyleImpl() { } - virtual float getCharWidth(NodeType::StyleType type) = 0; - virtual float getCharHeight(NodeType::StyleType type) = 0; + virtual float getCharWidth(const std::string& fontName, size_t fontSize) = 0; + virtual float getCharHeight(const std::string& fontName, size_t fontSize) = 0; virtual float getGraphViewZoomDifferenceForPlatform() = 0; }; diff --git a/src/lib/data/NodeType.cpp b/src/lib/data/NodeType.cpp index 237b9226..00ec1181 100644 --- a/src/lib/data/NodeType.cpp +++ b/src/lib/data/NodeType.cpp @@ -22,6 +22,127 @@ std::vector NodeType::getOverviewBundleNodeTypesOrdered() }; } +int NodeType::typeToInt(NodeType::Type type) +{ + return type; +} + +NodeType::Type NodeType::intToType(int value) +{ + switch (value) + { + case NodeType::NODE_TYPE: + return NodeType::NODE_TYPE; + case NodeType::NODE_BUILTIN_TYPE: + return NodeType::NODE_BUILTIN_TYPE; + case NodeType::NODE_NAMESPACE: + return NodeType::NODE_NAMESPACE; + case NodeType::NODE_PACKAGE: + return NodeType::NODE_PACKAGE; + case NodeType::NODE_STRUCT: + return NodeType::NODE_STRUCT; + case NodeType::NODE_CLASS: + return NodeType::NODE_CLASS; + case NodeType::NODE_INTERFACE: + return NodeType::NODE_INTERFACE; + case NodeType::NODE_GLOBAL_VARIABLE: + return NodeType::NODE_GLOBAL_VARIABLE; + case NodeType::NODE_FIELD: + return NodeType::NODE_FIELD; + case NodeType::NODE_FUNCTION: + return NodeType::NODE_FUNCTION; + case NodeType::NODE_METHOD: + return NodeType::NODE_METHOD; + case NodeType::NODE_ENUM: + return NodeType::NODE_ENUM; + case NodeType::NODE_ENUM_CONSTANT: + return NodeType::NODE_ENUM_CONSTANT; + case NodeType::NODE_TYPEDEF: + return NodeType::NODE_TYPEDEF; + case NodeType::NODE_TEMPLATE_PARAMETER_TYPE: + return NodeType::NODE_TEMPLATE_PARAMETER_TYPE; + case NodeType::NODE_TYPE_PARAMETER: + return NodeType::NODE_TYPE_PARAMETER; + case NodeType::NODE_FILE: + return NodeType::NODE_FILE; + case NodeType::NODE_MACRO: + return NodeType::NODE_MACRO; + case NodeType::NODE_UNION: + return NodeType::NODE_UNION; + } + + return NodeType::NODE_SYMBOL; +} + +std::string NodeType::getReadableTypeString(NodeType::Type type) +{ + switch (type) + { + case NodeType::NODE_SYMBOL: + return "symbol"; + case NodeType::NODE_BUILTIN_TYPE: + return "built-in type"; + case NodeType::NODE_TYPE: + return "type"; + case NodeType::NODE_NAMESPACE: + return "namespace"; + case NodeType::NODE_PACKAGE: + return "package"; + case NodeType::NODE_STRUCT: + return "struct"; + case NodeType::NODE_CLASS: + return "class"; + case NodeType::NODE_INTERFACE: + return "interface"; + case NodeType::NODE_GLOBAL_VARIABLE: + return "global variable"; + case NodeType::NODE_FIELD: + return "field"; + case NodeType::NODE_FUNCTION: + return "function"; + case NodeType::NODE_METHOD: + return "method"; + case NodeType::NODE_ENUM: + return "enum"; + case NodeType::NODE_ENUM_CONSTANT: + return "enum constant"; + case NodeType::NODE_TYPEDEF: + return "typedef"; + case NodeType::NODE_TEMPLATE_PARAMETER_TYPE: + return "template parameter type"; + case NodeType::NODE_TYPE_PARAMETER: + return "type parameter"; + case NodeType::NODE_FILE: + return "file"; + case NodeType::NODE_MACRO: + return "macro"; + case NodeType::NODE_UNION: + return "union"; + } + + return ""; +} + +std::wstring NodeType::getReadableTypeWString(NodeType::Type type) +{ + std::string str = getReadableTypeString(type); + return std::wstring(str.begin(), str.end()); +} + +NodeType::Type NodeType::getTypeForReadableTypeString(const std::wstring str) +{ + for (NodeType::TypeMask mask = 1; mask <= NodeType::NODE_MAX_VALUE; mask *= 2) + { + NodeType::Type type = intToType(mask); + if (getReadableTypeWString(type) == str) + { + return type; + } + } + + return NodeType::NODE_SYMBOL; +} + NodeType::NodeType(Type type) : m_type(type) { @@ -45,7 +166,7 @@ NodeType::Type NodeType::getType() const Id NodeType::getId() const { // TODO: add id in constructor and return it here - return utility::nodeTypeToInt(m_type); + return typeToInt(m_type); } bool NodeType::isFile() const @@ -304,7 +425,7 @@ std::string NodeType::getUnderscoredTypeString() const std::string NodeType::getReadableTypeString() const { - return utility::getReadableTypeString(m_type); + return getReadableTypeString(m_type); } std::wstring NodeType::getUnderscoredTypeWString() const @@ -318,124 +439,3 @@ std::wstring NodeType::getReadableTypeWString() const std::string str = getReadableTypeString(); return std::wstring(str.begin(), str.end()); } - -int utility::nodeTypeToInt(NodeType::Type type) -{ - return type; -} - -NodeType::Type utility::intToType(int value) -{ - switch (value) - { - case NodeType::NODE_TYPE: - return NodeType::NODE_TYPE; - case NodeType::NODE_BUILTIN_TYPE: - return NodeType::NODE_BUILTIN_TYPE; - case NodeType::NODE_NAMESPACE: - return NodeType::NODE_NAMESPACE; - case NodeType::NODE_PACKAGE: - return NodeType::NODE_PACKAGE; - case NodeType::NODE_STRUCT: - return NodeType::NODE_STRUCT; - case NodeType::NODE_CLASS: - return NodeType::NODE_CLASS; - case NodeType::NODE_INTERFACE: - return NodeType::NODE_INTERFACE; - case NodeType::NODE_GLOBAL_VARIABLE: - return NodeType::NODE_GLOBAL_VARIABLE; - case NodeType::NODE_FIELD: - return NodeType::NODE_FIELD; - case NodeType::NODE_FUNCTION: - return NodeType::NODE_FUNCTION; - case NodeType::NODE_METHOD: - return NodeType::NODE_METHOD; - case NodeType::NODE_ENUM: - return NodeType::NODE_ENUM; - case NodeType::NODE_ENUM_CONSTANT: - return NodeType::NODE_ENUM_CONSTANT; - case NodeType::NODE_TYPEDEF: - return NodeType::NODE_TYPEDEF; - case NodeType::NODE_TEMPLATE_PARAMETER_TYPE: - return NodeType::NODE_TEMPLATE_PARAMETER_TYPE; - case NodeType::NODE_TYPE_PARAMETER: - return NodeType::NODE_TYPE_PARAMETER; - case NodeType::NODE_FILE: - return NodeType::NODE_FILE; - case NodeType::NODE_MACRO: - return NodeType::NODE_MACRO; - case NodeType::NODE_UNION: - return NodeType::NODE_UNION; - } - - return NodeType::NODE_SYMBOL; -} - -std::string utility::getReadableTypeString(NodeType::Type type) -{ - switch (type) - { - case NodeType::NODE_SYMBOL: - return "symbol"; - case NodeType::NODE_BUILTIN_TYPE: - return "built-in type"; - case NodeType::NODE_TYPE: - return "type"; - case NodeType::NODE_NAMESPACE: - return "namespace"; - case NodeType::NODE_PACKAGE: - return "package"; - case NodeType::NODE_STRUCT: - return "struct"; - case NodeType::NODE_CLASS: - return "class"; - case NodeType::NODE_INTERFACE: - return "interface"; - case NodeType::NODE_GLOBAL_VARIABLE: - return "global variable"; - case NodeType::NODE_FIELD: - return "field"; - case NodeType::NODE_FUNCTION: - return "function"; - case NodeType::NODE_METHOD: - return "method"; - case NodeType::NODE_ENUM: - return "enum"; - case NodeType::NODE_ENUM_CONSTANT: - return "enum constant"; - case NodeType::NODE_TYPEDEF: - return "typedef"; - case NodeType::NODE_TEMPLATE_PARAMETER_TYPE: - return "template parameter type"; - case NodeType::NODE_TYPE_PARAMETER: - return "type parameter"; - case NodeType::NODE_FILE: - return "file"; - case NodeType::NODE_MACRO: - return "macro"; - case NodeType::NODE_UNION: - return "union"; - } - - return ""; -} - -std::wstring utility::getReadableTypeWString(NodeType::Type type) -{ - std::string str = getReadableTypeString(type); - return std::wstring(str.begin(), str.end()); -} - -NodeType::Type utility::getTypeForReadableTypeString(const std::wstring str) -{ - for (NodeType::TypeMask mask = 1; mask <= NodeType::NODE_MAX_VALUE; mask *= 2) - { - NodeType::Type type = intToType(mask); - if (getReadableTypeWString(type) == str) - { - return type; - } - } - - return NodeType::NODE_SYMBOL; -} diff --git a/src/lib/data/NodeType.h b/src/lib/data/NodeType.h index bb5bf1e2..97e9540a 100644 --- a/src/lib/data/NodeType.h +++ b/src/lib/data/NodeType.h @@ -78,6 +78,13 @@ public: static std::vector getOverviewBundleNodeTypesOrdered(); + static int typeToInt(NodeType::Type type); + static NodeType::Type intToType(int value); + + static std::string getReadableTypeString(NodeType::Type type); + static std::wstring getReadableTypeWString(NodeType::Type type); + static NodeType::Type getTypeForReadableTypeString(const std::wstring str); + NodeType(Type type); bool operator==(const NodeType& o) const; @@ -115,13 +122,4 @@ private: Type m_type; }; -namespace utility -{ - int nodeTypeToInt(NodeType::Type type); - NodeType::Type intToType(int value); - std::string getReadableTypeString(NodeType::Type type); - std::wstring getReadableTypeWString(NodeType::Type type); - NodeType::Type getTypeForReadableTypeString(const std::wstring str); -} - #endif // NODE_TYPE_H diff --git a/src/lib/data/name/NameElement.cpp b/src/lib/data/name/NameElement.cpp index 655eb8ec..c99f9395 100644 --- a/src/lib/data/name/NameElement.cpp +++ b/src/lib/data/name/NameElement.cpp @@ -53,7 +53,12 @@ const std::wstring& NameElement::Signature::getPostfix() const std::wstring NameElement::Signature::getParameterString() const { - return utility::substrBeforeLast(m_postfix, L')') + L')'; + if (m_postfix.size()) + { + return utility::substrBeforeLast(m_postfix, L')') + L')'; + } + + return m_postfix; } NameElement::NameElement(std::wstring name) diff --git a/src/lib/data/parser/ParserClientImpl.cpp b/src/lib/data/parser/ParserClientImpl.cpp index f0c55eb6..8352d849 100644 --- a/src/lib/data/parser/ParserClientImpl.cpp +++ b/src/lib/data/parser/ParserClientImpl.cpp @@ -228,7 +228,7 @@ Id ParserClientImpl::addNode(NodeType nodeType, const NameHierarchy& nameHierarc return 0; } - return m_storage->addNode(StorageNodeData(utility::nodeTypeToInt(nodeType.getType()), NameHierarchy::serialize(nameHierarchy))); + return m_storage->addNode(StorageNodeData(NodeType::typeToInt(nodeType.getType()), NameHierarchy::serialize(nameHierarchy))); } void ParserClientImpl::addFile(Id id, const FilePath& filePath, const std::string& modificationTime, bool indexed) diff --git a/src/lib/data/search/SearchMatch.cpp b/src/lib/data/search/SearchMatch.cpp index 5521f9b4..22652da9 100644 --- a/src/lib/data/search/SearchMatch.cpp +++ b/src/lib/data/search/SearchMatch.cpp @@ -85,6 +85,8 @@ std::wstring SearchMatch::getCommandName(CommandType type) return L"error"; case COMMAND_NODE_FILTER: return L"node_filter"; + case COMMAND_LEGEND: + return L"legend"; } return L"none"; @@ -244,6 +246,10 @@ SearchMatch::CommandType SearchMatch::getCommandType() const { return COMMAND_ERROR; } + else if (name == L"legend") + { + return COMMAND_LEGEND; + } return COMMAND_NODE_FILTER; } diff --git a/src/lib/data/search/SearchMatch.h b/src/lib/data/search/SearchMatch.h index 17f99fc0..ed52eb87 100644 --- a/src/lib/data/search/SearchMatch.h +++ b/src/lib/data/search/SearchMatch.h @@ -27,7 +27,8 @@ struct SearchMatch { COMMAND_ALL, COMMAND_ERROR, - COMMAND_NODE_FILTER + COMMAND_NODE_FILTER, + COMMAND_LEGEND }; static void log(const std::vector& matches, const std::wstring& query); diff --git a/src/lib/data/storage/PersistentStorage.cpp b/src/lib/data/storage/PersistentStorage.cpp index d5a90059..dedafd88 100644 --- a/src/lib/data/storage/PersistentStorage.cpp +++ b/src/lib/data/storage/PersistentStorage.cpp @@ -33,6 +33,7 @@ PersistentStorage::PersistentStorage(const FilePath& dbPath, const FilePath& boo { m_commandIndex.addNode(0, SearchMatch::getCommandName(SearchMatch::COMMAND_ALL)); m_commandIndex.addNode(0, SearchMatch::getCommandName(SearchMatch::COMMAND_ERROR)); + m_commandIndex.addNode(0, SearchMatch::getCommandName(SearchMatch::COMMAND_LEGEND)); for (const NodeType& nodeType : NodeTypeSet::all().getNodeTypes()) { @@ -535,7 +536,7 @@ std::map> PersistentStorage::getNodeIdToParentF NodeType PersistentStorage::getNodeTypeForNodeWithId(Id nodeId) const { - return utility::intToType(m_sqliteIndexStorage.getFirstById(nodeId).type); + return NodeType::intToType(m_sqliteIndexStorage.getFirstById(nodeId).type); } Id PersistentStorage::getIdForEdge( @@ -795,7 +796,7 @@ std::vector PersistentStorage::getAutocompletionSymbolMatches( match.tokenName = name; match.indices = result.indices; match.score = result.score; - match.nodeType = utility::intToType(firstNode->type); + match.nodeType = NodeType::intToType(firstNode->type); match.typeName = match.nodeType.getReadableTypeWString(); match.searchType = SearchMatch::SEARCH_TOKEN; @@ -877,7 +878,7 @@ std::vector PersistentStorage::getAutocompletionCommandMatches( if (match.getCommandType() == SearchMatch::COMMAND_NODE_FILTER) { - match.nodeType = utility::getTypeForReadableTypeString(match.name); + match.nodeType = NodeType::getTypeForReadableTypeString(match.name); match.typeName = L"filter"; } @@ -922,7 +923,7 @@ std::vector PersistentStorage::getSearchMatchesForTokenIds(const st match.tokenIds.push_back(elementId); match.tokenName = nameHierarchy; - match.nodeType = utility::intToType(node.type); + match.nodeType = NodeType::intToType(node.type); match.searchType = SearchMatch::SEARCH_TOKEN; if (match.nodeType.isFile()) @@ -946,7 +947,7 @@ std::shared_ptr PersistentStorage::getGraphForAll() const auto it = m_symbolDefinitionKinds.find(node.id); if (it != m_symbolDefinitionKinds.end() && it->second == DEFINITION_EXPLICIT && ( - NodeType(utility::intToType(node.type)).isPackage() || + NodeType(NodeType::intToType(node.type)).isPackage() || !m_hierarchyCache.isChildOfVisibleNodeOrInvisible(node.id) ) ){ @@ -977,7 +978,7 @@ std::shared_ptr PersistentStorage::getGraphForNodeTypes(NodeTypeSet nodeT std::vector tokenIds; for (StorageNode& node: m_sqliteIndexStorage.getAll()) { - if (nodeTypes.contains(utility::intToType(node.type))) + if (nodeTypes.contains(NodeType::intToType(node.type))) { auto it = m_symbolDefinitionKinds.find(node.id); if (it != m_symbolDefinitionKinds.end() && it->second == DEFINITION_EXPLICIT) @@ -1023,7 +1024,7 @@ std::shared_ptr PersistentStorage::getGraphForActiveTokenIds( if (node.id > 0) { - const NodeType nodeType = utility::intToType(node.type); + const NodeType nodeType = NodeType::intToType(node.type); if (nodeType.isPackage()) { ids.clear(); @@ -1356,7 +1357,7 @@ std::shared_ptr PersistentStorage::getSourceLocationsF if (path.empty() && m_symbolDefinitionKinds.find(tokenId) == m_symbolDefinitionKinds.end()) { const StorageNode fileNode = m_sqliteIndexStorage.getNodeById(tokenId); - if (NodeType(utility::intToType(fileNode.type)).isFile()) + if (NodeType(NodeType::intToType(fileNode.type)).isFile()) { path = FilePath(NameHierarchy::deserialize(fileNode.serializedName).getQualifiedName()); } @@ -1893,7 +1894,7 @@ TooltipInfo PersistentStorage::getTooltipInfoForTokenIds(const std::vector& return info; } - const NodeType type = utility::intToType(node.type); + const NodeType type = NodeType::intToType(node.type); info.title = type.getReadableTypeWString(); DefinitionKind defKind = DEFINITION_NONE; @@ -2201,7 +2202,7 @@ TooltipInfo PersistentStorage::getTooltipInfoForSourceLocationIdsAndLocalSymbolI snippet.locationFile->addSourceLocation( LOCATION_TOKEN, 0, std::vector(1, node.id), 1, 1, 1, snippet.code.size()); - if (NodeType(utility::intToType(node.type)).isCallable()) + if (NodeType(NodeType::intToType(node.type)).isCallable()) { snippet.code += L"()"; } @@ -2506,7 +2507,7 @@ void PersistentStorage::addNodesToGraph(const std::vector& newNodeIds, Graph { NameHierarchy nameHierarchy = NameHierarchy::deserialize(storageNode.serializedName); - const NodeType type(utility::intToType(storageNode.type)); + const NodeType type(NodeType::intToType(storageNode.type)); if (type.isFile()) { const FilePath filePath(nameHierarchy.getRawName()); @@ -2907,7 +2908,7 @@ void PersistentStorage::buildSearchIndex() for (const StorageNode& node : m_sqliteIndexStorage.getAll()) { - const NodeType type = utility::intToType(node.type); + const NodeType type = NodeType::intToType(node.type); if (type.isFile()) { bool indexed = getFileNodeIndexed(node.id); @@ -3088,7 +3089,7 @@ void PersistentStorage::buildHierarchyCache() std::map sourceNodeTypeMap; for (const StorageNode& node : m_sqliteIndexStorage.getAllByIds(sourceNodeIds)) { - sourceNodeTypeMap.emplace(node.id, utility::intToType(node.type)); + sourceNodeTypeMap.emplace(node.id, NodeType::intToType(node.type)); } for (const StorageEdge& edge : memberEdges) diff --git a/src/lib/utility/messaging/type/activation/MessageActivateLegend.h b/src/lib/utility/messaging/type/activation/MessageActivateLegend.h new file mode 100644 index 00000000..55f07ca7 --- /dev/null +++ b/src/lib/utility/messaging/type/activation/MessageActivateLegend.h @@ -0,0 +1,23 @@ +#ifndef MESSAGE_ACTIVATE_LEGEND_H +#define MESSAGE_ACTIVATE_LEGEND_H + +#include "utility/messaging/Message.h" +#include "utility/messaging/type/MessageActivateBase.h" + +class MessageActivateLegend + : public Message + , public MessageActivateBase +{ +public: + static const std::string getStaticType() + { + return "MessageActivateLegend"; + } + + std::vector getSearchMatches() const override + { + return { SearchMatch::createCommand(SearchMatch::COMMAND_LEGEND) }; + } +}; + +#endif // MESSAGE_ACTIVATE_LEGEND_H diff --git a/src/lib_gui/qt/element/QtAutocompletionList.cpp b/src/lib_gui/qt/element/QtAutocompletionList.cpp index f265c099..63fca356 100644 --- a/src/lib_gui/qt/element/QtAutocompletionList.cpp +++ b/src/lib_gui/qt/element/QtAutocompletionList.cpp @@ -141,7 +141,7 @@ void QtAutocompletionDelegate::paint(QPainter* painter, const QStyleOptionViewIt QString subtext = index.sibling(index.row(), index.column() + 2).data().toString(); QString type = index.sibling(index.row(), index.column() + 3).data().toString(); QList indices = index.sibling(index.row(), index.column() + 4).data().toList(); - NodeType nodeType = utility::intToType(index.sibling(index.row(), index.column() + 5).data().toInt()); + NodeType nodeType = NodeType::intToType(index.sibling(index.row(), index.column() + 5).data().toInt()); // define highlight colors ColorScheme* scheme = ColorScheme::getInstance().get(); diff --git a/src/lib_gui/qt/graphics/QtGraphicsView.cpp b/src/lib_gui/qt/graphics/QtGraphicsView.cpp index 69fc2737..60ef4395 100644 --- a/src/lib_gui/qt/graphics/QtGraphicsView.cpp +++ b/src/lib_gui/qt/graphics/QtGraphicsView.cpp @@ -20,6 +20,7 @@ #include "qt/utility/QtFileDialog.h" #include "qt/utility/utilityQt.h" #include "settings/ApplicationSettings.h" +#include "utility/messaging/type/activation/MessageActivateLegend.h" #include "utility/messaging/type/code/MessageCodeShowDefinition.h" #include "utility/messaging/type/MessageDisplayBookmarkCreator.h" #include "utility/messaging/type/MessageGraphNodeHide.h" @@ -102,6 +103,12 @@ QtGraphicsView::QtGraphicsView(QWidget* parent) m_zoomOutButton->setAutoRepeat(true); m_zoomOutButton->setToolTip("Zoom out (" + modifierName + " + Mousewheel back)"); connect(m_zoomOutButton, &QPushButton::pressed, this, &QtGraphicsView::zoomOutPressed); + + m_legendButton = new QtSelfRefreshIconButton( + "", ResourcePaths::getGuiPath().concatenate(L"graph_view/images/legend.png"), "search/button", this); + m_legendButton->setObjectName("legend_button"); + m_legendButton->setToolTip("Show graph legend"); + connect(m_legendButton, &QPushButton::clicked, this, &QtGraphicsView::legendClicked); } float QtGraphicsView::getZoomFactor() const @@ -201,10 +208,12 @@ void QtGraphicsView::resizeEvent(QResizeEvent* event) { m_zoomState->setGeometry(QRect(31, event->size().height() - 27, 65, 19)); m_zoomInButton->setGeometry(QRect(8, event->size().height() - 50, 19, 19)); - m_zoomOutButton->setGeometry(QRect(8, event->size().height() - 27, 19, 19)); + m_zoomOutButton->setGeometry(QRect(8, event->size().height() - 27, 18, 19)); + m_legendButton->setGeometry(QRect(event->size().width() - 24, event->size().height() - 24, 18, 18)); m_zoomInButton->setIconSize(QSize(15, 15)); m_zoomOutButton->setIconSize(QSize(15, 15)); + m_legendButton->setIconSize(QSize(10, 10)); emit resized(); } @@ -567,6 +576,11 @@ void QtGraphicsView::hideZoomLabel() m_zoomState->hide(); } +void QtGraphicsView::legendClicked() +{ + MessageActivateLegend().dispatch(); +} + bool QtGraphicsView::moves() const { return m_up || m_down || m_left || m_right; diff --git a/src/lib_gui/qt/graphics/QtGraphicsView.h b/src/lib_gui/qt/graphics/QtGraphicsView.h index 1b2da07f..ff61e6c8 100644 --- a/src/lib_gui/qt/graphics/QtGraphicsView.h +++ b/src/lib_gui/qt/graphics/QtGraphicsView.h @@ -67,6 +67,8 @@ private slots: void hideZoomLabel(); + void legendClicked(); + private: bool moves() const; @@ -104,6 +106,8 @@ private: QtSelfRefreshIconButton* m_zoomInButton; QtSelfRefreshIconButton* m_zoomOutButton; + QtSelfRefreshIconButton* m_legendButton; + float m_zoomInButtonSpeed; float m_zoomOutButtonSpeed; }; diff --git a/src/lib_gui/qt/view/QtGraphView.cpp b/src/lib_gui/qt/view/QtGraphView.cpp index 8e4bd49a..5c65629a 100644 --- a/src/lib_gui/qt/view/QtGraphView.cpp +++ b/src/lib_gui/qt/view/QtGraphView.cpp @@ -339,7 +339,8 @@ void QtGraphView::rebuildGraph( for (unsigned int i = 0; i < nodes.size(); i++) { - QtGraphNode* node = createNodeRecursive(view, nullptr, nodes[i].get(), activeNodeCount > 1); + QtGraphNode* node = + createNodeRecursive(view, nullptr, nodes[i].get(), activeNodeCount > 1, !params.disableInteraction); if (node) { m_nodes.push_back(node); @@ -367,14 +368,15 @@ void QtGraphView::rebuildGraph( { if (!edge->data || !edge->data->isType(Edge::EDGE_AGGREGATION)) { - createEdge(view, edge.get(), &visibleEdgeIds, trailMode, offset, params.bezierEdges); + createEdge( + view, edge.get(), &visibleEdgeIds, trailMode, offset, params.bezierEdges, !params.disableInteraction); } } for (const std::shared_ptr& edge : edges) { if (edge->data && edge->data->isType(Edge::EDGE_AGGREGATION)) { - createAggregationEdge(view, edge.get(), &visibleEdgeIds); + createAggregationEdge(view, edge.get(), &visibleEdgeIds, !params.disableInteraction); } } @@ -965,7 +967,7 @@ QtGraphNode* QtGraphView::findNodeRecursive(const std::list& nodes } QtGraphNode* QtGraphView::createNodeRecursive( - QGraphicsView* view, QtGraphNode* parentNode, const DummyNode* node, bool multipleActive + QGraphicsView* view, QtGraphNode* parentNode, const DummyNode* node, bool multipleActive, bool interactive ){ if (!node->visible) { @@ -975,7 +977,8 @@ QtGraphNode* QtGraphView::createNodeRecursive( QtGraphNode* newNode = nullptr; if (node->isGraphNode()) { - newNode = new QtGraphNodeData(node->data, node->name, node->childVisible, node->getQualifierNode() != nullptr); + newNode = new QtGraphNodeData( + node->data, node->name, node->childVisible, node->getQualifierNode() != nullptr, interactive); } else if (node->isAccessNode()) { @@ -995,7 +998,7 @@ QtGraphNode* QtGraphView::createNodeRecursive( } else if (node->isTextNode()) { - newNode = new QtGraphNodeText(node->name); + newNode = new QtGraphNodeText(node->name, node->fontSizeDiff); } else if (node->isGroupNode()) { @@ -1013,7 +1016,10 @@ QtGraphNode* QtGraphView::createNodeRecursive( newNode->setIsActive(node->active); newNode->setMultipleActive(multipleActive); - newNode->addComponent(std::make_shared(newNode)); + if (interactive) + { + newNode->addComponent(std::make_shared(newNode)); + } view->scene()->addItem(newNode); @@ -1021,7 +1027,7 @@ QtGraphNode* QtGraphView::createNodeRecursive( { newNode->setParent(parentNode); } - else if (!node->isTextNode()) + else if (!node->isTextNode() && interactive) { newNode->addComponent(std::make_shared(newNode)); } @@ -1033,7 +1039,7 @@ QtGraphNode* QtGraphView::createNodeRecursive( for (unsigned int i = 0; i < node->subNodes.size(); i++) { - QtGraphNode* subNode = createNodeRecursive(view, newNode, node->subNodes[i].get(), multipleActive); + QtGraphNode* subNode = createNodeRecursive(view, newNode, node->subNodes[i].get(), multipleActive, interactive); if (subNode) { newNode->addSubNode(subNode); @@ -1051,7 +1057,8 @@ QtGraphEdge* QtGraphView::createEdge( std::set* visibleEdgeIds, Graph::TrailMode trailMode, QPointF pathOffset, - bool useBezier) + bool useBezier, + bool interactive) { if (!edge->visible) { @@ -1064,7 +1071,7 @@ QtGraphEdge* QtGraphView::createEdge( if (owner != nullptr && target != nullptr) { QtGraphEdge* qtEdge = new QtGraphEdge( - owner, target, edge->data, edge->getWeight(), edge->active && !useBezier, edge->layoutHorizontal, + owner, target, edge->data, edge->getWeight(), edge->active && !useBezier, interactive, edge->layoutHorizontal, edge->getDirection()); if (trailMode != Graph::TRAIL_NONE) @@ -1112,7 +1119,7 @@ QtGraphEdge* QtGraphView::createEdge( } QtGraphEdge* QtGraphView::createAggregationEdge( - QGraphicsView* view, const DummyEdge* edge, std::set* visibleEdgeIds) + QGraphicsView* view, const DummyEdge* edge, std::set* visibleEdgeIds, bool interactive) { if (!edge->visible) { @@ -1135,7 +1142,7 @@ QtGraphEdge* QtGraphView::createAggregationEdge( return nullptr; } - return createEdge(view, edge, visibleEdgeIds, Graph::TRAIL_NONE, QPointF(), false); + return createEdge(view, edge, visibleEdgeIds, Graph::TRAIL_NONE, QPointF(), false, interactive); } QRectF QtGraphView::itemsBoundingRect(const std::list& items) const diff --git a/src/lib_gui/qt/view/QtGraphView.h b/src/lib_gui/qt/view/QtGraphView.h index 32649a16..a5e6d40e 100644 --- a/src/lib_gui/qt/view/QtGraphView.h +++ b/src/lib_gui/qt/view/QtGraphView.h @@ -103,12 +103,12 @@ private: QtGraphNode* findNodeRecursive(const std::list& nodes, Id tokenId); QtGraphNode* createNodeRecursive( - QGraphicsView* view, QtGraphNode* parentNode, const DummyNode* node, bool multipleActive); + QGraphicsView* view, QtGraphNode* parentNode, const DummyNode* node, bool multipleActive, bool interactive); QtGraphEdge* createEdge( QGraphicsView* view, const DummyEdge* edge, std::set* visibleEdgeIds, Graph::TrailMode trailMode, - QPointF pathOffset, bool useBezier); + QPointF pathOffset, bool useBezier, bool interactive); QtGraphEdge* createAggregationEdge( - QGraphicsView* view, const DummyEdge* edge, std::set* visibleEdgeIds); + QGraphicsView* view, const DummyEdge* edge, std::set* visibleEdgeIds, bool interactive); QRectF itemsBoundingRect(const std::list& items) const; QRectF getSceneRect(const std::list& items) const; diff --git a/src/lib_gui/qt/view/QtGraphViewStyleImpl.cpp b/src/lib_gui/qt/view/QtGraphViewStyleImpl.cpp index bfdc3446..c44804f3 100644 --- a/src/lib_gui/qt/view/QtGraphViewStyleImpl.cpp +++ b/src/lib_gui/qt/view/QtGraphViewStyleImpl.cpp @@ -1,22 +1,19 @@ #include "qt/view/QtGraphViewStyleImpl.h" +#include #include -#include "qt/view/graphElements/QtGraphNode.h" +#include "component/view/GraphViewStyle.h" #include "utility/utilityApp.h" -QtGraphViewStyleImpl::~QtGraphViewStyleImpl() +float QtGraphViewStyleImpl::getCharWidth(const std::string& fontName, size_t fontSize) { + return QFontMetrics(getFontForStyleType(fontName, fontSize)).width("QtGraphNode::QtGraphNode::QtGraphNode") / 37.0f; } -float QtGraphViewStyleImpl::getCharWidth(NodeType::StyleType type) +float QtGraphViewStyleImpl::getCharHeight(const std::string& fontName, size_t fontSize) { - return QFontMetrics(QtGraphNode::getFontForStyleType(type)).width("QtGraphNode::QtGraphNode::QtGraphNode") / 37.0f; -} - -float QtGraphViewStyleImpl::getCharHeight(NodeType::StyleType type) -{ - return QFontMetrics(QtGraphNode::getFontForStyleType(type)).height(); + return QFontMetrics(getFontForStyleType(fontName, fontSize)).height(); } float QtGraphViewStyleImpl::getGraphViewZoomDifferenceForPlatform() @@ -28,3 +25,10 @@ float QtGraphViewStyleImpl::getGraphViewZoomDifferenceForPlatform() return 1.25; } + +QFont QtGraphViewStyleImpl::getFontForStyleType(const std::string& fontName, size_t fontSize) const +{ + QFont font(fontName.c_str()); + font.setPixelSize(fontSize); + return font; +} diff --git a/src/lib_gui/qt/view/QtGraphViewStyleImpl.h b/src/lib_gui/qt/view/QtGraphViewStyleImpl.h index 3986a3bc..874ccf9c 100644 --- a/src/lib_gui/qt/view/QtGraphViewStyleImpl.h +++ b/src/lib_gui/qt/view/QtGraphViewStyleImpl.h @@ -3,14 +3,20 @@ #include "component/view/GraphViewStyleImpl.h" +class QFont; + class QtGraphViewStyleImpl : public GraphViewStyleImpl { public: - virtual ~QtGraphViewStyleImpl(); - virtual float getCharWidth(NodeType::StyleType type) override; - virtual float getCharHeight(NodeType::StyleType type) override; - virtual float getGraphViewZoomDifferenceForPlatform() override; + virtual ~QtGraphViewStyleImpl() = default; + + float getCharWidth(const std::string& fontName, size_t fontSize) override; + float getCharHeight(const std::string& fontName, size_t fontSize) override; + float getGraphViewZoomDifferenceForPlatform() override; + +private: + QFont getFontForStyleType(const std::string& fontName, size_t fontSize) const; }; #endif // QT_GRAPH_VIEW_STYLE_IMPL_H diff --git a/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp b/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp index 14860851..3add0a3c 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphEdge.cpp @@ -30,6 +30,7 @@ QtGraphEdge::QtGraphEdge( const Edge* data, size_t weight, bool isActive, + bool isInteractive, bool horizontal, TokenComponentAggregation::Direction direction ) @@ -44,6 +45,7 @@ QtGraphEdge::QtGraphEdge( , m_direction(direction) , m_isTrailEdge(false) , m_useBezier(false) + , m_isInteractive(isInteractive) , m_mousePos(0.0f, 0.0f) , m_mouseMoved(false) { @@ -401,7 +403,7 @@ void QtGraphEdge::mouseMoveEvent(QGraphicsSceneMouseEvent* event) void QtGraphEdge::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { - if (!m_mouseMoved) + if (!m_mouseMoved && m_isInteractive) { if (event->modifiers() & Qt::AltModifier) { diff --git a/src/lib_gui/qt/view/graphElements/QtGraphEdge.h b/src/lib_gui/qt/view/graphElements/QtGraphEdge.h index 18e65c28..e5d66080 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphEdge.h +++ b/src/lib_gui/qt/view/graphElements/QtGraphEdge.h @@ -27,6 +27,7 @@ public: const Edge* data, size_t weight, bool isActive, + bool isInteractive, bool horizontal, TokenComponentAggregation::Direction direction); virtual ~QtGraphEdge(); @@ -92,6 +93,7 @@ private: std::vector m_path; bool m_useBezier; + bool m_isInteractive; Vec2i m_mousePos; bool m_mouseMoved; diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp b/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp index f9a9ed60..7ffa3ebf 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphNode.cpp @@ -37,13 +37,6 @@ void QtGraphNode::hideNode() this->hide(); } -QFont QtGraphNode::getFontForStyleType(NodeType::StyleType type) -{ - QFont font(GraphViewStyle::getFontNameForDataNode().c_str()); - font.setPixelSize(GraphViewStyle::getFontSizeForStyleType(type)); - return font; -} - QtGraphNode::QtGraphNode() { this->setPen(QPen(Qt::transparent)); diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNode.h b/src/lib_gui/qt/view/graphElements/QtGraphNode.h index eec3cc79..06c4ad84 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNode.h +++ b/src/lib_gui/qt/view/graphElements/QtGraphNode.h @@ -31,8 +31,6 @@ public slots: void hideNode(); public: - static QFont getFontForStyleType(NodeType::StyleType type); - QtGraphNode(); virtual ~QtGraphNode(); diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp b/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp index 219979ff..ba5f1832 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeData.cpp @@ -5,14 +5,16 @@ #include "utility/messaging/type/MessageDeactivateEdge.h" #include "utility/messaging/type/MessageFocusIn.h" #include "utility/messaging/type/MessageFocusOut.h" +#include "utility/messaging/type/MessageTooltipShow.h" #include "utility/ResourcePaths.h" #include "data/graph/token_component/TokenComponentFilePath.h" -QtGraphNodeData::QtGraphNodeData(const Node* data, const std::wstring& name, bool childVisible, bool hasQualifier) +QtGraphNodeData::QtGraphNodeData(const Node* data, const std::wstring& name, bool childVisible, bool hasQualifier, bool isInteractive) : m_data(data) , m_childVisible(childVisible) , m_hasQualifier(hasQualifier) + , m_isInteractive(isInteractive) { this->setAcceptHoverEvents(true); this->setName(name); @@ -76,6 +78,26 @@ void QtGraphNodeData::updateStyle() void QtGraphNodeData::hoverEnterEvent(QGraphicsSceneHoverEvent* event) { MessageFocusIn(std::vector(1, m_data->getId()), TOOLTIP_ORIGIN_GRAPH).dispatch(); + + if (!m_isInteractive) + { + TooltipInfo info; + info.title = NodeType::getReadableTypeWString(m_data->getType().getType()); + info.offset = Vec2i(10, 20); + + if (!m_data->isDefined()) + { + info.title = L"non-indexed " + info.title; + } + else if (m_data->isImplicit()) + { + info.title = L"implicit " + info.title; + } + + MessageTooltipShow msg(info, TOOLTIP_ORIGIN_GRAPH); + msg.setSendAsTask(true); + msg.dispatch(); + } } void QtGraphNodeData::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeData.h b/src/lib_gui/qt/view/graphElements/QtGraphNodeData.h index 8aa85e48..60ac3c66 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeData.h +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeData.h @@ -10,7 +10,7 @@ class QtGraphNodeData { Q_OBJECT public: - QtGraphNodeData(const Node* data, const std::wstring& name, bool childVisible, bool hasQualifier); + QtGraphNodeData(const Node* data, const std::wstring& name, bool childVisible, bool hasQualifier, bool isInteractive); virtual ~QtGraphNodeData(); const Node* getData() const; @@ -32,6 +32,7 @@ private: const Node* m_data; bool m_childVisible; bool m_hasQualifier; + bool m_isInteractive; }; #endif // QT_GRAPH_NODE_DATA_H diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeText.cpp b/src/lib_gui/qt/view/graphElements/QtGraphNodeText.cpp index fa0e3e03..d825f48c 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeText.cpp +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeText.cpp @@ -1,6 +1,7 @@ #include "qt/view/graphElements/QtGraphNodeText.h" -QtGraphNodeText::QtGraphNodeText(const std::wstring& name) +QtGraphNodeText::QtGraphNodeText(const std::wstring& name, int fontSizeDiff) + : m_fontSizeDiff(fontSizeDiff) { setName(name); } @@ -16,5 +17,5 @@ bool QtGraphNodeText::isTextNode() const void QtGraphNodeText::updateStyle() { - setStyle(GraphViewStyle::getStyleOfTextNode()); + setStyle(GraphViewStyle::getStyleOfTextNode(m_fontSizeDiff)); } diff --git a/src/lib_gui/qt/view/graphElements/QtGraphNodeText.h b/src/lib_gui/qt/view/graphElements/QtGraphNodeText.h index da391bca..34691e82 100644 --- a/src/lib_gui/qt/view/graphElements/QtGraphNodeText.h +++ b/src/lib_gui/qt/view/graphElements/QtGraphNodeText.h @@ -8,13 +8,16 @@ class QtGraphNodeText { Q_OBJECT public: - QtGraphNodeText(const std::wstring& name); + QtGraphNodeText(const std::wstring& name, int fontSizeDiff); virtual ~QtGraphNodeText(); // QtGraphNode implementation virtual bool isTextNode() const; virtual void updateStyle(); + +private: + int m_fontSizeDiff; }; #endif // QT_GRAPH_NODE_TEXT_H diff --git a/src/test/StorageTestSuite.h b/src/test/StorageTestSuite.h index 304bd1aa..e35ab59b 100644 --- a/src/test/StorageTestSuite.h +++ b/src/test/StorageTestSuite.h @@ -21,7 +21,7 @@ public: std::wstring filePath = L"path/to/test.h"; std::shared_ptr intermetiateStorage = std::make_shared(); - Id id = intermetiateStorage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_FILE), NameHierarchy::serialize(NameHierarchy(filePath, NAME_DELIMITER_FILE)))); + Id id = intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_FILE), NameHierarchy::serialize(NameHierarchy(filePath, NAME_DELIMITER_FILE)))); intermetiateStorage->addFile(StorageFile(id, filePath, "someTime", true, true)); storage.inject(intermetiateStorage.get()); @@ -37,7 +37,7 @@ public: TestStorage storage; std::shared_ptr intermetiateStorage = std::make_shared(); - intermetiateStorage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_TYPEDEF), NameHierarchy::serialize(a))); + intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_TYPEDEF), NameHierarchy::serialize(a))); storage.inject(intermetiateStorage.get()); @@ -57,10 +57,10 @@ public: std::shared_ptr intermetiateStorage = std::make_shared(); - Id aId = intermetiateStorage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_STRUCT), NameHierarchy::serialize(a))); + Id aId = intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_STRUCT), NameHierarchy::serialize(a))); intermetiateStorage->addSymbol(StorageSymbol(aId, DEFINITION_EXPLICIT)); - Id bId = intermetiateStorage->addNode(StorageNodeData(utility::nodeTypeToInt(NodeType::NODE_FIELD), NameHierarchy::serialize(b))); + Id bId = intermetiateStorage->addNode(StorageNodeData(NodeType::typeToInt(NodeType::NODE_FIELD), NameHierarchy::serialize(b))); intermetiateStorage->addSymbol(StorageSymbol(bId, DEFINITION_EXPLICIT)); intermetiateStorage->addEdge(StorageEdgeData(Edge::typeToInt(Edge::EDGE_MEMBER), aId, bId));