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:
@@ -50,15 +50,15 @@
|
||||
<!-- NodeType -->
|
||||
<class>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
<hover>#ededed</hover>
|
||||
</class>
|
||||
<struct>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
<hover>#ededed</hover>
|
||||
</struct>
|
||||
<enum>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
<hover>#ededed</hover>
|
||||
</enum>
|
||||
<function>
|
||||
<normal>#ffe47a</normal>
|
||||
@@ -77,32 +77,28 @@
|
||||
<hover>#62b29d</hover>
|
||||
</global>
|
||||
<undefined>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
<normal>#00000000</normal>
|
||||
<hover>#00000000</hover>
|
||||
</undefined>
|
||||
<undefined_variable>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
<normal>#9ab4ad</normal>
|
||||
<hover>#62b29d</hover>
|
||||
</undefined_variable>
|
||||
<undefined_function>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
<normal>#ffe47a</normal>
|
||||
<hover>#ffcc00</hover>
|
||||
</undefined_function>
|
||||
<undefined_type>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
<hover>#ededed</hover>
|
||||
</undefined_type>
|
||||
<none>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
</none>
|
||||
<namespace>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
<normal>#00000000</normal>
|
||||
<hover>#00000000</hover>
|
||||
</namespace>
|
||||
<typedef>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
<hover>#ededed</hover>
|
||||
</typedef>
|
||||
<enum_constant>
|
||||
<normal>#9ab4ad</normal>
|
||||
@@ -110,7 +106,7 @@
|
||||
</enum_constant>
|
||||
<template_parameter_type>
|
||||
<normal>#ededed</normal>
|
||||
<hover>#dddddd</hover>
|
||||
<hover>#ededed</hover>
|
||||
</template_parameter_type>
|
||||
<file>
|
||||
<normal>#A3BA8A</normal>
|
||||
|
||||
@@ -26,8 +26,12 @@ add_files(
|
||||
qt/element/QtUndoRedo.cpp
|
||||
qt/element/QtUndoRedo.h
|
||||
|
||||
qt/graphics/QtGraphicsRoundedRectItem.cpp
|
||||
qt/graphics/QtGraphicsRoundedRectItem.h
|
||||
qt/graphics/QtAngledLineItem.cpp
|
||||
qt/graphics/QtAngledLineItem.h
|
||||
qt/graphics/QtRoundedRectItem.cpp
|
||||
qt/graphics/QtRoundedRectItem.h
|
||||
qt/graphics/QtStraightLineItem.cpp
|
||||
qt/graphics/QtStraightLineItem.h
|
||||
|
||||
qt/utility/QtDeviceScaledPixmap.h
|
||||
qt/utility/QtGraphPostprocessor.cpp
|
||||
@@ -58,6 +62,8 @@ add_files(
|
||||
qt/view/QtCompositeView.h
|
||||
qt/view/QtGraphView.cpp
|
||||
qt/view/QtGraphView.h
|
||||
qt/view/QtGraphViewStyleImpl.cpp
|
||||
qt/view/QtGraphViewStyleImpl.h
|
||||
qt/view/QtMainView.cpp
|
||||
qt/view/QtMainView.h
|
||||
qt/view/QtRefreshView.cpp
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
#include "qt/graphics/QtAngledLineItem.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
#include "utility/math/Vector2.h"
|
||||
|
||||
QtAngledLineItem::QtAngledLineItem(QGraphicsItem* parent)
|
||||
: QGraphicsLineItem(parent)
|
||||
{
|
||||
this->setAcceptHoverEvents(true);
|
||||
}
|
||||
|
||||
QtAngledLineItem::~QtAngledLineItem()
|
||||
{
|
||||
}
|
||||
|
||||
void QtAngledLineItem::updateLine(
|
||||
Vec4i ownerRect, Vec4i targetRect,
|
||||
Vec4i ownerParentRect, Vec4i targetParentRect,
|
||||
GraphViewStyle::EdgeStyle style
|
||||
){
|
||||
prepareGeometryChange();
|
||||
|
||||
m_ownerRect = ownerRect;
|
||||
m_targetRect = targetRect;
|
||||
m_ownerParentRect = ownerParentRect;
|
||||
m_targetParentRect = targetParentRect;
|
||||
|
||||
m_ownerRect.x = m_ownerRect.x - 1;
|
||||
m_ownerRect.z = m_ownerRect.z + 1;
|
||||
m_targetRect.x = m_targetRect.x - 1;
|
||||
m_targetRect.z = m_targetRect.z + 1;
|
||||
|
||||
m_style = style;
|
||||
|
||||
this->setPen(QPen(QBrush(style.color.c_str()), style.width, Qt::SolidLine, Qt::RoundCap));
|
||||
}
|
||||
|
||||
QPainterPath QtAngledLineItem::shape() const
|
||||
{
|
||||
int w = m_style.arrowWidth / 2 + 1;
|
||||
QPainterPath path;
|
||||
QPolygon poly = getPath();
|
||||
for (int i = 0; i < poly.size() - 1; i++)
|
||||
{
|
||||
path.addRect(QRectF(poly.at(i), poly.at(i + 1)).normalized().adjusted(-w, -w, w, w));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
void QtAngledLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem* options, QWidget* widget)
|
||||
{
|
||||
painter->setPen(pen());
|
||||
|
||||
QPainterPath path;
|
||||
|
||||
QPolygon poly = getPath();
|
||||
int i = poly.length() - 1;
|
||||
|
||||
path.moveTo(poly.at(i));
|
||||
|
||||
int radius = m_style.cornerRadius;
|
||||
int dir = getDirection(poly.at(i), poly.at(i - 1));
|
||||
while (i > 1)
|
||||
{
|
||||
i--;
|
||||
|
||||
QPointF a = poly.at(i);
|
||||
QPointF b = poly.at(i - 1);
|
||||
|
||||
int newDir = getDirection(a, b);
|
||||
int ar = radius;
|
||||
int br = m_style.cornerRadius;
|
||||
|
||||
if (i != 1)
|
||||
{
|
||||
if (dir % 2 == 1 && std::abs(a.y() - b.y()) < 2 * br)
|
||||
{
|
||||
br = std::abs(a.y() - b.y()) / 2;
|
||||
}
|
||||
else if (dir % 2 == 0 && std::abs(a.x() - b.x()) < 2 * br)
|
||||
{
|
||||
br = std::abs(a.x() - b.x()) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case 0: a.setY(a.y() + ar); break;
|
||||
case 1: a.setX(a.x() - ar); break;
|
||||
case 2: a.setY(a.y() - ar); break;
|
||||
case 3: a.setX(a.x() + ar); break;
|
||||
}
|
||||
|
||||
b = poly.at(i);
|
||||
switch (newDir)
|
||||
{
|
||||
case 0: b.setY(b.y() - br); break;
|
||||
case 1: b.setX(b.x() + br); break;
|
||||
case 2: b.setY(b.y() + br); break;
|
||||
case 3: b.setX(b.x() - br); break;
|
||||
}
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case 0:
|
||||
if (newDir == 1)
|
||||
{
|
||||
path.arcTo(a.x(), b.y(), 2 * br, 2 * ar, 180, -90);
|
||||
}
|
||||
else if (newDir == 3)
|
||||
{
|
||||
path.arcTo(b.x() - br, a.y() - ar, 2 * br, 2 * ar, 0, 90);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (newDir == 0)
|
||||
{
|
||||
path.arcTo(a.x() - ar, b.y() - br, 2 * ar, 2 * br, -90, 90);
|
||||
}
|
||||
else if (newDir == 2)
|
||||
{
|
||||
path.arcTo(a.x() - ar, a.y(), 2 * ar, 2 * br, 90, -90);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (newDir == 1)
|
||||
{
|
||||
path.arcTo(a.x(), a.y() - ar, 2 * br, 2 * ar, 180, 90);
|
||||
}
|
||||
else if (newDir == 3)
|
||||
{
|
||||
path.arcTo(b.x() - br, a.y() - ar, 2 * br, 2 * ar, 0, -90);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (newDir == 0)
|
||||
{
|
||||
path.arcTo(b.x(), b.y() - br, 2 * ar, 2 * br, -90, -90);
|
||||
}
|
||||
else if (newDir == 2)
|
||||
{
|
||||
path.arcTo(b.x(), a.y(), 2 * ar, 2 * br, 90, 90);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
dir = newDir;
|
||||
radius = br;
|
||||
}
|
||||
|
||||
QPointF arrow = poly.at(0) + QPointF((poly.at(0).x() - poly.at(1).x() > 0 ? -1 : 1) * m_style.arrowLength, 0);
|
||||
|
||||
if (m_style.arrowClosed)
|
||||
{
|
||||
path.lineTo(arrow);
|
||||
path.moveTo(poly.at(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
path.lineTo(poly.at(0));
|
||||
}
|
||||
|
||||
arrow.setY(arrow.y() - m_style.arrowWidth / 2);
|
||||
path.lineTo(arrow);
|
||||
arrow.setY(arrow.y() + m_style.arrowWidth);
|
||||
|
||||
if (m_style.arrowClosed)
|
||||
{
|
||||
path.lineTo(arrow);
|
||||
}
|
||||
else
|
||||
{
|
||||
path.moveTo(arrow);
|
||||
}
|
||||
path.lineTo(poly.at(0));
|
||||
|
||||
painter->drawPath(path);
|
||||
}
|
||||
|
||||
QPolygon QtAngledLineItem::getPath() const
|
||||
{
|
||||
const Vec4i& oR = m_ownerRect;
|
||||
const Vec4i& tR = m_targetRect;
|
||||
|
||||
Vec2f o[2] = { Vec2f(m_ownerParentRect.x, (oR.y + 2 * oR.w) / 3), Vec2f(m_ownerParentRect.z, (oR.y + 2 * oR.w) / 3) };
|
||||
Vec2f t[2] = { Vec2f(m_targetParentRect.x, (2 * tR.y + tR.w) / 3), Vec2f(m_targetParentRect.z, (2 * tR.y + tR.w) / 3) };
|
||||
|
||||
int io = -1;
|
||||
int it = -1;
|
||||
float dist = -1;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
Vec2f diff = o[i] - t[j];
|
||||
if (dist < 0 || diff.getLength() < dist)
|
||||
{
|
||||
dist = diff.getLength();
|
||||
io = i;
|
||||
it = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPoint tp((it ? 1 : -1) * m_style.targetOffset.x + t[it].x, t[it].y + m_style.targetOffset.y);
|
||||
QPoint op((io ? 1 : -1) * m_style.originOffset.x + o[io].x, o[io].y + m_style.originOffset.y);
|
||||
|
||||
if (it != io)
|
||||
{
|
||||
if (it && tp.x() < op.x())
|
||||
{
|
||||
io = 0;
|
||||
op = QPoint(o[io].x - m_style.originOffset.x, o[io].y + m_style.originOffset.y);
|
||||
}
|
||||
else if (!it && tp.x() < op.x())
|
||||
{
|
||||
it = 1;
|
||||
tp = QPoint(t[it].x + m_style.targetOffset.x, t[it].y + m_style.targetOffset.y);
|
||||
}
|
||||
else if (io && tp.x() > op.x())
|
||||
{
|
||||
io = 1;
|
||||
op = QPoint(o[io].x + m_style.originOffset.x, o[io].y + m_style.originOffset.y);
|
||||
}
|
||||
else if (!io && tp.x() > op.x())
|
||||
{
|
||||
it = 0;
|
||||
tp = QPoint(t[it].x - m_style.targetOffset.x, t[it].y + m_style.targetOffset.y);
|
||||
}
|
||||
}
|
||||
|
||||
if (it == io && ((it && tp.x() < op.x()) || (!it && tp.x() > op.x())) )
|
||||
{
|
||||
tp.setX(op.x());
|
||||
}
|
||||
else
|
||||
{
|
||||
op.setX(tp.x());
|
||||
}
|
||||
|
||||
o[0] = Vec2f(oR.x, (oR.y + 2 * oR.w) / 3);
|
||||
o[1] = Vec2f(oR.z, (oR.y + 2 * oR.w) / 3);
|
||||
t[0] = Vec2f(tR.x, (2 * tR.y + tR.w) / 3);
|
||||
t[1] = Vec2f(tR.z, (2 * tR.y + tR.w) / 3);
|
||||
|
||||
if (o[io].y < t[it].y)
|
||||
{
|
||||
op.setX(op.x() + m_style.verticalOffset);
|
||||
tp.setX(tp.x() + m_style.verticalOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
op.setX(op.x() - m_style.verticalOffset);
|
||||
tp.setX(tp.x() - m_style.verticalOffset);
|
||||
}
|
||||
|
||||
QPolygon poly;
|
||||
poly << QPoint(t[it].x, t[it].y + m_style.targetOffset.y);
|
||||
poly << tp;
|
||||
poly << op;
|
||||
poly << QPoint(o[io].x, o[io].y + m_style.originOffset.y);
|
||||
return poly;
|
||||
}
|
||||
|
||||
int QtAngledLineItem::getDirection(const QPointF& a, const QPointF& b) const
|
||||
{
|
||||
if (a.x() != b.x())
|
||||
{
|
||||
if (a.x() < b.x())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a.y() < b.y())
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef QT_ANGLED_LINE_ITEM_H
|
||||
#define QT_ANGLED_LINE_ITEM_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
#include "utility/math/Vector4.h"
|
||||
|
||||
#include "component/view/GraphViewStyle.h"
|
||||
|
||||
class QtAngledLineItem
|
||||
: public QGraphicsLineItem
|
||||
{
|
||||
public:
|
||||
QtAngledLineItem(QGraphicsItem* parent);
|
||||
virtual ~QtAngledLineItem();
|
||||
|
||||
void updateLine(
|
||||
Vec4i ownerRect, Vec4i targetRect,
|
||||
Vec4i ownerParentRect, Vec4i targetParentRect,
|
||||
GraphViewStyle::EdgeStyle style);
|
||||
|
||||
virtual QPainterPath shape() const;
|
||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem* options, QWidget* widget);
|
||||
|
||||
private:
|
||||
QPolygon getPath() const;
|
||||
int getDirection(const QPointF& a, const QPointF& b) const;
|
||||
|
||||
Vec4i m_ownerRect;
|
||||
Vec4i m_targetRect;
|
||||
|
||||
Vec4i m_ownerParentRect;
|
||||
Vec4i m_targetParentRect;
|
||||
|
||||
GraphViewStyle::EdgeStyle m_style;
|
||||
};
|
||||
|
||||
#endif // QT_ANGLED_LINE_ITEM_H
|
||||
+7
-7
@@ -1,20 +1,20 @@
|
||||
#include "qt/graphics/QtGraphicsRoundedRectItem.h"
|
||||
#include "qt/graphics/QtRoundedRectItem.h"
|
||||
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
#include <QPainter>
|
||||
|
||||
QtGraphicsRoundedRectItem::QtGraphicsRoundedRectItem(QGraphicsItem* parent)
|
||||
QtRoundedRectItem::QtRoundedRectItem(QGraphicsItem* parent)
|
||||
: QGraphicsRectItem(parent)
|
||||
, m_radius(0.0f)
|
||||
{
|
||||
this->setZValue(-1.0f);
|
||||
}
|
||||
|
||||
QtGraphicsRoundedRectItem::~QtGraphicsRoundedRectItem()
|
||||
QtRoundedRectItem::~QtRoundedRectItem()
|
||||
{
|
||||
}
|
||||
|
||||
void QtGraphicsRoundedRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem* options, QWidget* widget)
|
||||
void QtRoundedRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem* options, QWidget* widget)
|
||||
{
|
||||
painter->setPen(pen());
|
||||
painter->setBrush(brush());
|
||||
@@ -24,7 +24,7 @@ void QtGraphicsRoundedRectItem::paint(QPainter *painter, const QStyleOptionGraph
|
||||
painter->drawRoundedRect(this->rect(), m_radius, m_radius);
|
||||
}
|
||||
|
||||
void QtGraphicsRoundedRectItem::setShadow(QColor color, int blurRadius)
|
||||
void QtRoundedRectItem::setShadow(QColor color, int blurRadius)
|
||||
{
|
||||
QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect();
|
||||
effect->setColor(color);
|
||||
@@ -33,7 +33,7 @@ void QtGraphicsRoundedRectItem::setShadow(QColor color, int blurRadius)
|
||||
this->setGraphicsEffect(effect);
|
||||
}
|
||||
|
||||
void QtGraphicsRoundedRectItem::setShadowEnabled(bool enabled)
|
||||
void QtRoundedRectItem::setShadowEnabled(bool enabled)
|
||||
{
|
||||
if (this->graphicsEffect())
|
||||
{
|
||||
@@ -41,7 +41,7 @@ void QtGraphicsRoundedRectItem::setShadowEnabled(bool enabled)
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphicsRoundedRectItem::setRadius(qreal radius)
|
||||
void QtRoundedRectItem::setRadius(qreal radius)
|
||||
{
|
||||
m_radius = radius;
|
||||
}
|
||||
+3
-3
@@ -3,12 +3,12 @@
|
||||
|
||||
#include <QGraphicsRectItem>
|
||||
|
||||
class QtGraphicsRoundedRectItem
|
||||
class QtRoundedRectItem
|
||||
: public QGraphicsRectItem
|
||||
{
|
||||
public:
|
||||
QtGraphicsRoundedRectItem(QGraphicsItem* parent);
|
||||
virtual ~QtGraphicsRoundedRectItem();
|
||||
QtRoundedRectItem(QGraphicsItem* parent);
|
||||
virtual ~QtRoundedRectItem();
|
||||
|
||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem* options, QWidget* widget);
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
#include "qt/graphics/QtStraightLineItem.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
#include <QPen>
|
||||
|
||||
#include "utility/math/Vector2.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
#include "qt/graphics/QtRoundedRectItem.h"
|
||||
|
||||
QtStraightLineItem::QtStraightLineItem(QGraphicsItem* parent)
|
||||
: QGraphicsLineItem(parent)
|
||||
{
|
||||
this->setAcceptHoverEvents(true);
|
||||
|
||||
m_circle = new QtRoundedRectItem(this);
|
||||
m_circle->setRadius(10);
|
||||
m_circle->setBrush(QBrush(QColor("#FFF")));
|
||||
m_circle->setAcceptHoverEvents(true);
|
||||
|
||||
QFont font;
|
||||
font.setFamily(GraphViewStyle::getFontNameOfNumber().c_str());
|
||||
font.setPixelSize(GraphViewStyle::getFontSizeOfNumber());
|
||||
font.setWeight(QFont::Normal);
|
||||
|
||||
m_number = new QGraphicsSimpleTextItem(this);
|
||||
m_number->setFont(font);
|
||||
}
|
||||
|
||||
QtStraightLineItem::~QtStraightLineItem()
|
||||
{
|
||||
}
|
||||
|
||||
void QtStraightLineItem::updateLine(Vec4i ownerRect, Vec4i targetRect, int number, GraphViewStyle::EdgeStyle style)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
|
||||
const Vec4i& o = ownerRect;
|
||||
const Vec4i& t = targetRect;
|
||||
|
||||
Vec2f oc((o.x + o.z) / 2, (o.y + o.w) / 2);
|
||||
Vec2f tc((t.x + t.z) / 2, (t.y + t.w) / 2);
|
||||
|
||||
Vec2f mid;
|
||||
Vec2f op;
|
||||
Vec2f tp;
|
||||
|
||||
bool intersects = false;
|
||||
for (int i = 0; !intersects && i < 4; i++)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: intersects = utility::intersectionPoint(oc, tc, Vec2f(o.x, o.y), Vec2f(o.x, o.w), &op); break;
|
||||
case 1: intersects = utility::intersectionPoint(oc, tc, Vec2f(o.x, o.y), Vec2f(o.z, o.y), &op); break;
|
||||
case 2: intersects = utility::intersectionPoint(oc, tc, Vec2f(o.z, o.y), Vec2f(o.z, o.w), &op); break;
|
||||
case 3: intersects = utility::intersectionPoint(oc, tc, Vec2f(o.x, o.w), Vec2f(o.z, o.w), &op); break;
|
||||
}
|
||||
}
|
||||
|
||||
intersects = false;
|
||||
for (int i = 0; !intersects && i < 4; i++)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: intersects = utility::intersectionPoint(oc, tc, Vec2f(t.x, t.y), Vec2f(t.x, t.w), &tp); break;
|
||||
case 1: intersects = utility::intersectionPoint(oc, tc, Vec2f(t.x, t.y), Vec2f(t.z, t.y), &tp); break;
|
||||
case 2: intersects = utility::intersectionPoint(oc, tc, Vec2f(t.z, t.y), Vec2f(t.z, t.w), &tp); break;
|
||||
case 3: intersects = utility::intersectionPoint(oc, tc, Vec2f(t.x, t.w), Vec2f(t.z, t.w), &tp); break;
|
||||
}
|
||||
}
|
||||
|
||||
mid = (op + tp) / 2;
|
||||
|
||||
this->setLine(oc.x, oc.y, tc.x, tc.y);
|
||||
|
||||
m_circle->setRect(mid.x - 10, mid.y - 10, 20, 20);
|
||||
m_circle->setPen(QPen(QColor(style.color.c_str()), 2));
|
||||
|
||||
QString numberStr = QString::number(number);
|
||||
m_number->setText(numberStr);
|
||||
m_number->setBrush(QBrush(QColor("#666")));
|
||||
m_number->setPos(
|
||||
mid.x - QFontMetrics(m_number->font()).width(numberStr) / 2,
|
||||
mid.y - QFontMetrics(m_number->font()).height() / 2
|
||||
);
|
||||
|
||||
this->setPen(QPen(QBrush(style.color.c_str()), number + style.width, Qt::SolidLine, Qt::RoundCap));
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef QT_STRAIGHT_LINE_ITEM_H
|
||||
#define QT_STRAIGHT_LINE_ITEM_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
#include "utility/math/Vector4.h"
|
||||
|
||||
#include "component/view/GraphViewStyle.h"
|
||||
|
||||
class QtRoundedRectItem;
|
||||
|
||||
class QtStraightLineItem
|
||||
: public QGraphicsLineItem
|
||||
{
|
||||
public:
|
||||
QtStraightLineItem(QGraphicsItem* parent);
|
||||
virtual ~QtStraightLineItem();
|
||||
|
||||
void updateLine(Vec4i ownerRect, Vec4i targetRect, int number, GraphViewStyle::EdgeStyle style);
|
||||
|
||||
private:
|
||||
QtRoundedRectItem* m_circle;
|
||||
QGraphicsSimpleTextItem* m_number;
|
||||
};
|
||||
|
||||
#endif // QT_STRAIGHT_LINE_ITEM_H
|
||||
@@ -69,19 +69,10 @@ void QtGraphView::clear()
|
||||
m_clearFunctor();
|
||||
}
|
||||
|
||||
GraphView::Metrics QtGraphView::getViewMetrics() const
|
||||
Vec2i QtGraphView::getViewSize() const
|
||||
{
|
||||
GraphView::Metrics metrics;
|
||||
QGraphicsView* view = getView();
|
||||
|
||||
metrics.width = view->width();
|
||||
metrics.height = view->height();
|
||||
|
||||
metrics.typeNameCharWidth = QFontMetrics(QtGraphNode::getFontForNodeType(Node::NODE_CLASS)).width("QtGraphNode") / 11.0f;
|
||||
metrics.variableNameCharWidth = QFontMetrics(QtGraphNode::getFontForNodeType(Node::NODE_FIELD)).width("QtGraphNode") / 11.0f;
|
||||
metrics.functionNameCharWidth = QFontMetrics(QtGraphNode::getFontForNodeType(Node::NODE_METHOD)).width("QtGraphNode") / 11.0f;
|
||||
|
||||
return metrics;
|
||||
return Vec2i(view->width(), view->height());
|
||||
}
|
||||
|
||||
void QtGraphView::finishedTransition()
|
||||
@@ -261,7 +252,7 @@ std::shared_ptr<QtGraphNode> QtGraphView::createNodeRecursive(
|
||||
}
|
||||
}
|
||||
|
||||
newNode->setStyle();
|
||||
newNode->updateStyle();
|
||||
|
||||
return newNode;
|
||||
}
|
||||
@@ -281,11 +272,8 @@ std::shared_ptr<QtGraphEdge> QtGraphView::createEdge(QGraphicsView* view, const
|
||||
std::shared_ptr<QtGraphEdge> qtEdge = std::make_shared<QtGraphEdge>(owner, target, edge.data);
|
||||
qtEdge->setIsActive(edge.active);
|
||||
|
||||
bool added = owner->addOutEdge(qtEdge) | target->addInEdge(qtEdge);
|
||||
if (!added)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
owner->addOutEdge(qtEdge);
|
||||
target->addInEdge(qtEdge);
|
||||
|
||||
view->scene()->addItem(qtEdge.get());
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
virtual void rebuildGraph(std::shared_ptr<Graph> graph, const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges);
|
||||
virtual void clear();
|
||||
|
||||
virtual GraphView::Metrics getViewMetrics() const;
|
||||
virtual Vec2i getViewSize() const;
|
||||
|
||||
private slots:
|
||||
void finishedTransition();
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "qt/view/QtGraphViewStyleImpl.h"
|
||||
|
||||
#include <QFontMetrics>
|
||||
|
||||
float QtGraphViewStyleImpl::getCharWidthForNodeType(Node::NodeType type)
|
||||
{
|
||||
return QFontMetrics(QtGraphNode::getFontForNodeType(type)).width("QtGraphNode::QtGraphNode::QtGraphNode") / 37.0f;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef QT_GRAPH_VIEW_STYLE_IMPL_H
|
||||
#define QT_GRAPH_VIEW_STYLE_IMPL_H
|
||||
|
||||
#include "component/view/GraphViewStyleImpl.h"
|
||||
#include "qt/view/graphElements/QtGraphNode.h"
|
||||
|
||||
class QtGraphViewStyleImpl
|
||||
: public GraphViewStyleImpl
|
||||
{
|
||||
public:
|
||||
virtual float getCharWidthForNodeType(Node::NodeType type);
|
||||
};
|
||||
|
||||
#endif // QT_GRAPH_VIEW_STYLE_IMPL_H
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "qt/view/QtViewFactory.h"
|
||||
|
||||
#include "component/view/GraphViewStyle.h"
|
||||
#include "qt/view/QtCodeView.h"
|
||||
#include "qt/view/QtCompositeView.h"
|
||||
#include "qt/view/QtGraphView.h"
|
||||
#include "qt/view/QtGraphViewStyleImpl.h"
|
||||
#include "qt/view/QtMainView.h"
|
||||
#include "qt/view/QtRefreshView.h"
|
||||
#include "qt/view/QtSearchView.h"
|
||||
@@ -38,6 +40,7 @@ std::shared_ptr<CodeView> QtViewFactory::createCodeView(ViewLayout* viewLayout)
|
||||
|
||||
std::shared_ptr<GraphView> QtViewFactory::createGraphView(ViewLayout* viewLayout) const
|
||||
{
|
||||
GraphViewStyle::setImpl(std::make_shared<QtGraphViewStyleImpl>());
|
||||
return View::createInitAndAddToLayout<QtGraphView>(viewLayout);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,384 +1,16 @@
|
||||
#include "qt/view/graphElements/QtGraphEdge.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneEvent>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
|
||||
#include "utility/messaging/type/MessageActivateTokens.h"
|
||||
|
||||
#include "component/view/graphElements/GraphNode.h"
|
||||
#include "component/view/GraphViewStyle.h"
|
||||
#include "data/graph/token_component/TokenComponentAggregation.h"
|
||||
#include "qt/graphics/QtGraphicsRoundedRectItem.h"
|
||||
|
||||
QtStraightConnection::QtStraightConnection(Vec4i ownerRect, Vec4i targetRect, int number, QGraphicsItem* parent)
|
||||
: QGraphicsLineItem(parent)
|
||||
{
|
||||
const Vec4i& o = ownerRect;
|
||||
const Vec4i& t = targetRect;
|
||||
|
||||
Vec2f a((o.x + o.z) / 2, (o.y + o.w) / 2);
|
||||
Vec2f b((t.x + t.z) / 2, (t.y + t.w) / 2);
|
||||
|
||||
this->setLine(a.x, a.y, b.x, b.y);
|
||||
this->setAcceptHoverEvents(true);
|
||||
|
||||
Vec2f mid = (a + b) / 2;
|
||||
Vec2f u = b - a;
|
||||
float len = u.getLength();
|
||||
u.normalize();
|
||||
|
||||
float alpha = atan2(u.y, u.x);
|
||||
|
||||
Vec2f w;
|
||||
w.x = (o.z - o.x) / 2 * cos(alpha);
|
||||
w.y = (o.w - o.y) / 2 * sin(alpha);
|
||||
a += u * w.getLength();
|
||||
float newLen = w.getLength();
|
||||
|
||||
w.x = (t.z - t.x) / 2 * cos(alpha);
|
||||
w.y = (t.w - t.y) / 2 * sin(alpha);
|
||||
b += u * -w.getLength();
|
||||
newLen -= w.getLength();
|
||||
|
||||
if (newLen > 0 && newLen < len)
|
||||
{
|
||||
mid = (a + b) / 2;
|
||||
}
|
||||
|
||||
m_circle = new QtGraphicsRoundedRectItem(this);
|
||||
m_circle->setRect(mid.x - 10, mid.y - 10, 20, 20);
|
||||
m_circle->setRadius(10);
|
||||
m_circle->setPen(QPen(QColor("#F8F8F8"), 2));
|
||||
m_circle->setBrush(QBrush(QColor("#FFF")));
|
||||
m_circle->setAcceptHoverEvents(true);
|
||||
|
||||
QFont font;
|
||||
font.setFamily("Myriad Pro");
|
||||
font.setWeight(QFont::Normal);
|
||||
font.setPixelSize(9);
|
||||
|
||||
m_number = new QGraphicsSimpleTextItem(this);
|
||||
m_number->setFont(font);
|
||||
|
||||
QString numberStr = QString::number(number);
|
||||
m_number->setText(numberStr);
|
||||
m_number->setBrush(QBrush(QColor("#666")));
|
||||
m_number->setPos(
|
||||
mid.x - QFontMetrics(m_number->font()).width(numberStr) / 2,
|
||||
mid.y - QFontMetrics(m_number->font()).height() / 2
|
||||
);
|
||||
}
|
||||
|
||||
QtStraightConnection::~QtStraightConnection()
|
||||
{
|
||||
}
|
||||
|
||||
void QtStraightConnection::setColor(QColor color)
|
||||
{
|
||||
QPen p = this->pen();
|
||||
p.setColor(color);
|
||||
this->setPen(p);
|
||||
|
||||
p = m_circle->pen();
|
||||
p.setColor(color);
|
||||
m_circle->setPen(p);
|
||||
}
|
||||
|
||||
QtCorneredConnection::QtCorneredConnection(
|
||||
Vec4i ownerRect, Vec4i targetRect, Vec4i ownerParentRect, Vec4i targetParentRect, QGraphicsItem* parent
|
||||
)
|
||||
: QGraphicsLineItem(parent)
|
||||
, m_ownerRect(ownerRect)
|
||||
, m_targetRect(targetRect)
|
||||
, m_ownerParentRect(ownerParentRect)
|
||||
, m_targetParentRect(targetParentRect)
|
||||
, m_closed(false)
|
||||
, m_big(false)
|
||||
{
|
||||
this->setAcceptHoverEvents(true);
|
||||
|
||||
m_ownerRect.x = m_ownerRect.x - 1;
|
||||
m_ownerRect.z = m_ownerRect.z + 1;
|
||||
m_targetRect.x = m_targetRect.x - 1;
|
||||
m_targetRect.z = m_targetRect.z + 1;
|
||||
}
|
||||
|
||||
QtCorneredConnection::~QtCorneredConnection()
|
||||
{
|
||||
}
|
||||
|
||||
QPainterPath QtCorneredConnection::shape() const
|
||||
{
|
||||
int w = m_big ? 10 : 5;
|
||||
QPainterPath path;
|
||||
QPolygon poly = getPath();
|
||||
for (int i = 0; i < poly.size() - 1; i++)
|
||||
{
|
||||
path.addRect(QRectF(poly.at(i), poly.at(i + 1)).normalized().adjusted(-w, -w, w, w));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
void QtCorneredConnection::paint(QPainter *painter, const QStyleOptionGraphicsItem* options, QWidget* widget)
|
||||
{
|
||||
painter->setPen(pen());
|
||||
|
||||
QPainterPath path;
|
||||
|
||||
QPolygon poly = getPath();
|
||||
int i = poly.length() - 1;
|
||||
|
||||
path.moveTo(poly.at(i));
|
||||
|
||||
int radius = 10;
|
||||
int dir = getDirection(poly.at(i), poly.at(i - 1));
|
||||
while (i > 1)
|
||||
{
|
||||
i--;
|
||||
|
||||
QPointF a = poly.at(i);
|
||||
QPointF b = poly.at(i - 1);
|
||||
|
||||
int newDir = getDirection(a, b);
|
||||
int ar = radius;
|
||||
int br = 10;
|
||||
|
||||
if (i != 1)
|
||||
{
|
||||
if (dir % 2 == 1 && std::abs(a.y() - b.y()) < 2 * br)
|
||||
{
|
||||
br = std::abs(a.y() - b.y()) / 2;
|
||||
}
|
||||
else if (dir % 2 == 0 && std::abs(a.x() - b.x()) < 2 * br)
|
||||
{
|
||||
br = std::abs(a.x() - b.x()) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case 0: a.setY(a.y() + ar); break;
|
||||
case 1: a.setX(a.x() - ar); break;
|
||||
case 2: a.setY(a.y() - ar); break;
|
||||
case 3: a.setX(a.x() + ar); break;
|
||||
}
|
||||
|
||||
b = poly.at(i);
|
||||
switch (newDir)
|
||||
{
|
||||
case 0: b.setY(b.y() - br); break;
|
||||
case 1: b.setX(b.x() + br); break;
|
||||
case 2: b.setY(b.y() + br); break;
|
||||
case 3: b.setX(b.x() - br); break;
|
||||
}
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case 0:
|
||||
if (newDir == 1)
|
||||
{
|
||||
path.arcTo(a.x(), b.y(), 2 * br, 2 * ar, 180, -90);
|
||||
}
|
||||
else if (newDir == 3)
|
||||
{
|
||||
path.arcTo(b.x() - br, a.y() - ar, 2 * br, 2 * ar, 0, 90);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (newDir == 0)
|
||||
{
|
||||
path.arcTo(a.x() - ar, b.y() - br, 2 * ar, 2 * br, -90, 90);
|
||||
}
|
||||
else if (newDir == 2)
|
||||
{
|
||||
path.arcTo(a.x() - ar, a.y(), 2 * ar, 2 * br, 90, -90);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (newDir == 1)
|
||||
{
|
||||
path.arcTo(a.x(), a.y() - ar, 2 * br, 2 * ar, 180, 90);
|
||||
}
|
||||
else if (newDir == 3)
|
||||
{
|
||||
path.arcTo(b.x() - br, a.y() - ar, 2 * br, 2 * ar, 0, -90);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (newDir == 0)
|
||||
{
|
||||
path.arcTo(b.x(), b.y() - br, 2 * ar, 2 * br, -90, -90);
|
||||
}
|
||||
else if (newDir == 2)
|
||||
{
|
||||
path.arcTo(b.x(), a.y(), 2 * ar, 2 * br, 90, 90);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
dir = newDir;
|
||||
radius = br;
|
||||
}
|
||||
|
||||
int arrowLength = m_big ? 15 : 5;
|
||||
int arrowWidth = m_big ? 20 : 8;
|
||||
QPointF arrow = poly.at(0) + QPointF((poly.at(0).x() - poly.at(1).x() > 0 ? -1 : 1) * arrowLength, 0);
|
||||
|
||||
if (m_closed)
|
||||
{
|
||||
path.lineTo(arrow);
|
||||
path.moveTo(poly.at(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
path.lineTo(poly.at(0));
|
||||
}
|
||||
|
||||
arrow.setY(arrow.y() - arrowWidth / 2);
|
||||
path.lineTo(arrow);
|
||||
arrow.setY(arrow.y() + arrowWidth);
|
||||
if (m_closed)
|
||||
{
|
||||
path.lineTo(arrow);
|
||||
}
|
||||
else
|
||||
{
|
||||
path.moveTo(arrow);
|
||||
}
|
||||
path.lineTo(poly.at(0));
|
||||
|
||||
painter->drawPath(path);
|
||||
}
|
||||
|
||||
void QtCorneredConnection::setClosed(bool closed)
|
||||
{
|
||||
m_closed = closed;
|
||||
}
|
||||
|
||||
void QtCorneredConnection::setBig(bool big)
|
||||
{
|
||||
m_big = big;
|
||||
}
|
||||
|
||||
QPolygon QtCorneredConnection::getPath() const
|
||||
{
|
||||
const Vec4i& oR = m_ownerRect;
|
||||
const Vec4i& tR = m_targetRect;
|
||||
|
||||
Vec2f o[2] = { Vec2f(m_ownerParentRect.x, (oR.y + 2 * oR.w) / 3), Vec2f(m_ownerParentRect.z, (oR.y + 2 * oR.w) / 3) };
|
||||
Vec2f t[2] = { Vec2f(m_targetParentRect.x, (2 * tR.y + tR.w) / 3), Vec2f(m_targetParentRect.z, (2 * tR.y + tR.w) / 3) };
|
||||
|
||||
int io = -1;
|
||||
int it = -1;
|
||||
float dist = -1;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
Vec2f diff = o[i] - t[j];
|
||||
if (dist < 0 || diff.getLength() < dist)
|
||||
{
|
||||
dist = diff.getLength();
|
||||
io = i;
|
||||
it = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float offsetO = 17;
|
||||
float offsetT = m_big ? 29 : 17;
|
||||
|
||||
QPoint tp((it ? 1 : -1) * offsetT + t[it].x, t[it].y);
|
||||
QPoint op((io ? 1 : -1) * offsetO + o[io].x, o[io].y);
|
||||
|
||||
if (it != io)
|
||||
{
|
||||
if (it && tp.x() < op.x())
|
||||
{
|
||||
io = 0;
|
||||
op = QPoint(o[io].x - offsetO, o[io].y);
|
||||
}
|
||||
else if (!it && tp.x() < op.x())
|
||||
{
|
||||
it = 1;
|
||||
tp = QPoint(t[it].x + offsetT, t[it].y);
|
||||
}
|
||||
else if (io && tp.x() > op.x())
|
||||
{
|
||||
io = 1;
|
||||
op = QPoint(o[io].x + offsetO, o[io].y);
|
||||
}
|
||||
else if (!io && tp.x() > op.x())
|
||||
{
|
||||
it = 0;
|
||||
tp = QPoint(t[it].x - offsetT, t[it].y);
|
||||
}
|
||||
}
|
||||
|
||||
if (it == io && ((it && tp.x() < op.x()) || (!it && tp.x() > op.x())) )
|
||||
{
|
||||
tp.setX(op.x());
|
||||
}
|
||||
else
|
||||
{
|
||||
op.setX(tp.x());
|
||||
}
|
||||
|
||||
o[0] = Vec2f(oR.x, (oR.y + 2 * oR.w) / 3);
|
||||
o[1] = Vec2f(oR.z, (oR.y + 2 * oR.w) / 3);
|
||||
t[0] = Vec2f(tR.x, (2 * tR.y + tR.w) / 3);
|
||||
t[1] = Vec2f(tR.z, (2 * tR.y + tR.w) / 3);
|
||||
|
||||
int verticalOffset = 3;
|
||||
if (o[io].y < t[it].y)
|
||||
{
|
||||
op.setX(op.x() + verticalOffset);
|
||||
tp.setX(tp.x() + verticalOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
op.setX(op.x() - verticalOffset);
|
||||
tp.setX(tp.x() - verticalOffset);
|
||||
}
|
||||
|
||||
QPolygon poly;
|
||||
poly << QPoint(t[it].x, t[it].y);
|
||||
poly << tp;
|
||||
poly << op;
|
||||
poly << QPoint(o[io].x, o[io].y);
|
||||
return poly;
|
||||
}
|
||||
|
||||
int QtCorneredConnection::getDirection(const QPointF& a, const QPointF& b) const
|
||||
{
|
||||
if (a.x() != b.x())
|
||||
{
|
||||
if (a.x() < b.x())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a.y() < b.y())
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "qt/graphics/QtAngledLineItem.h"
|
||||
#include "qt/graphics/QtStraightLineItem.h"
|
||||
|
||||
QtGraphEdge::QtGraphEdge(const std::weak_ptr<GraphNode>& owner, const std::weak_ptr<GraphNode>& target, const Edge* data)
|
||||
: GraphEdge(data)
|
||||
@@ -389,9 +21,6 @@ QtGraphEdge::QtGraphEdge(const std::weak_ptr<GraphNode>& owner, const std::weak_
|
||||
, m_mousePos(0.0f, 0.0f)
|
||||
, m_mouseMoved(false)
|
||||
{
|
||||
this->setAcceptHoverEvents(true);
|
||||
this->setZValue(getZValue(false)); // Used to draw edges always on top of nodes.
|
||||
|
||||
this->updateLine();
|
||||
}
|
||||
|
||||
@@ -420,61 +49,38 @@ void QtGraphEdge::updateLine()
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_child)
|
||||
{
|
||||
delete m_child;
|
||||
}
|
||||
GraphViewStyle::EdgeStyle style = GraphViewStyle::getStyleForEdgeType(getData()->getType(), m_isActive, false);
|
||||
|
||||
if (isAggregation())
|
||||
if (style.isStraight)
|
||||
{
|
||||
m_child =
|
||||
new QtStraightConnection(owner->getBoundingRect(), target->getBoundingRect(), getAggregationCount(), this);
|
||||
if (!m_child)
|
||||
{
|
||||
m_child = new QtStraightLineItem(this);
|
||||
}
|
||||
|
||||
int number = 0;
|
||||
if (getData()->isType(Edge::EDGE_AGGREGATION))
|
||||
{
|
||||
number = getData()->getComponent<TokenComponentAggregation>()->getAggregationCount();
|
||||
}
|
||||
|
||||
dynamic_cast<QtStraightLineItem*>(m_child)->updateLine(
|
||||
owner->getBoundingRect(), target->getBoundingRect(), number, style);
|
||||
}
|
||||
else
|
||||
{
|
||||
QtCorneredConnection* child = new QtCorneredConnection(
|
||||
owner->getBoundingRect(), target->getBoundingRect(),
|
||||
owner->getParentBoundingRect(), target->getParentBoundingRect(),
|
||||
this
|
||||
);
|
||||
|
||||
if (isInheritance())
|
||||
if (!m_child)
|
||||
{
|
||||
child->setClosed(true);
|
||||
child->setBig(true);
|
||||
m_child = new QtAngledLineItem(this);
|
||||
}
|
||||
|
||||
m_child = child;
|
||||
dynamic_cast<QtAngledLineItem*>(m_child)->updateLine(
|
||||
owner->getBoundingRect(), target->getBoundingRect(),
|
||||
owner->getParentBoundingRect(), target->getParentBoundingRect(),
|
||||
style);
|
||||
}
|
||||
|
||||
QColor color;
|
||||
|
||||
switch (getData()->getType())
|
||||
{
|
||||
case Edge::EDGE_CALL:
|
||||
color = QColor("#F1C100");
|
||||
break;
|
||||
case Edge::EDGE_USAGE:
|
||||
color = QColor("#62B29D");
|
||||
break;
|
||||
case Edge::EDGE_INHERITANCE:
|
||||
case Edge::EDGE_OVERRIDE:
|
||||
color = QColor("#CC5E89");
|
||||
break;
|
||||
case Edge::EDGE_AGGREGATION:
|
||||
color = QColor("#F8F8F8");
|
||||
break;
|
||||
case Edge::EDGE_INCLUDE:
|
||||
color = QColor("#87BA50");
|
||||
break;
|
||||
default:
|
||||
color = QColor("#878787");
|
||||
break;
|
||||
}
|
||||
|
||||
m_child->setPen(QPen(color, getPenWidth(), Qt::SolidLine, Qt::RoundCap));
|
||||
|
||||
setIsActive(m_isActive);
|
||||
this->setZValue(style.zValue); // Used to draw edges always on top of nodes.
|
||||
}
|
||||
|
||||
bool QtGraphEdge::getIsActive() const
|
||||
@@ -486,39 +92,12 @@ void QtGraphEdge::setIsActive(bool isActive)
|
||||
{
|
||||
m_isActive = isActive;
|
||||
|
||||
if (isActive)
|
||||
{
|
||||
if (isAggregation())
|
||||
{
|
||||
dynamic_cast<QtStraightConnection*>(m_child)->setColor(QColor("#EEE"));
|
||||
}
|
||||
else
|
||||
{
|
||||
QPen p = m_child->pen();
|
||||
p.setWidthF(getPenWidth() + 1);
|
||||
m_child->setPen(p);
|
||||
}
|
||||
this->setZValue(getZValue(isActive));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isAggregation())
|
||||
{
|
||||
dynamic_cast<QtStraightConnection*>(m_child)->setColor(QColor("#F8F8F8"));
|
||||
}
|
||||
else
|
||||
{
|
||||
QPen p = m_child->pen();
|
||||
p.setWidthF(getPenWidth());
|
||||
m_child->setPen(p);
|
||||
}
|
||||
this->setZValue(getZValue(isActive));
|
||||
}
|
||||
updateLine();
|
||||
}
|
||||
|
||||
void QtGraphEdge::onClick()
|
||||
{
|
||||
if (isAggregation())
|
||||
if (getData()->isType(Edge::EDGE_AGGREGATION))
|
||||
{
|
||||
const std::set<Id>& ids = getData()->getComponent<TokenComponentAggregation>()->getAggregationIds();
|
||||
MessageActivateTokens message(std::vector<Id>(ids.begin(), ids.end()));
|
||||
@@ -568,49 +147,3 @@ void QtGraphEdge::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
|
||||
{
|
||||
this->setIsActive(m_isActive);
|
||||
}
|
||||
|
||||
bool QtGraphEdge::isAggregation() const
|
||||
{
|
||||
return getData()->getType() == Edge::EDGE_AGGREGATION;
|
||||
}
|
||||
|
||||
bool QtGraphEdge::isInheritance() const
|
||||
{
|
||||
return getData()->getType() == Edge::EDGE_INHERITANCE;
|
||||
}
|
||||
|
||||
int QtGraphEdge::getZValue(bool active) const
|
||||
{
|
||||
if (isAggregation())
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (active)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
float QtGraphEdge::getPenWidth() const
|
||||
{
|
||||
if (isAggregation())
|
||||
{
|
||||
return getAggregationCount() + 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int QtGraphEdge::getAggregationCount() const
|
||||
{
|
||||
if (isAggregation())
|
||||
{
|
||||
return getData()->getComponent<TokenComponentAggregation>()->getAggregationCount();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,49 +10,6 @@
|
||||
#include "component/view/graphElements/GraphEdge.h"
|
||||
|
||||
class GraphNode;
|
||||
class QtGraphicsRoundedRectItem;
|
||||
|
||||
class QtStraightConnection
|
||||
: public QGraphicsLineItem
|
||||
{
|
||||
public:
|
||||
QtStraightConnection(Vec4i ownerRect, Vec4i targetRect, int number, QGraphicsItem* parent);
|
||||
virtual ~QtStraightConnection();
|
||||
|
||||
void setColor(QColor color);
|
||||
|
||||
private:
|
||||
QtGraphicsRoundedRectItem* m_circle;
|
||||
QGraphicsSimpleTextItem* m_number;
|
||||
};
|
||||
|
||||
class QtCorneredConnection
|
||||
: public QGraphicsLineItem
|
||||
{
|
||||
public:
|
||||
QtCorneredConnection(Vec4i ownerRect, Vec4i targetRect, Vec4i ownerParentRect, Vec4i targetParentRect, QGraphicsItem* parent);
|
||||
virtual ~QtCorneredConnection();
|
||||
|
||||
virtual QPainterPath shape() const;
|
||||
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem* options, QWidget* widget);
|
||||
|
||||
void setClosed(bool closed);
|
||||
void setBig(bool big);
|
||||
|
||||
private:
|
||||
QPolygon getPath() const;
|
||||
int getDirection(const QPointF& a, const QPointF& b) const;
|
||||
|
||||
Vec4i m_ownerRect;
|
||||
Vec4i m_targetRect;
|
||||
|
||||
Vec4i m_ownerParentRect;
|
||||
Vec4i m_targetParentRect;
|
||||
|
||||
bool m_closed;
|
||||
bool m_big;
|
||||
};
|
||||
|
||||
|
||||
class QtGraphEdge
|
||||
: public QObject
|
||||
@@ -85,13 +42,6 @@ protected:
|
||||
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
|
||||
|
||||
private:
|
||||
bool isAggregation() const;
|
||||
bool isInheritance() const;
|
||||
|
||||
int getZValue(bool active) const;
|
||||
float getPenWidth() const;
|
||||
int getAggregationCount() const;
|
||||
|
||||
std::weak_ptr<GraphNode> m_owner;
|
||||
std::weak_ptr<GraphNode> m_target;
|
||||
|
||||
|
||||
@@ -7,11 +7,10 @@
|
||||
#include "utility/messaging/type/MessageActivateTokens.h"
|
||||
#include "utility/messaging/type/MessageGraphNodeMove.h"
|
||||
|
||||
#include "qt/graphics/QtGraphicsRoundedRectItem.h"
|
||||
#include "qt/graphics/QtRoundedRectItem.h"
|
||||
#include "qt/utility/QtDeviceScaledPixmap.h"
|
||||
#include "qt/view/graphElements/nodeComponents/QtGraphNodeComponent.h"
|
||||
#include "qt/view/graphElements/QtGraphEdge.h"
|
||||
#include "settings/ApplicationSettings.h"
|
||||
|
||||
void QtGraphNode::blendIn()
|
||||
{
|
||||
@@ -35,36 +34,8 @@ void QtGraphNode::hideNode()
|
||||
|
||||
QFont QtGraphNode::getFontForNodeType(Node::NodeType type)
|
||||
{
|
||||
QFont font("Source Code Pro");
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Node::NODE_UNDEFINED:
|
||||
case Node::NODE_NAMESPACE:
|
||||
font.setPixelSize(12);
|
||||
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:
|
||||
font.setPixelSize(14);
|
||||
break;
|
||||
|
||||
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:
|
||||
font.setPixelSize(11);
|
||||
break;
|
||||
}
|
||||
|
||||
QFont font(GraphViewStyle::getFontNameForNodeType(type).c_str());
|
||||
font.setPixelSize(GraphViewStyle::getFontSizeForNodeType(type));
|
||||
return font;
|
||||
}
|
||||
|
||||
@@ -76,7 +47,7 @@ QtGraphNode::QtGraphNode()
|
||||
{
|
||||
this->setPen(QPen(Qt::transparent));
|
||||
|
||||
m_rect = new QtGraphicsRoundedRectItem(this);
|
||||
m_rect = new QtRoundedRectItem(this);
|
||||
m_text = new QGraphicsSimpleTextItem(this);
|
||||
}
|
||||
|
||||
@@ -88,7 +59,7 @@ QtGraphNode::QtGraphNode(const Node* data)
|
||||
{
|
||||
this->setPen(QPen(Qt::transparent));
|
||||
|
||||
m_rect = new QtGraphicsRoundedRectItem(this);
|
||||
m_rect = new QtRoundedRectItem(this);
|
||||
m_text = new QGraphicsSimpleTextItem(this);
|
||||
|
||||
this->setAcceptHoverEvents(true);
|
||||
@@ -184,46 +155,22 @@ Vec4i QtGraphNode::getParentBoundingRect() const
|
||||
return node->getBoundingRect();
|
||||
}
|
||||
|
||||
bool QtGraphNode::addOutEdge(const std::shared_ptr<GraphEdge>& edge)
|
||||
void QtGraphNode::addOutEdge(const std::shared_ptr<GraphEdge>& edge)
|
||||
{
|
||||
// for (std::list<std::shared_ptr<GraphEdge>>::iterator it = m_outEdges.begin(); it != m_outEdges.end(); it++)
|
||||
// {
|
||||
// if ((*it)->getOwner().lock() == edge->getOwner().lock() &&
|
||||
// (*it)->getTarget().lock() == edge->getTarget().lock())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
m_outEdges.push_back(edge);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QtGraphNode::addInEdge(const std::weak_ptr<GraphEdge>& edge)
|
||||
void QtGraphNode::addInEdge(const std::weak_ptr<GraphEdge>& edge)
|
||||
{
|
||||
// for (std::list<std::weak_ptr<GraphEdge>>::iterator it = m_inEdges.begin(); it != m_inEdges.end(); it++)
|
||||
// {
|
||||
// std::shared_ptr<GraphEdge> existingEdge = it->lock();
|
||||
// if (existingEdge != NULL)
|
||||
// {
|
||||
// if (existingEdge->getOwner().lock() == edge.lock()->getOwner().lock() &&
|
||||
// existingEdge->getTarget().lock() == edge.lock()->getTarget().lock())
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
m_inEdges.push_back(edge);
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int QtGraphNode::getOutEdgeCount() const
|
||||
size_t QtGraphNode::getOutEdgeCount() const
|
||||
{
|
||||
return m_outEdges.size();
|
||||
}
|
||||
|
||||
unsigned int QtGraphNode::getInEdgeCount() const
|
||||
size_t QtGraphNode::getInEdgeCount() const
|
||||
{
|
||||
return m_inEdges.size();
|
||||
}
|
||||
@@ -247,7 +194,7 @@ void QtGraphNode::setIsActive(bool isActive)
|
||||
{
|
||||
m_isActive = isActive;
|
||||
|
||||
setStyle();
|
||||
updateStyle();
|
||||
}
|
||||
|
||||
QtGraphNode* QtGraphNode::getParent() const
|
||||
@@ -281,136 +228,6 @@ void QtGraphNode::addSubNode(const std::shared_ptr<QtGraphNode>& node)
|
||||
m_subNodes.push_back(node);
|
||||
}
|
||||
|
||||
void QtGraphNode::setStyle()
|
||||
{
|
||||
if (!m_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QColor color = Qt::lightGray;
|
||||
qreal radius = 0.0f;
|
||||
QPen p(Qt::transparent);
|
||||
QFont font(getFontForNodeType(m_data->getType()));
|
||||
|
||||
bool useUndefinedPattern = false;
|
||||
bool useUndefinedColor = false;
|
||||
|
||||
Vec2i padding;
|
||||
|
||||
switch (m_data->getType())
|
||||
{
|
||||
case Node::NODE_UNDEFINED:
|
||||
p.setStyle(Qt::DashLine);
|
||||
case Node::NODE_NAMESPACE:
|
||||
color = Qt::transparent;
|
||||
|
||||
p.setColor("#cc8d91");
|
||||
p.setWidth(1);
|
||||
|
||||
radius = 20.0f;
|
||||
padding.x = 15;
|
||||
padding.y = 6;
|
||||
break;
|
||||
|
||||
case Node::NODE_UNDEFINED_TYPE:
|
||||
useUndefinedPattern = 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 (m_isActive)
|
||||
{
|
||||
font.setWeight(QFont::Bold);
|
||||
}
|
||||
|
||||
if (m_isHovering)
|
||||
{
|
||||
m_rect->setShadow(QColor(0, 0, 0, 255), 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rect->setShadow(QColor(0, 0, 0, 128), 5);
|
||||
}
|
||||
|
||||
color = ApplicationSettings::getInstance()->getNodeTypeColor(m_data->getType()).c_str();
|
||||
if (m_subNodes.size())
|
||||
{
|
||||
radius = 20.0f;
|
||||
padding.x = 15;
|
||||
padding.y = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
radius = 10.0f;
|
||||
padding.x = 8;
|
||||
padding.y = 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case Node::NODE_UNDEFINED_FUNCTION:
|
||||
case Node::NODE_UNDEFINED_VARIABLE:
|
||||
useUndefinedPattern = true;
|
||||
useUndefinedColor = true;
|
||||
case Node::NODE_FUNCTION:
|
||||
case Node::NODE_METHOD:
|
||||
case Node::NODE_GLOBAL_VARIABLE:
|
||||
case Node::NODE_FIELD:
|
||||
case Node::NODE_ENUM_CONSTANT:
|
||||
if (m_isActive || m_isHovering)
|
||||
{
|
||||
color = ApplicationSettings::getInstance()->getNodeTypeColor(m_data->getType(), "hover").c_str();
|
||||
font.setWeight(QFont::Bold);
|
||||
}
|
||||
else
|
||||
{
|
||||
color = ApplicationSettings::getInstance()->getNodeTypeColor(m_data->getType()).c_str();
|
||||
}
|
||||
|
||||
radius = 8.0f;
|
||||
padding.x = 5;
|
||||
padding.y = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_isActive)
|
||||
{
|
||||
p.setWidthF(1.5f);
|
||||
p.setColor("#3c3c3c");
|
||||
}
|
||||
|
||||
m_rect->setPen(p);
|
||||
m_rect->setBrush(QBrush(color));
|
||||
m_rect->setRadius(radius);
|
||||
|
||||
if (useUndefinedPattern)
|
||||
{
|
||||
QtDeviceScaledPixmap pixmap("data/gui/graph_view/images/pattern.png");
|
||||
pixmap.scaleToHeight(10);
|
||||
|
||||
if (!m_undefinedRect)
|
||||
{
|
||||
m_undefinedRect = new QtGraphicsRoundedRectItem(this);
|
||||
setSize(getSize());
|
||||
}
|
||||
|
||||
p.setWidth(1);
|
||||
p.setColor(Qt::transparent);
|
||||
if (useUndefinedColor && !m_isActive)
|
||||
{
|
||||
p.setColor(color);
|
||||
}
|
||||
m_undefinedRect->setPen(p);
|
||||
m_undefinedRect->setBrush(QBrush(pixmap.pixmap()));
|
||||
m_undefinedRect->setRadius(radius);
|
||||
}
|
||||
|
||||
m_text->setFont(font);
|
||||
m_text->setPos(padding.x, padding.y);
|
||||
}
|
||||
|
||||
void QtGraphNode::setShadowEnabledRecursive(bool enabled)
|
||||
{
|
||||
m_rect->setShadowEnabled(enabled);
|
||||
@@ -440,6 +257,13 @@ void QtGraphNode::hoverEnter()
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::updateStyle()
|
||||
{
|
||||
GraphViewStyle::NodeStyle style =
|
||||
GraphViewStyle::getStyleForNodeType(m_data->getType(), m_isActive, m_isHovering, m_subNodes.size() > 0);
|
||||
setStyle(style);
|
||||
}
|
||||
|
||||
void QtGraphNode::mousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
event->ignore();
|
||||
@@ -500,13 +324,13 @@ void QtGraphNode::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
|
||||
void QtGraphNode::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
|
||||
{
|
||||
m_isHovering = true;
|
||||
setStyle();
|
||||
updateStyle();
|
||||
}
|
||||
|
||||
void QtGraphNode::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
|
||||
{
|
||||
m_isHovering = false;
|
||||
setStyle();
|
||||
updateStyle();
|
||||
}
|
||||
|
||||
void QtGraphNode::notifyEdgesAfterMove()
|
||||
@@ -530,3 +354,54 @@ void QtGraphNode::notifyEdgesAfterMove()
|
||||
node->notifyEdgesAfterMove();
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNode::setStyle(const GraphViewStyle::NodeStyle& style)
|
||||
{
|
||||
QColor color = style.color.c_str();
|
||||
qreal radius = style.cornerRadius;
|
||||
|
||||
QPen p(style.borderColor.c_str());
|
||||
p.setWidthF(style.borderWidth);
|
||||
if (style.borderDashed)
|
||||
{
|
||||
p.setStyle(Qt::DashLine);
|
||||
}
|
||||
|
||||
QFont font(style.fontName.c_str());
|
||||
font.setPixelSize(style.fontSize);
|
||||
if (style.fontBold)
|
||||
{
|
||||
font.setWeight(QFont::Bold);
|
||||
}
|
||||
|
||||
if (style.shadowColor.size())
|
||||
{
|
||||
m_rect->setShadow(style.shadowColor.c_str(), style.shadowBlurRadius);
|
||||
}
|
||||
|
||||
m_rect->setPen(p);
|
||||
m_rect->setBrush(QBrush(color));
|
||||
m_rect->setRadius(radius);
|
||||
|
||||
if (style.undefinedPattern)
|
||||
{
|
||||
QtDeviceScaledPixmap pixmap("data/gui/graph_view/images/pattern.png");
|
||||
pixmap.scaleToHeight(10);
|
||||
|
||||
if (!m_undefinedRect)
|
||||
{
|
||||
m_undefinedRect = new QtRoundedRectItem(this);
|
||||
setSize(getSize());
|
||||
}
|
||||
|
||||
p.setWidth(0);
|
||||
p.setColor(Qt::transparent);
|
||||
|
||||
m_undefinedRect->setPen(p);
|
||||
m_undefinedRect->setBrush(QBrush(pixmap.pixmap()));
|
||||
m_undefinedRect->setRadius(radius);
|
||||
}
|
||||
|
||||
m_text->setFont(font);
|
||||
m_text->setPos(style.textOffset.x, style.textOffset.y);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
#include <QGraphicsItem>
|
||||
|
||||
#include "component/view/graphElements/GraphNode.h"
|
||||
#include "component/view/GraphViewStyle.h"
|
||||
|
||||
class QtGraphEdge;
|
||||
class QtGraphicsRoundedRectItem;
|
||||
class QtRoundedRectItem;
|
||||
class QtGraphNodeComponent;
|
||||
|
||||
class QtGraphNode
|
||||
@@ -49,11 +50,11 @@ public:
|
||||
virtual Vec4i getBoundingRect() const;
|
||||
virtual Vec4i getParentBoundingRect() const;
|
||||
|
||||
virtual bool addOutEdge(const std::shared_ptr<GraphEdge>& edge);
|
||||
virtual bool addInEdge(const std::weak_ptr<GraphEdge>& edge);
|
||||
virtual void addOutEdge(const std::shared_ptr<GraphEdge>& edge);
|
||||
virtual void addInEdge(const std::weak_ptr<GraphEdge>& edge);
|
||||
|
||||
virtual unsigned int getOutEdgeCount() const;
|
||||
virtual unsigned int getInEdgeCount() const;
|
||||
virtual size_t getOutEdgeCount() const;
|
||||
virtual size_t getInEdgeCount() const;
|
||||
|
||||
QSize size() const;
|
||||
void setSize(const QSize& size);
|
||||
@@ -69,12 +70,13 @@ public:
|
||||
std::list<std::shared_ptr<QtGraphNode>> getSubNodes() const;
|
||||
virtual void addSubNode(const std::shared_ptr<QtGraphNode>& node);
|
||||
|
||||
void setStyle();
|
||||
void setShadowEnabledRecursive(bool enabled);
|
||||
|
||||
virtual void onClick();
|
||||
void hoverEnter();
|
||||
|
||||
virtual void updateStyle();
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
|
||||
@@ -85,6 +87,8 @@ protected:
|
||||
|
||||
void notifyEdgesAfterMove();
|
||||
|
||||
void setStyle(const GraphViewStyle::NodeStyle& style);
|
||||
|
||||
std::list<std::shared_ptr<GraphEdge>> m_outEdges;
|
||||
std::list<std::weak_ptr<GraphEdge>> m_inEdges;
|
||||
|
||||
@@ -92,8 +96,8 @@ protected:
|
||||
std::list<std::shared_ptr<QtGraphNode>> m_subNodes;
|
||||
|
||||
QGraphicsSimpleTextItem* m_text;
|
||||
QtGraphicsRoundedRectItem* m_rect;
|
||||
QtGraphicsRoundedRectItem* m_undefinedRect;
|
||||
QtRoundedRectItem* m_rect;
|
||||
QtRoundedRectItem* m_undefinedRect;
|
||||
|
||||
Vec2i m_size;
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
#include "utility/messaging/type/MessageGraphNodeExpand.h"
|
||||
|
||||
#include "qt/graphics/QtGraphicsRoundedRectItem.h"
|
||||
#include "component/view/GraphViewStyle.h"
|
||||
#include "qt/graphics/QtRoundedRectItem.h"
|
||||
#include "qt/utility/QtDeviceScaledPixmap.h"
|
||||
|
||||
QtGraphNodeAccess::QtAccessToggle::QtAccessToggle(bool expanded, int invisibleSubNodeCount, QGraphicsItem* parent)
|
||||
@@ -28,9 +29,9 @@ QtGraphNodeAccess::QtAccessToggle::QtAccessToggle(bool expanded, int invisibleSu
|
||||
if (invisibleSubNodeCount)
|
||||
{
|
||||
QFont font;
|
||||
font.setFamily("Myriad Pro");
|
||||
font.setFamily(GraphViewStyle::getFontNameOfNumber().c_str());
|
||||
font.setPixelSize(GraphViewStyle::getFontSizeOfNumber());
|
||||
font.setWeight(QFont::Normal);
|
||||
font.setPixelSize(9);
|
||||
|
||||
m_number = new QGraphicsSimpleTextItem(this);
|
||||
m_number->setFont(font);
|
||||
@@ -64,20 +65,6 @@ QtGraphNodeAccess::QtGraphNodeAccess(
|
||||
, m_access(accessType)
|
||||
, m_accessIconSize(20)
|
||||
{
|
||||
Vec2i padding(10, 10);
|
||||
|
||||
QFont font;
|
||||
font.setFamily("Myriad Pro");
|
||||
font.setWeight(QFont::Bold);
|
||||
font.setPixelSize(11);
|
||||
font.setCapitalization(QFont::AllUppercase);
|
||||
m_text->setFont(font);
|
||||
m_text->setPos(padding.x + m_accessIconSize + 3, padding.y + m_accessIconSize / 2 - 1);
|
||||
|
||||
m_rect->setPen(QPen(Qt::transparent));
|
||||
m_rect->setBrush(QBrush(Qt::white));
|
||||
m_rect->setRadius(12.0f);
|
||||
|
||||
std::string accessString = TokenComponentAccess::getAccessString(accessType);
|
||||
this->setName(accessString);
|
||||
m_text->hide();
|
||||
@@ -86,8 +73,6 @@ QtGraphNodeAccess::QtGraphNodeAccess(
|
||||
pixmap.scaleToHeight(m_accessIconSize);
|
||||
|
||||
m_accessIcon = new QGraphicsPixmapItem(pixmap.pixmap(), this);
|
||||
m_accessIcon->setPos(padding.x, padding.y);
|
||||
|
||||
m_accessToggle = new QtAccessToggle(expanded, invisibleSubNodeCount, this);
|
||||
}
|
||||
|
||||
@@ -128,6 +113,19 @@ void QtGraphNodeAccess::onClick()
|
||||
}
|
||||
}
|
||||
|
||||
void QtGraphNodeAccess::updateStyle()
|
||||
{
|
||||
GraphViewStyle::NodeStyle style = GraphViewStyle::getStyleOfAccessNode();
|
||||
setStyle(style);
|
||||
|
||||
QFont font = m_text->font();
|
||||
font.setCapitalization(QFont::AllUppercase);
|
||||
m_text->setFont(font);
|
||||
|
||||
m_text->setPos(style.textOffset.x + m_accessIconSize + 3, style.textOffset.y + m_accessIconSize / 2 - 1);
|
||||
m_accessIcon->setPos(style.textOffset.x, style.textOffset.y);
|
||||
}
|
||||
|
||||
void QtGraphNodeAccess::hideLabel()
|
||||
{
|
||||
m_text->hide();
|
||||
|
||||
@@ -30,6 +30,8 @@ public:
|
||||
virtual void addSubNode(const std::shared_ptr<QtGraphNode>& node);
|
||||
virtual void onClick();
|
||||
|
||||
virtual void updateStyle();
|
||||
|
||||
void hideLabel();
|
||||
|
||||
private:
|
||||
|
||||
@@ -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