aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmldesigner
diff options
context:
space:
mode:
authorHenning Gruendl <henning.gruendl@qt.io>2020-04-29 15:11:02 +0200
committerThomas Hartmann <thomas.hartmann@qt.io>2020-04-29 19:00:26 +0000
commit06c0f74fec27fa4c23fceb1991c626fe5606637c (patch)
tree76bf9a402a9fd4e03ad6651fe83db58b7a1305a7 /src/plugins/qmldesigner
parent1d5b54f1c87ff8509b9d568ce971deaf3f75d01e (diff)
QmlDesigner: Add radius to transition item
* Add support for rounded corners on transition item * Cleanup connection drawing Task-number: QDS-1788 Change-Id: I53698687b911ad9a43309c53bb599b7f0212f90d Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Diffstat (limited to 'src/plugins/qmldesigner')
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp289
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditoritem.h13
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp8
3 files changed, 178 insertions, 132 deletions
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp
index 37d9aa26f0..42847fa7e7 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp
@@ -793,10 +793,10 @@ QPointF FormEditorTransitionItem::instancePosition() const
static bool verticalOverlap(const QRectF &from, const QRectF &to)
{
- if (from.top() < to.bottom() && (from.top() + from.height()) > to.top())
+ if (from.top() < to.bottom() && from.bottom() > to.top())
return true;
- if (to.top() < from.bottom() && (to.top() + to.height()) > from.top())
+ if (to.top() < from.bottom() && to.bottom() > from.top())
return true;
return false;
@@ -805,25 +805,77 @@ static bool verticalOverlap(const QRectF &from, const QRectF &to)
static bool horizontalOverlap(const QRectF &from, const QRectF &to)
{
- if (from.left() < to.right() && (from.left() + from.width()) > to.left())
+ if (from.left() < to.right() && from.right() > to.left())
return true;
- if (to.left() < from.right() && (to.left() + to.width()) > from.left())
+ if (to.left() < from.right() && to.right() > from.left())
return true;
return false;
}
+static void drawArrow(QPainter *painter,
+ const QLineF &line,
+ int arrowLength,
+ int arrowWidth)
+{
+ const QPointF peakP(0, 0);
+ const QPointF leftP(-arrowLength, -arrowWidth * 0.5);
+ const QPointF rightP(-arrowLength, arrowWidth * 0.5);
+
+ painter->save();
+
+ painter->translate(line.p2());
+ painter->rotate(-line.angle());
+ painter->drawLine(leftP, peakP);
+ painter->drawLine(rightP, peakP);
+
+ painter->restore();
+}
+
+static void drawRoundedCorner(QPainter *painter,
+ const QPointF &s,
+ const QPointF &m,
+ const QPointF &e,
+ int radius)
+{
+ const QVector2D sm(m - s);
+ const QVector2D me(e - m);
+ const float smLength = sm.length();
+ const float meLength = me.length();
+ const int actualRadius = qMin(radius, static_cast<int>(qMin(smLength, meLength)));
+ const QVector2D smNorm = sm.normalized();
+ const QVector2D meNorm = me.normalized();
+
+ const QPointF arcStartP = s + (smNorm * (smLength - actualRadius)).toPointF();
+
+ QRectF rect(m, QSizeF(actualRadius * 2, actualRadius * 2));
+
+ painter->drawLine(s, arcStartP);
+
+ if ((smNorm.y() < 0 && meNorm.x() > 0) || (smNorm.x() < 0 && meNorm.y() > 0)) {
+ rect.moveTopLeft(m);
+ painter->drawArc(rect, 90 * 16, 90 * 16);
+ } else if ((smNorm.y() > 0 && meNorm.x() > 0) || (smNorm.x() < 0 && meNorm.y() < 0)) {
+ rect.moveBottomLeft(m);
+ painter->drawArc(rect, 180 * 16, 90 * 16);
+ } else if ((smNorm.x() > 0 && meNorm.y() > 0) || (smNorm.y() < 0 && meNorm.x() < 0)) {
+ rect.moveTopRight(m);
+ painter->drawArc(rect, 0 * 16, 90 * 16);
+ } else if ((smNorm.y() > 0 && meNorm.x() < 0) || (smNorm.x() > 0 && meNorm.y() < 0)) {
+ rect.moveBottomRight(m);
+ painter->drawArc(rect, 270 * 16, 90 * 16);
+ }
+
+ const QPointF arcEndP = e - (meNorm * (meLength - actualRadius)).toPointF();
+
+ painter->drawLine(arcEndP, e);
+}
+
static void paintConnection(QPainter *painter,
const QRectF &from,
const QRectF &to,
- qreal width,
- qreal adjustedWidth,
- const QColor &color,
- bool dash,
- int startOffset,
- int endOffset,
- int breakOffset)
+ const ConnectionStyle &style)
{
painter->save();
painter->setRenderHint(QPainter::Antialiasing);
@@ -832,23 +884,22 @@ static void paintConnection(QPainter *painter,
pen.setCosmetic(true);
pen.setJoinStyle(Qt::MiterJoin);
pen.setCapStyle(Qt::RoundCap);
+ pen.setColor(style.color);
- pen.setColor(color);
-
- if (dash)
+ if (style.dash)
pen.setStyle(Qt::DashLine);
else
pen.setStyle(Qt::SolidLine);
- pen.setWidthF(width);
+ pen.setWidthF(style.width);
painter->setPen(pen);
//const bool forceVertical = false;
//const bool forceHorizontal = false;
- const int padding = 2 * width + 2 * adjustedWidth;
+ const int padding = 2 * style.width + 2 * style.adjustedWidth;
- const int arrowLength = 4 * adjustedWidth;
- const int arrowWidth = 8 * adjustedWidth;
+ const int arrowLength = 4 * style.adjustedWidth;
+ const int arrowWidth = 8 * style.adjustedWidth;
const bool boolExitRight = from.right() < to.center().x();
const bool boolExitBottom = from.bottom() < to.center().y();
@@ -860,9 +911,10 @@ static void paintConnection(QPainter *painter,
horizontalFirst = false;
*/
- const qreal middleFactor = breakOffset / 100.0;
+ const qreal middleFactor = style.breakOffset / 100.0;
QPointF startP;
+ QLineF lastSegment;
bool extraLine = false;
@@ -886,130 +938,97 @@ static void paintConnection(QPainter *painter,
}
if (horizontalFirst) {
- const qreal startY = from.center().y() + startOffset;
- qreal startX = from.x() - padding;
- if (boolExitRight)
- startX = from.right() + padding;
+ const qreal startX = boolExitRight ? from.right() + padding : from.x() - padding;
+ const qreal startY = from.center().y() + style.outOffset;
startP = QPointF(startX, startY);
- qreal endY = to.top() - padding;
-
- if (from.bottom() > to.y())
- endY = to.bottom() + padding;
+ const qreal endY = (from.bottom() > to.y()) ? to.bottom() + padding : to.top() - padding;
if (!extraLine) {
-
-
- const qreal endX = to.center().x() + endOffset;
-
+ const qreal endX = to.center().x() + style.inOffset;
const QPointF midP(endX, startY);
-
const QPointF endP(endX, endY);
- painter->drawLine(startP, midP);
- painter->drawLine(midP, endP);
-
- int flip = 1;
-
- if (midP.y() < endP.y())
- flip = -1;
+ if (style.radius == 0) {
+ painter->drawLine(startP, midP);
+ painter->drawLine(midP, endP);
+ } else {
+ drawRoundedCorner(painter, startP, midP, endP, style.radius);
+ }
- pen.setStyle(Qt::SolidLine);
- painter->setPen(pen);
- painter->drawLine(endP + flip * QPoint(arrowWidth / 2, arrowLength), endP);
- painter->drawLine(endP + flip * QPoint(-arrowWidth / 2, arrowLength), endP);
+ lastSegment = QLineF(midP, endP);
} else {
-
- qreal endX = to.left() - padding;
-
- if (from.right() > to.x())
- endX = to.right() + padding;
-
- const qreal midX = startX * middleFactor + endX * (1-middleFactor);
+ const qreal endX = (from.right() > to.x()) ? to.right() + padding : to.left() - padding;
+ const qreal midX = startX * middleFactor + endX * (1 - middleFactor);
const QPointF midP(midX, startY);
- const QPointF midP2(midX, to.center().y() + endOffset);
- const QPointF endP(endX, to.center().y() + endOffset);
- painter->drawLine(startP, midP);
- painter->drawLine(midP, midP2);
- painter->drawLine(midP2, endP);
-
- int flip = 1;
+ const QPointF midP2(midX, to.center().y() + style.inOffset);
+ const QPointF endP(endX, to.center().y() + style.inOffset);
- if (midP2.x() < endP.x())
- flip = -1;
+ if (style.radius == 0) {
+ painter->drawLine(startP, midP);
+ painter->drawLine(midP, midP2);
+ painter->drawLine(midP2, endP);
+ } else {
+ const QLineF breakLine(midP, midP2);
+ drawRoundedCorner(painter, startP, midP, breakLine.center(), style.radius);
+ drawRoundedCorner(painter, breakLine.center(), midP2, endP, style.radius);
+ }
- pen.setStyle(Qt::SolidLine);
- painter->setPen(pen);
- painter->drawLine(endP + flip * QPoint(arrowWidth / 2, arrowWidth / 2), endP);
- painter->drawLine(endP + flip * QPoint(arrowLength, -arrowWidth / 2), endP);
+ lastSegment = QLineF(midP2, endP);
}
} else {
- const qreal startX = from.center().x() + startOffset;
-
- qreal startY = from.top() - padding;
- if (boolExitBottom)
- startY = from.bottom() + padding;
+ const qreal startX = from.center().x() + style.outOffset;
+ const qreal startY = boolExitBottom ? from.bottom() + padding : from.top() - padding;
startP = QPointF(startX, startY);
- qreal endX = to.left() - padding;
- if (from.right() > to.x())
- endX = to.right() + padding;
+ const qreal endX = (from.right() > to.x()) ? to.right() + padding : to.left() - padding;
if (!extraLine) {
- const qreal endY = to.center().y() + endOffset;
-
+ const qreal endY = to.center().y() + style.inOffset;
const QPointF midP(startX, endY);
-
const QPointF endP(endX, endY);
- painter->drawLine(startP, midP);
- painter->drawLine(midP, endP);
-
- int flip = 1;
-
- if (midP.x() < endP.x())
- flip = -1;
+ if (style.radius == 0) {
+ painter->drawLine(startP, midP);
+ painter->drawLine(midP, endP);
+ } else {
+ drawRoundedCorner(painter, startP, midP, endP, style.radius);
+ }
- pen.setStyle(Qt::SolidLine);
- painter->setPen(pen);
- painter->drawLine(endP + flip * QPoint(arrowWidth / 2, arrowWidth / 2), endP);
- painter->drawLine(endP + flip * QPoint(arrowLength, -arrowWidth / 2), endP);
+ lastSegment = QLineF(midP, endP);
} else {
+ const qreal endY = (from.bottom() > to.y()) ? to.bottom() + padding : to.top() - padding;
- qreal endY = to.top() - padding;
-
- if (from.bottom() > to.y())
- endY = to.bottom() + padding;
-
- const qreal midY = startY * middleFactor + endY * (1-middleFactor);
+ const qreal midY = startY * middleFactor + endY * (1 - middleFactor);
const QPointF midP(startX, midY);
- const QPointF midP2(to.center().x() + endOffset, midY);
- const QPointF endP(to.center().x() + endOffset, endY);
+ const QPointF midP2(to.center().x() + style.inOffset, midY);
+ const QPointF endP(to.center().x() + style.inOffset, endY);
- painter->drawLine(startP, midP);
- painter->drawLine(midP, midP2);
- painter->drawLine(midP2, endP);
-
- int flip = 1;
-
- if (midP2.y() < endP.y())
- flip = -1;
+ if (style.radius == 0) {
+ painter->drawLine(startP, midP);
+ painter->drawLine(midP, midP2);
+ painter->drawLine(midP2, endP);
+ } else {
+ const QLineF breakLine(midP, midP2);
+ drawRoundedCorner(painter, startP, midP, breakLine.center(), style.radius);
+ drawRoundedCorner(painter, breakLine.center(), midP2, endP, style.radius);
+ }
- pen.setStyle(Qt::SolidLine);
- painter->setPen(pen);
- painter->drawLine(endP + flip * QPoint(arrowWidth / 2, arrowLength), endP);
- painter->drawLine(endP + flip * QPoint(-arrowWidth / 2, arrowLength), endP);
+ lastSegment = QLineF(midP2, endP);
}
}
- pen.setWidthF(width);
+ pen.setWidthF(style.width);
pen.setStyle(Qt::SolidLine);
painter->setPen(pen);
+
+ drawArrow(painter, lastSegment, arrowLength, arrowWidth);
+
painter->setBrush(Qt::white);
- painter->drawEllipse(startP, arrowLength / 3, arrowLength / 3);
+ painter->drawEllipse(startP, arrowLength / 3, arrowLength / 3);
painter->restore();
}
@@ -1066,57 +1085,67 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
toRect.translate(-pos());
fromRect.translate(-pos());
- qreal width = 2;
+ ConnectionStyle style;
+
+ style.width = 2;
const qreal scaleFactor = viewportTransform().m11();
if (qmlItemNode().modelNode().hasAuxiliaryData("width"))
- width = qmlItemNode().modelNode().auxiliaryData("width").toInt();
+ style.width = qmlItemNode().modelNode().auxiliaryData("width").toInt();
- qreal adjustedWidth = width / scaleFactor;
+ style.adjustedWidth = style.width / scaleFactor;
if (qmlItemNode().modelNode().isSelected())
- width += 2;
+ style.width += 2;
if (m_hitTest)
- width *= 8;
+ style.width *= 8;
- QColor color = "#e71919";
+ style.color = "#e71919";
if (resolved.isStartLine)
- color = "blue";
+ style.color = "blue";
if (resolved.isWildcardLine)
- color = "green";
-
- bool dash = false;
+ style.color = "green";
if (qmlItemNode().rootModelNode().hasAuxiliaryData("transitionColor"))
- color = qmlItemNode().rootModelNode().auxiliaryData("transitionColor").value<QColor>();
+ style.color = qmlItemNode().rootModelNode().auxiliaryData("transitionColor").value<QColor>();
if (qmlItemNode().modelNode().hasAuxiliaryData("color"))
- color = qmlItemNode().modelNode().auxiliaryData("color").value<QColor>();
+ style.color = qmlItemNode().modelNode().auxiliaryData("color").value<QColor>();
+
+ style.dash = false;
if (qmlItemNode().modelNode().hasAuxiliaryData("dash"))
- dash = qmlItemNode().modelNode().auxiliaryData("dash").toBool();
+ style.dash = qmlItemNode().modelNode().auxiliaryData("dash").toBool();
- int outOffset = 0;
- int inOffset = 0;
+ style.outOffset = 0;
+ style.inOffset = 0;
if (qmlItemNode().modelNode().hasAuxiliaryData("outOffset"))
- outOffset = qmlItemNode().modelNode().auxiliaryData("outOffset").toInt();
+ style.outOffset = qmlItemNode().modelNode().auxiliaryData("outOffset").toInt();
if (qmlItemNode().modelNode().hasAuxiliaryData("inOffset"))
- inOffset = qmlItemNode().modelNode().auxiliaryData("inOffset").toInt();
+ style.inOffset = qmlItemNode().modelNode().auxiliaryData("inOffset").toInt();
- int breakOffset = 50;
+ style.breakOffset = 50;
if (qmlItemNode().modelNode().hasAuxiliaryData("breakPoint"))
- breakOffset = qmlItemNode().modelNode().auxiliaryData("breakPoint").toInt();
+ style.breakOffset = qmlItemNode().modelNode().auxiliaryData("breakPoint").toInt();
+
+ style.radius = 8;
+
+ if (qmlItemNode().rootModelNode().hasAuxiliaryData("transitionRadius"))
+ style.radius = qmlItemNode().rootModelNode().auxiliaryData("transitionRadius").toInt();
+
+ if (qmlItemNode().modelNode().hasAuxiliaryData("radius"))
+ style.radius = qmlItemNode().modelNode().auxiliaryData("radius").toInt();
if (resolved.isStartLine)
- fromRect.translate(0, inOffset);
+ fromRect.translate(0, style.outOffset);
- paintConnection(painter, fromRect, toRect, width, adjustedWidth ,color, dash, outOffset, inOffset, breakOffset);
+ paintConnection(painter, fromRect, toRect, style);
if (resolved.isStartLine) {
@@ -1124,7 +1153,7 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
QPen pen;
pen.setCosmetic(true);
- pen.setColor(color);
+ pen.setColor(style.color);
painter->setPen(pen);
const int iconAdjust = 48;
@@ -1134,7 +1163,7 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
const int x = fromRect.topRight().x() - offset;
const int y = fromRect.topRight().y();
painter->drawRoundedRect(x, y , size - 10, size, size / 2, iconSize / 2);
- drawIcon(painter, x + iconAdjust / 2, y + iconAdjust / 2, icon, iconSize, iconSize, color);
+ drawIcon(painter, x + iconAdjust / 2, y + iconAdjust / 2, icon, iconSize, iconSize, style.color);
}
painter->restore();
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.h b/src/plugins/qmldesigner/components/formeditor/formeditoritem.h
index 91dcad44a4..d0fcd99319 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.h
+++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.h
@@ -47,6 +47,19 @@ namespace Internal {
class MoveController;
}
+class ConnectionStyle
+{
+public:
+ qreal width;
+ qreal adjustedWidth;
+ QColor color;
+ bool dash;
+ int outOffset;
+ int inOffset;
+ int breakOffset;
+ int radius;
+};
+
class QMLDESIGNERCORE_EXPORT FormEditorItem : public QGraphicsItem
{
friend class QmlDesigner::FormEditorScene;
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
index a9aad59fbf..1a6025acef 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
@@ -167,6 +167,10 @@ QVariant properDefaultAuxiliaryProperties(const QmlObjectNode &qmlObjectNode,
return 0;
else if (propertyName == "breakPoint")
return 50;
+ else if (propertyName == "transitionRadius")
+ return 8;
+ else if (propertyName == "radius")
+ return 8;
else if (propertyName == "customId")
return QString();
else if (propertyName == "joinConnection")
@@ -236,7 +240,7 @@ void PropertyEditorQmlBackend::setupAuxiliaryProperties(const QmlObjectNode &qml
propertyNames.append("customId");
if (itemNode.isFlowTransition()) {
- propertyNames.append({"color", "width", "inOffset", "outOffset", "dash", "breakPoint"});
+ propertyNames.append({"color", "width", "inOffset", "outOffset", "dash", "breakPoint", "radius"});
} else if (itemNode.isFlowItem()) {
propertyNames.append({"color", "width", "inOffset", "outOffset", "joinConnection"});
} else if (itemNode.isFlowActionArea()) {
@@ -246,7 +250,7 @@ void PropertyEditorQmlBackend::setupAuxiliaryProperties(const QmlObjectNode &qml
} else if (itemNode.isFlowWildcard()) {
propertyNames.append({"color", "width", "fillColor", "dash"});
} else if (itemNode.isFlowView()) {
- propertyNames.append({"transitionColor", "areaColor", "areaFillColor", "blockColor" });
+ propertyNames.append({"transitionColor", "areaColor", "areaFillColor", "blockColor", "transitionRadius"});
}
for (const PropertyName &propertyName : propertyNames) {