src/declarative/graphicsitems/qdeclarativepath.cpp
changeset 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "private/qdeclarativepath_p.h"
       
    43 #include "private/qdeclarativepath_p_p.h"
       
    44 
       
    45 #include <QSet>
       
    46 #include <QTime>
       
    47 
       
    48 #include <private/qbezier_p.h>
       
    49 
       
    50 QT_BEGIN_NAMESPACE
       
    51 
       
    52 /*!
       
    53     \qmlclass PathElement QDeclarativePathElement
       
    54     \since 4.7
       
    55     \brief PathElement is the base path type.
       
    56 
       
    57     This type is the base for all path types.  It cannot
       
    58     be instantiated.
       
    59 
       
    60     \sa Path, PathAttribute, PathPercent, PathLine, PathQuad, PathCubic
       
    61 */
       
    62 
       
    63 /*!
       
    64     \internal
       
    65     \class QDeclarativePathElement
       
    66 */
       
    67 
       
    68 /*!
       
    69     \qmlclass Path QDeclarativePath
       
    70     \since 4.7
       
    71     \brief A Path object defines a path for use by \l PathView.
       
    72 
       
    73     A Path is composed of one or more path segments - PathLine, PathQuad,
       
    74     PathCubic.
       
    75 
       
    76     The spacing of the items along the Path can be adjusted via a
       
    77     PathPercent object.
       
    78 
       
    79     PathAttribute allows named attributes with values to be defined
       
    80     along the path.
       
    81 
       
    82     \sa PathView, PathAttribute, PathPercent, PathLine, PathQuad, PathCubic
       
    83 */
       
    84 
       
    85 /*!
       
    86     \internal
       
    87     \class QDeclarativePath
       
    88     \brief The QDeclarativePath class defines a path.
       
    89     \sa QDeclarativePathView
       
    90 */
       
    91 QDeclarativePath::QDeclarativePath(QObject *parent)
       
    92  : QObject(*(new QDeclarativePathPrivate), parent)
       
    93 {
       
    94 }
       
    95 
       
    96 QDeclarativePath::~QDeclarativePath()
       
    97 {
       
    98 }
       
    99 
       
   100 /*!
       
   101     \qmlproperty real Path::startX
       
   102     \qmlproperty real Path::startY
       
   103     These properties hold the starting position of the path.
       
   104 */
       
   105 qreal QDeclarativePath::startX() const
       
   106 {
       
   107     Q_D(const QDeclarativePath);
       
   108     return d->startX;
       
   109 }
       
   110 
       
   111 void QDeclarativePath::setStartX(qreal x)
       
   112 {
       
   113     Q_D(QDeclarativePath);
       
   114     if (qFuzzyCompare(x, d->startX))
       
   115         return;
       
   116     d->startX = x;
       
   117     emit startXChanged();
       
   118     processPath();
       
   119 }
       
   120 
       
   121 qreal QDeclarativePath::startY() const
       
   122 {
       
   123     Q_D(const QDeclarativePath);
       
   124     return d->startY;
       
   125 }
       
   126 
       
   127 void QDeclarativePath::setStartY(qreal y)
       
   128 {
       
   129     Q_D(QDeclarativePath);
       
   130     if (qFuzzyCompare(y, d->startY))
       
   131         return;
       
   132     d->startY = y;
       
   133     emit startYChanged();
       
   134     processPath();
       
   135 }
       
   136 
       
   137 /*!
       
   138     \qmlproperty bool Path::closed
       
   139     This property holds whether the start and end of the path are identical.
       
   140 */
       
   141 bool QDeclarativePath::isClosed() const
       
   142 {
       
   143     Q_D(const QDeclarativePath);
       
   144     return d->closed;
       
   145 }
       
   146 
       
   147 /*!
       
   148     \qmlproperty list<PathElement> Path::pathElements
       
   149     This property holds the objects composing the path.
       
   150 
       
   151     \default
       
   152 
       
   153     A path can contain the following path objects:
       
   154     \list
       
   155         \i \l PathLine - a straight line to a given position.
       
   156         \i \l PathQuad - a quadratic Bezier curve to a given position with a control point.
       
   157         \i \l PathCubic - a cubic Bezier curve to a given position with two control points.
       
   158         \i \l PathAttribute - an attribute at a given position in the path.
       
   159         \i \l PathPercent - a way to spread out items along various segments of the path.
       
   160     \endlist
       
   161 
       
   162     \snippet doc/src/snippets/declarative/pathview/pathattributes.qml 2
       
   163 */
       
   164 
       
   165 QDeclarativeListProperty<QDeclarativePathElement> QDeclarativePath::pathElements()
       
   166 {
       
   167     Q_D(QDeclarativePath);
       
   168     return QDeclarativeListProperty<QDeclarativePathElement>(this, d->_pathElements);
       
   169 }
       
   170 
       
   171 void QDeclarativePath::interpolate(int idx, const QString &name, qreal value)
       
   172 {
       
   173     Q_D(QDeclarativePath);
       
   174     if (!idx)
       
   175         return;
       
   176 
       
   177     qreal lastValue = 0;
       
   178     qreal lastPercent = 0;
       
   179     int search = idx - 1;
       
   180     while(search >= 0) {
       
   181         const AttributePoint &point = d->_attributePoints.at(search);
       
   182         if (point.values.contains(name)) {
       
   183             lastValue = point.values.value(name);
       
   184             lastPercent = point.origpercent;
       
   185             break;
       
   186         }
       
   187         --search;
       
   188     }
       
   189 
       
   190     ++search;
       
   191 
       
   192     const AttributePoint &curPoint = d->_attributePoints.at(idx);
       
   193 
       
   194     for (int ii = search; ii < idx; ++ii) {
       
   195         AttributePoint &point = d->_attributePoints[ii];
       
   196 
       
   197         qreal val = lastValue + (value - lastValue) * (point.origpercent - lastPercent) / (curPoint.origpercent - lastPercent);
       
   198         point.values.insert(name, val);
       
   199     }
       
   200 }
       
   201 
       
   202 void QDeclarativePath::endpoint(const QString &name)
       
   203 {
       
   204     Q_D(QDeclarativePath);
       
   205     const AttributePoint &first = d->_attributePoints.first();
       
   206     qreal val = first.values.value(name);
       
   207     for (int ii = d->_attributePoints.count() - 1; ii >= 0; ii--) {
       
   208         const AttributePoint &point = d->_attributePoints.at(ii);
       
   209         if (point.values.contains(name)) {
       
   210             for (int jj = ii + 1; jj < d->_attributePoints.count(); ++jj) {
       
   211                 AttributePoint &setPoint = d->_attributePoints[jj];
       
   212                 setPoint.values.insert(name, val);
       
   213             }
       
   214             return;
       
   215         }
       
   216     }
       
   217 }
       
   218 
       
   219 void QDeclarativePath::processPath()
       
   220 {
       
   221     Q_D(QDeclarativePath);
       
   222 
       
   223     if (!d->componentComplete)
       
   224         return;
       
   225 
       
   226     d->_pointCache.clear();
       
   227     d->_attributePoints.clear();
       
   228     d->_path = QPainterPath();
       
   229 
       
   230     AttributePoint first;
       
   231     for (int ii = 0; ii < d->_attributes.count(); ++ii)
       
   232         first.values[d->_attributes.at(ii)] = 0;
       
   233     d->_attributePoints << first;
       
   234 
       
   235     d->_path.moveTo(d->startX, d->startY);
       
   236 
       
   237     QDeclarativeCurve *lastCurve = 0;
       
   238     foreach (QDeclarativePathElement *pathElement, d->_pathElements) {
       
   239         if (QDeclarativeCurve *curve = qobject_cast<QDeclarativeCurve *>(pathElement)) {
       
   240             curve->addToPath(d->_path);
       
   241             AttributePoint p;
       
   242             p.origpercent = d->_path.length();
       
   243             d->_attributePoints << p;
       
   244             lastCurve = curve;
       
   245         } else if (QDeclarativePathAttribute *attribute = qobject_cast<QDeclarativePathAttribute *>(pathElement)) {
       
   246             AttributePoint &point = d->_attributePoints.last();
       
   247             point.values[attribute->name()] = attribute->value();
       
   248             interpolate(d->_attributePoints.count() - 1, attribute->name(), attribute->value());
       
   249         } else if (QDeclarativePathPercent *percent = qobject_cast<QDeclarativePathPercent *>(pathElement)) {
       
   250             AttributePoint &point = d->_attributePoints.last();
       
   251             point.values[QLatin1String("_qfx_percent")] = percent->value();
       
   252             interpolate(d->_attributePoints.count() - 1, QLatin1String("_qfx_percent"), percent->value());
       
   253         }
       
   254     }
       
   255 
       
   256     // Fixup end points
       
   257     const AttributePoint &last = d->_attributePoints.last();
       
   258     for (int ii = 0; ii < d->_attributes.count(); ++ii) {
       
   259         if (!last.values.contains(d->_attributes.at(ii)))
       
   260             endpoint(d->_attributes.at(ii));
       
   261     }
       
   262 
       
   263     // Adjust percent
       
   264     qreal length = d->_path.length();
       
   265     qreal prevpercent = 0;
       
   266     qreal prevorigpercent = 0;
       
   267     for (int ii = 0; ii < d->_attributePoints.count(); ++ii) {
       
   268         const AttributePoint &point = d->_attributePoints.at(ii);
       
   269         if (point.values.contains(QLatin1String("_qfx_percent"))) { //special string for QDeclarativePathPercent
       
   270             if ( ii > 0) {
       
   271                 qreal scale = (d->_attributePoints[ii].origpercent/length - prevorigpercent) /
       
   272                             (point.values.value(QLatin1String("_qfx_percent"))-prevpercent);
       
   273                 d->_attributePoints[ii].scale = scale;
       
   274             }
       
   275             d->_attributePoints[ii].origpercent /= length;
       
   276             d->_attributePoints[ii].percent = point.values.value(QLatin1String("_qfx_percent"));
       
   277             prevorigpercent = d->_attributePoints[ii].origpercent;
       
   278             prevpercent = d->_attributePoints[ii].percent;
       
   279         } else {
       
   280             d->_attributePoints[ii].origpercent /= length;
       
   281             d->_attributePoints[ii].percent = d->_attributePoints[ii].origpercent;
       
   282         }
       
   283     }
       
   284 
       
   285     d->closed = lastCurve && d->startX == lastCurve->x() && d->startY == lastCurve->y();
       
   286 
       
   287     emit changed();
       
   288 }
       
   289 
       
   290 void QDeclarativePath::classBegin()
       
   291 {
       
   292     Q_D(QDeclarativePath);
       
   293     d->componentComplete = false;
       
   294 }
       
   295 
       
   296 void QDeclarativePath::componentComplete()
       
   297 {
       
   298     Q_D(QDeclarativePath);
       
   299     QSet<QString> attrs;
       
   300     d->componentComplete = true;
       
   301 
       
   302     // First gather up all the attributes
       
   303     foreach (QDeclarativePathElement *pathElement, d->_pathElements) {
       
   304         if (QDeclarativePathAttribute *attribute =
       
   305             qobject_cast<QDeclarativePathAttribute *>(pathElement))
       
   306             attrs.insert(attribute->name());
       
   307     }
       
   308     d->_attributes = attrs.toList();
       
   309 
       
   310     processPath();
       
   311 
       
   312     foreach (QDeclarativePathElement *pathElement, d->_pathElements)
       
   313         connect(pathElement, SIGNAL(changed()), this, SLOT(processPath()));
       
   314 }
       
   315 
       
   316 QPainterPath QDeclarativePath::path() const
       
   317 {
       
   318     Q_D(const QDeclarativePath);
       
   319     return d->_path;
       
   320 }
       
   321 
       
   322 QStringList QDeclarativePath::attributes() const
       
   323 {
       
   324     Q_D(const QDeclarativePath);
       
   325     if (!d->componentComplete) {
       
   326         QSet<QString> attrs;
       
   327 
       
   328         // First gather up all the attributes
       
   329         foreach (QDeclarativePathElement *pathElement, d->_pathElements) {
       
   330             if (QDeclarativePathAttribute *attribute =
       
   331                 qobject_cast<QDeclarativePathAttribute *>(pathElement))
       
   332                 attrs.insert(attribute->name());
       
   333         }
       
   334         return attrs.toList();
       
   335     }
       
   336     return d->_attributes;
       
   337 }
       
   338 
       
   339 static inline QBezier nextBezier(const QPainterPath &path, int *from, qreal *bezLength)
       
   340 {
       
   341     const int lastElement = path.elementCount() - 1;
       
   342     for (int i=*from; i <= lastElement; ++i) {
       
   343         const QPainterPath::Element &e = path.elementAt(i);
       
   344 
       
   345         switch (e.type) {
       
   346         case QPainterPath::MoveToElement:
       
   347             break;
       
   348         case QPainterPath::LineToElement:
       
   349         {
       
   350             QLineF line(path.elementAt(i-1), e);
       
   351             *bezLength = line.length();
       
   352             QPointF a = path.elementAt(i-1);
       
   353             QPointF delta = e - a;
       
   354             *from = i+1;
       
   355             return QBezier::fromPoints(a, a + delta / 3, a + 2 * delta / 3, e);
       
   356         }
       
   357         case QPainterPath::CurveToElement:
       
   358         {
       
   359             QBezier b = QBezier::fromPoints(path.elementAt(i-1),
       
   360                                             e,
       
   361                                             path.elementAt(i+1),
       
   362                                             path.elementAt(i+2));
       
   363             *bezLength = b.length();
       
   364             *from = i+3;
       
   365             return b;
       
   366         }
       
   367         default:
       
   368             break;
       
   369         }
       
   370     }
       
   371     *from = lastElement;
       
   372     *bezLength = 0;
       
   373     return QBezier();
       
   374 }
       
   375 
       
   376 void QDeclarativePath::createPointCache() const
       
   377 {
       
   378     Q_D(const QDeclarativePath);
       
   379     qreal pathLength = d->_path.length();
       
   380     // more points means less jitter between items as they move along the
       
   381     // path, but takes longer to generate
       
   382     const int points = int(pathLength*5);
       
   383     const int lastElement = d->_path.elementCount() - 1;
       
   384     d->_pointCache.resize(points+1);
       
   385 
       
   386     int currElement = 0;
       
   387     qreal bezLength = 0;
       
   388     QBezier currBez = nextBezier(d->_path, &currElement, &bezLength);
       
   389     qreal currLength = bezLength;
       
   390     qreal epc = currLength / pathLength;
       
   391 
       
   392     for (int i = 0; i < d->_pointCache.size(); i++) {
       
   393         //find which set we are in
       
   394         qreal prevPercent = 0;
       
   395         qreal prevOrigPercent = 0;
       
   396         for (int ii = 0; ii < d->_attributePoints.count(); ++ii) {
       
   397             qreal percent = qreal(i)/points;
       
   398             const AttributePoint &point = d->_attributePoints.at(ii);
       
   399             if (percent < point.percent || ii == d->_attributePoints.count() - 1) { //### || is special case for very last item
       
   400                 qreal elementPercent = (percent - prevPercent);
       
   401 
       
   402                 qreal spc = prevOrigPercent + elementPercent * point.scale;
       
   403 
       
   404                 while (spc > epc) {
       
   405                     if (currElement > lastElement)
       
   406                         break;
       
   407                     currBez = nextBezier(d->_path, &currElement, &bezLength);
       
   408                     if (bezLength == 0.0) {
       
   409                         currLength = pathLength;
       
   410                         epc = 1.0;
       
   411                         break;
       
   412                     }
       
   413                     currLength += bezLength;
       
   414                     epc = currLength / pathLength;
       
   415                 }
       
   416                 qreal realT = (pathLength * spc - (currLength - bezLength)) / bezLength;
       
   417                 d->_pointCache[i] = currBez.pointAt(qBound(qreal(0), realT, qreal(1)));
       
   418                 break;
       
   419             }
       
   420             prevOrigPercent = point.origpercent;
       
   421             prevPercent = point.percent;
       
   422         }
       
   423     }
       
   424 }
       
   425 
       
   426 QPointF QDeclarativePath::pointAt(qreal p) const
       
   427 {
       
   428     Q_D(const QDeclarativePath);
       
   429     if (d->_pointCache.isEmpty()) {
       
   430         createPointCache();
       
   431     }
       
   432     int idx = qRound(p*d->_pointCache.size());
       
   433     if (idx >= d->_pointCache.size())
       
   434         idx = d->_pointCache.size() - 1;
       
   435     else if (idx < 0)
       
   436         idx = 0;
       
   437     return d->_pointCache.at(idx);
       
   438 }
       
   439 
       
   440 qreal QDeclarativePath::attributeAt(const QString &name, qreal percent) const
       
   441 {
       
   442     Q_D(const QDeclarativePath);
       
   443     if (percent < 0 || percent > 1)
       
   444         return 0;
       
   445 
       
   446     for (int ii = 0; ii < d->_attributePoints.count(); ++ii) {
       
   447         const AttributePoint &point = d->_attributePoints.at(ii);
       
   448 
       
   449         if (point.percent == percent) {
       
   450             return point.values.value(name);
       
   451         } else if (point.percent > percent) {
       
   452             qreal lastValue =
       
   453                 ii?(d->_attributePoints.at(ii - 1).values.value(name)):0;
       
   454             qreal lastPercent =
       
   455                 ii?(d->_attributePoints.at(ii - 1).percent):0;
       
   456             qreal curValue = point.values.value(name);
       
   457             qreal curPercent = point.percent;
       
   458 
       
   459             return lastValue + (curValue - lastValue) * (percent - lastPercent) / (curPercent - lastPercent);
       
   460         }
       
   461     }
       
   462 
       
   463     return 0;
       
   464 }
       
   465 
       
   466 /****************************************************************************/
       
   467 
       
   468 qreal QDeclarativeCurve::x() const
       
   469 {
       
   470     return _x;
       
   471 }
       
   472 
       
   473 void QDeclarativeCurve::setX(qreal x)
       
   474 {
       
   475     if (_x != x) {
       
   476         _x = x;
       
   477         emit changed();
       
   478     }
       
   479 }
       
   480 
       
   481 qreal QDeclarativeCurve::y() const
       
   482 {
       
   483     return _y;
       
   484 }
       
   485 
       
   486 void QDeclarativeCurve::setY(qreal y)
       
   487 {
       
   488     if (_y != y) {
       
   489         _y = y;
       
   490         emit changed();
       
   491     }
       
   492 }
       
   493 
       
   494 /****************************************************************************/
       
   495 
       
   496 /*!
       
   497     \qmlclass PathAttribute QDeclarativePathAttribute
       
   498     \since 4.7
       
   499     \brief The PathAttribute allows setting an attribute at a given position in a Path.
       
   500 
       
   501     The PathAttribute object allows attibutes consisting of a name and
       
   502     a value to be specified for the endpoints of path segments.  The
       
   503     attributes are exposed to the delegate as
       
   504     \l{qdeclarativeintroduction.html#attached-properties} {Attached Properties}.
       
   505     The value of an attribute at any particular point is interpolated
       
   506     from the PathAttributes bounding the point.
       
   507 
       
   508     The example below shows a path with the items scaled to 30% with
       
   509     opacity 50% at the top of the path and scaled 100% with opacity
       
   510     100% at the bottom.  Note the use of the PathView.scale and
       
   511     PathView.opacity attached properties to set the scale and opacity
       
   512     of the delegate.
       
   513 
       
   514     \table
       
   515     \row
       
   516     \o \image declarative-pathattribute.png
       
   517     \o
       
   518     \snippet doc/src/snippets/declarative/pathview/pathattributes.qml 0
       
   519     \endtable
       
   520 
       
   521    \sa Path
       
   522 */
       
   523 
       
   524 /*!
       
   525     \internal
       
   526     \class QDeclarativePathAttribute
       
   527     \brief The QDeclarativePathAttribute class allows to set the value of an attribute at a given position in the path.
       
   528 
       
   529     \sa QDeclarativePath
       
   530 */
       
   531 
       
   532 
       
   533 /*!
       
   534     \qmlproperty string PathAttribute::name
       
   535     the name of the attribute to change.
       
   536 */
       
   537 
       
   538 /*!
       
   539     the name of the attribute to change.
       
   540 */
       
   541 
       
   542 QString QDeclarativePathAttribute::name() const
       
   543 {
       
   544     return _name;
       
   545 }
       
   546 
       
   547 void QDeclarativePathAttribute::setName(const QString &name)
       
   548 {
       
   549     if (_name == name)
       
   550         return;
       
   551      _name = name;
       
   552     emit nameChanged();
       
   553 }
       
   554 
       
   555 /*!
       
   556    \qmlproperty string PathAttribute::value
       
   557    the new value of the attribute.
       
   558 */
       
   559 
       
   560 /*!
       
   561     the new value of the attribute.
       
   562 */
       
   563 qreal QDeclarativePathAttribute::value() const
       
   564 {
       
   565     return _value;
       
   566 }
       
   567 
       
   568 void QDeclarativePathAttribute::setValue(qreal value)
       
   569 {
       
   570     if (_value != value) {
       
   571         _value = value;
       
   572         emit changed();
       
   573     }
       
   574 }
       
   575 
       
   576 /****************************************************************************/
       
   577 
       
   578 /*!
       
   579     \qmlclass PathLine QDeclarativePathLine
       
   580     \since 4.7
       
   581     \brief The PathLine defines a straight line.
       
   582 
       
   583     The example below creates a path consisting of a straight line from
       
   584     0,100 to 200,100:
       
   585 
       
   586     \qml
       
   587     Path {
       
   588         startX: 0; startY: 100
       
   589         PathLine { x: 200; y: 100 }
       
   590     }
       
   591     \endqml
       
   592 
       
   593     \sa Path, PathQuad, PathCubic
       
   594 */
       
   595 
       
   596 /*!
       
   597     \internal
       
   598     \class QDeclarativePathLine
       
   599     \brief The QDeclarativePathLine class defines a straight line.
       
   600 
       
   601     \sa QDeclarativePath
       
   602 */
       
   603 
       
   604 /*!
       
   605     \qmlproperty real PathLine::x
       
   606     \qmlproperty real PathLine::y
       
   607 
       
   608     Defines the end point of the line.
       
   609 */
       
   610 
       
   611 void QDeclarativePathLine::addToPath(QPainterPath &path)
       
   612 {
       
   613     path.lineTo(x(), y());
       
   614 }
       
   615 
       
   616 /****************************************************************************/
       
   617 
       
   618 /*!
       
   619     \qmlclass PathQuad QDeclarativePathQuad
       
   620     \since 4.7
       
   621     \brief The PathQuad defines a quadratic Bezier curve with a control point.
       
   622 
       
   623     The following QML produces the path shown below:
       
   624     \table
       
   625     \row
       
   626     \o \image declarative-pathquad.png
       
   627     \o
       
   628     \qml
       
   629     Path {
       
   630         startX: 0; startY: 0
       
   631         PathQuad x: 200; y: 0; controlX: 100; controlY: 150 }
       
   632     }
       
   633     \endqml
       
   634     \endtable
       
   635 
       
   636     \sa Path, PathCubic, PathLine
       
   637 */
       
   638 
       
   639 /*!
       
   640     \internal
       
   641     \class QDeclarativePathQuad
       
   642     \brief The QDeclarativePathQuad class defines a quadratic Bezier curve with a control point.
       
   643 
       
   644     \sa QDeclarativePath
       
   645 */
       
   646 
       
   647 
       
   648 /*!
       
   649     \qmlproperty real PathQuad::x
       
   650     \qmlproperty real PathQuad::y
       
   651 
       
   652     Defines the end point of the curve.
       
   653 */
       
   654 
       
   655 /*!
       
   656    \qmlproperty real PathQuad::controlX
       
   657    \qmlproperty real PathQuad::controlY
       
   658 
       
   659    Defines the position of the control point.
       
   660 */
       
   661 
       
   662 /*!
       
   663     the x position of the control point.
       
   664 */
       
   665 qreal QDeclarativePathQuad::controlX() const
       
   666 {
       
   667     return _controlX;
       
   668 }
       
   669 
       
   670 void QDeclarativePathQuad::setControlX(qreal x)
       
   671 {
       
   672     if (_controlX != x) {
       
   673         _controlX = x;
       
   674         emit changed();
       
   675     }
       
   676 }
       
   677 
       
   678 
       
   679 /*!
       
   680     the y position of the control point.
       
   681 */
       
   682 qreal QDeclarativePathQuad::controlY() const
       
   683 {
       
   684     return _controlY;
       
   685 }
       
   686 
       
   687 void QDeclarativePathQuad::setControlY(qreal y)
       
   688 {
       
   689     if (_controlY != y) {
       
   690         _controlY = y;
       
   691         emit changed();
       
   692     }
       
   693 }
       
   694 
       
   695 void QDeclarativePathQuad::addToPath(QPainterPath &path)
       
   696 {
       
   697     path.quadTo(controlX(), controlY(), x(), y());
       
   698 }
       
   699 
       
   700 /****************************************************************************/
       
   701 
       
   702 /*!
       
   703    \qmlclass PathCubic QDeclarativePathCubic
       
   704     \since 4.7
       
   705    \brief The PathCubic defines a cubic Bezier curve with two control points.
       
   706 
       
   707     The following QML produces the path shown below:
       
   708     \table
       
   709     \row
       
   710     \o \image declarative-pathcubic.png
       
   711     \o
       
   712     \qml
       
   713     Path {
       
   714         startX: 20; startY: 0
       
   715         PathCubic {
       
   716             x: 180; y: 0; control1X: -10; control1Y: 90
       
   717                           control2X: 210; control2Y: 90
       
   718         }
       
   719     }
       
   720     \endqml
       
   721     \endtable
       
   722 
       
   723     \sa Path, PathQuad, PathLine
       
   724 */
       
   725 
       
   726 /*!
       
   727     \internal
       
   728     \class QDeclarativePathCubic
       
   729     \brief The QDeclarativePathCubic class defines a cubic Bezier curve with two control points.
       
   730 
       
   731     \sa QDeclarativePath
       
   732 */
       
   733 
       
   734 /*!
       
   735     \qmlproperty real PathCubic::x
       
   736     \qmlproperty real PathCubic::y
       
   737 
       
   738     Defines the end point of the curve.
       
   739 */
       
   740 
       
   741 /*!
       
   742    \qmlproperty real PathCubic::control1X
       
   743    \qmlproperty real PathCubic::control1Y
       
   744 
       
   745     Defines the position of the first control point.
       
   746 */
       
   747 qreal QDeclarativePathCubic::control1X() const
       
   748 {
       
   749     return _control1X;
       
   750 }
       
   751 
       
   752 void QDeclarativePathCubic::setControl1X(qreal x)
       
   753 {
       
   754     if (_control1X != x) {
       
   755         _control1X = x;
       
   756         emit changed();
       
   757     }
       
   758 }
       
   759 
       
   760 qreal QDeclarativePathCubic::control1Y() const
       
   761 {
       
   762     return _control1Y;
       
   763 }
       
   764 
       
   765 void QDeclarativePathCubic::setControl1Y(qreal y)
       
   766 {
       
   767     if (_control1Y != y) {
       
   768         _control1Y = y;
       
   769         emit changed();
       
   770     }
       
   771 }
       
   772 
       
   773 /*!
       
   774    \qmlproperty real PathCubic::control2X
       
   775    \qmlproperty real PathCubic::control2Y
       
   776 
       
   777     Defines the position of the second control point.
       
   778 */
       
   779 qreal QDeclarativePathCubic::control2X() const
       
   780 {
       
   781     return _control2X;
       
   782 }
       
   783 
       
   784 void QDeclarativePathCubic::setControl2X(qreal x)
       
   785 {
       
   786     if (_control2X != x) {
       
   787         _control2X = x;
       
   788         emit changed();
       
   789     }
       
   790 }
       
   791 
       
   792 qreal QDeclarativePathCubic::control2Y() const
       
   793 {
       
   794     return _control2Y;
       
   795 }
       
   796 
       
   797 void QDeclarativePathCubic::setControl2Y(qreal y)
       
   798 {
       
   799     if (_control2Y != y) {
       
   800         _control2Y = y;
       
   801         emit changed();
       
   802     }
       
   803 }
       
   804 
       
   805 void QDeclarativePathCubic::addToPath(QPainterPath &path)
       
   806 {
       
   807     path.cubicTo(control1X(), control1Y(), control2X(), control2Y(), x(), y());
       
   808 }
       
   809 
       
   810 /****************************************************************************/
       
   811 
       
   812 /*!
       
   813     \qmlclass PathPercent QDeclarativePathPercent
       
   814     \since 4.7
       
   815     \brief The PathPercent manipulates the way a path is interpreted.
       
   816 
       
   817     The examples below show the normal distrubution of items along a path
       
   818     compared to a distribution which places 50% of the items along the
       
   819     PathLine section of the path.
       
   820     \table
       
   821     \row
       
   822     \o \image declarative-nopercent.png
       
   823     \o
       
   824     \qml
       
   825     Path {
       
   826         startX: 20; startY: 0
       
   827         PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
       
   828         PathLine { x: 150; y: 80 }
       
   829         PathQuad { x: 180; y: 0; controlX: 200; controlY: 80 }
       
   830     }
       
   831     \endqml
       
   832     \row
       
   833     \o \image declarative-percent.png
       
   834     \o
       
   835     \qml
       
   836     Path {
       
   837         startX: 20; startY: 0
       
   838         PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
       
   839         PathPercent { value: 0.25 }
       
   840         PathLine { x: 150; y: 80 }
       
   841         PathPercent { value: 0.75 }
       
   842         PathQuad { x: 180; y: 0; controlX: 200; controlY: 80 }
       
   843         PathPercent { value: 1 }
       
   844     }
       
   845     \endqml
       
   846     \endtable
       
   847 
       
   848     \sa Path
       
   849 */
       
   850 
       
   851 /*!
       
   852     \internal
       
   853     \class QDeclarativePathPercent
       
   854     \brief The QDeclarativePathPercent class manipulates the way a path is interpreted.
       
   855 
       
   856     QDeclarativePathPercent allows you to bunch up items (or spread out items) along various
       
   857     segments of a QDeclarativePathView's path.
       
   858 
       
   859     \sa QDeclarativePath
       
   860 
       
   861 */
       
   862 
       
   863 qreal QDeclarativePathPercent::value() const
       
   864 {
       
   865     return _value;
       
   866 }
       
   867 
       
   868 void QDeclarativePathPercent::setValue(qreal value)
       
   869 {
       
   870     _value = value;
       
   871 }
       
   872 QT_END_NAMESPACE