src/declarative/util/qdeclarativestateoperations.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
       
     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/qdeclarativestateoperations_p.h"
       
    43 
       
    44 #include <qdeclarative.h>
       
    45 #include <qdeclarativecontext.h>
       
    46 #include <qdeclarativeexpression.h>
       
    47 #include <qdeclarativeinfo.h>
       
    48 #include <qdeclarativeanchors_p_p.h>
       
    49 #include <qdeclarativeitem_p.h>
       
    50 #include <qdeclarativeguard_p.h>
       
    51 #include <qdeclarativenullablevalue_p_p.h>
       
    52 #include "private/qdeclarativecontext_p.h"
       
    53 #include "private/qdeclarativeproperty_p.h"
       
    54 #include "private/qdeclarativebinding_p.h"
       
    55 
       
    56 #include <QtCore/qdebug.h>
       
    57 #include <QtGui/qgraphicsitem.h>
       
    58 #include <QtCore/qmath.h>
       
    59 
       
    60 #include <private/qobject_p.h>
       
    61 
       
    62 QT_BEGIN_NAMESPACE
       
    63 
       
    64 class QDeclarativeParentChangePrivate : public QObjectPrivate
       
    65 {
       
    66     Q_DECLARE_PUBLIC(QDeclarativeParentChange)
       
    67 public:
       
    68     QDeclarativeParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0),
       
    69         rewindParent(0), rewindStackBefore(0) {}
       
    70 
       
    71     QDeclarativeItem *target;
       
    72     QDeclarativeGuard<QDeclarativeItem> parent;
       
    73     QDeclarativeGuard<QDeclarativeItem> origParent;
       
    74     QDeclarativeGuard<QDeclarativeItem> origStackBefore;
       
    75     QDeclarativeItem *rewindParent;
       
    76     QDeclarativeItem *rewindStackBefore;
       
    77 
       
    78     QDeclarativeNullableValue<QDeclarativeScriptString> xString;
       
    79     QDeclarativeNullableValue<QDeclarativeScriptString> yString;
       
    80     QDeclarativeNullableValue<QDeclarativeScriptString> widthString;
       
    81     QDeclarativeNullableValue<QDeclarativeScriptString> heightString;
       
    82     QDeclarativeNullableValue<QDeclarativeScriptString> scaleString;
       
    83     QDeclarativeNullableValue<QDeclarativeScriptString> rotationString;
       
    84 
       
    85     void doChange(QDeclarativeItem *targetParent, QDeclarativeItem *stackBefore = 0);
       
    86 };
       
    87 
       
    88 void QDeclarativeParentChangePrivate::doChange(QDeclarativeItem *targetParent, QDeclarativeItem *stackBefore)
       
    89 {
       
    90     if (targetParent && target && target->parentItem()) {
       
    91         Q_Q(QDeclarativeParentChange);
       
    92         bool ok;
       
    93         const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
       
    94         if (transform.type() >= QTransform::TxShear || !ok) {
       
    95             qmlInfo(q) << QDeclarativeParentChange::tr("Unable to preserve appearance under complex transform");
       
    96             ok = false;
       
    97         }
       
    98 
       
    99         qreal scale = 1;
       
   100         qreal rotation = 0;
       
   101         if (ok && transform.type() != QTransform::TxRotate) {
       
   102             if (transform.m11() == transform.m22())
       
   103                 scale = transform.m11();
       
   104             else {
       
   105                 qmlInfo(q) << QDeclarativeParentChange::tr("Unable to preserve appearance under non-uniform scale");
       
   106                 ok = false;
       
   107             }
       
   108         } else if (ok && transform.type() == QTransform::TxRotate) {
       
   109             if (transform.m11() == transform.m22())
       
   110                 scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
       
   111             else {
       
   112                 qmlInfo(q) << QDeclarativeParentChange::tr("Unable to preserve appearance under non-uniform scale");
       
   113                 ok = false;
       
   114             }
       
   115 
       
   116             if (scale != 0)
       
   117                 rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
       
   118             else {
       
   119                 qmlInfo(q) << QDeclarativeParentChange::tr("Unable to preserve appearance under scale of 0");
       
   120                 ok = false;
       
   121             }
       
   122         }
       
   123 
       
   124         const QPointF &point = transform.map(QPointF(target->x(),target->y()));
       
   125         qreal x = point.x();
       
   126         qreal y = point.y();
       
   127 
       
   128         // setParentItem will update the transformOriginPoint if needed
       
   129         target->setParentItem(targetParent);
       
   130 
       
   131         if (ok && target->transformOrigin() != QDeclarativeItem::TopLeft) {
       
   132             qreal tempxt = target->transformOriginPoint().x();
       
   133             qreal tempyt = target->transformOriginPoint().y();
       
   134             QTransform t;
       
   135             t.translate(-tempxt, -tempyt);
       
   136             t.rotate(rotation);
       
   137             t.scale(scale, scale);
       
   138             t.translate(tempxt, tempyt);
       
   139             const QPointF &offset = t.map(QPointF(0,0));
       
   140             x += offset.x();
       
   141             y += offset.y();
       
   142         }
       
   143 
       
   144         if (ok) {
       
   145             //qDebug() << x << y << rotation << scale;
       
   146             target->setX(x);
       
   147             target->setY(y);
       
   148             target->setRotation(target->rotation() + rotation);
       
   149             target->setScale(target->scale() * scale);
       
   150         }
       
   151     } else if (target) {
       
   152         target->setParentItem(targetParent);
       
   153     }
       
   154 
       
   155     //restore the original stack position.
       
   156     //### if stackBefore has also been reparented this won't work
       
   157     if (stackBefore)
       
   158         target->stackBefore(stackBefore);
       
   159 }
       
   160 
       
   161 /*!
       
   162     \preliminary
       
   163     \qmlclass ParentChange QDeclarativeParentChange
       
   164     \brief The ParentChange element allows you to reparent an Item in a state change.
       
   165 
       
   166     ParentChange reparents an item while preserving its visual appearance (position, size,
       
   167     rotation, and scale) on screen. You can then specify a transition to move/resize/rotate/scale
       
   168     the item to its final intended appearance.
       
   169 
       
   170     ParentChange can only preserve visual appearance if no complex transforms are involved.
       
   171     More specifically, it will not work if the transform property has been set for any
       
   172     items involved in the reparenting (i.e. items in the common ancestor tree
       
   173     for the original and new parent).
       
   174 
       
   175     You can specify at which point in a transition you want a ParentChange to occur by
       
   176     using a ParentAnimation.
       
   177 */
       
   178 
       
   179 
       
   180 QDeclarativeParentChange::QDeclarativeParentChange(QObject *parent)
       
   181     : QDeclarativeStateOperation(*(new QDeclarativeParentChangePrivate), parent)
       
   182 {
       
   183 }
       
   184 
       
   185 QDeclarativeParentChange::~QDeclarativeParentChange()
       
   186 {
       
   187 }
       
   188 
       
   189 /*!
       
   190     \qmlproperty real ParentChange::x
       
   191     \qmlproperty real ParentChange::y
       
   192     \qmlproperty real ParentChange::width
       
   193     \qmlproperty real ParentChange::height
       
   194     \qmlproperty real ParentChange::scale
       
   195     \qmlproperty real ParentChange::rotation
       
   196     These properties hold the new position, size, scale, and rotation
       
   197     for the item in this state.
       
   198 */
       
   199 QDeclarativeScriptString QDeclarativeParentChange::x() const
       
   200 {
       
   201     Q_D(const QDeclarativeParentChange);
       
   202     return d->xString.value;
       
   203 }
       
   204 
       
   205 void QDeclarativeParentChange::setX(QDeclarativeScriptString x)
       
   206 {
       
   207     Q_D(QDeclarativeParentChange);
       
   208     d->xString = x;
       
   209 }
       
   210 
       
   211 bool QDeclarativeParentChange::xIsSet() const
       
   212 {
       
   213     Q_D(const QDeclarativeParentChange);
       
   214     return d->xString.isValid();
       
   215 }
       
   216 
       
   217 QDeclarativeScriptString QDeclarativeParentChange::y() const
       
   218 {
       
   219     Q_D(const QDeclarativeParentChange);
       
   220     return d->yString.value;
       
   221 }
       
   222 
       
   223 void QDeclarativeParentChange::setY(QDeclarativeScriptString y)
       
   224 {
       
   225     Q_D(QDeclarativeParentChange);
       
   226     d->yString = y;
       
   227 }
       
   228 
       
   229 bool QDeclarativeParentChange::yIsSet() const
       
   230 {
       
   231     Q_D(const QDeclarativeParentChange);
       
   232     return d->yString.isValid();
       
   233 }
       
   234 
       
   235 QDeclarativeScriptString QDeclarativeParentChange::width() const
       
   236 {
       
   237     Q_D(const QDeclarativeParentChange);
       
   238     return d->widthString.value;
       
   239 }
       
   240 
       
   241 void QDeclarativeParentChange::setWidth(QDeclarativeScriptString width)
       
   242 {
       
   243     Q_D(QDeclarativeParentChange);
       
   244     d->widthString = width;
       
   245 }
       
   246 
       
   247 bool QDeclarativeParentChange::widthIsSet() const
       
   248 {
       
   249     Q_D(const QDeclarativeParentChange);
       
   250     return d->widthString.isValid();
       
   251 }
       
   252 
       
   253 QDeclarativeScriptString QDeclarativeParentChange::height() const
       
   254 {
       
   255     Q_D(const QDeclarativeParentChange);
       
   256     return d->heightString.value;
       
   257 }
       
   258 
       
   259 void QDeclarativeParentChange::setHeight(QDeclarativeScriptString height)
       
   260 {
       
   261     Q_D(QDeclarativeParentChange);
       
   262     d->heightString = height;
       
   263 }
       
   264 
       
   265 bool QDeclarativeParentChange::heightIsSet() const
       
   266 {
       
   267     Q_D(const QDeclarativeParentChange);
       
   268     return d->heightString.isValid();
       
   269 }
       
   270 
       
   271 QDeclarativeScriptString QDeclarativeParentChange::scale() const
       
   272 {
       
   273     Q_D(const QDeclarativeParentChange);
       
   274     return d->scaleString.value;
       
   275 }
       
   276 
       
   277 void QDeclarativeParentChange::setScale(QDeclarativeScriptString scale)
       
   278 {
       
   279     Q_D(QDeclarativeParentChange);
       
   280     d->scaleString = scale;
       
   281 }
       
   282 
       
   283 bool QDeclarativeParentChange::scaleIsSet() const
       
   284 {
       
   285     Q_D(const QDeclarativeParentChange);
       
   286     return d->scaleString.isValid();
       
   287 }
       
   288 
       
   289 QDeclarativeScriptString QDeclarativeParentChange::rotation() const
       
   290 {
       
   291     Q_D(const QDeclarativeParentChange);
       
   292     return d->rotationString.value;
       
   293 }
       
   294 
       
   295 void QDeclarativeParentChange::setRotation(QDeclarativeScriptString rotation)
       
   296 {
       
   297     Q_D(QDeclarativeParentChange);
       
   298     d->rotationString = rotation;
       
   299 }
       
   300 
       
   301 bool QDeclarativeParentChange::rotationIsSet() const
       
   302 {
       
   303     Q_D(const QDeclarativeParentChange);
       
   304     return d->rotationString.isValid();
       
   305 }
       
   306 
       
   307 QDeclarativeItem *QDeclarativeParentChange::originalParent() const
       
   308 {
       
   309     Q_D(const QDeclarativeParentChange);
       
   310     return d->origParent;
       
   311 }
       
   312 
       
   313 /*!
       
   314     \qmlproperty Item ParentChange::target
       
   315     This property holds the item to be reparented
       
   316 */
       
   317 
       
   318 QDeclarativeItem *QDeclarativeParentChange::object() const
       
   319 {
       
   320     Q_D(const QDeclarativeParentChange);
       
   321     return d->target;
       
   322 }
       
   323 
       
   324 void QDeclarativeParentChange::setObject(QDeclarativeItem *target)
       
   325 {
       
   326     Q_D(QDeclarativeParentChange);
       
   327     d->target = target;
       
   328 }
       
   329 
       
   330 /*!
       
   331     \qmlproperty Item ParentChange::parent
       
   332     This property holds the new parent for the item in this state.
       
   333 */
       
   334 
       
   335 QDeclarativeItem *QDeclarativeParentChange::parent() const
       
   336 {
       
   337     Q_D(const QDeclarativeParentChange);
       
   338     return d->parent;
       
   339 }
       
   340 
       
   341 void QDeclarativeParentChange::setParent(QDeclarativeItem *parent)
       
   342 {
       
   343     Q_D(QDeclarativeParentChange);
       
   344     d->parent = parent;
       
   345 }
       
   346 
       
   347 QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
       
   348 {
       
   349     Q_D(QDeclarativeParentChange);
       
   350     if (!d->target || !d->parent)
       
   351         return ActionList();
       
   352 
       
   353     ActionList actions;
       
   354 
       
   355     QDeclarativeAction a;
       
   356     a.event = this;
       
   357     actions << a;
       
   358 
       
   359     if (d->xString.isValid()) {
       
   360         bool ok = false;
       
   361         QString script = d->xString.value.script();
       
   362         qreal x = script.toFloat(&ok);
       
   363         if (ok) {
       
   364             QDeclarativeAction xa(d->target, QLatin1String("x"), x);
       
   365             actions << xa;
       
   366         } else {
       
   367             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
       
   368             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("x")));
       
   369             QDeclarativeAction xa;
       
   370             xa.property = newBinding->property();
       
   371             xa.toBinding = newBinding;
       
   372             xa.fromValue = xa.property.read();
       
   373             xa.deletableToBinding = true;
       
   374             actions << xa;
       
   375         }
       
   376     }
       
   377 
       
   378     if (d->yString.isValid()) {
       
   379         bool ok = false;
       
   380         QString script = d->yString.value.script();
       
   381         qreal y = script.toFloat(&ok);
       
   382         if (ok) {
       
   383             QDeclarativeAction ya(d->target, QLatin1String("y"), y);
       
   384             actions << ya;
       
   385         } else {
       
   386             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
       
   387             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("y")));
       
   388             QDeclarativeAction ya;
       
   389             ya.property = newBinding->property();
       
   390             ya.toBinding = newBinding;
       
   391             ya.fromValue = ya.property.read();
       
   392             ya.deletableToBinding = true;
       
   393             actions << ya;
       
   394         }
       
   395     }
       
   396 
       
   397     if (d->scaleString.isValid()) {
       
   398         bool ok = false;
       
   399         QString script = d->scaleString.value.script();
       
   400         qreal scale = script.toFloat(&ok);
       
   401         if (ok) {
       
   402             QDeclarativeAction sa(d->target, QLatin1String("scale"), scale);
       
   403             actions << sa;
       
   404         } else {
       
   405             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
       
   406             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("scale")));
       
   407             QDeclarativeAction sa;
       
   408             sa.property = newBinding->property();
       
   409             sa.toBinding = newBinding;
       
   410             sa.fromValue = sa.property.read();
       
   411             sa.deletableToBinding = true;
       
   412             actions << sa;
       
   413         }
       
   414     }
       
   415 
       
   416     if (d->rotationString.isValid()) {
       
   417         bool ok = false;
       
   418         QString script = d->rotationString.value.script();
       
   419         qreal rotation = script.toFloat(&ok);
       
   420         if (ok) {
       
   421             QDeclarativeAction ra(d->target, QLatin1String("rotation"), rotation);
       
   422             actions << ra;
       
   423         } else {
       
   424             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
       
   425             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("rotation")));
       
   426             QDeclarativeAction ra;
       
   427             ra.property = newBinding->property();
       
   428             ra.toBinding = newBinding;
       
   429             ra.fromValue = ra.property.read();
       
   430             ra.deletableToBinding = true;
       
   431             actions << ra;
       
   432         }
       
   433     }
       
   434 
       
   435     if (d->widthString.isValid()) {
       
   436         bool ok = false;
       
   437         QString script = d->widthString.value.script();
       
   438         qreal width = script.toFloat(&ok);
       
   439         if (ok) {
       
   440             QDeclarativeAction wa(d->target, QLatin1String("width"), width);
       
   441             actions << wa;
       
   442         } else {
       
   443             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
       
   444             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("width")));
       
   445             QDeclarativeAction wa;
       
   446             wa.property = newBinding->property();
       
   447             wa.toBinding = newBinding;
       
   448             wa.fromValue = wa.property.read();
       
   449             wa.deletableToBinding = true;
       
   450             actions << wa;
       
   451         }
       
   452     }
       
   453 
       
   454     if (d->heightString.isValid()) {
       
   455         bool ok = false;
       
   456         QString script = d->heightString.value.script();
       
   457         qreal height = script.toFloat(&ok);
       
   458         if (ok) {
       
   459             QDeclarativeAction ha(d->target, QLatin1String("height"), height);
       
   460             actions << ha;
       
   461         } else {
       
   462             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
       
   463             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("height")));
       
   464             QDeclarativeAction ha;
       
   465             ha.property = newBinding->property();
       
   466             ha.toBinding = newBinding;
       
   467             ha.fromValue = ha.property.read();
       
   468             ha.deletableToBinding = true;
       
   469             actions << ha;
       
   470         }
       
   471     }
       
   472 
       
   473     return actions;
       
   474 }
       
   475 
       
   476 class AccessibleFxItem : public QDeclarativeItem
       
   477 {
       
   478     Q_OBJECT
       
   479     Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativeItem)
       
   480 public:
       
   481     int siblingIndex() {
       
   482         Q_D(QDeclarativeItem);
       
   483         return d->siblingIndex;
       
   484     }
       
   485 };
       
   486 
       
   487 void QDeclarativeParentChange::saveOriginals()
       
   488 {
       
   489     Q_D(QDeclarativeParentChange);
       
   490     saveCurrentValues();
       
   491     d->origParent = d->rewindParent;
       
   492     d->origStackBefore = d->rewindStackBefore;
       
   493 }
       
   494 
       
   495 /*void QDeclarativeParentChange::copyOriginals(QDeclarativeActionEvent *other)
       
   496 {
       
   497     Q_D(QDeclarativeParentChange);
       
   498     QDeclarativeParentChange *pc = static_cast<QDeclarativeParentChange*>(other);
       
   499 
       
   500     d->origParent = pc->d_func()->rewindParent;
       
   501     d->origStackBefore = pc->d_func()->rewindStackBefore;
       
   502 
       
   503     saveCurrentValues();
       
   504 }*/
       
   505 
       
   506 void QDeclarativeParentChange::execute(Reason)
       
   507 {
       
   508     Q_D(QDeclarativeParentChange);
       
   509     d->doChange(d->parent);
       
   510 }
       
   511 
       
   512 bool QDeclarativeParentChange::isReversable()
       
   513 {
       
   514     return true;
       
   515 }
       
   516 
       
   517 void QDeclarativeParentChange::reverse(Reason)
       
   518 {
       
   519     Q_D(QDeclarativeParentChange);
       
   520     d->doChange(d->origParent, d->origStackBefore);
       
   521 }
       
   522 
       
   523 QString QDeclarativeParentChange::typeName() const
       
   524 {
       
   525     return QLatin1String("ParentChange");
       
   526 }
       
   527 
       
   528 bool QDeclarativeParentChange::override(QDeclarativeActionEvent*other)
       
   529 {
       
   530     Q_D(QDeclarativeParentChange);
       
   531     if (other->typeName() != QLatin1String("ParentChange"))
       
   532         return false;
       
   533     if (QDeclarativeParentChange *otherPC = static_cast<QDeclarativeParentChange*>(other))
       
   534         return (d->target == otherPC->object());
       
   535     return false;
       
   536 }
       
   537 
       
   538 void QDeclarativeParentChange::saveCurrentValues()
       
   539 {
       
   540     Q_D(QDeclarativeParentChange);
       
   541     if (!d->target) {
       
   542         d->rewindParent = 0;
       
   543         d->rewindStackBefore = 0;
       
   544         return;
       
   545     }
       
   546 
       
   547     d->rewindParent = d->target->parentItem();
       
   548     d->rewindStackBefore = 0;
       
   549 
       
   550     if (!d->rewindParent)
       
   551         return;
       
   552 
       
   553     //try to determine the item's original stack position so we can restore it
       
   554     int siblingIndex = ((AccessibleFxItem*)d->target)->siblingIndex() + 1;
       
   555     QList<QGraphicsItem*> children = d->rewindParent->childItems();
       
   556     for (int i = 0; i < children.count(); ++i) {
       
   557         QDeclarativeItem *child = qobject_cast<QDeclarativeItem*>(children.at(i));
       
   558         if (!child)
       
   559             continue;
       
   560         if (((AccessibleFxItem*)child)->siblingIndex() == siblingIndex) {
       
   561             d->rewindStackBefore = child;
       
   562             break;
       
   563         }
       
   564     }
       
   565 }
       
   566 
       
   567 void QDeclarativeParentChange::rewind()
       
   568 {
       
   569     Q_D(QDeclarativeParentChange);
       
   570     d->doChange(d->rewindParent, d->rewindStackBefore);
       
   571 }
       
   572 
       
   573 class QDeclarativeStateChangeScriptPrivate : public QObjectPrivate
       
   574 {
       
   575 public:
       
   576     QDeclarativeStateChangeScriptPrivate() {}
       
   577 
       
   578     QDeclarativeScriptString script;
       
   579     QString name;
       
   580 };
       
   581 
       
   582 /*!
       
   583     \qmlclass StateChangeScript QDeclarativeStateChangeScript
       
   584     \brief The StateChangeScript element allows you to run a script in a state.
       
   585 
       
   586     StateChangeScripts are run when entering the state. You can use
       
   587     ScriptAction to specify at which point in the transition
       
   588     you want the StateChangeScript to be run.
       
   589 
       
   590     \qml
       
   591     State {
       
   592         name "state1"
       
   593         StateChangeScript {
       
   594             name: "myScript"
       
   595             script: doStateStuff();
       
   596         }
       
   597         ...
       
   598     }
       
   599     ...
       
   600     Transition {
       
   601         to: "state1"
       
   602         SequentialAnimation {
       
   603             NumberAnimation { ... }
       
   604             ScriptAction { scriptName: "myScript" }
       
   605             NumberAnimation { ... }
       
   606         }
       
   607     }
       
   608     \endqml
       
   609 
       
   610     \sa ScriptAction
       
   611 */
       
   612 
       
   613 QDeclarativeStateChangeScript::QDeclarativeStateChangeScript(QObject *parent)
       
   614 : QDeclarativeStateOperation(*(new QDeclarativeStateChangeScriptPrivate), parent)
       
   615 {
       
   616 }
       
   617 
       
   618 QDeclarativeStateChangeScript::~QDeclarativeStateChangeScript()
       
   619 {
       
   620 }
       
   621 
       
   622 /*!
       
   623     \qmlproperty script StateChangeScript::script
       
   624     This property holds the script to run when the state is current.
       
   625 */
       
   626 QDeclarativeScriptString QDeclarativeStateChangeScript::script() const
       
   627 {
       
   628     Q_D(const QDeclarativeStateChangeScript);
       
   629     return d->script;
       
   630 }
       
   631 
       
   632 void QDeclarativeStateChangeScript::setScript(const QDeclarativeScriptString &s)
       
   633 {
       
   634     Q_D(QDeclarativeStateChangeScript);
       
   635     d->script = s;
       
   636 }
       
   637 
       
   638 /*!
       
   639     \qmlproperty script StateChangeScript::script
       
   640     This property holds the name of the script. This name can be used by a
       
   641     ScriptAction to target a specific script.
       
   642 
       
   643     \sa ScriptAction::stateChangeScriptName
       
   644 */
       
   645 QString QDeclarativeStateChangeScript::name() const
       
   646 {
       
   647     Q_D(const QDeclarativeStateChangeScript);
       
   648     return d->name;
       
   649 }
       
   650 
       
   651 void QDeclarativeStateChangeScript::setName(const QString &n)
       
   652 {
       
   653     Q_D(QDeclarativeStateChangeScript);
       
   654     d->name = n;
       
   655 }
       
   656 
       
   657 void QDeclarativeStateChangeScript::execute(Reason)
       
   658 {
       
   659     Q_D(QDeclarativeStateChangeScript);
       
   660     const QString &script = d->script.script();
       
   661     if (!script.isEmpty()) {
       
   662         QDeclarativeExpression expr(d->script.context(), d->script.scopeObject(), script);
       
   663         QDeclarativeData *ddata = QDeclarativeData::get(this);
       
   664         if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty())
       
   665             expr.setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber);
       
   666         expr.evaluate();
       
   667         if (expr.hasError())
       
   668             qmlInfo(this, expr.error());
       
   669     }
       
   670 }
       
   671 
       
   672 QDeclarativeStateChangeScript::ActionList QDeclarativeStateChangeScript::actions()
       
   673 {
       
   674     ActionList rv;
       
   675     QDeclarativeAction a;
       
   676     a.event = this;
       
   677     rv << a;
       
   678     return rv;
       
   679 }
       
   680 
       
   681 QString QDeclarativeStateChangeScript::typeName() const
       
   682 {
       
   683     return QLatin1String("StateChangeScript");
       
   684 }
       
   685 
       
   686 /*!
       
   687     \qmlclass AnchorChanges QDeclarativeAnchorChanges
       
   688     \brief The AnchorChanges element allows you to change the anchors of an item in a state.
       
   689 
       
   690     In the following example we change the top and bottom anchors of an item:
       
   691     \qml
       
   692     State {
       
   693         name: "reanchored"
       
   694         AnchorChanges {
       
   695             target: content;
       
   696             anchors.top: window.top;
       
   697             anchors.bottom: window.bottom
       
   698         }
       
   699         PropertyChanges {
       
   700             target: content;
       
   701             anchors.topMargin: 3
       
   702             anchors.bottomMargin: 3;
       
   703         }
       
   704     }
       
   705     \endqml
       
   706 
       
   707     AnchorChanges can be animated using AnchorAnimation.
       
   708     \qml
       
   709     //animate our anchor changes
       
   710     Transition {
       
   711         AnchorAnimation {}
       
   712     }
       
   713     \endqml
       
   714 
       
   715     Margin animations can be animated using NumberAnimation.
       
   716 
       
   717     For more information on anchors see \l {anchor-layout}{Anchor Layouts}.
       
   718 */
       
   719 
       
   720 class QDeclarativeAnchorSetPrivate : public QObjectPrivate
       
   721 {
       
   722     Q_DECLARE_PUBLIC(QDeclarativeAnchorSet)
       
   723 public:
       
   724     QDeclarativeAnchorSetPrivate()
       
   725       : usedAnchors(0), resetAnchors(0), fill(0),
       
   726         centerIn(0)/*, leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0),
       
   727         margins(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0)*/
       
   728     {
       
   729     }
       
   730 
       
   731     QDeclarativeAnchors::Anchors usedAnchors;
       
   732     QDeclarativeAnchors::Anchors resetAnchors;
       
   733 
       
   734     QDeclarativeItem *fill;
       
   735     QDeclarativeItem *centerIn;
       
   736 
       
   737     QDeclarativeScriptString leftScript;
       
   738     QDeclarativeScriptString rightScript;
       
   739     QDeclarativeScriptString topScript;
       
   740     QDeclarativeScriptString bottomScript;
       
   741     QDeclarativeScriptString hCenterScript;
       
   742     QDeclarativeScriptString vCenterScript;
       
   743     QDeclarativeScriptString baselineScript;
       
   744 
       
   745     /*qreal leftMargin;
       
   746     qreal rightMargin;
       
   747     qreal topMargin;
       
   748     qreal bottomMargin;
       
   749     qreal margins;
       
   750     qreal vCenterOffset;
       
   751     qreal hCenterOffset;
       
   752     qreal baselineOffset;*/
       
   753 };
       
   754 
       
   755 QDeclarativeAnchorSet::QDeclarativeAnchorSet(QObject *parent)
       
   756   : QObject(*new QDeclarativeAnchorSetPrivate, parent)
       
   757 {
       
   758 }
       
   759 
       
   760 QDeclarativeAnchorSet::~QDeclarativeAnchorSet()
       
   761 {
       
   762 }
       
   763 
       
   764 QDeclarativeScriptString QDeclarativeAnchorSet::top() const
       
   765 {
       
   766     Q_D(const QDeclarativeAnchorSet);
       
   767     return d->topScript;
       
   768 }
       
   769 
       
   770 void QDeclarativeAnchorSet::setTop(const QDeclarativeScriptString &edge)
       
   771 {
       
   772     Q_D(QDeclarativeAnchorSet);
       
   773     d->usedAnchors |= QDeclarativeAnchors::TopAnchor;
       
   774     d->topScript = edge;
       
   775     if (edge.script() == QLatin1String("undefined"))
       
   776         resetTop();
       
   777 }
       
   778 
       
   779 void QDeclarativeAnchorSet::resetTop()
       
   780 {
       
   781     Q_D(QDeclarativeAnchorSet);
       
   782     d->usedAnchors &= ~QDeclarativeAnchors::TopAnchor;
       
   783     d->topScript = QDeclarativeScriptString();
       
   784     d->resetAnchors |= QDeclarativeAnchors::TopAnchor;
       
   785 }
       
   786 
       
   787 QDeclarativeScriptString QDeclarativeAnchorSet::bottom() const
       
   788 {
       
   789     Q_D(const QDeclarativeAnchorSet);
       
   790     return d->bottomScript;
       
   791 }
       
   792 
       
   793 void QDeclarativeAnchorSet::setBottom(const QDeclarativeScriptString &edge)
       
   794 {
       
   795     Q_D(QDeclarativeAnchorSet);
       
   796     d->usedAnchors |= QDeclarativeAnchors::BottomAnchor;
       
   797     d->bottomScript = edge;
       
   798     if (edge.script() == QLatin1String("undefined"))
       
   799         resetBottom();
       
   800 }
       
   801 
       
   802 void QDeclarativeAnchorSet::resetBottom()
       
   803 {
       
   804     Q_D(QDeclarativeAnchorSet);
       
   805     d->usedAnchors &= ~QDeclarativeAnchors::BottomAnchor;
       
   806     d->bottomScript = QDeclarativeScriptString();
       
   807     d->resetAnchors |= QDeclarativeAnchors::BottomAnchor;
       
   808 }
       
   809 
       
   810 QDeclarativeScriptString QDeclarativeAnchorSet::verticalCenter() const
       
   811 {
       
   812     Q_D(const QDeclarativeAnchorSet);
       
   813     return d->vCenterScript;
       
   814 }
       
   815 
       
   816 void QDeclarativeAnchorSet::setVerticalCenter(const QDeclarativeScriptString &edge)
       
   817 {
       
   818     Q_D(QDeclarativeAnchorSet);
       
   819     d->usedAnchors |= QDeclarativeAnchors::VCenterAnchor;
       
   820     d->vCenterScript = edge;
       
   821     if (edge.script() == QLatin1String("undefined"))
       
   822         resetVerticalCenter();
       
   823 }
       
   824 
       
   825 void QDeclarativeAnchorSet::resetVerticalCenter()
       
   826 {
       
   827     Q_D(QDeclarativeAnchorSet);
       
   828     d->usedAnchors &= ~QDeclarativeAnchors::VCenterAnchor;
       
   829     d->vCenterScript = QDeclarativeScriptString();
       
   830     d->resetAnchors |= QDeclarativeAnchors::VCenterAnchor;
       
   831 }
       
   832 
       
   833 QDeclarativeScriptString QDeclarativeAnchorSet::baseline() const
       
   834 {
       
   835     Q_D(const QDeclarativeAnchorSet);
       
   836     return d->baselineScript;
       
   837 }
       
   838 
       
   839 void QDeclarativeAnchorSet::setBaseline(const QDeclarativeScriptString &edge)
       
   840 {
       
   841     Q_D(QDeclarativeAnchorSet);
       
   842     d->usedAnchors |= QDeclarativeAnchors::BaselineAnchor;
       
   843     d->baselineScript = edge;
       
   844     if (edge.script() == QLatin1String("undefined"))
       
   845         resetBaseline();
       
   846 }
       
   847 
       
   848 void QDeclarativeAnchorSet::resetBaseline()
       
   849 {
       
   850     Q_D(QDeclarativeAnchorSet);
       
   851     d->usedAnchors &= ~QDeclarativeAnchors::BaselineAnchor;
       
   852     d->baselineScript = QDeclarativeScriptString();
       
   853     d->resetAnchors |= QDeclarativeAnchors::BaselineAnchor;
       
   854 }
       
   855 
       
   856 QDeclarativeScriptString QDeclarativeAnchorSet::left() const
       
   857 {
       
   858     Q_D(const QDeclarativeAnchorSet);
       
   859     return d->leftScript;
       
   860 }
       
   861 
       
   862 void QDeclarativeAnchorSet::setLeft(const QDeclarativeScriptString &edge)
       
   863 {
       
   864     Q_D(QDeclarativeAnchorSet);
       
   865     d->usedAnchors |= QDeclarativeAnchors::LeftAnchor;
       
   866     d->leftScript = edge;
       
   867     if (edge.script() == QLatin1String("undefined"))
       
   868         resetLeft();
       
   869 }
       
   870 
       
   871 void QDeclarativeAnchorSet::resetLeft()
       
   872 {
       
   873     Q_D(QDeclarativeAnchorSet);
       
   874     d->usedAnchors &= ~QDeclarativeAnchors::LeftAnchor;
       
   875     d->leftScript = QDeclarativeScriptString();
       
   876     d->resetAnchors |= QDeclarativeAnchors::LeftAnchor;
       
   877 }
       
   878 
       
   879 QDeclarativeScriptString QDeclarativeAnchorSet::right() const
       
   880 {
       
   881     Q_D(const QDeclarativeAnchorSet);
       
   882     return d->rightScript;
       
   883 }
       
   884 
       
   885 void QDeclarativeAnchorSet::setRight(const QDeclarativeScriptString &edge)
       
   886 {
       
   887     Q_D(QDeclarativeAnchorSet);
       
   888     d->usedAnchors |= QDeclarativeAnchors::RightAnchor;
       
   889     d->rightScript = edge;
       
   890     if (edge.script() == QLatin1String("undefined"))
       
   891         resetRight();
       
   892 }
       
   893 
       
   894 void QDeclarativeAnchorSet::resetRight()
       
   895 {
       
   896     Q_D(QDeclarativeAnchorSet);
       
   897     d->usedAnchors &= ~QDeclarativeAnchors::RightAnchor;
       
   898     d->rightScript = QDeclarativeScriptString();
       
   899     d->resetAnchors |= QDeclarativeAnchors::RightAnchor;
       
   900 }
       
   901 
       
   902 QDeclarativeScriptString QDeclarativeAnchorSet::horizontalCenter() const
       
   903 {
       
   904     Q_D(const QDeclarativeAnchorSet);
       
   905     return d->hCenterScript;
       
   906 }
       
   907 
       
   908 void QDeclarativeAnchorSet::setHorizontalCenter(const QDeclarativeScriptString &edge)
       
   909 {
       
   910     Q_D(QDeclarativeAnchorSet);
       
   911     d->usedAnchors |= QDeclarativeAnchors::HCenterAnchor;
       
   912     d->hCenterScript = edge;
       
   913     if (edge.script() == QLatin1String("undefined"))
       
   914         resetHorizontalCenter();
       
   915 }
       
   916 
       
   917 void QDeclarativeAnchorSet::resetHorizontalCenter()
       
   918 {
       
   919     Q_D(QDeclarativeAnchorSet);
       
   920     d->usedAnchors &= ~QDeclarativeAnchors::HCenterAnchor;
       
   921     d->hCenterScript = QDeclarativeScriptString();
       
   922     d->resetAnchors |= QDeclarativeAnchors::HCenterAnchor;
       
   923 }
       
   924 
       
   925 QDeclarativeItem *QDeclarativeAnchorSet::fill() const
       
   926 {
       
   927     Q_D(const QDeclarativeAnchorSet);
       
   928     return d->fill;
       
   929 }
       
   930 
       
   931 void QDeclarativeAnchorSet::setFill(QDeclarativeItem *f)
       
   932 {
       
   933     Q_D(QDeclarativeAnchorSet);
       
   934     d->fill = f;
       
   935 }
       
   936 
       
   937 void QDeclarativeAnchorSet::resetFill()
       
   938 {
       
   939     setFill(0);
       
   940 }
       
   941 
       
   942 QDeclarativeItem *QDeclarativeAnchorSet::centerIn() const
       
   943 {
       
   944     Q_D(const QDeclarativeAnchorSet);
       
   945     return d->centerIn;
       
   946 }
       
   947 
       
   948 void QDeclarativeAnchorSet::setCenterIn(QDeclarativeItem* c)
       
   949 {
       
   950     Q_D(QDeclarativeAnchorSet);
       
   951     d->centerIn = c;
       
   952 }
       
   953 
       
   954 void QDeclarativeAnchorSet::resetCenterIn()
       
   955 {
       
   956     setCenterIn(0);
       
   957 }
       
   958 
       
   959 
       
   960 class QDeclarativeAnchorChangesPrivate : public QObjectPrivate
       
   961 {
       
   962 public:
       
   963     QDeclarativeAnchorChangesPrivate()
       
   964         : target(0), anchorSet(new QDeclarativeAnchorSet),
       
   965           leftBinding(0), rightBinding(0), hCenterBinding(0),
       
   966           topBinding(0), bottomBinding(0), vCenterBinding(0), baselineBinding(0),
       
   967           origLeftBinding(0), origRightBinding(0), origHCenterBinding(0),
       
   968           origTopBinding(0), origBottomBinding(0), origVCenterBinding(0),
       
   969           origBaselineBinding(0)
       
   970     {
       
   971 
       
   972     }
       
   973     ~QDeclarativeAnchorChangesPrivate() { delete anchorSet; }
       
   974 
       
   975     QDeclarativeItem *target;
       
   976     QDeclarativeAnchorSet *anchorSet;
       
   977 
       
   978     QDeclarativeBinding *leftBinding;
       
   979     QDeclarativeBinding *rightBinding;
       
   980     QDeclarativeBinding *hCenterBinding;
       
   981     QDeclarativeBinding *topBinding;
       
   982     QDeclarativeBinding *bottomBinding;
       
   983     QDeclarativeBinding *vCenterBinding;
       
   984     QDeclarativeBinding *baselineBinding;
       
   985 
       
   986     QDeclarativeAbstractBinding *origLeftBinding;
       
   987     QDeclarativeAbstractBinding *origRightBinding;
       
   988     QDeclarativeAbstractBinding *origHCenterBinding;
       
   989     QDeclarativeAbstractBinding *origTopBinding;
       
   990     QDeclarativeAbstractBinding *origBottomBinding;
       
   991     QDeclarativeAbstractBinding *origVCenterBinding;
       
   992     QDeclarativeAbstractBinding *origBaselineBinding;
       
   993 
       
   994     QDeclarativeAnchorLine rewindLeft;
       
   995     QDeclarativeAnchorLine rewindRight;
       
   996     QDeclarativeAnchorLine rewindHCenter;
       
   997     QDeclarativeAnchorLine rewindTop;
       
   998     QDeclarativeAnchorLine rewindBottom;
       
   999     QDeclarativeAnchorLine rewindVCenter;
       
  1000     QDeclarativeAnchorLine rewindBaseline;
       
  1001 
       
  1002     qreal fromX;
       
  1003     qreal fromY;
       
  1004     qreal fromWidth;
       
  1005     qreal fromHeight;
       
  1006 
       
  1007     qreal toX;
       
  1008     qreal toY;
       
  1009     qreal toWidth;
       
  1010     qreal toHeight;
       
  1011 
       
  1012     qreal rewindX;
       
  1013     qreal rewindY;
       
  1014     qreal rewindWidth;
       
  1015     qreal rewindHeight;
       
  1016 
       
  1017     bool applyOrigLeft;
       
  1018     bool applyOrigRight;
       
  1019     bool applyOrigHCenter;
       
  1020     bool applyOrigTop;
       
  1021     bool applyOrigBottom;
       
  1022     bool applyOrigVCenter;
       
  1023     bool applyOrigBaseline;
       
  1024 
       
  1025     QList<QDeclarativeAbstractBinding*> oldBindings;
       
  1026 
       
  1027     QDeclarativeProperty leftProp;
       
  1028     QDeclarativeProperty rightProp;
       
  1029     QDeclarativeProperty hCenterProp;
       
  1030     QDeclarativeProperty topProp;
       
  1031     QDeclarativeProperty bottomProp;
       
  1032     QDeclarativeProperty vCenterProp;
       
  1033     QDeclarativeProperty baselineProp;
       
  1034 };
       
  1035 
       
  1036 /*!
       
  1037     \qmlproperty Item AnchorChanges::target
       
  1038     This property holds the Item whose anchors will change
       
  1039 */
       
  1040 
       
  1041 QDeclarativeAnchorChanges::QDeclarativeAnchorChanges(QObject *parent)
       
  1042  : QDeclarativeStateOperation(*(new QDeclarativeAnchorChangesPrivate), parent)
       
  1043 {
       
  1044 }
       
  1045 
       
  1046 QDeclarativeAnchorChanges::~QDeclarativeAnchorChanges()
       
  1047 {
       
  1048 }
       
  1049 
       
  1050 QDeclarativeAnchorChanges::ActionList QDeclarativeAnchorChanges::actions()
       
  1051 {
       
  1052     Q_D(QDeclarativeAnchorChanges);
       
  1053     d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding
       
  1054                    = d->bottomBinding = d->vCenterBinding = d->baselineBinding = 0;
       
  1055 
       
  1056     d->leftProp = QDeclarativeProperty(d->target, QLatin1String("anchors.left"));
       
  1057     d->rightProp = QDeclarativeProperty(d->target, QLatin1String("anchors.right"));
       
  1058     d->hCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.horizontalCenter"));
       
  1059     d->topProp = QDeclarativeProperty(d->target, QLatin1String("anchors.top"));
       
  1060     d->bottomProp = QDeclarativeProperty(d->target, QLatin1String("anchors.bottom"));
       
  1061     d->vCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.verticalCenter"));
       
  1062     d->baselineProp = QDeclarativeProperty(d->target, QLatin1String("anchors.baseline"));
       
  1063 
       
  1064     if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::LeftAnchor) {
       
  1065         d->leftBinding = new QDeclarativeBinding(d->anchorSet->d_func()->leftScript.script(), d->target, qmlContext(this));
       
  1066         d->leftBinding->setTarget(d->leftProp);
       
  1067     }
       
  1068     if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::RightAnchor) {
       
  1069         d->rightBinding = new QDeclarativeBinding(d->anchorSet->d_func()->rightScript.script(), d->target, qmlContext(this));
       
  1070         d->rightBinding->setTarget(d->rightProp);
       
  1071     }
       
  1072     if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::HCenterAnchor) {
       
  1073         d->hCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->hCenterScript.script(), d->target, qmlContext(this));
       
  1074         d->hCenterBinding->setTarget(d->hCenterProp);
       
  1075     }
       
  1076     if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::TopAnchor) {
       
  1077         d->topBinding = new QDeclarativeBinding(d->anchorSet->d_func()->topScript.script(), d->target, qmlContext(this));
       
  1078         d->topBinding->setTarget(d->topProp);
       
  1079     }
       
  1080     if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::BottomAnchor) {
       
  1081         d->bottomBinding = new QDeclarativeBinding(d->anchorSet->d_func()->bottomScript.script(), d->target, qmlContext(this));
       
  1082         d->bottomBinding->setTarget(d->bottomProp);
       
  1083     }
       
  1084     if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::VCenterAnchor) {
       
  1085         d->vCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->vCenterScript.script(), d->target, qmlContext(this));
       
  1086         d->vCenterBinding->setTarget(d->vCenterProp);
       
  1087     }
       
  1088     if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::BaselineAnchor) {
       
  1089         d->baselineBinding = new QDeclarativeBinding(d->anchorSet->d_func()->baselineScript.script(), d->target, qmlContext(this));
       
  1090         d->baselineBinding->setTarget(d->baselineProp);
       
  1091     }
       
  1092 
       
  1093     QDeclarativeAction a;
       
  1094     a.event = this;
       
  1095     return ActionList() << a;
       
  1096 }
       
  1097 
       
  1098 QDeclarativeAnchorSet *QDeclarativeAnchorChanges::anchors()
       
  1099 {
       
  1100     Q_D(QDeclarativeAnchorChanges);
       
  1101     return d->anchorSet;
       
  1102 }
       
  1103 
       
  1104 QDeclarativeItem *QDeclarativeAnchorChanges::object() const
       
  1105 {
       
  1106     Q_D(const QDeclarativeAnchorChanges);
       
  1107     return d->target;
       
  1108 }
       
  1109 
       
  1110 void QDeclarativeAnchorChanges::setObject(QDeclarativeItem *target)
       
  1111 {
       
  1112     Q_D(QDeclarativeAnchorChanges);
       
  1113     d->target = target;
       
  1114 }
       
  1115 
       
  1116 /*!
       
  1117     \qmlproperty AnchorLine AnchorChanges::anchors.left
       
  1118     \qmlproperty AnchorLine AnchorChanges::anchors.right
       
  1119     \qmlproperty AnchorLine AnchorChanges::anchors.horizontalCenter
       
  1120     \qmlproperty AnchorLine AnchorChanges::anchors.top
       
  1121     \qmlproperty AnchorLine AnchorChanges::anchors.bottom
       
  1122     \qmlproperty AnchorLine AnchorChanges::anchors.verticalCenter
       
  1123     \qmlproperty AnchorLine AnchorChanges::anchors.baseline
       
  1124 
       
  1125     These properties change the respective anchors of the item.
       
  1126 
       
  1127     To reset an anchor you can assign \c undefined:
       
  1128     \qml
       
  1129     AnchorChanges {
       
  1130         target: myItem
       
  1131         left: undefined          //remove myItem's left anchor
       
  1132         right: otherItem.right
       
  1133     }
       
  1134     \endqml
       
  1135 */
       
  1136 
       
  1137 void QDeclarativeAnchorChanges::execute(Reason reason)
       
  1138 {
       
  1139     Q_D(QDeclarativeAnchorChanges);
       
  1140     if (!d->target)
       
  1141         return;
       
  1142 
       
  1143     QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target);
       
  1144     //incorporate any needed "reverts"
       
  1145     if (d->applyOrigLeft) {
       
  1146         if (!d->origLeftBinding)
       
  1147             targetPrivate->anchors()->resetLeft();
       
  1148         QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
       
  1149     }
       
  1150     if (d->applyOrigRight) {
       
  1151         if (!d->origRightBinding)
       
  1152             targetPrivate->anchors()->resetRight();
       
  1153         QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
       
  1154     }
       
  1155     if (d->applyOrigHCenter) {
       
  1156         if (!d->origHCenterBinding)
       
  1157             targetPrivate->anchors()->resetHorizontalCenter();
       
  1158         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
       
  1159     }
       
  1160     if (d->applyOrigTop) {
       
  1161         if (!d->origTopBinding)
       
  1162             targetPrivate->anchors()->resetTop();
       
  1163         QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
       
  1164     }
       
  1165     if (d->applyOrigBottom) {
       
  1166         if (!d->origBottomBinding)
       
  1167             targetPrivate->anchors()->resetBottom();
       
  1168         QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
       
  1169     }
       
  1170     if (d->applyOrigVCenter) {
       
  1171         if (!d->origVCenterBinding)
       
  1172             targetPrivate->anchors()->resetVerticalCenter();
       
  1173         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
       
  1174     }
       
  1175     if (d->applyOrigBaseline) {
       
  1176         if (!d->origBaselineBinding)
       
  1177             targetPrivate->anchors()->resetBaseline();
       
  1178         QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
       
  1179     }
       
  1180 
       
  1181     //destroy old bindings
       
  1182     if (reason == ActualChange) {
       
  1183         for (int i = 0; i < d->oldBindings.size(); ++i) {
       
  1184             QDeclarativeAbstractBinding *binding = d->oldBindings.at(i);
       
  1185             if (binding)
       
  1186                 binding->destroy();
       
  1187         }
       
  1188         d->oldBindings.clear();
       
  1189     }
       
  1190 
       
  1191     //reset any anchors that have been specified as "undefined"
       
  1192     if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::LeftAnchor) {
       
  1193         targetPrivate->anchors()->resetLeft();
       
  1194         QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
       
  1195     }
       
  1196     if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::RightAnchor) {
       
  1197         targetPrivate->anchors()->resetRight();
       
  1198         QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
       
  1199     }
       
  1200     if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::HCenterAnchor) {
       
  1201         targetPrivate->anchors()->resetHorizontalCenter();
       
  1202         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
       
  1203     }
       
  1204     if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::TopAnchor) {
       
  1205         targetPrivate->anchors()->resetTop();
       
  1206         QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
       
  1207     }
       
  1208     if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::BottomAnchor) {
       
  1209         targetPrivate->anchors()->resetBottom();
       
  1210         QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
       
  1211     }
       
  1212     if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::VCenterAnchor) {
       
  1213         targetPrivate->anchors()->resetVerticalCenter();
       
  1214         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
       
  1215     }
       
  1216     if (d->anchorSet->d_func()->resetAnchors & QDeclarativeAnchors::BaselineAnchor) {
       
  1217         targetPrivate->anchors()->resetBaseline();
       
  1218         QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
       
  1219     }
       
  1220 
       
  1221     //set any anchors that have been specified
       
  1222     if (d->leftBinding)
       
  1223         QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), d->leftBinding);
       
  1224     if (d->rightBinding)
       
  1225         QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), d->rightBinding);
       
  1226     if (d->hCenterBinding)
       
  1227         QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), d->hCenterBinding);
       
  1228     if (d->topBinding)
       
  1229         QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), d->topBinding);
       
  1230     if (d->bottomBinding)
       
  1231         QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), d->bottomBinding);
       
  1232     if (d->vCenterBinding)
       
  1233         QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), d->vCenterBinding);
       
  1234     if (d->baselineBinding)
       
  1235         QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), d->baselineBinding);
       
  1236 }
       
  1237 
       
  1238 bool QDeclarativeAnchorChanges::isReversable()
       
  1239 {
       
  1240     return true;
       
  1241 }
       
  1242 
       
  1243 void QDeclarativeAnchorChanges::reverse(Reason reason)
       
  1244 {
       
  1245     Q_D(QDeclarativeAnchorChanges);
       
  1246     if (!d->target)
       
  1247         return;
       
  1248 
       
  1249     QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target);
       
  1250     //reset any anchors set by the state
       
  1251     if (d->leftBinding) {
       
  1252         targetPrivate->anchors()->resetLeft();
       
  1253         QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), 0);
       
  1254         if (reason == ActualChange) {
       
  1255             d->leftBinding->destroy(); d->leftBinding = 0;
       
  1256         }
       
  1257     }
       
  1258     if (d->rightBinding) {
       
  1259         targetPrivate->anchors()->resetRight();
       
  1260         QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), 0);
       
  1261         if (reason == ActualChange) {
       
  1262             d->rightBinding->destroy(); d->rightBinding = 0;
       
  1263         }
       
  1264     }
       
  1265     if (d->hCenterBinding) {
       
  1266         targetPrivate->anchors()->resetHorizontalCenter();
       
  1267         QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), 0);
       
  1268         if (reason == ActualChange) {
       
  1269             d->hCenterBinding->destroy(); d->hCenterBinding = 0;
       
  1270         }
       
  1271     }
       
  1272     if (d->topBinding) {
       
  1273         targetPrivate->anchors()->resetTop();
       
  1274         QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), 0);
       
  1275         if (reason == ActualChange) {
       
  1276             d->topBinding->destroy(); d->topBinding = 0;
       
  1277         }
       
  1278     }
       
  1279     if (d->bottomBinding) {
       
  1280         targetPrivate->anchors()->resetBottom();
       
  1281         QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), 0);
       
  1282         if (reason == ActualChange) {
       
  1283             d->bottomBinding->destroy(); d->bottomBinding = 0;
       
  1284         }
       
  1285     }
       
  1286     if (d->vCenterBinding) {
       
  1287         targetPrivate->anchors()->resetVerticalCenter();
       
  1288         QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), 0);
       
  1289         if (reason == ActualChange) {
       
  1290             d->vCenterBinding->destroy(); d->vCenterBinding = 0;
       
  1291         }
       
  1292     }
       
  1293     if (d->baselineBinding) {
       
  1294         targetPrivate->anchors()->resetBaseline();
       
  1295         QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), 0);
       
  1296         if (reason == ActualChange) {
       
  1297             d->baselineBinding->destroy(); d->baselineBinding = 0;
       
  1298         }
       
  1299     }
       
  1300 
       
  1301     //restore previous anchors
       
  1302     if (d->origLeftBinding)
       
  1303         QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
       
  1304     if (d->origRightBinding)
       
  1305         QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
       
  1306     if (d->origHCenterBinding)
       
  1307         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
       
  1308     if (d->origTopBinding)
       
  1309         QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
       
  1310     if (d->origBottomBinding)
       
  1311         QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
       
  1312     if (d->origVCenterBinding)
       
  1313         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
       
  1314     if (d->origBaselineBinding)
       
  1315         QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
       
  1316 }
       
  1317 
       
  1318 QString QDeclarativeAnchorChanges::typeName() const
       
  1319 {
       
  1320     return QLatin1String("AnchorChanges");
       
  1321 }
       
  1322 
       
  1323 QList<QDeclarativeAction> QDeclarativeAnchorChanges::additionalActions()
       
  1324 {
       
  1325     Q_D(QDeclarativeAnchorChanges);
       
  1326     QList<QDeclarativeAction> extra;
       
  1327 
       
  1328     QDeclarativeAnchors::Anchors combined = d->anchorSet->d_func()->usedAnchors | d->anchorSet->d_func()->resetAnchors;
       
  1329     bool hChange = combined & QDeclarativeAnchors::Horizontal_Mask;
       
  1330     bool vChange = combined & QDeclarativeAnchors::Vertical_Mask;
       
  1331 
       
  1332     if (d->target) {
       
  1333         QDeclarativeAction a;
       
  1334         if (hChange && d->fromX != d->toX) {
       
  1335             a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
       
  1336             a.toValue = d->toX;
       
  1337             extra << a;
       
  1338         }
       
  1339         if (vChange && d->fromY != d->toY) {
       
  1340             a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
       
  1341             a.toValue = d->toY;
       
  1342             extra << a;
       
  1343         }
       
  1344         if (hChange && d->fromWidth != d->toWidth) {
       
  1345             a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
       
  1346             a.toValue = d->toWidth;
       
  1347             extra << a;
       
  1348         }
       
  1349         if (vChange && d->fromHeight != d->toHeight) {
       
  1350             a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
       
  1351             a.toValue = d->toHeight;
       
  1352             extra << a;
       
  1353         }
       
  1354     }
       
  1355 
       
  1356     return extra;
       
  1357 }
       
  1358 
       
  1359 bool QDeclarativeAnchorChanges::changesBindings()
       
  1360 {
       
  1361     return true;
       
  1362 }
       
  1363 
       
  1364 void QDeclarativeAnchorChanges::saveOriginals()
       
  1365 {
       
  1366     Q_D(QDeclarativeAnchorChanges);
       
  1367     if (!d->target)
       
  1368         return;
       
  1369 
       
  1370     d->origLeftBinding = QDeclarativePropertyPrivate::binding(d->leftProp);
       
  1371     d->origRightBinding = QDeclarativePropertyPrivate::binding(d->rightProp);
       
  1372     d->origHCenterBinding = QDeclarativePropertyPrivate::binding(d->hCenterProp);
       
  1373     d->origTopBinding = QDeclarativePropertyPrivate::binding(d->topProp);
       
  1374     d->origBottomBinding = QDeclarativePropertyPrivate::binding(d->bottomProp);
       
  1375     d->origVCenterBinding = QDeclarativePropertyPrivate::binding(d->vCenterProp);
       
  1376     d->origBaselineBinding = QDeclarativePropertyPrivate::binding(d->baselineProp);
       
  1377 
       
  1378     d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
       
  1379       = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false;
       
  1380 
       
  1381     saveCurrentValues();
       
  1382 }
       
  1383 
       
  1384 void QDeclarativeAnchorChanges::copyOriginals(QDeclarativeActionEvent *other)
       
  1385 {
       
  1386     Q_D(QDeclarativeAnchorChanges);
       
  1387     QDeclarativeAnchorChanges *ac = static_cast<QDeclarativeAnchorChanges*>(other);
       
  1388     QDeclarativeAnchorChangesPrivate *acp = ac->d_func();
       
  1389 
       
  1390     QDeclarativeAnchors::Anchors combined = acp->anchorSet->d_func()->usedAnchors |
       
  1391                                             acp->anchorSet->d_func()->resetAnchors;
       
  1392 
       
  1393     //probably also need to revert some things
       
  1394     d->applyOrigLeft = (combined & QDeclarativeAnchors::LeftAnchor);
       
  1395     d->applyOrigRight = (combined & QDeclarativeAnchors::RightAnchor);
       
  1396     d->applyOrigHCenter = (combined & QDeclarativeAnchors::HCenterAnchor);
       
  1397     d->applyOrigTop = (combined & QDeclarativeAnchors::TopAnchor);
       
  1398     d->applyOrigBottom = (combined & QDeclarativeAnchors::BottomAnchor);
       
  1399     d->applyOrigVCenter = (combined & QDeclarativeAnchors::VCenterAnchor);
       
  1400     d->applyOrigBaseline = (combined & QDeclarativeAnchors::BaselineAnchor);
       
  1401 
       
  1402     d->origLeftBinding = acp->origLeftBinding;
       
  1403     d->origRightBinding = acp->origRightBinding;
       
  1404     d->origHCenterBinding = acp->origHCenterBinding;
       
  1405     d->origTopBinding = acp->origTopBinding;
       
  1406     d->origBottomBinding = acp->origBottomBinding;
       
  1407     d->origVCenterBinding = acp->origVCenterBinding;
       
  1408     d->origBaselineBinding = acp->origBaselineBinding;
       
  1409 
       
  1410     d->oldBindings.clear();
       
  1411     d->oldBindings << acp->leftBinding << acp->rightBinding << acp->hCenterBinding
       
  1412                 << acp->topBinding << acp->bottomBinding << acp->baselineBinding;
       
  1413 
       
  1414     saveCurrentValues();
       
  1415 }
       
  1416 
       
  1417 void QDeclarativeAnchorChanges::clearBindings()
       
  1418 {
       
  1419     Q_D(QDeclarativeAnchorChanges);
       
  1420     if (!d->target)
       
  1421         return;
       
  1422 
       
  1423     d->fromX = d->target->x();
       
  1424     d->fromY = d->target->y();
       
  1425     d->fromWidth = d->target->width();
       
  1426     d->fromHeight = d->target->height();
       
  1427 
       
  1428     QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target);
       
  1429     //reset any anchors with corresponding reverts
       
  1430     //reset any anchors that have been specified as "undefined"
       
  1431     //reset any anchors that we'll be setting in the state
       
  1432     QDeclarativeAnchors::Anchors combined = d->anchorSet->d_func()->resetAnchors |
       
  1433                                             d->anchorSet->d_func()->usedAnchors;
       
  1434     if (d->applyOrigLeft || (combined & QDeclarativeAnchors::LeftAnchor)) {
       
  1435         targetPrivate->anchors()->resetLeft();
       
  1436         QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
       
  1437     }
       
  1438     if (d->applyOrigRight || (combined & QDeclarativeAnchors::RightAnchor)) {
       
  1439         targetPrivate->anchors()->resetRight();
       
  1440         QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
       
  1441     }
       
  1442     if (d->applyOrigHCenter || (combined & QDeclarativeAnchors::HCenterAnchor)) {
       
  1443         targetPrivate->anchors()->resetHorizontalCenter();
       
  1444         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
       
  1445     }
       
  1446     if (d->applyOrigTop || (combined & QDeclarativeAnchors::TopAnchor)) {
       
  1447         targetPrivate->anchors()->resetTop();
       
  1448         QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
       
  1449     }
       
  1450     if (d->applyOrigBottom || (combined & QDeclarativeAnchors::BottomAnchor)) {
       
  1451         targetPrivate->anchors()->resetBottom();
       
  1452         QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
       
  1453     }
       
  1454     if (d->applyOrigVCenter || (combined & QDeclarativeAnchors::VCenterAnchor)) {
       
  1455         targetPrivate->anchors()->resetVerticalCenter();
       
  1456         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
       
  1457     }
       
  1458     if (d->applyOrigBaseline || (combined & QDeclarativeAnchors::BaselineAnchor)) {
       
  1459         targetPrivate->anchors()->resetBaseline();
       
  1460         QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
       
  1461     }
       
  1462 }
       
  1463 
       
  1464 bool QDeclarativeAnchorChanges::override(QDeclarativeActionEvent*other)
       
  1465 {
       
  1466     if (other->typeName() != QLatin1String("AnchorChanges"))
       
  1467         return false;
       
  1468     if (static_cast<QDeclarativeActionEvent*>(this) == other)
       
  1469         return true;
       
  1470     if (static_cast<QDeclarativeAnchorChanges*>(other)->object() == object())
       
  1471         return true;
       
  1472     return false;
       
  1473 }
       
  1474 
       
  1475 void QDeclarativeAnchorChanges::rewind()
       
  1476 {
       
  1477     Q_D(QDeclarativeAnchorChanges);
       
  1478     if (!d->target)
       
  1479         return;
       
  1480 
       
  1481     QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target);
       
  1482     //restore previous anchors
       
  1483     if (d->rewindLeft.anchorLine != QDeclarativeAnchorLine::Invalid)
       
  1484         targetPrivate->anchors()->setLeft(d->rewindLeft);
       
  1485     if (d->rewindRight.anchorLine != QDeclarativeAnchorLine::Invalid)
       
  1486         targetPrivate->anchors()->setRight(d->rewindRight);
       
  1487     if (d->rewindHCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
       
  1488         targetPrivate->anchors()->setHorizontalCenter(d->rewindHCenter);
       
  1489     if (d->rewindTop.anchorLine != QDeclarativeAnchorLine::Invalid)
       
  1490         targetPrivate->anchors()->setTop(d->rewindTop);
       
  1491     if (d->rewindBottom.anchorLine != QDeclarativeAnchorLine::Invalid)
       
  1492         targetPrivate->anchors()->setBottom(d->rewindBottom);
       
  1493     if (d->rewindVCenter.anchorLine != QDeclarativeAnchorLine::Invalid)
       
  1494         targetPrivate->anchors()->setVerticalCenter(d->rewindVCenter);
       
  1495     if (d->rewindBaseline.anchorLine != QDeclarativeAnchorLine::Invalid)
       
  1496         targetPrivate->anchors()->setBaseline(d->rewindBaseline);
       
  1497 
       
  1498     d->target->setX(d->rewindX);
       
  1499     d->target->setY(d->rewindY);
       
  1500     d->target->setWidth(d->rewindWidth);
       
  1501     d->target->setHeight(d->rewindHeight);
       
  1502 }
       
  1503 
       
  1504 void QDeclarativeAnchorChanges::saveCurrentValues()
       
  1505 {
       
  1506     Q_D(QDeclarativeAnchorChanges);
       
  1507     if (!d->target)
       
  1508         return;
       
  1509 
       
  1510     QDeclarativeItemPrivate *targetPrivate = QDeclarativeItemPrivate::get(d->target);
       
  1511     d->rewindLeft = targetPrivate->anchors()->left();
       
  1512     d->rewindRight = targetPrivate->anchors()->right();
       
  1513     d->rewindHCenter = targetPrivate->anchors()->horizontalCenter();
       
  1514     d->rewindTop = targetPrivate->anchors()->top();
       
  1515     d->rewindBottom = targetPrivate->anchors()->bottom();
       
  1516     d->rewindVCenter = targetPrivate->anchors()->verticalCenter();
       
  1517     d->rewindBaseline = targetPrivate->anchors()->baseline();
       
  1518 
       
  1519     d->rewindX = d->target->x();
       
  1520     d->rewindY = d->target->y();
       
  1521     d->rewindWidth = d->target->width();
       
  1522     d->rewindHeight = d->target->height();
       
  1523 }
       
  1524 
       
  1525 void QDeclarativeAnchorChanges::saveTargetValues()
       
  1526 {
       
  1527     Q_D(QDeclarativeAnchorChanges);
       
  1528     if (!d->target)
       
  1529         return;
       
  1530 
       
  1531     d->toX = d->target->x();
       
  1532     d->toY = d->target->y();
       
  1533     d->toWidth = d->target->width();
       
  1534     d->toHeight = d->target->height();
       
  1535 }
       
  1536 
       
  1537 #include <qdeclarativestateoperations.moc>
       
  1538 #include <moc_qdeclarativestateoperations_p.cpp>
       
  1539 
       
  1540 QT_END_NAMESPACE
       
  1541