Reduce objects: Make ShapePath inherit Path

Shape { ShapePath { Path { ... } } } simply becomes
Shape { ShapePath { ... } }

Change-Id: Ie57936cd7953c8a8d6c67e78b9d73bdbe2a05316
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
This commit is contained in:
Laszlo Agocs 2017-06-02 15:12:05 +02:00
parent 961da5273e
commit 5af4c9b237
27 changed files with 2575 additions and 3166 deletions

View File

@ -69,12 +69,10 @@ Rectangle {
PauseAnimation { duration: 2000 }
}
Path {
startX: 30; startY: 30
PathLine { x: ctr.width - 30; y: ctr.height - 30 }
PathLine { x: 30; y: ctr.height - 30 }
PathLine { x: 30; y: 30 }
}
startX: 30; startY: 30
PathLine { x: ctr.width - 30; y: ctr.height - 30 }
PathLine { x: 30; y: ctr.height - 30 }
PathLine { x: 30; y: 30 }
}
}
}

View File

@ -68,13 +68,11 @@ Rectangle {
strokeColor: "black"
fillColor: "lightBlue"
Path {
startX: 50; startY: 100
PathCubic {
x: 150; y: 100
control1X: cp1.x; control1Y: cp1.y
control2X: cp2.x; control2Y: cp2.y
}
startX: 50; startY: 100
PathCubic {
x: 150; y: 100
control1X: cp1.x; control1Y: cp1.y
control2X: cp2.x; control2Y: cp2.y
}
}
}

View File

@ -66,24 +66,22 @@ Rectangle {
ShapeGradientStop { position: 1; color: "green" }
}
Path {
startX: 10; startY: 100
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 25
}
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 35
}
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 60
}
PathArc {
relativeX: 50; y: 100
radiusX: 50; radiusY: 120
}
startX: 10; startY: 100
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 25
}
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 35
}
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 60
}
PathArc {
relativeX: 50; y: 100
radiusX: 50; radiusY: 120
}
}
}
@ -102,13 +100,11 @@ Rectangle {
strokeWidth: 20
capStyle: ShapePath.RoundCap
Path {
startX: 20; startY: 50
PathArc {
x: 20; y: 90
radiusX: 45; radiusY: 45
useLargeArc: true
}
startX: 20; startY: 50
PathArc {
x: 20; y: 90
radiusX: 45; radiusY: 45
useLargeArc: true
}
}
}

View File

@ -72,13 +72,11 @@ Rectangle {
ShapeGradientStop { position: 1; color: "red" }
}
Path {
startX: 10; startY: 10
PathLine { relativeX: 180; relativeY: 0 }
PathLine { relativeX: 0; relativeY: 180 }
PathLine { relativeX: -180; relativeY: 0 }
PathLine { relativeX: 0; relativeY: -180 }
}
startX: 10; startY: 10
PathLine { relativeX: 180; relativeY: 0 }
PathLine { relativeX: 0; relativeY: 180 }
PathLine { relativeX: -180; relativeY: 0 }
PathLine { relativeX: 0; relativeY: -180 }
}
}
@ -100,12 +98,10 @@ Rectangle {
strokeColor: "gray"
strokeWidth: 2
fillColor: "transparent"
Path {
PathMove { x: 0; y: 50 }
PathLine { relativeX: 200; relativeY: 0 }
PathMove { x: 0; y: 150 }
PathLine { relativeX: 200; relativeY: 0 }
}
PathMove { x: 0; y: 50 }
PathLine { relativeX: 200; relativeY: 0 }
PathMove { x: 0; y: 150 }
PathLine { relativeX: 200; relativeY: 0 }
}
}
}

View File

@ -71,14 +71,12 @@ Rectangle {
strokeStyle: ShapePath.DashLine
strokeWidth: 4
Path {
startX: 4; startY: 4
PathArc {
id: arc
x: 96; y: 96
radiusX: 100; radiusY: 100
direction: model.index === 0 ? PathArc.Clockwise : PathArc.Counterclockwise
}
startX: 4; startY: 4
PathArc {
id: arc
x: 96; y: 96
radiusX: 100; radiusY: 100
direction: model.index === 0 ? PathArc.Clockwise : PathArc.Counterclockwise
}
}
}

View File

@ -67,13 +67,11 @@ Rectangle {
strokeStyle: ShapePath.DashLine
strokeWidth: 4
Path {
startX: 50; startY: 100
PathArc {
x: 100; y: 150
radiusX: 50; radiusY: 50
useLargeArc: model.index === 1
}
startX: 50; startY: 100
PathArc {
x: 100; y: 150
radiusX: 50; radiusY: 50
useLargeArc: model.index === 1
}
}
}

View File

@ -67,13 +67,11 @@ Rectangle {
strokeStyle: ShapePath.DashLine
strokeWidth: 4
Path {
startX: 50; startY: 100
PathArc {
x: 150; y: 100
radiusX: 50; radiusY: 20
xAxisRotation: model.index === 0 ? 0 : 45
}
startX: 50; startY: 100
PathArc {
x: 150; y: 100
radiusX: 50; radiusY: 20
xAxisRotation: model.index === 0 ? 0 : 45
}
}
}
@ -90,14 +88,12 @@ Rectangle {
fillColor: "transparent"
strokeColor: model.index === 0 ? "red" : "blue"
Path {
startX: 50; startY: 100
PathArc {
x: 150; y: 100
radiusX: 50; radiusY: 20
xAxisRotation: model.index === 0 ? 0 : 45
direction: PathArc.Counterclockwise
}
startX: 50; startY: 100
PathArc {
x: 150; y: 100
radiusX: 50; radiusY: 20
xAxisRotation: model.index === 0 ? 0 : 45
direction: PathArc.Counterclockwise
}
}
}

View File

@ -59,6 +59,7 @@ Rectangle {
anchors.fill: parent
ShapePath {
id: p1
fillColor: "transparent" // stroke only
strokeWidth: 4
@ -81,23 +82,20 @@ Rectangle {
}
}
Path {
id: p1
property real r: 60
startX: circ1.width / 2 - r
startY: circ1.height / 2 - r
PathArc {
x: circ1.width / 2 + p1.r
y: circ1.height / 2 + p1.r
radiusX: p1.r; radiusY: p1.r
useLargeArc: true
}
PathArc {
x: circ1.width / 2 - p1.r
y: circ1.height / 2 - p1.r
radiusX: p1.r; radiusY: p1.r
useLargeArc: true
}
property real r: 60
startX: circ1.width / 2 - r
startY: circ1.height / 2 - r
PathArc {
x: circ1.width / 2 + p1.r
y: circ1.height / 2 + p1.r
radiusX: p1.r; radiusY: p1.r
useLargeArc: true
}
PathArc {
x: circ1.width / 2 - p1.r
y: circ1.height / 2 - p1.r
radiusX: p1.r; radiusY: p1.r
useLargeArc: true
}
}
}
@ -113,6 +111,7 @@ Rectangle {
}
ShapePath {
id: p2
strokeWidth: -1 // or strokeColor: "transparent"
SequentialAnimation on fillColor {
@ -134,23 +133,20 @@ Rectangle {
}
}
Path {
id: p2
property real r: 40
startX: circ2.width / 2 - r
startY: circ2.height / 2 - r
PathArc {
x: circ2.width / 2 + p2.r
y: circ2.height / 2 + p2.r
radiusX: p2.r; radiusY: p2.r
useLargeArc: true
}
PathArc {
x: circ2.width / 2 - p2.r
y: circ2.height / 2 - p2.r
radiusX: p2.r; radiusY: p2.r
useLargeArc: true
}
property real r: 40
startX: circ2.width / 2 - r
startY: circ2.height / 2 - r
PathArc {
x: circ2.width / 2 + p2.r
y: circ2.height / 2 + p2.r
radiusX: p2.r; radiusY: p2.r
useLargeArc: true
}
PathArc {
x: circ2.width / 2 - p2.r
y: circ2.height / 2 - p2.r
radiusX: p2.r; radiusY: p2.r
useLargeArc: true
}
}
}

View File

@ -58,30 +58,28 @@ Rectangle {
anchors.fill: parent
ShapePath {
id: p
strokeWidth: 5
strokeColor: "blue"
strokeStyle: ShapePath.DashLine
dashPattern: [ 1, 4, 4, 4 ]
fillColor: "lightBlue"
Path {
id: p
property real xr: 70
property real yr: 30
startX: shape.width / 2 - xr
startY: shape.height / 2 - yr
PathArc {
x: shape.width / 2 + p.xr
y: shape.height / 2 + p.yr
radiusX: p.xr; radiusY: p.yr
useLargeArc: true
}
PathArc {
x: shape.width / 2 - p.xr
y: shape.height / 2 - p.yr
radiusX: p.xr; radiusY: p.yr
useLargeArc: true
}
property real xr: 70
property real yr: 30
startX: shape.width / 2 - xr
startY: shape.height / 2 - yr
PathArc {
x: shape.width / 2 + p.xr
y: shape.height / 2 + p.yr
radiusX: p.xr; radiusY: p.yr
useLargeArc: true
}
PathArc {
x: shape.width / 2 - p.xr
y: shape.height / 2 - p.yr
radiusX: p.xr; radiusY: p.yr
useLargeArc: true
}
}
}

View File

@ -72,12 +72,10 @@ Rectangle {
fillColor: "blue" // ignored with the gradient set
strokeStyle: ShapePath.DashLine
dashPattern: [ 1, 4 ]
Path {
startX: 20; startY: 20
PathLine { x: 180; y: 130 }
PathLine { x: 20; y: 130 }
PathLine { x: 20; y: 20 }
}
startX: 20; startY: 20
PathLine { x: 180; y: 130 }
PathLine { x: 20; y: 130 }
PathLine { x: 20; y: 20 }
}
transform: Rotation { origin.x: 100; origin.y: 50; axis { x: 0; y: 1; z: 0 }
SequentialAnimation on angle {

View File

@ -62,14 +62,12 @@ Rectangle {
strokeColor: "blue"
fillColor: "magenta"
strokeWidth: 2
Path {
PathMove { x: 90; y: 50 }
PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
PathLine { x: 90; y: 50 }
}
PathMove { x: 90; y: 50 }
PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
PathLine { x: 90; y: 50 }
}
NumberAnimation on rotation {
from: 0

View File

@ -73,12 +73,10 @@ Rectangle {
joinStyle: styles[joinStyleIdx]
Path {
startX: 30
startY: 30
PathLine { x: 100; y: 100 }
PathLine { x: 30; y: 100 }
}
startX: 30
startY: 30
PathLine { x: 100; y: 100 }
PathLine { x: 30; y: 100 }
}
}

View File

@ -71,12 +71,10 @@ Rectangle {
capStyle: styles[capStyleIdx]
Path {
startX: 40; startY: 30
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
}
startX: 40; startY: 30
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
}
}

View File

@ -68,13 +68,11 @@ Rectangle {
strokeColor: "black"
fillColor: "transparent"
Path {
startX: 50
startY: 50
PathQuad {
x: 150; y: 50
controlX: cp.x; controlY: cp.y
}
startX: 50
startY: 50
PathQuad {
x: 150; y: 50
controlX: cp.x; controlY: cp.y
}
}
}

View File

@ -192,20 +192,20 @@ Rectangle {
var p = Qt.createQmlObject('import QtQuick 2.9; import QtQuick.Shapes 1.0; ShapePath {' +
'strokeColor: "black"; fillColor: "transparent";'+
'strokeWidth: ' + widthSlider.value + ';' +
'Path { startX: ' + x + '; startY: ' + y + ';' +
'PathLine { x: ' + x + ' + 1; y: ' + y + ' + 1 } } }',
'startX: ' + x + '; startY: ' + y + ';' +
'PathLine { x: ' + x + ' + 1; y: ' + y + ' + 1 } }',
root, "dynamic_visual_path");
shape.elements.push(p);
activePath = p;
}, "move": function(x, y) {
if (!activePath)
return;
var pathObj = activePath.path.pathElements[0];
var pathObj = activePath.pathElements[0];
pathObj.x = x;
pathObj.y = y;
}, "end": function() {
canvas.genResizer(activePath.path, activePath.path.startX, activePath.path.startY, "startX", "startY", "red");
var pathObj = activePath.path.pathElements[0];
canvas.genResizer(activePath, activePath.startX, activePath.startY, "startX", "startY", "red");
var pathObj = activePath.pathElements[0];
canvas.genResizer(pathObj, pathObj.x, pathObj.y, "x", "y", "red");
activePath = null;
}
@ -214,21 +214,21 @@ Rectangle {
var p = Qt.createQmlObject('import QtQuick 2.9; import QtQuick.Shapes 1.0; ShapePath {' +
'strokeColor: "black"; fillColor: "' + (root.fill ? 'green' : 'transparent') + '";'+
'strokeWidth: ' + widthSlider.value + ';' +
'Path { startX: ' + x + '; startY: ' + y + ';' +
'startX: ' + x + '; startY: ' + y + ';' +
'PathCubic { x: ' + x + ' + 1; y: ' + y + ' + 1;' +
'control1X: ' + x + ' + 50; control1Y: ' + y + ' + 50; control2X: ' + x + ' + 150; control2Y: ' + y + ' + 50; } } }',
'control1X: ' + x + ' + 50; control1Y: ' + y + ' + 50; control2X: ' + x + ' + 150; control2Y: ' + y + ' + 50; } }',
root, "dynamic_visual_path");
shape.elements.push(p);
activePath = p;
}, "move": function(x, y) {
if (!activePath)
return;
var pathObj = activePath.path.pathElements[0];
var pathObj = activePath.pathElements[0];
pathObj.x = x;
pathObj.y = y;
}, "end": function() {
canvas.genResizer(activePath.path, activePath.path.startX, activePath.path.startY, "startX", "startY", "red");
var pathObj = activePath.path.pathElements[0];
canvas.genResizer(activePath, activePath.startX, activePath.startY, "startX", "startY", "red");
var pathObj = activePath.pathElements[0];
canvas.genResizer(pathObj, pathObj.x, pathObj.y, "x", "y", "red");
canvas.genResizer(pathObj, pathObj.control1X, pathObj.control1Y, "control1X", "control1Y", "blue");
canvas.genResizer(pathObj, pathObj.control2X, pathObj.control2Y, "control2X", "control2Y", "lightBlue");
@ -239,21 +239,21 @@ Rectangle {
var p = Qt.createQmlObject('import QtQuick 2.9; import QtQuick.Shapes 1.0; ShapePath {' +
'strokeColor: "black"; fillColor: "' + (root.fill ? 'green' : 'transparent') + '";'+
'strokeWidth: ' + widthSlider.value + ';' +
'Path { startX: ' + x + '; startY: ' + y + ';' +
'startX: ' + x + '; startY: ' + y + ';' +
'PathQuad { x: ' + x + ' + 1; y: ' + y + ' + 1;' +
'controlX: ' + x + ' + 50; controlY: ' + y + ' + 50 } } }',
'controlX: ' + x + ' + 50; controlY: ' + y + ' + 50 } }',
root, "dynamic_visual_path");
shape.elements.push(p);
activePath = p;
}, "move": function(x, y) {
if (!activePath)
return;
var pathObj = activePath.path.pathElements[0];
var pathObj = activePath.pathElements[0];
pathObj.x = x;
pathObj.y = y;
}, "end": function() {
canvas.genResizer(activePath.path, activePath.path.startX, activePath.path.startY, "startX", "startY", "red");
var pathObj = activePath.path.pathElements[0];
canvas.genResizer(activePath, activePath.startX, activePath.startY, "startX", "startY", "red");
var pathObj = activePath.pathElements[0];
canvas.genResizer(pathObj, pathObj.x, pathObj.y, "x", "y", "red");
canvas.genResizer(pathObj, pathObj.controlX, pathObj.controlY, "controlX", "controlY", "blue");
activePath = null;

View File

@ -95,12 +95,10 @@ Rectangle {
fillColor: "transparent"
capStyle: ShapePath.RoundCap
Path {
startX: 40; startY: 30
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
}
startX: 40; startY: 30
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
}
}
}
@ -136,12 +134,10 @@ Rectangle {
fillColor: "transparent"
capStyle: ShapePath.RoundCap
Path {
startX: 40; startY: 30
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
}
startX: 40; startY: 30
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
}
}
}
@ -178,12 +174,10 @@ Rectangle {
fillColor: "transparent"
capStyle: ShapePath.RoundCap
Path {
startX: 40; startY: 30
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
}
startX: 40; startY: 30
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -133,17 +133,17 @@ QPainterPath QQuickShapePathCommands::toPainterPath() const
\inqmlmodule QtQuick.Shapes
\ingroup qtquick-paths
\ingroup qtquick-views
\inherits Object
\inherits Path
\brief Describes a Path and associated properties for stroking and filling
\since 5.10
A Shape contains one or more ShapePath elements. At least one
ShapePath is necessary in order to have a Shape output anything
visible. A ShapeItem in turn contains a Path and properties describing the
stroking and filling parameters, such as the stroke width and color, the
fill color or gradient, join and cap styles, and so on. Finally, the Path
object contains a list of path elements like PathMove, PathLine, PathCubic,
PathQuad, PathArc.
A Shape contains one or more ShapePath elements. At least one ShapePath is
necessary in order to have a Shape output anything visible. A ShapePath
itself is a \l Path with additional properties describing the stroking and
filling parameters, such as the stroke width and color, the fill color or
gradient, join and cap styles, and so on. As with ordinary \l Path objects,
ShapePath also contains a list of path elements like \l PathMove, \l PathLine,
\l PathCubic, \l PathQuad, \l PathArc, together with a starting position.
Any property changes in these data sets will be bubble up and change the
output of the Shape. This means that it is simple and easy to change, or
@ -166,12 +166,10 @@ QPainterPath QQuickShapePathCommands::toPainterPath() const
joinStyle: styles[joinStyleIndex]
Path {
startX: 30
startY: 30
PathLine { x: 100; y: 100 }
PathLine { x: 30; y: 100 }
}
startX: 30
startY: 30
PathLine { x: 100; y: 100 }
PathLine { x: 30; y: 100 }
}
\endcode
@ -182,59 +180,29 @@ QPainterPath QQuickShapePathCommands::toPainterPath() const
*/
QQuickShapePathPrivate::QQuickShapePathPrivate()
: path(nullptr),
dirty(DirtyAll)
: dirty(DirtyAll)
{
}
QQuickShapePath::QQuickShapePath(QObject *parent)
: QObject(*(new QQuickShapePathPrivate), parent)
: QQuickPath(*(new QQuickShapePathPrivate), parent)
{
// The inherited changed() and the shapePathChanged() signals remain
// distinct, and this is intentional. Combining the two is not possible due
// to the difference in semantics and the need to act (see dirty flag
// below) differently on QQuickPath-related changes.
connect(this, &QQuickPath::changed, [this]() {
Q_D(QQuickShapePath);
d->dirty |= QQuickShapePathPrivate::DirtyPath;
emit shapePathChanged();
});
}
QQuickShapePath::~QQuickShapePath()
{
}
/*!
\qmlproperty Path QtQuick.Shapes::ShapePath::path
This property holds the Path object.
\default
*/
QQuickPath *QQuickShapePath::path() const
{
Q_D(const QQuickShapePath);
return d->path;
}
void QQuickShapePath::setPath(QQuickPath *path)
{
Q_D(QQuickShapePath);
if (d->path == path)
return;
if (d->path)
qmlobject_disconnect(d->path, QQuickPath, SIGNAL(changed()),
this, QQuickShapePath, SLOT(_q_pathChanged()));
d->path = path;
qmlobject_connect(d->path, QQuickPath, SIGNAL(changed()),
this, QQuickShapePath, SLOT(_q_pathChanged()));
d->dirty |= QQuickShapePathPrivate::DirtyPath;
emit pathChanged();
emit changed();
}
void QQuickShapePathPrivate::_q_pathChanged()
{
Q_Q(QQuickShapePath);
dirty |= DirtyPath;
emit q->changed();
}
/*!
\qmlproperty color QtQuick.Shapes::ShapePath::strokeColor
@ -258,7 +226,7 @@ void QQuickShapePath::setStrokeColor(const QColor &color)
d->sfp.strokeColor = color;
d->dirty |= QQuickShapePathPrivate::DirtyStrokeColor;
emit strokeColorChanged();
emit changed();
emit shapePathChanged();
}
}
@ -285,7 +253,7 @@ void QQuickShapePath::setStrokeWidth(qreal w)
d->sfp.strokeWidth = w;
d->dirty |= QQuickShapePathPrivate::DirtyStrokeWidth;
emit strokeWidthChanged();
emit changed();
emit shapePathChanged();
}
}
@ -312,7 +280,7 @@ void QQuickShapePath::setFillColor(const QColor &color)
d->sfp.fillColor = color;
d->dirty |= QQuickShapePathPrivate::DirtyFillColor;
emit fillColorChanged();
emit changed();
emit shapePathChanged();
}
}
@ -342,7 +310,7 @@ void QQuickShapePath::setFillRule(FillRule fillRule)
d->sfp.fillRule = fillRule;
d->dirty |= QQuickShapePathPrivate::DirtyFillRule;
emit fillRuleChanged();
emit changed();
emit shapePathChanged();
}
}
@ -372,7 +340,7 @@ void QQuickShapePath::setJoinStyle(JoinStyle style)
d->sfp.joinStyle = style;
d->dirty |= QQuickShapePathPrivate::DirtyStyle;
emit joinStyleChanged();
emit changed();
emit shapePathChanged();
}
}
@ -398,7 +366,7 @@ void QQuickShapePath::setMiterLimit(int limit)
d->sfp.miterLimit = limit;
d->dirty |= QQuickShapePathPrivate::DirtyStyle;
emit miterLimitChanged();
emit changed();
emit shapePathChanged();
}
}
@ -428,7 +396,7 @@ void QQuickShapePath::setCapStyle(CapStyle style)
d->sfp.capStyle = style;
d->dirty |= QQuickShapePathPrivate::DirtyStyle;
emit capStyleChanged();
emit changed();
emit shapePathChanged();
}
}
@ -457,7 +425,7 @@ void QQuickShapePath::setStrokeStyle(StrokeStyle style)
d->sfp.strokeStyle = style;
d->dirty |= QQuickShapePathPrivate::DirtyDash;
emit strokeStyleChanged();
emit changed();
emit shapePathChanged();
}
}
@ -485,7 +453,7 @@ void QQuickShapePath::setDashOffset(qreal offset)
d->sfp.dashOffset = offset;
d->dirty |= QQuickShapePathPrivate::DirtyDash;
emit dashOffsetChanged();
emit changed();
emit shapePathChanged();
}
}
@ -516,7 +484,7 @@ void QQuickShapePath::setDashPattern(const QVector<qreal> &array)
d->sfp.dashPattern = array;
d->dirty |= QQuickShapePathPrivate::DirtyDash;
emit dashPatternChanged();
emit changed();
emit shapePathChanged();
}
}
@ -549,7 +517,7 @@ void QQuickShapePath::setFillGradient(QQuickShapeGradient *gradient)
qmlobject_connect(d->sfp.fillGradient, QQuickShapeGradient, SIGNAL(updated()),
this, QQuickShapePath, SLOT(_q_fillGradientChanged()));
d->dirty |= QQuickShapePathPrivate::DirtyFillGradient;
emit changed();
emit shapePathChanged();
}
}
@ -557,7 +525,7 @@ void QQuickShapePathPrivate::_q_fillGradientChanged()
{
Q_Q(QQuickShapePath);
dirty |= DirtyFillGradient;
emit q->changed();
emit q->shapePathChanged();
}
void QQuickShapePath::resetFillGradient()
@ -613,12 +581,10 @@ void QQuickShapePath::resetFillGradient()
}
strokeStyle: ShapePath.DashLine
dashPattern: [ 1, 4 ]
Path {
startX: 20; startY: 20
PathLine { x: 180; y: 130 }
PathLine { x: 20; y: 130 }
PathLine { x: 20; y: 20 }
}
startX: 20; startY: 20
PathLine { x: 180; y: 130 }
PathLine { x: 20; y: 130 }
PathLine { x: 20; y: 20 }
}
}
\endcode
@ -838,7 +804,7 @@ static void vpe_append(QQmlListProperty<QQuickShapePath> *property, QQuickShapeP
d->qmlData.sp.append(obj);
if (d->componentComplete) {
QObject::connect(obj, SIGNAL(changed()), item, SLOT(_q_shapePathChanged()));
QObject::connect(obj, SIGNAL(shapePathChanged()), item, SLOT(_q_shapePathChanged()));
d->_q_shapePathChanged();
}
}
@ -855,7 +821,7 @@ static void vpe_clear(QQmlListProperty<QQuickShapePath> *property)
QQuickShapePrivate *d = QQuickShapePrivate::get(item);
for (QQuickShapePath *p : d->qmlData.sp)
QObject::disconnect(p, SIGNAL(changed()), item, SLOT(_q_shapePathChanged()));
QObject::disconnect(p, SIGNAL(shapePathChanged()), item, SLOT(_q_shapePathChanged()));
d->qmlData.sp.clear();
@ -894,7 +860,7 @@ void QQuickShape::componentComplete()
d->componentComplete = true;
for (QQuickShapePath *p : d->qmlData.sp)
connect(p, SIGNAL(changed()), this, SLOT(_q_shapePathChanged()));
connect(p, SIGNAL(shapePathChanged()), this, SLOT(_q_shapePathChanged()));
d->_q_shapePathChanged();
}
@ -1042,7 +1008,7 @@ void QQuickShapePrivate::sync()
int &dirty(QQuickShapePathPrivate::get(p)->dirty);
if (dirty & QQuickShapePathPrivate::DirtyPath)
renderer->setPath(i, p->path());
renderer->setPath(i, p);
if (dirty & QQuickShapePathPrivate::DirtyStrokeColor)
renderer->setStrokeColor(i, p->strokeColor());
if (dirty & QQuickShapePathPrivate::DirtyStrokeWidth)

View File

@ -54,7 +54,7 @@
#include "qquickitem.h"
#include <private/qtquickglobal_p.h>
#include <private/qquickpath_p.h>
#include <private/qquickpath_p_p.h>
#include <private/qv8engine_p.h>
#include <QGradientStops>
@ -152,13 +152,10 @@ private:
QPointF m_end;
};
class QQuickShapePath : public QObject
class QQuickShapePath : public QQuickPath
{
Q_OBJECT
Q_PROPERTY(QQuickPath *path READ path WRITE setPath NOTIFY pathChanged)
Q_CLASSINFO("DefaultProperty", "path")
Q_PROPERTY(QColor strokeColor READ strokeColor WRITE setStrokeColor NOTIFY strokeColorChanged)
Q_PROPERTY(qreal strokeWidth READ strokeWidth WRITE setStrokeWidth NOTIFY strokeWidthChanged)
Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor NOTIFY fillColorChanged)
@ -201,9 +198,6 @@ public:
QQuickShapePath(QObject *parent = nullptr);
~QQuickShapePath();
QQuickPath *path() const;
void setPath(QQuickPath *path);
QColor strokeColor() const;
void setStrokeColor(const QColor &color);
@ -239,8 +233,7 @@ public:
void resetFillGradient();
Q_SIGNALS:
void changed();
void pathChanged();
void shapePathChanged();
void strokeColorChanged();
void strokeWidthChanged();
void fillColorChanged();
@ -256,7 +249,6 @@ Q_SIGNALS:
private:
Q_DISABLE_COPY(QQuickShapePath)
Q_DECLARE_PRIVATE(QQuickShapePath)
Q_PRIVATE_SLOT(d_func(), void _q_pathChanged())
Q_PRIVATE_SLOT(d_func(), void _q_fillGradientChanged())
};

View File

@ -131,7 +131,7 @@ public:
Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickAbstractPathRenderer::Flags)
class QQuickShapePathPrivate : public QObjectPrivate
class QQuickShapePathPrivate : public QQuickPathPrivate
{
Q_DECLARE_PUBLIC(QQuickShapePath)
@ -156,7 +156,6 @@ public:
static QQuickShapePathPrivate *get(QQuickShapePath *p) { return p->d_func(); }
QQuickPath *path;
int dirty;
QQuickShapeStrokeFillParams sfp;
};

View File

@ -153,6 +153,11 @@ QQuickPath::QQuickPath(QObject *parent)
{
}
QQuickPath::QQuickPath(QQuickPathPrivate &dd, QObject *parent)
: QObject(dd, parent)
{
}
QQuickPath::~QQuickPath()
{
}

View File

@ -419,6 +419,7 @@ Q_SIGNALS:
void startYChanged();
protected:
QQuickPath(QQuickPathPrivate &dd, QObject *parent = nullptr);
void componentComplete() override;
void classBegin() override;
void disconnectPathElements();

View File

@ -64,7 +64,7 @@ QT_REQUIRE_CONFIG(quick_path);
QT_BEGIN_NAMESPACE
class QQuickPathPrivate : public QObjectPrivate
class Q_QUICK_PRIVATE_EXPORT QQuickPathPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QQuickPath)

View File

@ -24,12 +24,10 @@ Item {
}
strokeStyle: ShapePath.DashLine
dashPattern: [ 1, 4 ]
Path {
startX: 20; startY: 20
PathLine { x: 180; y: 130 }
PathLine { x: 20; y: 130 }
PathLine { x: 20; y: 20 }
}
startX: 20; startY: 20
PathLine { x: 180; y: 130 }
PathLine { x: 20; y: 130 }
PathLine { x: 20; y: 20 }
}
}
}

View File

@ -13,22 +13,18 @@ Item {
ShapePath {
strokeColor: "red"
fillColor: "green"
Path {
startX: 40; startY: 30
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
}
startX: 40; startY: 30
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
}
ShapePath {
strokeWidth: 10
fillColor: "transparent"
strokeColor: "blue"
Path {
startX: 40; startY: 30
PathCubic { x: 50; y: 80; control1X: 0; control1Y: 80; control2X: 100; control2Y: 100 }
}
startX: 40; startY: 30
PathCubic { x: 50; y: 80; control1X: 0; control1Y: 80; control2X: 100; control2Y: 100 }
}
ShapePath {
@ -38,24 +34,22 @@ Item {
ShapeGradientStop { position: 1; color: "green" }
}
Path {
startX: 10; startY: 100
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 25
}
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 35
}
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 60
}
PathArc {
relativeX: 50; y: 100
radiusX: 50; radiusY: 120
}
startX: 10; startY: 100
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 25
}
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 35
}
PathArc {
relativeX: 50; y: 100
radiusX: 25; radiusY: 60
}
PathArc {
relativeX: 50; y: 100
radiusX: 50; radiusY: 120
}
}
}

View File

@ -103,7 +103,8 @@ void tst_QQuickShape::vpInitValues()
QQuickShapePath *vp = vps.at(&vps, 0);
QVERIFY(vp != nullptr);
QVERIFY(!vp->path());
QQmlListReference pathList(vp, "pathElements");
QCOMPARE(pathList.count(), 0);
QCOMPARE(vp->strokeColor(), QColor(Qt::white));
QCOMPARE(vp->strokeWidth(), 1.0f);
QCOMPARE(vp->fillColor(), QColor(Qt::white));
@ -134,7 +135,6 @@ void tst_QQuickShape::basicShape()
QVERIFY(vp != nullptr);
QCOMPARE(vp->strokeWidth(), 4.0f);
QVERIFY(vp->fillGradient() != nullptr);
QVERIFY(vp->path() != nullptr);
QCOMPARE(vp->strokeStyle(), QQuickShapePath::DashLine);
vp->setStrokeWidth(5.0f);
@ -148,7 +148,7 @@ void tst_QQuickShape::basicShape()
QCOMPARE(stopList.count(), 5);
QVERIFY(stopList.at(2) != nullptr);
QQuickPath *path = vp->path();
QQuickPath *path = vp;
QCOMPARE(path->startX(), 20.0f);
QQmlListReference pathList(path, "pathElements");
QCOMPARE(pathList.count(), 3);
@ -173,8 +173,8 @@ void tst_QQuickShape::changeSignals()
QQuickShapePath *vp = qobject_cast<QQuickShapePath *>(list.at(0));
QVERIFY(vp != nullptr);
// Verify that VisualPath property changes emit changed().
QSignalSpy vpChangeSpy(vp, SIGNAL(changed()));
// Verify that VisualPath property changes emit shapePathChanged().
QSignalSpy vpChangeSpy(vp, SIGNAL(shapePathChanged()));
QSignalSpy strokeColorPropSpy(vp, SIGNAL(strokeColorChanged()));
vp->setStrokeColor(Qt::blue);
vp->setStrokeWidth(1.0f);
@ -190,15 +190,15 @@ void tst_QQuickShape::changeSignals()
QCOMPARE(strokeColorPropSpy.count(), 1);
QCOMPARE(vpChangeSpy.count(), 10);
// Verify that property changes from Path and its elements bubble up and result in changed().
QQuickPath *path = vp->path();
// Verify that property changes from Path and its elements bubble up and result in shapePathChanged().
QQuickPath *path = vp;
path->setStartX(30);
QCOMPARE(vpChangeSpy.count(), 11);
QQmlListReference pathList(path, "pathElements");
qobject_cast<QQuickPathLine *>(pathList.at(1))->setY(200);
QCOMPARE(vpChangeSpy.count(), 12);
// Verify that property changes from the gradient bubble up and result in changed().
// Verify that property changes from the gradient bubble up and result in shapePathChanged().
vp->setFillGradient(g);
QCOMPARE(vpChangeSpy.count(), 13);
QQuickShapeLinearGradient *lgrad = qobject_cast<QQuickShapeLinearGradient *>(g);

View File

@ -95,11 +95,9 @@ Rectangle {
fillColor: "blue" // ignored with the gradient set
strokeStyle: ShapePath.DashLine
dashPattern: [ 1, 4 ]
Path {
PathLine { x: 200; y: 100 }
PathLine { x: 0; y: 100 }
PathLine { x: 0; y: 0 }
}
PathLine { x: 200; y: 100 }
PathLine { x: 0; y: 100 }
PathLine { x: 0; y: 0 }
}
transform: Rotation { origin.x: 100; origin.y: 50; axis { x: 0; y: 1; z: 0 }
SequentialAnimation on angle {
@ -125,13 +123,11 @@ Rectangle {
strokeColor: sc
property color fc: "yellow"
fillColor: fc
Path {
startX: 20; startY: 10
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 180; y: 10; controlX: 200; controlY: 80 }
PathLine { x: 20; y: 10 }
}
startX: 20; startY: 10
PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
PathLine { x: 150; y: 80 }
PathQuad { x: 180; y: 10; controlX: 200; controlY: 80 }
PathLine { x: 20; y: 10 }
// Dynamic changes via property bindings etc. all work but can
// be computationally expense with the generic backend for properties
// that need retriangulating on every change. Should be cheap with NVPR.
@ -168,12 +164,10 @@ Rectangle {
anchors.fill: parent
ShapePath {
strokeColor: "black"
Path {
startX: 0; startY: 50
PathLine { relativeX: 100; y: 50 }
PathMove { relativeX: 100; y: 50 }
PathLine { relativeX: 100; y: 50 }
}
startX: 0; startY: 50
PathLine { relativeX: 100; y: 50 }
PathMove { relativeX: 100; y: 50 }
PathLine { relativeX: 100; y: 50 }
}
}
}
@ -191,12 +185,10 @@ Rectangle {
strokeWidth: 16
fillColor: "transparent"
capStyle: ShapePath.RoundCap
Path {
startX: 30
startY: 30
PathLine { x: 100; y: 100 }
PathLine { x: 30; y: 100 }
}
startX: 30
startY: 30
PathLine { x: 100; y: 100 }
PathLine { x: 30; y: 100 }
}
}
Timer {
@ -226,14 +218,12 @@ Rectangle {
strokeColor: "blue"
fillColor: "lightGray"
strokeWidth: 2
Path {
PathMove { x: 90; y: 50 }
PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
PathLine { x: 90; y: 50 }
}
PathMove { x: 90; y: 50 }
PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
PathLine { x: 90; y: 50 }
}
}
Timer {
@ -255,14 +245,12 @@ Rectangle {
strokeWidth: 4
strokeColor: "black"
fillColor: "transparent"
Path {
startX: 20; startY: 10
PathCubic {
id: cb
x: 180; y: 10
control1X: -10; control1Y: 90; control2Y: 90
NumberAnimation on control2X { from: 400; to: 0; duration: 5000; loops: Animation.Infinite }
}
startX: 20; startY: 10
PathCubic {
id: cb
x: 180; y: 10
control1X: -10; control1Y: 90; control2Y: 90
NumberAnimation on control2X { from: 400; to: 0; duration: 5000; loops: Animation.Infinite }
}
}
}
@ -283,13 +271,11 @@ Rectangle {
fillColor: "transparent"
strokeColor: "red"
strokeWidth: 4
Path {
startX: 10; startY: 40
PathArc {
x: 10; y: 60
radiusX: 40; radiusY: 40
useLargeArc: true
}
startX: 10; startY: 40
PathArc {
x: 10; y: 60
radiusX: 40; radiusY: 40
useLargeArc: true
}
}
}
@ -320,12 +306,10 @@ Rectangle {
fillColor: "blue"
strokeColor: "red"
strokeWidth: 4
Path {
startX: 10; startY: 10
PathLine { x: 140; y: 140 }
PathLine { x: 10; y: 140 }
PathLine { x: 10; y: 10 }
}
startX: 10; startY: 10
PathLine { x: 140; y: 140 }
PathLine { x: 10; y: 140 }
PathLine { x: 10; y: 10 }
}
}
}
@ -353,14 +337,12 @@ Rectangle {
strokeColor: "blue"
fillColor: "lightGray"
strokeWidth: 2
Path {
PathMove { x: 90; y: 50 }
PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
PathLine { x: 90; y: 50 }
}
PathMove { x: 90; y: 50 }
PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
PathLine { x: 90; y: 50 }
}
}
Timer {
@ -381,16 +363,12 @@ Rectangle {
anchors.fill: parent
ShapePath {
strokeColor: "red"
Path {
PathLine { x: 100; y: 100 }
}
PathLine { x: 100; y: 100 }
}
ShapePath {
strokeColor: "blue"
Path {
startX: 100; startY: 0
PathLine { x: 0; y: 100 }
}
startX: 100; startY: 0
PathLine { x: 0; y: 100 }
}
}
}