ui: separated GraphView style settings into class GraphViewStyle
This change adds the class GraphViewStyle that holds all values for defining the style of Nodes and Edges in the Graph. The GraphViewStyleImpl interface and the QtGraphViewStyleImpl implementation are used to request Qt specific metrics, like the charwidth of used fonts. This change includes the following fixes: * aggregation number always in the middle between nodes * darker color for aggregation edge * split off QGraphicsLineItem implementations from QtGraphEdge * fixed some colors in color scheme fortune cookie message = Sorge dich nicht! Du wirst bekommen was du brauchst.
This commit is contained in:
@@ -54,6 +54,9 @@ add_files(
|
||||
component/view/CompositeView.h
|
||||
component/view/GraphView.cpp
|
||||
component/view/GraphView.h
|
||||
component/view/GraphViewStyle.cpp
|
||||
component/view/GraphViewStyle.h
|
||||
component/view/GraphViewStyleImpl.h
|
||||
component/view/MainView.cpp
|
||||
component/view/MainView.h
|
||||
component/view/RefreshView.cpp
|
||||
@@ -264,6 +267,8 @@ add_files(
|
||||
utility/ConfigManager.h
|
||||
utility/Property.h
|
||||
utility/types.h
|
||||
utility/utility.cpp
|
||||
utility/utility.h
|
||||
utility/utilityString.cpp
|
||||
utility/utilityString.h
|
||||
utility/Vector.h
|
||||
|
||||
@@ -7,22 +7,10 @@
|
||||
#include "component/view/graphElements/GraphEdge.h"
|
||||
#include "component/view/graphElements/GraphNode.h"
|
||||
#include "component/view/GraphView.h"
|
||||
#include "component/view/GraphViewStyle.h"
|
||||
#include "data/access/StorageAccess.h"
|
||||
#include "data/graph/Graph.h"
|
||||
|
||||
GraphController::Margins::Margins()
|
||||
: left(0)
|
||||
, right(0)
|
||||
, top(0)
|
||||
, bottom(0)
|
||||
, betweenX(0)
|
||||
, betweenY(0)
|
||||
, minWidth(0)
|
||||
, charWidth(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
GraphController::GraphController(StorageAccess* storageAccess)
|
||||
: m_storageAccess(storageAccess)
|
||||
{
|
||||
@@ -357,11 +345,6 @@ void GraphController::setNodeVisibilityRecursiveTopDown(DummyNode& node) const
|
||||
|
||||
void GraphController::layoutNesting()
|
||||
{
|
||||
if (!m_viewMetrics.width)
|
||||
{
|
||||
m_viewMetrics = getView()->getViewMetrics();
|
||||
}
|
||||
|
||||
for (DummyNode& node : m_dummyNodes)
|
||||
{
|
||||
layoutNestingRecursive(node);
|
||||
@@ -370,7 +353,26 @@ void GraphController::layoutNesting()
|
||||
|
||||
void GraphController::layoutNestingRecursive(DummyNode& node) const
|
||||
{
|
||||
Margins margins = getMarginsForDummyNode(node);
|
||||
GraphViewStyle::NodeMargins margins;
|
||||
|
||||
if (node.data)
|
||||
{
|
||||
margins = GraphViewStyle::getMarginsForNodeType(node.data->getType(), node.subNodes.size() > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
node.invisibleSubNodeCount = 0;
|
||||
for (const DummyNode& subNode : node.subNodes)
|
||||
{
|
||||
if (!subNode.visible)
|
||||
{
|
||||
node.invisibleSubNodeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
margins = GraphViewStyle::getMarginsOfAccessNode(
|
||||
node.isExpanded(), node.subNodes.size(), node.invisibleSubNodeCount);
|
||||
}
|
||||
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
@@ -410,7 +412,7 @@ void GraphController::layoutNestingRecursive(DummyNode& node) const
|
||||
|
||||
if (layoutHorizontal)
|
||||
{
|
||||
x += subNode.size.x + margins.betweenX;
|
||||
x += subNode.size.x + margins.spacingX;
|
||||
if (subNode.size.y > height)
|
||||
{
|
||||
height = subNode.size.y;
|
||||
@@ -418,7 +420,7 @@ void GraphController::layoutNestingRecursive(DummyNode& node) const
|
||||
}
|
||||
else
|
||||
{
|
||||
y += subNode.size.y + margins.betweenY;
|
||||
y += subNode.size.y + margins.spacingY;
|
||||
if (subNode.size.x > width)
|
||||
{
|
||||
width = subNode.size.x;
|
||||
@@ -428,11 +430,11 @@ void GraphController::layoutNestingRecursive(DummyNode& node) const
|
||||
|
||||
if (x > 0)
|
||||
{
|
||||
x -= margins.betweenX;
|
||||
x -= margins.spacingX;
|
||||
}
|
||||
if (y > 0)
|
||||
{
|
||||
y -= margins.betweenY;
|
||||
y -= margins.spacingY;
|
||||
}
|
||||
|
||||
if (layoutHorizontal && x > width)
|
||||
@@ -444,107 +446,6 @@ void GraphController::layoutNestingRecursive(DummyNode& node) const
|
||||
node.size.y = margins.top + y + height + margins.bottom;
|
||||
}
|
||||
|
||||
GraphController::Margins GraphController::getMarginsForDummyNode(DummyNode& node) const
|
||||
{
|
||||
Margins margins;
|
||||
margins.betweenX = margins.betweenY = 8;
|
||||
|
||||
if (node.data)
|
||||
{
|
||||
switch (node.data->getType())
|
||||
{
|
||||
case Node::NODE_UNDEFINED:
|
||||
case Node::NODE_NAMESPACE:
|
||||
margins.left = margins.right = 15;
|
||||
margins.top = 28;
|
||||
margins.bottom = 15;
|
||||
|
||||
margins.charWidth = m_viewMetrics.typeNameCharWidth;
|
||||
break;
|
||||
|
||||
case Node::NODE_UNDEFINED_TYPE:
|
||||
case Node::NODE_STRUCT:
|
||||
case Node::NODE_CLASS:
|
||||
case Node::NODE_ENUM:
|
||||
case Node::NODE_TYPEDEF:
|
||||
case Node::NODE_TEMPLATE_PARAMETER_TYPE:
|
||||
case Node::NODE_FILE:
|
||||
if (node.subNodes.size())
|
||||
{
|
||||
margins.left = margins.right = 15;
|
||||
margins.top = 30;
|
||||
margins.bottom = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
margins.left = margins.right = 8;
|
||||
margins.top = margins.bottom = 13;
|
||||
}
|
||||
|
||||
margins.charWidth = m_viewMetrics.typeNameCharWidth;
|
||||
break;
|
||||
|
||||
case Node::NODE_UNDEFINED_FUNCTION:
|
||||
case Node::NODE_FUNCTION:
|
||||
case Node::NODE_METHOD:
|
||||
margins.left = margins.right = 5;
|
||||
margins.top = margins.bottom = 10;
|
||||
|
||||
margins.charWidth = m_viewMetrics.functionNameCharWidth;
|
||||
break;
|
||||
|
||||
case Node::NODE_UNDEFINED_VARIABLE:
|
||||
case Node::NODE_GLOBAL_VARIABLE:
|
||||
case Node::NODE_FIELD:
|
||||
case Node::NODE_ENUM_CONSTANT:
|
||||
margins.left = margins.right = 5;
|
||||
margins.top = margins.bottom = 10;
|
||||
|
||||
margins.charWidth = m_viewMetrics.variableNameCharWidth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
node.invisibleSubNodeCount = 0;
|
||||
for (const DummyNode& subNode : node.subNodes)
|
||||
{
|
||||
if (!subNode.visible)
|
||||
{
|
||||
node.invisibleSubNodeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
margins.left = margins.right = 10;
|
||||
margins.top = 40;
|
||||
|
||||
if (node.invisibleSubNodeCount == node.subNodes.size())
|
||||
{
|
||||
margins.minWidth = 20;
|
||||
margins.bottom = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
margins.minWidth = 82;
|
||||
|
||||
if (node.isExpanded())
|
||||
{
|
||||
margins.bottom = 15;
|
||||
}
|
||||
else if (node.invisibleSubNodeCount)
|
||||
{
|
||||
margins.bottom = 23;
|
||||
}
|
||||
else
|
||||
{
|
||||
margins.bottom = 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return margins;
|
||||
}
|
||||
|
||||
DummyNode* GraphController::findDummyNodeRecursive(std::vector<DummyNode>& nodes, Id tokenId)
|
||||
{
|
||||
for (DummyNode& node : nodes)
|
||||
|
||||
@@ -27,23 +27,6 @@ class GraphController
|
||||
, public MessageListener<MessageGraphNodeMove>
|
||||
{
|
||||
public:
|
||||
struct Margins
|
||||
{
|
||||
Margins();
|
||||
|
||||
int left;
|
||||
int right;
|
||||
|
||||
int top;
|
||||
int bottom;
|
||||
|
||||
int betweenX;
|
||||
int betweenY;
|
||||
|
||||
int minWidth;
|
||||
float charWidth;
|
||||
};
|
||||
|
||||
GraphController(StorageAccess* storageAccess);
|
||||
~GraphController();
|
||||
|
||||
@@ -70,12 +53,10 @@ private:
|
||||
void layoutNesting();
|
||||
void layoutNestingRecursive(DummyNode& node) const;
|
||||
|
||||
Margins getMarginsForDummyNode(DummyNode& node) const;
|
||||
DummyNode* findDummyNodeRecursive(std::vector<DummyNode>& nodes, Id tokenId);
|
||||
DummyNode* findDummyNodeAccessRecursive(std::vector<DummyNode>& nodes, Id parentId, TokenComponentAccess::AccessType type);
|
||||
|
||||
StorageAccess* m_storageAccess;
|
||||
GraphView::Metrics m_viewMetrics;
|
||||
|
||||
std::vector<DummyNode> m_dummyNodes;
|
||||
std::vector<DummyEdge> m_dummyEdges;
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
#include "component/view/GraphView.h"
|
||||
|
||||
GraphView::Metrics::Metrics()
|
||||
: width(0)
|
||||
, height(0)
|
||||
, typeNameCharWidth(0.0f)
|
||||
, variableNameCharWidth(0.0f)
|
||||
, functionNameCharWidth(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
GraphView::GraphView(ViewLayout* viewLayout)
|
||||
: View(viewLayout)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#include "utility/math/Vector2.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
#include "component/view/View.h"
|
||||
@@ -15,18 +16,6 @@ class Graph;
|
||||
class GraphView : public View
|
||||
{
|
||||
public:
|
||||
struct Metrics
|
||||
{
|
||||
Metrics();
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
||||
float typeNameCharWidth;
|
||||
float variableNameCharWidth;
|
||||
float functionNameCharWidth;
|
||||
};
|
||||
|
||||
GraphView(ViewLayout* viewLayout);
|
||||
virtual ~GraphView();
|
||||
|
||||
@@ -36,7 +25,7 @@ public:
|
||||
std::shared_ptr<Graph> graph, const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges) = 0;
|
||||
virtual void clear() = 0;
|
||||
|
||||
virtual Metrics getViewMetrics() const = 0;
|
||||
virtual Vec2i getViewSize() const = 0;
|
||||
};
|
||||
|
||||
#endif // GRAPH_VIEW_H
|
||||
#endif // GRAPH_VIEW_H
|
||||
|
||||
@@ -0,0 +1,401 @@
|
||||
#include "component/view/GraphViewStyle.h"
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
#include "settings/ApplicationSettings.h"
|
||||
|
||||
GraphViewStyle::NodeMargins::NodeMargins()
|
||||
: left(0)
|
||||
, right(0)
|
||||
, top(0)
|
||||
, bottom(0)
|
||||
, spacingX(0)
|
||||
, spacingY(0)
|
||||
, minWidth(0)
|
||||
, charWidth(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
GraphViewStyle::NodeStyle::NodeStyle()
|
||||
: shadowBlurRadius(0)
|
||||
, cornerRadius(0)
|
||||
, borderWidth(0)
|
||||
, borderDashed(false)
|
||||
, fontSize(0)
|
||||
, fontBold(false)
|
||||
, undefinedPattern(false)
|
||||
{
|
||||
}
|
||||
|
||||
GraphViewStyle::EdgeStyle::EdgeStyle()
|
||||
: width(0)
|
||||
, zValue(0)
|
||||
, isStraight(false)
|
||||
, arrowLength(0)
|
||||
, arrowWidth(0)
|
||||
, arrowClosed(false)
|
||||
, cornerRadius(0)
|
||||
, verticalOffset(0)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<GraphViewStyleImpl> GraphViewStyle::getImpl()
|
||||
{
|
||||
if (!s_impl)
|
||||
{
|
||||
LOG_ERROR("No GraphViewStyleImpl instance set.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return s_impl;
|
||||
}
|
||||
|
||||
void GraphViewStyle::setImpl(std::shared_ptr<GraphViewStyleImpl> impl)
|
||||
{
|
||||
s_impl = impl;
|
||||
}
|
||||
|
||||
float GraphViewStyle::getCharWidthForNodeType(Node::NodeType type)
|
||||
{
|
||||
std::map<Node::NodeType, float>::const_iterator it = s_charWidths.find(type);
|
||||
|
||||
if (it != s_charWidths.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
float charWidth = getImpl()->getCharWidthForNodeType(type);
|
||||
s_charWidths.emplace(type, charWidth);
|
||||
return charWidth;
|
||||
}
|
||||
|
||||
size_t GraphViewStyle::getFontSizeForNodeType(Node::NodeType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Node::NODE_UNDEFINED:
|
||||
case Node::NODE_NAMESPACE:
|
||||
return 12;
|
||||
|
||||
case Node::NODE_UNDEFINED_TYPE:
|
||||
case Node::NODE_STRUCT:
|
||||
case Node::NODE_CLASS:
|
||||
case Node::NODE_ENUM:
|
||||
case Node::NODE_TYPEDEF:
|
||||
case Node::NODE_TEMPLATE_PARAMETER_TYPE:
|
||||
case Node::NODE_FILE:
|
||||
return 14;
|
||||
|
||||
case Node::NODE_UNDEFINED_FUNCTION:
|
||||
case Node::NODE_UNDEFINED_VARIABLE:
|
||||
case Node::NODE_FUNCTION:
|
||||
case Node::NODE_METHOD:
|
||||
case Node::NODE_GLOBAL_VARIABLE:
|
||||
case Node::NODE_FIELD:
|
||||
case Node::NODE_ENUM_CONSTANT:
|
||||
return 11;
|
||||
}
|
||||
}
|
||||
|
||||
size_t GraphViewStyle::getFontSizeOfAccessNode()
|
||||
{
|
||||
return 11;
|
||||
}
|
||||
|
||||
size_t GraphViewStyle::getFontSizeOfNumber()
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
|
||||
std::string GraphViewStyle::getFontNameForNodeType(Node::NodeType type)
|
||||
{
|
||||
return "Source Code Pro";
|
||||
}
|
||||
|
||||
std::string GraphViewStyle::getFontNameOfAccessNode()
|
||||
{
|
||||
return "Myriad Pro";
|
||||
}
|
||||
|
||||
std::string GraphViewStyle::getFontNameOfNumber()
|
||||
{
|
||||
return "Myriad Pro";
|
||||
}
|
||||
|
||||
GraphViewStyle::NodeMargins GraphViewStyle::getMarginsForNodeType(Node::NodeType type, bool hasChildren)
|
||||
{
|
||||
NodeMargins margins;
|
||||
margins.spacingX = margins.spacingY = 8;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Node::NODE_UNDEFINED:
|
||||
case Node::NODE_NAMESPACE:
|
||||
margins.left = margins.right = 15;
|
||||
margins.top = 28;
|
||||
margins.bottom = 15;
|
||||
break;
|
||||
|
||||
case Node::NODE_UNDEFINED_TYPE:
|
||||
case Node::NODE_STRUCT:
|
||||
case Node::NODE_CLASS:
|
||||
case Node::NODE_ENUM:
|
||||
case Node::NODE_TYPEDEF:
|
||||
case Node::NODE_TEMPLATE_PARAMETER_TYPE:
|
||||
case Node::NODE_FILE:
|
||||
if (hasChildren)
|
||||
{
|
||||
margins.left = margins.right = 15;
|
||||
margins.top = 30;
|
||||
margins.bottom = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
margins.left = margins.right = 8;
|
||||
margins.top = margins.bottom = 13;
|
||||
}
|
||||
break;
|
||||
|
||||
case Node::NODE_UNDEFINED_FUNCTION:
|
||||
case Node::NODE_FUNCTION:
|
||||
case Node::NODE_METHOD:
|
||||
margins.left = margins.right = 5;
|
||||
margins.top = margins.bottom = 10;
|
||||
break;
|
||||
|
||||
case Node::NODE_UNDEFINED_VARIABLE:
|
||||
case Node::NODE_GLOBAL_VARIABLE:
|
||||
case Node::NODE_FIELD:
|
||||
case Node::NODE_ENUM_CONSTANT:
|
||||
margins.left = margins.right = 5;
|
||||
margins.top = margins.bottom = 10;
|
||||
break;
|
||||
}
|
||||
|
||||
margins.charWidth = getCharWidthForNodeType(type);
|
||||
|
||||
return margins;
|
||||
}
|
||||
|
||||
GraphViewStyle::NodeMargins GraphViewStyle::getMarginsOfAccessNode(
|
||||
bool expanded, size_t subNodeCount, size_t invisibleSubNodeCount
|
||||
){
|
||||
NodeMargins margins;
|
||||
margins.spacingX = margins.spacingY = 8;
|
||||
|
||||
margins.left = margins.right = 10;
|
||||
margins.top = 40;
|
||||
|
||||
if (invisibleSubNodeCount == subNodeCount)
|
||||
{
|
||||
margins.minWidth = 20;
|
||||
margins.bottom = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
margins.minWidth = 82;
|
||||
|
||||
if (expanded)
|
||||
{
|
||||
margins.bottom = 15;
|
||||
}
|
||||
else if (invisibleSubNodeCount)
|
||||
{
|
||||
margins.bottom = 23;
|
||||
}
|
||||
else
|
||||
{
|
||||
margins.bottom = 10;
|
||||
}
|
||||
}
|
||||
|
||||
return margins;
|
||||
}
|
||||
|
||||
GraphViewStyle::NodeStyle GraphViewStyle::getStyleForNodeType(
|
||||
Node::NodeType type, bool isActive, bool isFocused, bool hasChildren
|
||||
){
|
||||
NodeStyle style;
|
||||
|
||||
style.color = "#D3D3D3";
|
||||
style.borderColor = "#00000000";
|
||||
|
||||
style.fontName = getFontNameForNodeType(type);
|
||||
style.fontSize = getFontSizeForNodeType(type);
|
||||
|
||||
if (isActive)
|
||||
{
|
||||
style.borderColor = "#3c3c3c";
|
||||
}
|
||||
|
||||
if (isActive || isFocused)
|
||||
{
|
||||
style.color = ApplicationSettings::getInstance()->getNodeTypeColor(type, "hover");
|
||||
}
|
||||
else
|
||||
{
|
||||
style.color = ApplicationSettings::getInstance()->getNodeTypeColor(type);
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Node::NODE_UNDEFINED:
|
||||
style.borderDashed = true;
|
||||
|
||||
case Node::NODE_NAMESPACE:
|
||||
style.borderColor = "#cc8d91";
|
||||
style.borderWidth = 1;
|
||||
|
||||
style.cornerRadius = 20;
|
||||
|
||||
style.textOffset.x = 15;
|
||||
style.textOffset.y = 6;
|
||||
break;
|
||||
|
||||
case Node::NODE_UNDEFINED_TYPE:
|
||||
style.undefinedPattern = true;
|
||||
|
||||
case Node::NODE_STRUCT:
|
||||
case Node::NODE_CLASS:
|
||||
case Node::NODE_ENUM:
|
||||
case Node::NODE_TYPEDEF:
|
||||
case Node::NODE_TEMPLATE_PARAMETER_TYPE:
|
||||
case Node::NODE_FILE:
|
||||
if (isActive)
|
||||
{
|
||||
style.fontBold = true;
|
||||
}
|
||||
|
||||
if (isFocused)
|
||||
{
|
||||
style.shadowColor = "#FF000000";
|
||||
}
|
||||
else
|
||||
{
|
||||
style.shadowColor = "#80000000";
|
||||
}
|
||||
style.shadowBlurRadius = 5;
|
||||
|
||||
if (hasChildren)
|
||||
{
|
||||
style.cornerRadius = 20;
|
||||
style.textOffset.x = 15;
|
||||
style.textOffset.y = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
style.cornerRadius = 10;
|
||||
style.textOffset.x = 8;
|
||||
style.textOffset.y = 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case Node::NODE_UNDEFINED_FUNCTION:
|
||||
case Node::NODE_UNDEFINED_VARIABLE:
|
||||
style.undefinedPattern = true;
|
||||
|
||||
case Node::NODE_FUNCTION:
|
||||
case Node::NODE_METHOD:
|
||||
case Node::NODE_GLOBAL_VARIABLE:
|
||||
case Node::NODE_FIELD:
|
||||
case Node::NODE_ENUM_CONSTANT:
|
||||
if (isActive || isFocused)
|
||||
{
|
||||
style.fontBold = true;
|
||||
}
|
||||
|
||||
style.cornerRadius = 8;
|
||||
style.textOffset.x = 5;
|
||||
style.textOffset.y = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isActive)
|
||||
{
|
||||
style.borderWidth = 1.5f;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
GraphViewStyle::NodeStyle GraphViewStyle::getStyleOfAccessNode()
|
||||
{
|
||||
NodeStyle style;
|
||||
|
||||
style.color = "#FFFFFF";
|
||||
style.borderColor = "#00000000";
|
||||
|
||||
style.cornerRadius = 12;
|
||||
|
||||
style.fontName = getFontNameOfAccessNode();
|
||||
style.fontSize = getFontSizeOfAccessNode();
|
||||
style.fontBold = true;
|
||||
|
||||
style.textOffset.x = 10;
|
||||
style.textOffset.y = 10;
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
GraphViewStyle::EdgeStyle GraphViewStyle::getStyleForEdgeType(Edge::EdgeType type, bool isActive, bool isFocused)
|
||||
{
|
||||
EdgeStyle style;
|
||||
|
||||
style.width = isActive ? 2 : 1;
|
||||
style.zValue = isActive ? 5 : 1;
|
||||
|
||||
style.arrowLength = 5;
|
||||
style.arrowWidth = 8;
|
||||
|
||||
style.cornerRadius = 10;
|
||||
style.verticalOffset = 2;
|
||||
|
||||
style.originOffset.x = 17;
|
||||
style.targetOffset.x = 17;
|
||||
|
||||
style.originOffset.y = -1;
|
||||
style.targetOffset.y = 1;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Edge::EDGE_AGGREGATION:
|
||||
style.isStraight = true;
|
||||
style.color = isActive ? "#DDD" : "#EEE";
|
||||
style.width = 1;
|
||||
style.zValue = isActive ? -1 : -5;
|
||||
break;
|
||||
|
||||
case Edge::EDGE_CALL:
|
||||
style.color = "#F1C100";
|
||||
style.originOffset.y = 1;
|
||||
style.targetOffset.y = -1;
|
||||
style.verticalOffset = 4;
|
||||
break;
|
||||
case Edge::EDGE_USAGE:
|
||||
style.color = "#62B29D";
|
||||
style.originOffset.y = 3;
|
||||
style.targetOffset.y = -3;
|
||||
style.verticalOffset = 6;
|
||||
break;
|
||||
case Edge::EDGE_INHERITANCE:
|
||||
style.arrowLength = 15;
|
||||
style.arrowWidth = 20;
|
||||
style.arrowClosed = true;
|
||||
style.targetOffset.x = 29;
|
||||
case Edge::EDGE_OVERRIDE:
|
||||
style.color = "#CC5E89";
|
||||
break;
|
||||
case Edge::EDGE_INCLUDE:
|
||||
style.color = "#87BA50";
|
||||
break;
|
||||
|
||||
default:
|
||||
style.color = "#878787";
|
||||
break;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
std::map<Node::NodeType, float> GraphViewStyle::s_charWidths;
|
||||
std::shared_ptr<GraphViewStyleImpl> GraphViewStyle::s_impl;
|
||||
@@ -0,0 +1,103 @@
|
||||
#ifndef GRAPH_VIEW_STYLE_H
|
||||
#define GRAPH_VIEW_STYLE_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include "component/view/graphElements/GraphNode.h"
|
||||
#include "component/view/GraphViewStyleImpl.h"
|
||||
#include "data/graph/Node.h"
|
||||
|
||||
class GraphViewStyle
|
||||
{
|
||||
public:
|
||||
struct NodeMargins
|
||||
{
|
||||
NodeMargins();
|
||||
|
||||
int left;
|
||||
int right;
|
||||
|
||||
int top;
|
||||
int bottom;
|
||||
|
||||
int spacingX;
|
||||
int spacingY;
|
||||
|
||||
int minWidth;
|
||||
float charWidth;
|
||||
};
|
||||
|
||||
struct NodeStyle
|
||||
{
|
||||
NodeStyle();
|
||||
|
||||
std::string color;
|
||||
|
||||
std::string shadowColor;
|
||||
int shadowBlurRadius;
|
||||
|
||||
int cornerRadius;
|
||||
|
||||
float borderWidth;
|
||||
std::string borderColor;
|
||||
bool borderDashed;
|
||||
|
||||
std::string fontName;
|
||||
size_t fontSize;
|
||||
bool fontBold;
|
||||
|
||||
Vec2i textOffset;
|
||||
|
||||
bool undefinedPattern;
|
||||
};
|
||||
|
||||
struct EdgeStyle
|
||||
{
|
||||
EdgeStyle();
|
||||
|
||||
std::string color;
|
||||
|
||||
float width;
|
||||
int zValue;
|
||||
|
||||
bool isStraight;
|
||||
|
||||
int arrowLength;
|
||||
int arrowWidth;
|
||||
bool arrowClosed;
|
||||
|
||||
int cornerRadius;
|
||||
int verticalOffset;
|
||||
|
||||
Vec2i originOffset;
|
||||
Vec2i targetOffset;
|
||||
};
|
||||
|
||||
static std::shared_ptr<GraphViewStyleImpl> getImpl();
|
||||
static void setImpl(std::shared_ptr<GraphViewStyleImpl> impl);
|
||||
|
||||
static float getCharWidthForNodeType(Node::NodeType type);
|
||||
|
||||
static size_t getFontSizeForNodeType(Node::NodeType type);
|
||||
static size_t getFontSizeOfAccessNode();
|
||||
static size_t getFontSizeOfNumber();
|
||||
|
||||
static std::string getFontNameForNodeType(Node::NodeType type);
|
||||
static std::string getFontNameOfAccessNode();
|
||||
static std::string getFontNameOfNumber();
|
||||
|
||||
static NodeMargins getMarginsForNodeType(Node::NodeType type, bool hasChildren);
|
||||
static NodeMargins getMarginsOfAccessNode(bool expanded, size_t subNodeCount, size_t invisibleSubNodeCount);
|
||||
|
||||
static NodeStyle getStyleForNodeType(Node::NodeType type, bool isActive, bool isFocused, bool hasChildren);
|
||||
static NodeStyle getStyleOfAccessNode();
|
||||
|
||||
static EdgeStyle getStyleForEdgeType(Edge::EdgeType type, bool isActive, bool isFocused);
|
||||
|
||||
private:
|
||||
static std::map<Node::NodeType, float> s_charWidths;
|
||||
static std::shared_ptr<GraphViewStyleImpl> s_impl;
|
||||
};
|
||||
|
||||
#endif // GRAPH_VIEW_STYLE_H
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef GRAPH_VIEW_STYLE_IMPL_H
|
||||
#define GRAPH_VIEW_STYLE_IMPL_H
|
||||
|
||||
#include "data/graph/Node.h"
|
||||
|
||||
class GraphViewStyleImpl
|
||||
{
|
||||
public:
|
||||
virtual float getCharWidthForNodeType(Node::NodeType type) = 0;
|
||||
};
|
||||
|
||||
#endif // GRAPH_VIEW_STYLE_IMPL_H
|
||||
@@ -37,11 +37,11 @@ public:
|
||||
virtual Vec4i getBoundingRect() const = 0;
|
||||
virtual Vec4i getParentBoundingRect() const = 0;
|
||||
|
||||
virtual bool addOutEdge(const std::shared_ptr<GraphEdge>& edge) = 0;
|
||||
virtual bool addInEdge(const std::weak_ptr<GraphEdge>& edge) = 0;
|
||||
virtual void addOutEdge(const std::shared_ptr<GraphEdge>& edge) = 0;
|
||||
virtual void addInEdge(const std::weak_ptr<GraphEdge>& edge) = 0;
|
||||
|
||||
virtual unsigned int getOutEdgeCount() const = 0;
|
||||
virtual unsigned int getInEdgeCount() const = 0;
|
||||
virtual size_t getOutEdgeCount() const = 0;
|
||||
virtual size_t getInEdgeCount() const = 0;
|
||||
|
||||
protected:
|
||||
const Node* m_data;
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "utility/utility.h"
|
||||
|
||||
float utility::duration(std::function<void()> func)
|
||||
{
|
||||
std::chrono::time_point<std::chrono::system_clock> start = std::chrono::system_clock::now();
|
||||
|
||||
func();
|
||||
|
||||
std::chrono::duration<float> duration =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start);
|
||||
return duration.count();
|
||||
}
|
||||
|
||||
bool utility::intersectionPoint(Vec2f a1, Vec2f b1, Vec2f a2, Vec2f b2, Vec2f* i)
|
||||
{
|
||||
Vec2f p = a1;
|
||||
Vec2f v = b1 - a1;
|
||||
Vec2f q = a2;
|
||||
Vec2f w = b2 - a2;
|
||||
|
||||
float denominator = v.x * w.y - v.y * w.x;
|
||||
if (denominator != 0)
|
||||
{
|
||||
float t = (p.y * w.x - p.x * w.y + q.x * w.y - q.y * w.x) / denominator;
|
||||
float s = (q.y * v.x - q.x * v.y + p.x * v.y - p.y * v.x) / -denominator;
|
||||
|
||||
if (t >= 0 && t <= 1 && s >= 0 && s <= 1)
|
||||
{
|
||||
*i = p + v * t;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
+30
-25
@@ -2,40 +2,45 @@
|
||||
#define UTILITY_H
|
||||
|
||||
#include <chrono>
|
||||
#include <set>
|
||||
|
||||
#include "utility/math/Vector2.h"
|
||||
|
||||
namespace utility
|
||||
{
|
||||
float duration(std::function<void()> func)
|
||||
{
|
||||
std::chrono::time_point<std::chrono::system_clock> start = std::chrono::system_clock::now();
|
||||
|
||||
func();
|
||||
|
||||
std::chrono::duration<float> duration =
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start);
|
||||
return duration.count();
|
||||
}
|
||||
float duration(std::function<void()> func);
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> concat(const std::vector<T>& a, const std::vector<T>& b)
|
||||
{
|
||||
std::vector<T> r(a.size() + b.size());
|
||||
append(r, a);
|
||||
append(r, b);
|
||||
return r;
|
||||
}
|
||||
std::vector<T> concat(const std::vector<T>& a, const std::vector<T>& b);
|
||||
|
||||
template<typename T>
|
||||
void append(std::vector<T>& a, const std::vector<T>& b)
|
||||
{
|
||||
a.insert(a.begin(), b.begin(), b.end());
|
||||
}
|
||||
void append(std::vector<T>& a, const std::vector<T>& b);
|
||||
|
||||
template<typename T>
|
||||
void append(std::set<T>& a, const std::set<T>& b)
|
||||
{
|
||||
a.insert(b.begin(), b.end());
|
||||
}
|
||||
void append(std::set<T>& a, const std::set<T>& b);
|
||||
|
||||
bool intersectionPoint(Vec2f a1, Vec2f b1, Vec2f a2, Vec2f b2, Vec2f* i);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> utility::concat(const std::vector<T>& a, const std::vector<T>& b)
|
||||
{
|
||||
std::vector<T> r(a.size() + b.size());
|
||||
append(r, a);
|
||||
append(r, b);
|
||||
return r;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void utility::append(std::vector<T>& a, const std::vector<T>& b)
|
||||
{
|
||||
a.insert(a.begin(), b.begin(), b.end());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void utility::append(std::set<T>& a, const std::set<T>& b)
|
||||
{
|
||||
a.insert(b.begin(), b.end());
|
||||
}
|
||||
|
||||
#endif // UTILITY_H
|
||||
|
||||
Reference in New Issue
Block a user