Initial import from qtquick2.
[profile/ivi/qtdeclarative.git] / src / declarative / items / qsgstateoperations.cpp
1 // Commit: 726a8b16c52fe4608c89d740b47361a2b073ce01
2 /****************************************************************************
3 **
4 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
5 ** All rights reserved.
6 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 **
8 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 **
10 ** $QT_BEGIN_LICENSE:LGPL$
11 ** No Commercial Usage
12 ** This file contains pre-release code and may not be distributed.
13 ** You may use this file in accordance with the terms and conditions
14 ** contained in the Technology Preview License Agreement accompanying
15 ** this package.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 **
39 ** $QT_END_LICENSE$
40 **
41 ****************************************************************************/
42
43 #include "qsgstateoperations_p.h"
44 #include "qsgitem_p.h"
45
46 #include <private/qdeclarativestate_p_p.h>
47
48 #include <QtDeclarative/qdeclarativeinfo.h>
49 #include <QtCore/qmath.h>
50
51 QT_BEGIN_NAMESPACE
52
53 class QSGParentChangePrivate : public QDeclarativeStateOperationPrivate
54 {
55     Q_DECLARE_PUBLIC(QSGParentChange)
56 public:
57     QSGParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0),
58         rewindParent(0), rewindStackBefore(0) {}
59
60     QSGItem *target;
61     QDeclarativeGuard<QSGItem> parent;
62     QDeclarativeGuard<QSGItem> origParent;
63     QDeclarativeGuard<QSGItem> origStackBefore;
64     QSGItem *rewindParent;
65     QSGItem *rewindStackBefore;
66
67     QDeclarativeNullableValue<QDeclarativeScriptString> xString;
68     QDeclarativeNullableValue<QDeclarativeScriptString> yString;
69     QDeclarativeNullableValue<QDeclarativeScriptString> widthString;
70     QDeclarativeNullableValue<QDeclarativeScriptString> heightString;
71     QDeclarativeNullableValue<QDeclarativeScriptString> scaleString;
72     QDeclarativeNullableValue<QDeclarativeScriptString> rotationString;
73
74     void doChange(QSGItem *targetParent, QSGItem *stackBefore = 0);
75 };
76
77 void QSGParentChangePrivate::doChange(QSGItem *targetParent, QSGItem *stackBefore)
78 {
79     if (targetParent && target && target->parentItem()) {
80         Q_Q(QSGParentChange);
81         bool ok;
82         const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
83         if (transform.type() >= QTransform::TxShear || !ok) {
84             qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under complex transform");
85             ok = false;
86         }
87
88         qreal scale = 1;
89         qreal rotation = 0;
90         bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
91         if (ok && !isRotate) {
92             if (transform.m11() == transform.m22())
93                 scale = transform.m11();
94             else {
95                 qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under non-uniform scale");
96                 ok = false;
97             }
98         } else if (ok && isRotate) {
99             if (transform.m11() == transform.m22())
100                 scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
101             else {
102                 qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under non-uniform scale");
103                 ok = false;
104             }
105
106             if (scale != 0)
107                 rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
108             else {
109                 qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under scale of 0");
110                 ok = false;
111             }
112         }
113
114         const QPointF &point = transform.map(QPointF(target->x(),target->y()));
115         qreal x = point.x();
116         qreal y = point.y();
117
118         // setParentItem will update the transformOriginPoint if needed
119         target->setParentItem(targetParent);
120
121         if (ok && target->transformOrigin() != QSGItem::TopLeft) {
122             qreal tempxt = target->transformOriginPoint().x();
123             qreal tempyt = target->transformOriginPoint().y();
124             QTransform t;
125             t.translate(-tempxt, -tempyt);
126             t.rotate(rotation);
127             t.scale(scale, scale);
128             t.translate(tempxt, tempyt);
129             const QPointF &offset = t.map(QPointF(0,0));
130             x += offset.x();
131             y += offset.y();
132         }
133
134         if (ok) {
135             //qDebug() << x << y << rotation << scale;
136             target->setX(x);
137             target->setY(y);
138             target->setRotation(target->rotation() + rotation);
139             target->setScale(target->scale() * scale);
140         }
141     } else if (target) {
142         target->setParentItem(targetParent);
143     }
144
145     //restore the original stack position.
146     //### if stackBefore has also been reparented this won't work
147     if (stackBefore)
148         target->stackBefore(stackBefore);
149 }
150
151 QSGParentChange::QSGParentChange(QObject *parent)
152     : QDeclarativeStateOperation(*(new QSGParentChangePrivate), parent)
153 {
154 }
155
156 QSGParentChange::~QSGParentChange()
157 {
158 }
159
160 QDeclarativeScriptString QSGParentChange::x() const
161 {
162     Q_D(const QSGParentChange);
163     return d->xString.value;
164 }
165
166 void QSGParentChange::setX(QDeclarativeScriptString x)
167 {
168     Q_D(QSGParentChange);
169     d->xString = x;
170 }
171
172 bool QSGParentChange::xIsSet() const
173 {
174     Q_D(const QSGParentChange);
175     return d->xString.isValid();
176 }
177
178 QDeclarativeScriptString QSGParentChange::y() const
179 {
180     Q_D(const QSGParentChange);
181     return d->yString.value;
182 }
183
184 void QSGParentChange::setY(QDeclarativeScriptString y)
185 {
186     Q_D(QSGParentChange);
187     d->yString = y;
188 }
189
190 bool QSGParentChange::yIsSet() const
191 {
192     Q_D(const QSGParentChange);
193     return d->yString.isValid();
194 }
195
196 QDeclarativeScriptString QSGParentChange::width() const
197 {
198     Q_D(const QSGParentChange);
199     return d->widthString.value;
200 }
201
202 void QSGParentChange::setWidth(QDeclarativeScriptString width)
203 {
204     Q_D(QSGParentChange);
205     d->widthString = width;
206 }
207
208 bool QSGParentChange::widthIsSet() const
209 {
210     Q_D(const QSGParentChange);
211     return d->widthString.isValid();
212 }
213
214 QDeclarativeScriptString QSGParentChange::height() const
215 {
216     Q_D(const QSGParentChange);
217     return d->heightString.value;
218 }
219
220 void QSGParentChange::setHeight(QDeclarativeScriptString height)
221 {
222     Q_D(QSGParentChange);
223     d->heightString = height;
224 }
225
226 bool QSGParentChange::heightIsSet() const
227 {
228     Q_D(const QSGParentChange);
229     return d->heightString.isValid();
230 }
231
232 QDeclarativeScriptString QSGParentChange::scale() const
233 {
234     Q_D(const QSGParentChange);
235     return d->scaleString.value;
236 }
237
238 void QSGParentChange::setScale(QDeclarativeScriptString scale)
239 {
240     Q_D(QSGParentChange);
241     d->scaleString = scale;
242 }
243
244 bool QSGParentChange::scaleIsSet() const
245 {
246     Q_D(const QSGParentChange);
247     return d->scaleString.isValid();
248 }
249
250 QDeclarativeScriptString QSGParentChange::rotation() const
251 {
252     Q_D(const QSGParentChange);
253     return d->rotationString.value;
254 }
255
256 void QSGParentChange::setRotation(QDeclarativeScriptString rotation)
257 {
258     Q_D(QSGParentChange);
259     d->rotationString = rotation;
260 }
261
262 bool QSGParentChange::rotationIsSet() const
263 {
264     Q_D(const QSGParentChange);
265     return d->rotationString.isValid();
266 }
267
268 QSGItem *QSGParentChange::originalParent() const
269 {
270     Q_D(const QSGParentChange);
271     return d->origParent;
272 }
273
274 QSGItem *QSGParentChange::object() const
275 {
276     Q_D(const QSGParentChange);
277     return d->target;
278 }
279
280 void QSGParentChange::setObject(QSGItem *target)
281 {
282     Q_D(QSGParentChange);
283     d->target = target;
284 }
285
286 QSGItem *QSGParentChange::parent() const
287 {
288     Q_D(const QSGParentChange);
289     return d->parent;
290 }
291
292 void QSGParentChange::setParent(QSGItem *parent)
293 {
294     Q_D(QSGParentChange);
295     d->parent = parent;
296 }
297
298 QDeclarativeStateOperation::ActionList QSGParentChange::actions()
299 {
300     Q_D(QSGParentChange);
301     if (!d->target || !d->parent)
302         return ActionList();
303
304     ActionList actions;
305
306     QDeclarativeAction a;
307     a.event = this;
308     actions << a;
309
310     if (d->xString.isValid()) {
311         bool ok = false;
312         QString script = d->xString.value.script();
313         qreal x = script.toFloat(&ok);
314         if (ok) {
315             QDeclarativeAction xa(d->target, QLatin1String("x"), x);
316             actions << xa;
317         } else {
318             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
319             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("x")));
320             QDeclarativeAction xa;
321             xa.property = newBinding->property();
322             xa.toBinding = newBinding;
323             xa.fromValue = xa.property.read();
324             xa.deletableToBinding = true;
325             actions << xa;
326         }
327     }
328
329     if (d->yString.isValid()) {
330         bool ok = false;
331         QString script = d->yString.value.script();
332         qreal y = script.toFloat(&ok);
333         if (ok) {
334             QDeclarativeAction ya(d->target, QLatin1String("y"), y);
335             actions << ya;
336         } else {
337             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
338             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("y")));
339             QDeclarativeAction ya;
340             ya.property = newBinding->property();
341             ya.toBinding = newBinding;
342             ya.fromValue = ya.property.read();
343             ya.deletableToBinding = true;
344             actions << ya;
345         }
346     }
347
348     if (d->scaleString.isValid()) {
349         bool ok = false;
350         QString script = d->scaleString.value.script();
351         qreal scale = script.toFloat(&ok);
352         if (ok) {
353             QDeclarativeAction sa(d->target, QLatin1String("scale"), scale);
354             actions << sa;
355         } else {
356             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
357             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("scale")));
358             QDeclarativeAction sa;
359             sa.property = newBinding->property();
360             sa.toBinding = newBinding;
361             sa.fromValue = sa.property.read();
362             sa.deletableToBinding = true;
363             actions << sa;
364         }
365     }
366
367     if (d->rotationString.isValid()) {
368         bool ok = false;
369         QString script = d->rotationString.value.script();
370         qreal rotation = script.toFloat(&ok);
371         if (ok) {
372             QDeclarativeAction ra(d->target, QLatin1String("rotation"), rotation);
373             actions << ra;
374         } else {
375             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
376             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("rotation")));
377             QDeclarativeAction ra;
378             ra.property = newBinding->property();
379             ra.toBinding = newBinding;
380             ra.fromValue = ra.property.read();
381             ra.deletableToBinding = true;
382             actions << ra;
383         }
384     }
385
386     if (d->widthString.isValid()) {
387         bool ok = false;
388         QString script = d->widthString.value.script();
389         qreal width = script.toFloat(&ok);
390         if (ok) {
391             QDeclarativeAction wa(d->target, QLatin1String("width"), width);
392             actions << wa;
393         } else {
394             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
395             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("width")));
396             QDeclarativeAction wa;
397             wa.property = newBinding->property();
398             wa.toBinding = newBinding;
399             wa.fromValue = wa.property.read();
400             wa.deletableToBinding = true;
401             actions << wa;
402         }
403     }
404
405     if (d->heightString.isValid()) {
406         bool ok = false;
407         QString script = d->heightString.value.script();
408         qreal height = script.toFloat(&ok);
409         if (ok) {
410             QDeclarativeAction ha(d->target, QLatin1String("height"), height);
411             actions << ha;
412         } else {
413             QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
414             newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("height")));
415             QDeclarativeAction ha;
416             ha.property = newBinding->property();
417             ha.toBinding = newBinding;
418             ha.fromValue = ha.property.read();
419             ha.deletableToBinding = true;
420             actions << ha;
421         }
422     }
423
424     return actions;
425 }
426
427 void QSGParentChange::saveOriginals()
428 {
429     Q_D(QSGParentChange);
430     saveCurrentValues();
431     d->origParent = d->rewindParent;
432     d->origStackBefore = d->rewindStackBefore;
433 }
434
435 /*void QSGParentChange::copyOriginals(QDeclarativeActionEvent *other)
436 {
437     Q_D(QSGParentChange);
438     QSGParentChange *pc = static_cast<QSGParentChange*>(other);
439
440     d->origParent = pc->d_func()->rewindParent;
441     d->origStackBefore = pc->d_func()->rewindStackBefore;
442
443     saveCurrentValues();
444 }*/
445
446 void QSGParentChange::execute(Reason)
447 {
448     Q_D(QSGParentChange);
449     d->doChange(d->parent);
450 }
451
452 bool QSGParentChange::isReversable()
453 {
454     return true;
455 }
456
457 void QSGParentChange::reverse(Reason)
458 {
459     Q_D(QSGParentChange);
460     d->doChange(d->origParent, d->origStackBefore);
461 }
462
463 QString QSGParentChange::typeName() const
464 {
465     return QLatin1String("ParentChange");
466 }
467
468 bool QSGParentChange::override(QDeclarativeActionEvent*other)
469 {
470     Q_D(QSGParentChange);
471     if (other->typeName() != QLatin1String("ParentChange"))
472         return false;
473     if (QSGParentChange *otherPC = static_cast<QSGParentChange*>(other))
474         return (d->target == otherPC->object());
475     return false;
476 }
477
478 void QSGParentChange::saveCurrentValues()
479 {
480     Q_D(QSGParentChange);
481     if (!d->target) {
482         d->rewindParent = 0;
483         d->rewindStackBefore = 0;
484         return;
485     }
486
487     d->rewindParent = d->target->parentItem();
488     d->rewindStackBefore = 0;
489
490     if (!d->rewindParent)
491         return;
492
493     QList<QSGItem *> children = d->rewindParent->childItems();
494     for (int ii = 0; ii < children.count() - 1; ++ii) {
495         if (children.at(ii) == d->target) {
496             d->rewindStackBefore = children.at(ii + 1);
497             break;
498         }
499     }
500 }
501
502 void QSGParentChange::rewind()
503 {
504     Q_D(QSGParentChange);
505     d->doChange(d->rewindParent, d->rewindStackBefore);
506 }
507
508 class QSGAnchorSetPrivate : public QObjectPrivate
509 {
510     Q_DECLARE_PUBLIC(QSGAnchorSet)
511 public:
512     QSGAnchorSetPrivate()
513       : usedAnchors(0), resetAnchors(0), fill(0),
514         centerIn(0)/*, leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0),
515         margins(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0)*/
516     {
517     }
518
519     QSGAnchors::Anchors usedAnchors;
520     QSGAnchors::Anchors resetAnchors;
521
522     QSGItem *fill;
523     QSGItem *centerIn;
524
525     QDeclarativeScriptString leftScript;
526     QDeclarativeScriptString rightScript;
527     QDeclarativeScriptString topScript;
528     QDeclarativeScriptString bottomScript;
529     QDeclarativeScriptString hCenterScript;
530     QDeclarativeScriptString vCenterScript;
531     QDeclarativeScriptString baselineScript;
532
533     /*qreal leftMargin;
534     qreal rightMargin;
535     qreal topMargin;
536     qreal bottomMargin;
537     qreal margins;
538     qreal vCenterOffset;
539     qreal hCenterOffset;
540     qreal baselineOffset;*/
541 };
542
543 QSGAnchorSet::QSGAnchorSet(QObject *parent)
544   : QObject(*new QSGAnchorSetPrivate, parent)
545 {
546 }
547
548 QSGAnchorSet::~QSGAnchorSet()
549 {
550 }
551
552 QDeclarativeScriptString QSGAnchorSet::top() const
553 {
554     Q_D(const QSGAnchorSet);
555     return d->topScript;
556 }
557
558 void QSGAnchorSet::setTop(const QDeclarativeScriptString &edge)
559 {
560     Q_D(QSGAnchorSet);
561     d->usedAnchors |= QSGAnchors::TopAnchor;
562     d->topScript = edge;
563     if (edge.script() == QLatin1String("undefined"))
564         resetTop();
565 }
566
567 void QSGAnchorSet::resetTop()
568 {
569     Q_D(QSGAnchorSet);
570     d->usedAnchors &= ~QSGAnchors::TopAnchor;
571     d->topScript = QDeclarativeScriptString();
572     d->resetAnchors |= QSGAnchors::TopAnchor;
573 }
574
575 QDeclarativeScriptString QSGAnchorSet::bottom() const
576 {
577     Q_D(const QSGAnchorSet);
578     return d->bottomScript;
579 }
580
581 void QSGAnchorSet::setBottom(const QDeclarativeScriptString &edge)
582 {
583     Q_D(QSGAnchorSet);
584     d->usedAnchors |= QSGAnchors::BottomAnchor;
585     d->bottomScript = edge;
586     if (edge.script() == QLatin1String("undefined"))
587         resetBottom();
588 }
589
590 void QSGAnchorSet::resetBottom()
591 {
592     Q_D(QSGAnchorSet);
593     d->usedAnchors &= ~QSGAnchors::BottomAnchor;
594     d->bottomScript = QDeclarativeScriptString();
595     d->resetAnchors |= QSGAnchors::BottomAnchor;
596 }
597
598 QDeclarativeScriptString QSGAnchorSet::verticalCenter() const
599 {
600     Q_D(const QSGAnchorSet);
601     return d->vCenterScript;
602 }
603
604 void QSGAnchorSet::setVerticalCenter(const QDeclarativeScriptString &edge)
605 {
606     Q_D(QSGAnchorSet);
607     d->usedAnchors |= QSGAnchors::VCenterAnchor;
608     d->vCenterScript = edge;
609     if (edge.script() == QLatin1String("undefined"))
610         resetVerticalCenter();
611 }
612
613 void QSGAnchorSet::resetVerticalCenter()
614 {
615     Q_D(QSGAnchorSet);
616     d->usedAnchors &= ~QSGAnchors::VCenterAnchor;
617     d->vCenterScript = QDeclarativeScriptString();
618     d->resetAnchors |= QSGAnchors::VCenterAnchor;
619 }
620
621 QDeclarativeScriptString QSGAnchorSet::baseline() const
622 {
623     Q_D(const QSGAnchorSet);
624     return d->baselineScript;
625 }
626
627 void QSGAnchorSet::setBaseline(const QDeclarativeScriptString &edge)
628 {
629     Q_D(QSGAnchorSet);
630     d->usedAnchors |= QSGAnchors::BaselineAnchor;
631     d->baselineScript = edge;
632     if (edge.script() == QLatin1String("undefined"))
633         resetBaseline();
634 }
635
636 void QSGAnchorSet::resetBaseline()
637 {
638     Q_D(QSGAnchorSet);
639     d->usedAnchors &= ~QSGAnchors::BaselineAnchor;
640     d->baselineScript = QDeclarativeScriptString();
641     d->resetAnchors |= QSGAnchors::BaselineAnchor;
642 }
643
644 QDeclarativeScriptString QSGAnchorSet::left() const
645 {
646     Q_D(const QSGAnchorSet);
647     return d->leftScript;
648 }
649
650 void QSGAnchorSet::setLeft(const QDeclarativeScriptString &edge)
651 {
652     Q_D(QSGAnchorSet);
653     d->usedAnchors |= QSGAnchors::LeftAnchor;
654     d->leftScript = edge;
655     if (edge.script() == QLatin1String("undefined"))
656         resetLeft();
657 }
658
659 void QSGAnchorSet::resetLeft()
660 {
661     Q_D(QSGAnchorSet);
662     d->usedAnchors &= ~QSGAnchors::LeftAnchor;
663     d->leftScript = QDeclarativeScriptString();
664     d->resetAnchors |= QSGAnchors::LeftAnchor;
665 }
666
667 QDeclarativeScriptString QSGAnchorSet::right() const
668 {
669     Q_D(const QSGAnchorSet);
670     return d->rightScript;
671 }
672
673 void QSGAnchorSet::setRight(const QDeclarativeScriptString &edge)
674 {
675     Q_D(QSGAnchorSet);
676     d->usedAnchors |= QSGAnchors::RightAnchor;
677     d->rightScript = edge;
678     if (edge.script() == QLatin1String("undefined"))
679         resetRight();
680 }
681
682 void QSGAnchorSet::resetRight()
683 {
684     Q_D(QSGAnchorSet);
685     d->usedAnchors &= ~QSGAnchors::RightAnchor;
686     d->rightScript = QDeclarativeScriptString();
687     d->resetAnchors |= QSGAnchors::RightAnchor;
688 }
689
690 QDeclarativeScriptString QSGAnchorSet::horizontalCenter() const
691 {
692     Q_D(const QSGAnchorSet);
693     return d->hCenterScript;
694 }
695
696 void QSGAnchorSet::setHorizontalCenter(const QDeclarativeScriptString &edge)
697 {
698     Q_D(QSGAnchorSet);
699     d->usedAnchors |= QSGAnchors::HCenterAnchor;
700     d->hCenterScript = edge;
701     if (edge.script() == QLatin1String("undefined"))
702         resetHorizontalCenter();
703 }
704
705 void QSGAnchorSet::resetHorizontalCenter()
706 {
707     Q_D(QSGAnchorSet);
708     d->usedAnchors &= ~QSGAnchors::HCenterAnchor;
709     d->hCenterScript = QDeclarativeScriptString();
710     d->resetAnchors |= QSGAnchors::HCenterAnchor;
711 }
712
713 QSGItem *QSGAnchorSet::fill() const
714 {
715     Q_D(const QSGAnchorSet);
716     return d->fill;
717 }
718
719 void QSGAnchorSet::setFill(QSGItem *f)
720 {
721     Q_D(QSGAnchorSet);
722     d->fill = f;
723 }
724
725 void QSGAnchorSet::resetFill()
726 {
727     setFill(0);
728 }
729
730 QSGItem *QSGAnchorSet::centerIn() const
731 {
732     Q_D(const QSGAnchorSet);
733     return d->centerIn;
734 }
735
736 void QSGAnchorSet::setCenterIn(QSGItem* c)
737 {
738     Q_D(QSGAnchorSet);
739     d->centerIn = c;
740 }
741
742 void QSGAnchorSet::resetCenterIn()
743 {
744     setCenterIn(0);
745 }
746
747
748 class QSGAnchorChangesPrivate : public QDeclarativeStateOperationPrivate
749 {
750 public:
751     QSGAnchorChangesPrivate()
752         : target(0), anchorSet(new QSGAnchorSet),
753           leftBinding(0), rightBinding(0), hCenterBinding(0),
754           topBinding(0), bottomBinding(0), vCenterBinding(0), baselineBinding(0),
755           origLeftBinding(0), origRightBinding(0), origHCenterBinding(0),
756           origTopBinding(0), origBottomBinding(0), origVCenterBinding(0),
757           origBaselineBinding(0)
758     {
759
760     }
761     ~QSGAnchorChangesPrivate() { delete anchorSet; }
762
763     QSGItem *target;
764     QSGAnchorSet *anchorSet;
765
766     QDeclarativeBinding *leftBinding;
767     QDeclarativeBinding *rightBinding;
768     QDeclarativeBinding *hCenterBinding;
769     QDeclarativeBinding *topBinding;
770     QDeclarativeBinding *bottomBinding;
771     QDeclarativeBinding *vCenterBinding;
772     QDeclarativeBinding *baselineBinding;
773
774     QDeclarativeAbstractBinding *origLeftBinding;
775     QDeclarativeAbstractBinding *origRightBinding;
776     QDeclarativeAbstractBinding *origHCenterBinding;
777     QDeclarativeAbstractBinding *origTopBinding;
778     QDeclarativeAbstractBinding *origBottomBinding;
779     QDeclarativeAbstractBinding *origVCenterBinding;
780     QDeclarativeAbstractBinding *origBaselineBinding;
781
782     QSGAnchorLine rewindLeft;
783     QSGAnchorLine rewindRight;
784     QSGAnchorLine rewindHCenter;
785     QSGAnchorLine rewindTop;
786     QSGAnchorLine rewindBottom;
787     QSGAnchorLine rewindVCenter;
788     QSGAnchorLine rewindBaseline;
789
790     qreal fromX;
791     qreal fromY;
792     qreal fromWidth;
793     qreal fromHeight;
794
795     qreal toX;
796     qreal toY;
797     qreal toWidth;
798     qreal toHeight;
799
800     qreal rewindX;
801     qreal rewindY;
802     qreal rewindWidth;
803     qreal rewindHeight;
804
805     bool applyOrigLeft;
806     bool applyOrigRight;
807     bool applyOrigHCenter;
808     bool applyOrigTop;
809     bool applyOrigBottom;
810     bool applyOrigVCenter;
811     bool applyOrigBaseline;
812
813     QDeclarativeNullableValue<qreal> origWidth;
814     QDeclarativeNullableValue<qreal> origHeight;
815     qreal origX;
816     qreal origY;
817
818     QList<QDeclarativeAbstractBinding*> oldBindings;
819
820     QDeclarativeProperty leftProp;
821     QDeclarativeProperty rightProp;
822     QDeclarativeProperty hCenterProp;
823     QDeclarativeProperty topProp;
824     QDeclarativeProperty bottomProp;
825     QDeclarativeProperty vCenterProp;
826     QDeclarativeProperty baselineProp;
827 };
828
829 QSGAnchorChanges::QSGAnchorChanges(QObject *parent)
830  : QDeclarativeStateOperation(*(new QSGAnchorChangesPrivate), parent)
831 {
832 }
833
834 QSGAnchorChanges::~QSGAnchorChanges()
835 {
836 }
837
838 QSGAnchorChanges::ActionList QSGAnchorChanges::actions()
839 {
840     Q_D(QSGAnchorChanges);
841     d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding
842                    = d->bottomBinding = d->vCenterBinding = d->baselineBinding = 0;
843
844     d->leftProp = QDeclarativeProperty(d->target, QLatin1String("anchors.left"));
845     d->rightProp = QDeclarativeProperty(d->target, QLatin1String("anchors.right"));
846     d->hCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.horizontalCenter"));
847     d->topProp = QDeclarativeProperty(d->target, QLatin1String("anchors.top"));
848     d->bottomProp = QDeclarativeProperty(d->target, QLatin1String("anchors.bottom"));
849     d->vCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.verticalCenter"));
850     d->baselineProp = QDeclarativeProperty(d->target, QLatin1String("anchors.baseline"));
851
852     if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::LeftAnchor) {
853         d->leftBinding = new QDeclarativeBinding(d->anchorSet->d_func()->leftScript.script(), d->target, qmlContext(this));
854         d->leftBinding->setTarget(d->leftProp);
855     }
856     if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::RightAnchor) {
857         d->rightBinding = new QDeclarativeBinding(d->anchorSet->d_func()->rightScript.script(), d->target, qmlContext(this));
858         d->rightBinding->setTarget(d->rightProp);
859     }
860     if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::HCenterAnchor) {
861         d->hCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->hCenterScript.script(), d->target, qmlContext(this));
862         d->hCenterBinding->setTarget(d->hCenterProp);
863     }
864     if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::TopAnchor) {
865         d->topBinding = new QDeclarativeBinding(d->anchorSet->d_func()->topScript.script(), d->target, qmlContext(this));
866         d->topBinding->setTarget(d->topProp);
867     }
868     if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::BottomAnchor) {
869         d->bottomBinding = new QDeclarativeBinding(d->anchorSet->d_func()->bottomScript.script(), d->target, qmlContext(this));
870         d->bottomBinding->setTarget(d->bottomProp);
871     }
872     if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::VCenterAnchor) {
873         d->vCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->vCenterScript.script(), d->target, qmlContext(this));
874         d->vCenterBinding->setTarget(d->vCenterProp);
875     }
876     if (d->anchorSet->d_func()->usedAnchors & QSGAnchors::BaselineAnchor) {
877         d->baselineBinding = new QDeclarativeBinding(d->anchorSet->d_func()->baselineScript.script(), d->target, qmlContext(this));
878         d->baselineBinding->setTarget(d->baselineProp);
879     }
880
881     QDeclarativeAction a;
882     a.event = this;
883     return ActionList() << a;
884 }
885
886 QSGAnchorSet *QSGAnchorChanges::anchors()
887 {
888     Q_D(QSGAnchorChanges);
889     return d->anchorSet;
890 }
891
892 QSGItem *QSGAnchorChanges::object() const
893 {
894     Q_D(const QSGAnchorChanges);
895     return d->target;
896 }
897
898 void QSGAnchorChanges::setObject(QSGItem *target)
899 {
900     Q_D(QSGAnchorChanges);
901     d->target = target;
902 }
903
904 void QSGAnchorChanges::execute(Reason reason)
905 {
906     Q_D(QSGAnchorChanges);
907     if (!d->target)
908         return;
909
910     QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
911     //incorporate any needed "reverts"
912     if (d->applyOrigLeft) {
913         if (!d->origLeftBinding)
914             targetPrivate->anchors()->resetLeft();
915         QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
916     }
917     if (d->applyOrigRight) {
918         if (!d->origRightBinding)
919             targetPrivate->anchors()->resetRight();
920         QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
921     }
922     if (d->applyOrigHCenter) {
923         if (!d->origHCenterBinding)
924             targetPrivate->anchors()->resetHorizontalCenter();
925         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
926     }
927     if (d->applyOrigTop) {
928         if (!d->origTopBinding)
929             targetPrivate->anchors()->resetTop();
930         QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
931     }
932     if (d->applyOrigBottom) {
933         if (!d->origBottomBinding)
934             targetPrivate->anchors()->resetBottom();
935         QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
936     }
937     if (d->applyOrigVCenter) {
938         if (!d->origVCenterBinding)
939             targetPrivate->anchors()->resetVerticalCenter();
940         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
941     }
942     if (d->applyOrigBaseline) {
943         if (!d->origBaselineBinding)
944             targetPrivate->anchors()->resetBaseline();
945         QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
946     }
947
948     //destroy old bindings
949     if (reason == ActualChange) {
950         for (int i = 0; i < d->oldBindings.size(); ++i) {
951             QDeclarativeAbstractBinding *binding = d->oldBindings.at(i);
952             if (binding)
953                 binding->destroy();
954         }
955         d->oldBindings.clear();
956     }
957
958     //reset any anchors that have been specified as "undefined"
959     if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::LeftAnchor) {
960         targetPrivate->anchors()->resetLeft();
961         QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
962     }
963     if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::RightAnchor) {
964         targetPrivate->anchors()->resetRight();
965         QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
966     }
967     if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::HCenterAnchor) {
968         targetPrivate->anchors()->resetHorizontalCenter();
969         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
970     }
971     if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::TopAnchor) {
972         targetPrivate->anchors()->resetTop();
973         QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
974     }
975     if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::BottomAnchor) {
976         targetPrivate->anchors()->resetBottom();
977         QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
978     }
979     if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::VCenterAnchor) {
980         targetPrivate->anchors()->resetVerticalCenter();
981         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
982     }
983     if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::BaselineAnchor) {
984         targetPrivate->anchors()->resetBaseline();
985         QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
986     }
987
988     //set any anchors that have been specified
989     if (d->leftBinding)
990         QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), d->leftBinding);
991     if (d->rightBinding)
992         QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), d->rightBinding);
993     if (d->hCenterBinding)
994         QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), d->hCenterBinding);
995     if (d->topBinding)
996         QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), d->topBinding);
997     if (d->bottomBinding)
998         QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), d->bottomBinding);
999     if (d->vCenterBinding)
1000         QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), d->vCenterBinding);
1001     if (d->baselineBinding)
1002         QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), d->baselineBinding);
1003 }
1004
1005 bool QSGAnchorChanges::isReversable()
1006 {
1007     return true;
1008 }
1009
1010 void QSGAnchorChanges::reverse(Reason reason)
1011 {
1012     Q_D(QSGAnchorChanges);
1013     if (!d->target)
1014         return;
1015
1016     QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
1017     //reset any anchors set by the state
1018     if (d->leftBinding) {
1019         targetPrivate->anchors()->resetLeft();
1020         QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), 0);
1021         if (reason == ActualChange) {
1022             d->leftBinding->destroy(); d->leftBinding = 0;
1023         }
1024     }
1025     if (d->rightBinding) {
1026         targetPrivate->anchors()->resetRight();
1027         QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), 0);
1028         if (reason == ActualChange) {
1029             d->rightBinding->destroy(); d->rightBinding = 0;
1030         }
1031     }
1032     if (d->hCenterBinding) {
1033         targetPrivate->anchors()->resetHorizontalCenter();
1034         QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), 0);
1035         if (reason == ActualChange) {
1036             d->hCenterBinding->destroy(); d->hCenterBinding = 0;
1037         }
1038     }
1039     if (d->topBinding) {
1040         targetPrivate->anchors()->resetTop();
1041         QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), 0);
1042         if (reason == ActualChange) {
1043             d->topBinding->destroy(); d->topBinding = 0;
1044         }
1045     }
1046     if (d->bottomBinding) {
1047         targetPrivate->anchors()->resetBottom();
1048         QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), 0);
1049         if (reason == ActualChange) {
1050             d->bottomBinding->destroy(); d->bottomBinding = 0;
1051         }
1052     }
1053     if (d->vCenterBinding) {
1054         targetPrivate->anchors()->resetVerticalCenter();
1055         QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), 0);
1056         if (reason == ActualChange) {
1057             d->vCenterBinding->destroy(); d->vCenterBinding = 0;
1058         }
1059     }
1060     if (d->baselineBinding) {
1061         targetPrivate->anchors()->resetBaseline();
1062         QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), 0);
1063         if (reason == ActualChange) {
1064             d->baselineBinding->destroy(); d->baselineBinding = 0;
1065         }
1066     }
1067
1068     //restore previous anchors
1069     if (d->origLeftBinding)
1070         QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
1071     if (d->origRightBinding)
1072         QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
1073     if (d->origHCenterBinding)
1074         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
1075     if (d->origTopBinding)
1076         QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
1077     if (d->origBottomBinding)
1078         QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
1079     if (d->origVCenterBinding)
1080         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
1081     if (d->origBaselineBinding)
1082         QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
1083
1084     //restore any absolute geometry changed by the state's anchors
1085     QSGAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QSGAnchors::Vertical_Mask;
1086     QSGAnchors::Anchors origVAnchors = targetPrivate->anchors()->usedAnchors() & QSGAnchors::Vertical_Mask;
1087     QSGAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QSGAnchors::Horizontal_Mask;
1088     QSGAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QSGAnchors::Horizontal_Mask;
1089
1090     bool stateSetWidth = (stateHAnchors &&
1091                           stateHAnchors != QSGAnchors::LeftAnchor &&
1092                           stateHAnchors != QSGAnchors::RightAnchor &&
1093                           stateHAnchors != QSGAnchors::HCenterAnchor);
1094     bool origSetWidth = (origHAnchors &&
1095                          origHAnchors != QSGAnchors::LeftAnchor &&
1096                          origHAnchors != QSGAnchors::RightAnchor &&
1097                          origHAnchors != QSGAnchors::HCenterAnchor);
1098     if (d->origWidth.isValid() && stateSetWidth && !origSetWidth)
1099         d->target->setWidth(d->origWidth.value);
1100
1101     bool stateSetHeight = (stateVAnchors &&
1102                            stateVAnchors != QSGAnchors::TopAnchor &&
1103                            stateVAnchors != QSGAnchors::BottomAnchor &&
1104                            stateVAnchors != QSGAnchors::VCenterAnchor &&
1105                            stateVAnchors != QSGAnchors::BaselineAnchor);
1106     bool origSetHeight = (origVAnchors &&
1107                           origVAnchors != QSGAnchors::TopAnchor &&
1108                           origVAnchors != QSGAnchors::BottomAnchor &&
1109                           origVAnchors != QSGAnchors::VCenterAnchor &&
1110                           origVAnchors != QSGAnchors::BaselineAnchor);
1111     if (d->origHeight.isValid() && stateSetHeight && !origSetHeight)
1112         d->target->setHeight(d->origHeight.value);
1113
1114     if (stateHAnchors && !origHAnchors)
1115         d->target->setX(d->origX);
1116
1117     if (stateVAnchors && !origVAnchors)
1118         d->target->setY(d->origY);
1119 }
1120
1121 QString QSGAnchorChanges::typeName() const
1122 {
1123     return QLatin1String("AnchorChanges");
1124 }
1125
1126 QList<QDeclarativeAction> QSGAnchorChanges::additionalActions()
1127 {
1128     Q_D(QSGAnchorChanges);
1129     QList<QDeclarativeAction> extra;
1130
1131     QSGAnchors::Anchors combined = d->anchorSet->d_func()->usedAnchors | d->anchorSet->d_func()->resetAnchors;
1132     bool hChange = combined & QSGAnchors::Horizontal_Mask;
1133     bool vChange = combined & QSGAnchors::Vertical_Mask;
1134
1135     if (d->target) {
1136         QDeclarativeAction a;
1137         if (hChange && d->fromX != d->toX) {
1138             a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
1139             a.toValue = d->toX;
1140             extra << a;
1141         }
1142         if (vChange && d->fromY != d->toY) {
1143             a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
1144             a.toValue = d->toY;
1145             extra << a;
1146         }
1147         if (hChange && d->fromWidth != d->toWidth) {
1148             a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
1149             a.toValue = d->toWidth;
1150             extra << a;
1151         }
1152         if (vChange && d->fromHeight != d->toHeight) {
1153             a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
1154             a.toValue = d->toHeight;
1155             extra << a;
1156         }
1157     }
1158
1159     return extra;
1160 }
1161
1162 bool QSGAnchorChanges::changesBindings()
1163 {
1164     return true;
1165 }
1166
1167 void QSGAnchorChanges::saveOriginals()
1168 {
1169     Q_D(QSGAnchorChanges);
1170     if (!d->target)
1171         return;
1172
1173     d->origLeftBinding = QDeclarativePropertyPrivate::binding(d->leftProp);
1174     d->origRightBinding = QDeclarativePropertyPrivate::binding(d->rightProp);
1175     d->origHCenterBinding = QDeclarativePropertyPrivate::binding(d->hCenterProp);
1176     d->origTopBinding = QDeclarativePropertyPrivate::binding(d->topProp);
1177     d->origBottomBinding = QDeclarativePropertyPrivate::binding(d->bottomProp);
1178     d->origVCenterBinding = QDeclarativePropertyPrivate::binding(d->vCenterProp);
1179     d->origBaselineBinding = QDeclarativePropertyPrivate::binding(d->baselineProp);
1180
1181     QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
1182     if (targetPrivate->widthValid)
1183         d->origWidth = d->target->width();
1184     if (targetPrivate->heightValid)
1185         d->origHeight = d->target->height();
1186     d->origX = d->target->x();
1187     d->origY = d->target->y();
1188
1189     d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
1190       = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false;
1191
1192     saveCurrentValues();
1193 }
1194
1195 void QSGAnchorChanges::copyOriginals(QDeclarativeActionEvent *other)
1196 {
1197     Q_D(QSGAnchorChanges);
1198     QSGAnchorChanges *ac = static_cast<QSGAnchorChanges*>(other);
1199     QSGAnchorChangesPrivate *acp = ac->d_func();
1200
1201     QSGAnchors::Anchors combined = acp->anchorSet->d_func()->usedAnchors |
1202                                             acp->anchorSet->d_func()->resetAnchors;
1203
1204     //probably also need to revert some things
1205     d->applyOrigLeft = (combined & QSGAnchors::LeftAnchor);
1206     d->applyOrigRight = (combined & QSGAnchors::RightAnchor);
1207     d->applyOrigHCenter = (combined & QSGAnchors::HCenterAnchor);
1208     d->applyOrigTop = (combined & QSGAnchors::TopAnchor);
1209     d->applyOrigBottom = (combined & QSGAnchors::BottomAnchor);
1210     d->applyOrigVCenter = (combined & QSGAnchors::VCenterAnchor);
1211     d->applyOrigBaseline = (combined & QSGAnchors::BaselineAnchor);
1212
1213     d->origLeftBinding = acp->origLeftBinding;
1214     d->origRightBinding = acp->origRightBinding;
1215     d->origHCenterBinding = acp->origHCenterBinding;
1216     d->origTopBinding = acp->origTopBinding;
1217     d->origBottomBinding = acp->origBottomBinding;
1218     d->origVCenterBinding = acp->origVCenterBinding;
1219     d->origBaselineBinding = acp->origBaselineBinding;
1220
1221     d->origWidth = acp->origWidth;
1222     d->origHeight = acp->origHeight;
1223     d->origX = acp->origX;
1224     d->origY = acp->origY;
1225
1226     d->oldBindings.clear();
1227     d->oldBindings << acp->leftBinding << acp->rightBinding << acp->hCenterBinding
1228                 << acp->topBinding << acp->bottomBinding << acp->baselineBinding;
1229
1230     saveCurrentValues();
1231 }
1232
1233 void QSGAnchorChanges::clearBindings()
1234 {
1235     Q_D(QSGAnchorChanges);
1236     if (!d->target)
1237         return;
1238
1239     //### should this (saving "from" values) be moved to saveCurrentValues()?
1240     d->fromX = d->target->x();
1241     d->fromY = d->target->y();
1242     d->fromWidth = d->target->width();
1243     d->fromHeight = d->target->height();
1244
1245     QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
1246     //reset any anchors with corresponding reverts
1247     //reset any anchors that have been specified as "undefined"
1248     //reset any anchors that we'll be setting in the state
1249     QSGAnchors::Anchors combined = d->anchorSet->d_func()->resetAnchors |
1250                                             d->anchorSet->d_func()->usedAnchors;
1251     if (d->applyOrigLeft || (combined & QSGAnchors::LeftAnchor)) {
1252         targetPrivate->anchors()->resetLeft();
1253         QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
1254     }
1255     if (d->applyOrigRight || (combined & QSGAnchors::RightAnchor)) {
1256         targetPrivate->anchors()->resetRight();
1257         QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
1258     }
1259     if (d->applyOrigHCenter || (combined & QSGAnchors::HCenterAnchor)) {
1260         targetPrivate->anchors()->resetHorizontalCenter();
1261         QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
1262     }
1263     if (d->applyOrigTop || (combined & QSGAnchors::TopAnchor)) {
1264         targetPrivate->anchors()->resetTop();
1265         QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
1266     }
1267     if (d->applyOrigBottom || (combined & QSGAnchors::BottomAnchor)) {
1268         targetPrivate->anchors()->resetBottom();
1269         QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
1270     }
1271     if (d->applyOrigVCenter || (combined & QSGAnchors::VCenterAnchor)) {
1272         targetPrivate->anchors()->resetVerticalCenter();
1273         QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
1274     }
1275     if (d->applyOrigBaseline || (combined & QSGAnchors::BaselineAnchor)) {
1276         targetPrivate->anchors()->resetBaseline();
1277         QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
1278     }
1279 }
1280
1281 bool QSGAnchorChanges::override(QDeclarativeActionEvent*other)
1282 {
1283     if (other->typeName() != QLatin1String("AnchorChanges"))
1284         return false;
1285     if (static_cast<QDeclarativeActionEvent*>(this) == other)
1286         return true;
1287     if (static_cast<QSGAnchorChanges*>(other)->object() == object())
1288         return true;
1289     return false;
1290 }
1291
1292 void QSGAnchorChanges::rewind()
1293 {
1294     Q_D(QSGAnchorChanges);
1295     if (!d->target)
1296         return;
1297
1298     QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
1299
1300     //restore previous values (but not previous bindings, i.e. anchors)
1301     d->target->setX(d->rewindX);
1302     d->target->setY(d->rewindY);
1303     if (targetPrivate->widthValid) {
1304         d->target->setWidth(d->rewindWidth);
1305     }
1306     if (targetPrivate->heightValid) {
1307         d->target->setHeight(d->rewindHeight);
1308     }
1309 }
1310
1311 void QSGAnchorChanges::saveCurrentValues()
1312 {
1313     Q_D(QSGAnchorChanges);
1314     if (!d->target)
1315         return;
1316
1317     QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
1318     d->rewindLeft = targetPrivate->anchors()->left();
1319     d->rewindRight = targetPrivate->anchors()->right();
1320     d->rewindHCenter = targetPrivate->anchors()->horizontalCenter();
1321     d->rewindTop = targetPrivate->anchors()->top();
1322     d->rewindBottom = targetPrivate->anchors()->bottom();
1323     d->rewindVCenter = targetPrivate->anchors()->verticalCenter();
1324     d->rewindBaseline = targetPrivate->anchors()->baseline();
1325
1326     d->rewindX = d->target->x();
1327     d->rewindY = d->target->y();
1328     d->rewindWidth = d->target->width();
1329     d->rewindHeight = d->target->height();
1330 }
1331
1332 void QSGAnchorChanges::saveTargetValues()
1333 {
1334     Q_D(QSGAnchorChanges);
1335     if (!d->target)
1336         return;
1337
1338     d->toX = d->target->x();
1339     d->toY = d->target->y();
1340     d->toWidth = d->target->width();
1341     d->toHeight = d->target->height();
1342 }
1343
1344 #include <moc_qsgstateoperations_p.cpp>
1345
1346 QT_END_NAMESPACE
1347