1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickstateoperations_p.h"
43 #include "qquickitem_p.h"
45 #include <private/qdeclarativestate_p_p.h>
47 #include <QtDeclarative/qdeclarativeinfo.h>
48 #include <QtCore/qmath.h>
52 class QQuickParentChangePrivate : public QDeclarativeStateOperationPrivate
54 Q_DECLARE_PUBLIC(QQuickParentChange)
56 QQuickParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0),
57 rewindParent(0), rewindStackBefore(0) {}
60 QDeclarativeGuard<QQuickItem> parent;
61 QDeclarativeGuard<QQuickItem> origParent;
62 QDeclarativeGuard<QQuickItem> origStackBefore;
63 QQuickItem *rewindParent;
64 QQuickItem *rewindStackBefore;
66 QDeclarativeNullableValue<QDeclarativeScriptString> xString;
67 QDeclarativeNullableValue<QDeclarativeScriptString> yString;
68 QDeclarativeNullableValue<QDeclarativeScriptString> widthString;
69 QDeclarativeNullableValue<QDeclarativeScriptString> heightString;
70 QDeclarativeNullableValue<QDeclarativeScriptString> scaleString;
71 QDeclarativeNullableValue<QDeclarativeScriptString> rotationString;
73 void doChange(QQuickItem *targetParent, QQuickItem *stackBefore = 0);
76 void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *stackBefore)
78 if (targetParent && target && target->parentItem()) {
79 Q_Q(QQuickParentChange);
81 const QTransform &transform = target->parentItem()->itemTransform(targetParent, &ok);
82 if (transform.type() >= QTransform::TxShear || !ok) {
83 qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under complex transform");
89 bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
90 if (ok && !isRotate) {
91 if (transform.m11() == transform.m22())
92 scale = transform.m11();
94 qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
97 } else if (ok && isRotate) {
98 if (transform.m11() == transform.m22())
99 scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
101 qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under non-uniform scale");
106 rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
108 qmlInfo(q) << QQuickParentChange::tr("Unable to preserve appearance under scale of 0");
113 const QPointF &point = transform.map(QPointF(target->x(),target->y()));
117 // setParentItem will update the transformOriginPoint if needed
118 target->setParentItem(targetParent);
120 if (ok && target->transformOrigin() != QQuickItem::TopLeft) {
121 qreal tempxt = target->transformOriginPoint().x();
122 qreal tempyt = target->transformOriginPoint().y();
124 t.translate(-tempxt, -tempyt);
126 t.scale(scale, scale);
127 t.translate(tempxt, tempyt);
128 const QPointF &offset = t.map(QPointF(0,0));
134 //qDebug() << x << y << rotation << scale;
137 target->setRotation(target->rotation() + rotation);
138 target->setScale(target->scale() * scale);
141 target->setParentItem(targetParent);
144 //restore the original stack position.
145 //### if stackBefore has also been reparented this won't work
147 target->stackBefore(stackBefore);
150 QQuickParentChange::QQuickParentChange(QObject *parent)
151 : QDeclarativeStateOperation(*(new QQuickParentChangePrivate), parent)
155 QQuickParentChange::~QQuickParentChange()
159 QDeclarativeScriptString QQuickParentChange::x() const
161 Q_D(const QQuickParentChange);
162 return d->xString.value;
165 void QQuickParentChange::setX(QDeclarativeScriptString x)
167 Q_D(QQuickParentChange);
171 bool QQuickParentChange::xIsSet() const
173 Q_D(const QQuickParentChange);
174 return d->xString.isValid();
177 QDeclarativeScriptString QQuickParentChange::y() const
179 Q_D(const QQuickParentChange);
180 return d->yString.value;
183 void QQuickParentChange::setY(QDeclarativeScriptString y)
185 Q_D(QQuickParentChange);
189 bool QQuickParentChange::yIsSet() const
191 Q_D(const QQuickParentChange);
192 return d->yString.isValid();
195 QDeclarativeScriptString QQuickParentChange::width() const
197 Q_D(const QQuickParentChange);
198 return d->widthString.value;
201 void QQuickParentChange::setWidth(QDeclarativeScriptString width)
203 Q_D(QQuickParentChange);
204 d->widthString = width;
207 bool QQuickParentChange::widthIsSet() const
209 Q_D(const QQuickParentChange);
210 return d->widthString.isValid();
213 QDeclarativeScriptString QQuickParentChange::height() const
215 Q_D(const QQuickParentChange);
216 return d->heightString.value;
219 void QQuickParentChange::setHeight(QDeclarativeScriptString height)
221 Q_D(QQuickParentChange);
222 d->heightString = height;
225 bool QQuickParentChange::heightIsSet() const
227 Q_D(const QQuickParentChange);
228 return d->heightString.isValid();
231 QDeclarativeScriptString QQuickParentChange::scale() const
233 Q_D(const QQuickParentChange);
234 return d->scaleString.value;
237 void QQuickParentChange::setScale(QDeclarativeScriptString scale)
239 Q_D(QQuickParentChange);
240 d->scaleString = scale;
243 bool QQuickParentChange::scaleIsSet() const
245 Q_D(const QQuickParentChange);
246 return d->scaleString.isValid();
249 QDeclarativeScriptString QQuickParentChange::rotation() const
251 Q_D(const QQuickParentChange);
252 return d->rotationString.value;
255 void QQuickParentChange::setRotation(QDeclarativeScriptString rotation)
257 Q_D(QQuickParentChange);
258 d->rotationString = rotation;
261 bool QQuickParentChange::rotationIsSet() const
263 Q_D(const QQuickParentChange);
264 return d->rotationString.isValid();
267 QQuickItem *QQuickParentChange::originalParent() const
269 Q_D(const QQuickParentChange);
270 return d->origParent;
273 QQuickItem *QQuickParentChange::object() const
275 Q_D(const QQuickParentChange);
279 void QQuickParentChange::setObject(QQuickItem *target)
281 Q_D(QQuickParentChange);
285 QQuickItem *QQuickParentChange::parent() const
287 Q_D(const QQuickParentChange);
291 void QQuickParentChange::setParent(QQuickItem *parent)
293 Q_D(QQuickParentChange);
297 QDeclarativeStateOperation::ActionList QQuickParentChange::actions()
299 Q_D(QQuickParentChange);
300 if (!d->target || !d->parent)
305 QDeclarativeAction a;
309 if (d->xString.isValid()) {
311 QString script = d->xString.value.script();
312 qreal x = script.toFloat(&ok);
314 QDeclarativeAction xa(d->target, QLatin1String("x"), x);
317 QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
318 QDeclarativeProperty property(d->target, QLatin1String("x"));
319 newBinding->setTarget(property);
320 QDeclarativeAction xa;
321 xa.property = property;
322 xa.toBinding = newBinding;
323 xa.fromValue = xa.property.read();
324 xa.deletableToBinding = true;
329 if (d->yString.isValid()) {
331 QString script = d->yString.value.script();
332 qreal y = script.toFloat(&ok);
334 QDeclarativeAction ya(d->target, QLatin1String("y"), y);
337 QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
338 QDeclarativeProperty property(d->target, QLatin1String("y"));
339 newBinding->setTarget(property);
340 QDeclarativeAction ya;
341 ya.property = property;
342 ya.toBinding = newBinding;
343 ya.fromValue = ya.property.read();
344 ya.deletableToBinding = true;
349 if (d->scaleString.isValid()) {
351 QString script = d->scaleString.value.script();
352 qreal scale = script.toFloat(&ok);
354 QDeclarativeAction sa(d->target, QLatin1String("scale"), scale);
357 QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
358 QDeclarativeProperty property(d->target, QLatin1String("scale"));
359 newBinding->setTarget(property);
360 QDeclarativeAction sa;
361 sa.property = property;
362 sa.toBinding = newBinding;
363 sa.fromValue = sa.property.read();
364 sa.deletableToBinding = true;
369 if (d->rotationString.isValid()) {
371 QString script = d->rotationString.value.script();
372 qreal rotation = script.toFloat(&ok);
374 QDeclarativeAction ra(d->target, QLatin1String("rotation"), rotation);
377 QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
378 QDeclarativeProperty property(d->target, QLatin1String("rotation"));
379 newBinding->setTarget(property);
380 QDeclarativeAction ra;
381 ra.property = property;
382 ra.toBinding = newBinding;
383 ra.fromValue = ra.property.read();
384 ra.deletableToBinding = true;
389 if (d->widthString.isValid()) {
391 QString script = d->widthString.value.script();
392 qreal width = script.toFloat(&ok);
394 QDeclarativeAction wa(d->target, QLatin1String("width"), width);
397 QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
398 QDeclarativeProperty property(d->target, QLatin1String("width"));
399 newBinding->setTarget(property);
400 QDeclarativeAction wa;
401 wa.property = property;
402 wa.toBinding = newBinding;
403 wa.fromValue = wa.property.read();
404 wa.deletableToBinding = true;
409 if (d->heightString.isValid()) {
411 QString script = d->heightString.value.script();
412 qreal height = script.toFloat(&ok);
414 QDeclarativeAction ha(d->target, QLatin1String("height"), height);
417 QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
418 QDeclarativeProperty property(d->target, QLatin1String("height"));
419 newBinding->setTarget(property);
420 QDeclarativeAction ha;
421 ha.property = property;
422 ha.toBinding = newBinding;
423 ha.fromValue = ha.property.read();
424 ha.deletableToBinding = true;
432 void QQuickParentChange::saveOriginals()
434 Q_D(QQuickParentChange);
436 d->origParent = d->rewindParent;
437 d->origStackBefore = d->rewindStackBefore;
440 /*void QQuickParentChange::copyOriginals(QDeclarativeActionEvent *other)
442 Q_D(QQuickParentChange);
443 QQuickParentChange *pc = static_cast<QQuickParentChange*>(other);
445 d->origParent = pc->d_func()->rewindParent;
446 d->origStackBefore = pc->d_func()->rewindStackBefore;
451 void QQuickParentChange::execute(Reason)
453 Q_D(QQuickParentChange);
454 d->doChange(d->parent);
457 bool QQuickParentChange::isReversable()
462 void QQuickParentChange::reverse(Reason)
464 Q_D(QQuickParentChange);
465 d->doChange(d->origParent, d->origStackBefore);
468 QString QQuickParentChange::typeName() const
470 return QLatin1String("ParentChange");
473 bool QQuickParentChange::override(QDeclarativeActionEvent*other)
475 Q_D(QQuickParentChange);
476 if (other->typeName() != QLatin1String("ParentChange"))
478 if (QQuickParentChange *otherPC = static_cast<QQuickParentChange*>(other))
479 return (d->target == otherPC->object());
483 void QQuickParentChange::saveCurrentValues()
485 Q_D(QQuickParentChange);
488 d->rewindStackBefore = 0;
492 d->rewindParent = d->target->parentItem();
493 d->rewindStackBefore = 0;
495 if (!d->rewindParent)
498 QList<QQuickItem *> children = d->rewindParent->childItems();
499 for (int ii = 0; ii < children.count() - 1; ++ii) {
500 if (children.at(ii) == d->target) {
501 d->rewindStackBefore = children.at(ii + 1);
507 void QQuickParentChange::rewind()
509 Q_D(QQuickParentChange);
510 d->doChange(d->rewindParent, d->rewindStackBefore);
513 class QQuickAnchorSetPrivate : public QObjectPrivate
515 Q_DECLARE_PUBLIC(QQuickAnchorSet)
517 QQuickAnchorSetPrivate()
518 : usedAnchors(0), resetAnchors(0), fill(0),
519 centerIn(0)/*, leftMargin(0), rightMargin(0), topMargin(0), bottomMargin(0),
520 margins(0), vCenterOffset(0), hCenterOffset(0), baselineOffset(0)*/
524 QQuickAnchors::Anchors usedAnchors;
525 QQuickAnchors::Anchors resetAnchors;
528 QQuickItem *centerIn;
530 QDeclarativeScriptString leftScript;
531 QDeclarativeScriptString rightScript;
532 QDeclarativeScriptString topScript;
533 QDeclarativeScriptString bottomScript;
534 QDeclarativeScriptString hCenterScript;
535 QDeclarativeScriptString vCenterScript;
536 QDeclarativeScriptString baselineScript;
545 qreal baselineOffset;*/
548 QQuickAnchorSet::QQuickAnchorSet(QObject *parent)
549 : QObject(*new QQuickAnchorSetPrivate, parent)
553 QQuickAnchorSet::~QQuickAnchorSet()
557 QDeclarativeScriptString QQuickAnchorSet::top() const
559 Q_D(const QQuickAnchorSet);
563 void QQuickAnchorSet::setTop(const QDeclarativeScriptString &edge)
565 Q_D(QQuickAnchorSet);
566 d->usedAnchors |= QQuickAnchors::TopAnchor;
568 if (edge.script() == QLatin1String("undefined"))
572 void QQuickAnchorSet::resetTop()
574 Q_D(QQuickAnchorSet);
575 d->usedAnchors &= ~QQuickAnchors::TopAnchor;
576 d->topScript = QDeclarativeScriptString();
577 d->resetAnchors |= QQuickAnchors::TopAnchor;
580 QDeclarativeScriptString QQuickAnchorSet::bottom() const
582 Q_D(const QQuickAnchorSet);
583 return d->bottomScript;
586 void QQuickAnchorSet::setBottom(const QDeclarativeScriptString &edge)
588 Q_D(QQuickAnchorSet);
589 d->usedAnchors |= QQuickAnchors::BottomAnchor;
590 d->bottomScript = edge;
591 if (edge.script() == QLatin1String("undefined"))
595 void QQuickAnchorSet::resetBottom()
597 Q_D(QQuickAnchorSet);
598 d->usedAnchors &= ~QQuickAnchors::BottomAnchor;
599 d->bottomScript = QDeclarativeScriptString();
600 d->resetAnchors |= QQuickAnchors::BottomAnchor;
603 QDeclarativeScriptString QQuickAnchorSet::verticalCenter() const
605 Q_D(const QQuickAnchorSet);
606 return d->vCenterScript;
609 void QQuickAnchorSet::setVerticalCenter(const QDeclarativeScriptString &edge)
611 Q_D(QQuickAnchorSet);
612 d->usedAnchors |= QQuickAnchors::VCenterAnchor;
613 d->vCenterScript = edge;
614 if (edge.script() == QLatin1String("undefined"))
615 resetVerticalCenter();
618 void QQuickAnchorSet::resetVerticalCenter()
620 Q_D(QQuickAnchorSet);
621 d->usedAnchors &= ~QQuickAnchors::VCenterAnchor;
622 d->vCenterScript = QDeclarativeScriptString();
623 d->resetAnchors |= QQuickAnchors::VCenterAnchor;
626 QDeclarativeScriptString QQuickAnchorSet::baseline() const
628 Q_D(const QQuickAnchorSet);
629 return d->baselineScript;
632 void QQuickAnchorSet::setBaseline(const QDeclarativeScriptString &edge)
634 Q_D(QQuickAnchorSet);
635 d->usedAnchors |= QQuickAnchors::BaselineAnchor;
636 d->baselineScript = edge;
637 if (edge.script() == QLatin1String("undefined"))
641 void QQuickAnchorSet::resetBaseline()
643 Q_D(QQuickAnchorSet);
644 d->usedAnchors &= ~QQuickAnchors::BaselineAnchor;
645 d->baselineScript = QDeclarativeScriptString();
646 d->resetAnchors |= QQuickAnchors::BaselineAnchor;
649 QDeclarativeScriptString QQuickAnchorSet::left() const
651 Q_D(const QQuickAnchorSet);
652 return d->leftScript;
655 void QQuickAnchorSet::setLeft(const QDeclarativeScriptString &edge)
657 Q_D(QQuickAnchorSet);
658 d->usedAnchors |= QQuickAnchors::LeftAnchor;
659 d->leftScript = edge;
660 if (edge.script() == QLatin1String("undefined"))
664 void QQuickAnchorSet::resetLeft()
666 Q_D(QQuickAnchorSet);
667 d->usedAnchors &= ~QQuickAnchors::LeftAnchor;
668 d->leftScript = QDeclarativeScriptString();
669 d->resetAnchors |= QQuickAnchors::LeftAnchor;
672 QDeclarativeScriptString QQuickAnchorSet::right() const
674 Q_D(const QQuickAnchorSet);
675 return d->rightScript;
678 void QQuickAnchorSet::setRight(const QDeclarativeScriptString &edge)
680 Q_D(QQuickAnchorSet);
681 d->usedAnchors |= QQuickAnchors::RightAnchor;
682 d->rightScript = edge;
683 if (edge.script() == QLatin1String("undefined"))
687 void QQuickAnchorSet::resetRight()
689 Q_D(QQuickAnchorSet);
690 d->usedAnchors &= ~QQuickAnchors::RightAnchor;
691 d->rightScript = QDeclarativeScriptString();
692 d->resetAnchors |= QQuickAnchors::RightAnchor;
695 QDeclarativeScriptString QQuickAnchorSet::horizontalCenter() const
697 Q_D(const QQuickAnchorSet);
698 return d->hCenterScript;
701 void QQuickAnchorSet::setHorizontalCenter(const QDeclarativeScriptString &edge)
703 Q_D(QQuickAnchorSet);
704 d->usedAnchors |= QQuickAnchors::HCenterAnchor;
705 d->hCenterScript = edge;
706 if (edge.script() == QLatin1String("undefined"))
707 resetHorizontalCenter();
710 void QQuickAnchorSet::resetHorizontalCenter()
712 Q_D(QQuickAnchorSet);
713 d->usedAnchors &= ~QQuickAnchors::HCenterAnchor;
714 d->hCenterScript = QDeclarativeScriptString();
715 d->resetAnchors |= QQuickAnchors::HCenterAnchor;
718 QQuickItem *QQuickAnchorSet::fill() const
720 Q_D(const QQuickAnchorSet);
724 void QQuickAnchorSet::setFill(QQuickItem *f)
726 Q_D(QQuickAnchorSet);
730 void QQuickAnchorSet::resetFill()
735 QQuickItem *QQuickAnchorSet::centerIn() const
737 Q_D(const QQuickAnchorSet);
741 void QQuickAnchorSet::setCenterIn(QQuickItem* c)
743 Q_D(QQuickAnchorSet);
747 void QQuickAnchorSet::resetCenterIn()
753 class QQuickAnchorChangesPrivate : public QDeclarativeStateOperationPrivate
756 QQuickAnchorChangesPrivate()
757 : target(0), anchorSet(new QQuickAnchorSet),
758 leftBinding(0), rightBinding(0), hCenterBinding(0),
759 topBinding(0), bottomBinding(0), vCenterBinding(0), baselineBinding(0),
760 origLeftBinding(0), origRightBinding(0), origHCenterBinding(0),
761 origTopBinding(0), origBottomBinding(0), origVCenterBinding(0),
762 origBaselineBinding(0)
766 ~QQuickAnchorChangesPrivate() { delete anchorSet; }
769 QQuickAnchorSet *anchorSet;
771 QDeclarativeBinding *leftBinding;
772 QDeclarativeBinding *rightBinding;
773 QDeclarativeBinding *hCenterBinding;
774 QDeclarativeBinding *topBinding;
775 QDeclarativeBinding *bottomBinding;
776 QDeclarativeBinding *vCenterBinding;
777 QDeclarativeBinding *baselineBinding;
779 QDeclarativeAbstractBinding *origLeftBinding;
780 QDeclarativeAbstractBinding *origRightBinding;
781 QDeclarativeAbstractBinding *origHCenterBinding;
782 QDeclarativeAbstractBinding *origTopBinding;
783 QDeclarativeAbstractBinding *origBottomBinding;
784 QDeclarativeAbstractBinding *origVCenterBinding;
785 QDeclarativeAbstractBinding *origBaselineBinding;
787 QQuickAnchorLine rewindLeft;
788 QQuickAnchorLine rewindRight;
789 QQuickAnchorLine rewindHCenter;
790 QQuickAnchorLine rewindTop;
791 QQuickAnchorLine rewindBottom;
792 QQuickAnchorLine rewindVCenter;
793 QQuickAnchorLine rewindBaseline;
812 bool applyOrigHCenter;
814 bool applyOrigBottom;
815 bool applyOrigVCenter;
816 bool applyOrigBaseline;
818 QDeclarativeNullableValue<qreal> origWidth;
819 QDeclarativeNullableValue<qreal> origHeight;
823 QList<QDeclarativeAbstractBinding*> oldBindings;
825 QDeclarativeProperty leftProp;
826 QDeclarativeProperty rightProp;
827 QDeclarativeProperty hCenterProp;
828 QDeclarativeProperty topProp;
829 QDeclarativeProperty bottomProp;
830 QDeclarativeProperty vCenterProp;
831 QDeclarativeProperty baselineProp;
834 QQuickAnchorChanges::QQuickAnchorChanges(QObject *parent)
835 : QDeclarativeStateOperation(*(new QQuickAnchorChangesPrivate), parent)
839 QQuickAnchorChanges::~QQuickAnchorChanges()
843 QQuickAnchorChanges::ActionList QQuickAnchorChanges::actions()
845 Q_D(QQuickAnchorChanges);
846 d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding
847 = d->bottomBinding = d->vCenterBinding = d->baselineBinding = 0;
849 d->leftProp = QDeclarativeProperty(d->target, QLatin1String("anchors.left"));
850 d->rightProp = QDeclarativeProperty(d->target, QLatin1String("anchors.right"));
851 d->hCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.horizontalCenter"));
852 d->topProp = QDeclarativeProperty(d->target, QLatin1String("anchors.top"));
853 d->bottomProp = QDeclarativeProperty(d->target, QLatin1String("anchors.bottom"));
854 d->vCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.verticalCenter"));
855 d->baselineProp = QDeclarativeProperty(d->target, QLatin1String("anchors.baseline"));
857 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::LeftAnchor) {
858 d->leftBinding = new QDeclarativeBinding(d->anchorSet->d_func()->leftScript.script(), d->target, qmlContext(this));
859 d->leftBinding->setTarget(d->leftProp);
861 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::RightAnchor) {
862 d->rightBinding = new QDeclarativeBinding(d->anchorSet->d_func()->rightScript.script(), d->target, qmlContext(this));
863 d->rightBinding->setTarget(d->rightProp);
865 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::HCenterAnchor) {
866 d->hCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->hCenterScript.script(), d->target, qmlContext(this));
867 d->hCenterBinding->setTarget(d->hCenterProp);
869 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::TopAnchor) {
870 d->topBinding = new QDeclarativeBinding(d->anchorSet->d_func()->topScript.script(), d->target, qmlContext(this));
871 d->topBinding->setTarget(d->topProp);
873 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BottomAnchor) {
874 d->bottomBinding = new QDeclarativeBinding(d->anchorSet->d_func()->bottomScript.script(), d->target, qmlContext(this));
875 d->bottomBinding->setTarget(d->bottomProp);
877 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::VCenterAnchor) {
878 d->vCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->vCenterScript.script(), d->target, qmlContext(this));
879 d->vCenterBinding->setTarget(d->vCenterProp);
881 if (d->anchorSet->d_func()->usedAnchors & QQuickAnchors::BaselineAnchor) {
882 d->baselineBinding = new QDeclarativeBinding(d->anchorSet->d_func()->baselineScript.script(), d->target, qmlContext(this));
883 d->baselineBinding->setTarget(d->baselineProp);
886 QDeclarativeAction a;
888 return ActionList() << a;
891 QQuickAnchorSet *QQuickAnchorChanges::anchors()
893 Q_D(QQuickAnchorChanges);
897 QQuickItem *QQuickAnchorChanges::object() const
899 Q_D(const QQuickAnchorChanges);
903 void QQuickAnchorChanges::setObject(QQuickItem *target)
905 Q_D(QQuickAnchorChanges);
909 void QQuickAnchorChanges::execute(Reason reason)
911 Q_D(QQuickAnchorChanges);
915 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
916 //incorporate any needed "reverts"
917 if (d->applyOrigLeft) {
918 if (!d->origLeftBinding)
919 targetPrivate->anchors()->resetLeft();
920 QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
922 if (d->applyOrigRight) {
923 if (!d->origRightBinding)
924 targetPrivate->anchors()->resetRight();
925 QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
927 if (d->applyOrigHCenter) {
928 if (!d->origHCenterBinding)
929 targetPrivate->anchors()->resetHorizontalCenter();
930 QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
932 if (d->applyOrigTop) {
933 if (!d->origTopBinding)
934 targetPrivate->anchors()->resetTop();
935 QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
937 if (d->applyOrigBottom) {
938 if (!d->origBottomBinding)
939 targetPrivate->anchors()->resetBottom();
940 QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
942 if (d->applyOrigVCenter) {
943 if (!d->origVCenterBinding)
944 targetPrivate->anchors()->resetVerticalCenter();
945 QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
947 if (d->applyOrigBaseline) {
948 if (!d->origBaselineBinding)
949 targetPrivate->anchors()->resetBaseline();
950 QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
953 //destroy old bindings
954 if (reason == ActualChange) {
955 for (int i = 0; i < d->oldBindings.size(); ++i) {
956 QDeclarativeAbstractBinding *binding = d->oldBindings.at(i);
960 d->oldBindings.clear();
963 //reset any anchors that have been specified as "undefined"
964 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::LeftAnchor) {
965 targetPrivate->anchors()->resetLeft();
966 QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
968 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::RightAnchor) {
969 targetPrivate->anchors()->resetRight();
970 QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
972 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::HCenterAnchor) {
973 targetPrivate->anchors()->resetHorizontalCenter();
974 QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
976 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::TopAnchor) {
977 targetPrivate->anchors()->resetTop();
978 QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
980 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BottomAnchor) {
981 targetPrivate->anchors()->resetBottom();
982 QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
984 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::VCenterAnchor) {
985 targetPrivate->anchors()->resetVerticalCenter();
986 QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
988 if (d->anchorSet->d_func()->resetAnchors & QQuickAnchors::BaselineAnchor) {
989 targetPrivate->anchors()->resetBaseline();
990 QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
993 //set any anchors that have been specified
995 QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), d->leftBinding);
997 QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), d->rightBinding);
998 if (d->hCenterBinding)
999 QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), d->hCenterBinding);
1001 QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), d->topBinding);
1002 if (d->bottomBinding)
1003 QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), d->bottomBinding);
1004 if (d->vCenterBinding)
1005 QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), d->vCenterBinding);
1006 if (d->baselineBinding)
1007 QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), d->baselineBinding);
1010 bool QQuickAnchorChanges::isReversable()
1015 void QQuickAnchorChanges::reverse(Reason reason)
1017 Q_D(QQuickAnchorChanges);
1021 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1022 //reset any anchors set by the state
1023 if (d->leftBinding) {
1024 targetPrivate->anchors()->resetLeft();
1025 QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), 0);
1026 if (reason == ActualChange) {
1027 d->leftBinding->destroy(); d->leftBinding = 0;
1030 if (d->rightBinding) {
1031 targetPrivate->anchors()->resetRight();
1032 QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), 0);
1033 if (reason == ActualChange) {
1034 d->rightBinding->destroy(); d->rightBinding = 0;
1037 if (d->hCenterBinding) {
1038 targetPrivate->anchors()->resetHorizontalCenter();
1039 QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), 0);
1040 if (reason == ActualChange) {
1041 d->hCenterBinding->destroy(); d->hCenterBinding = 0;
1044 if (d->topBinding) {
1045 targetPrivate->anchors()->resetTop();
1046 QDeclarativePropertyPrivate::setBinding(d->topBinding->property(), 0);
1047 if (reason == ActualChange) {
1048 d->topBinding->destroy(); d->topBinding = 0;
1051 if (d->bottomBinding) {
1052 targetPrivate->anchors()->resetBottom();
1053 QDeclarativePropertyPrivate::setBinding(d->bottomBinding->property(), 0);
1054 if (reason == ActualChange) {
1055 d->bottomBinding->destroy(); d->bottomBinding = 0;
1058 if (d->vCenterBinding) {
1059 targetPrivate->anchors()->resetVerticalCenter();
1060 QDeclarativePropertyPrivate::setBinding(d->vCenterBinding->property(), 0);
1061 if (reason == ActualChange) {
1062 d->vCenterBinding->destroy(); d->vCenterBinding = 0;
1065 if (d->baselineBinding) {
1066 targetPrivate->anchors()->resetBaseline();
1067 QDeclarativePropertyPrivate::setBinding(d->baselineBinding->property(), 0);
1068 if (reason == ActualChange) {
1069 d->baselineBinding->destroy(); d->baselineBinding = 0;
1073 //restore previous anchors
1074 if (d->origLeftBinding)
1075 QDeclarativePropertyPrivate::setBinding(d->leftProp, d->origLeftBinding);
1076 if (d->origRightBinding)
1077 QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
1078 if (d->origHCenterBinding)
1079 QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
1080 if (d->origTopBinding)
1081 QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
1082 if (d->origBottomBinding)
1083 QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
1084 if (d->origVCenterBinding)
1085 QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
1086 if (d->origBaselineBinding)
1087 QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
1089 //restore any absolute geometry changed by the state's anchors
1090 QQuickAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Vertical_Mask;
1091 QQuickAnchors::Anchors origVAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Vertical_Mask;
1092 QQuickAnchors::Anchors stateHAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Horizontal_Mask;
1093 QQuickAnchors::Anchors origHAnchors = targetPrivate->anchors()->usedAnchors() & QQuickAnchors::Horizontal_Mask;
1095 bool stateSetWidth = (stateHAnchors &&
1096 stateHAnchors != QQuickAnchors::LeftAnchor &&
1097 stateHAnchors != QQuickAnchors::RightAnchor &&
1098 stateHAnchors != QQuickAnchors::HCenterAnchor);
1099 bool origSetWidth = (origHAnchors &&
1100 origHAnchors != QQuickAnchors::LeftAnchor &&
1101 origHAnchors != QQuickAnchors::RightAnchor &&
1102 origHAnchors != QQuickAnchors::HCenterAnchor);
1103 if (d->origWidth.isValid() && stateSetWidth && !origSetWidth)
1104 d->target->setWidth(d->origWidth.value);
1106 bool stateSetHeight = (stateVAnchors &&
1107 stateVAnchors != QQuickAnchors::TopAnchor &&
1108 stateVAnchors != QQuickAnchors::BottomAnchor &&
1109 stateVAnchors != QQuickAnchors::VCenterAnchor &&
1110 stateVAnchors != QQuickAnchors::BaselineAnchor);
1111 bool origSetHeight = (origVAnchors &&
1112 origVAnchors != QQuickAnchors::TopAnchor &&
1113 origVAnchors != QQuickAnchors::BottomAnchor &&
1114 origVAnchors != QQuickAnchors::VCenterAnchor &&
1115 origVAnchors != QQuickAnchors::BaselineAnchor);
1116 if (d->origHeight.isValid() && stateSetHeight && !origSetHeight)
1117 d->target->setHeight(d->origHeight.value);
1119 if (stateHAnchors && !origHAnchors)
1120 d->target->setX(d->origX);
1122 if (stateVAnchors && !origVAnchors)
1123 d->target->setY(d->origY);
1126 QString QQuickAnchorChanges::typeName() const
1128 return QLatin1String("AnchorChanges");
1131 QList<QDeclarativeAction> QQuickAnchorChanges::additionalActions()
1133 Q_D(QQuickAnchorChanges);
1134 QList<QDeclarativeAction> extra;
1136 QQuickAnchors::Anchors combined = d->anchorSet->d_func()->usedAnchors | d->anchorSet->d_func()->resetAnchors;
1137 bool hChange = combined & QQuickAnchors::Horizontal_Mask;
1138 bool vChange = combined & QQuickAnchors::Vertical_Mask;
1141 QDeclarativeAction a;
1142 if (hChange && d->fromX != d->toX) {
1143 a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
1147 if (vChange && d->fromY != d->toY) {
1148 a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
1152 if (hChange && d->fromWidth != d->toWidth) {
1153 a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
1154 a.toValue = d->toWidth;
1157 if (vChange && d->fromHeight != d->toHeight) {
1158 a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
1159 a.toValue = d->toHeight;
1167 bool QQuickAnchorChanges::changesBindings()
1172 void QQuickAnchorChanges::saveOriginals()
1174 Q_D(QQuickAnchorChanges);
1178 d->origLeftBinding = QDeclarativePropertyPrivate::binding(d->leftProp);
1179 d->origRightBinding = QDeclarativePropertyPrivate::binding(d->rightProp);
1180 d->origHCenterBinding = QDeclarativePropertyPrivate::binding(d->hCenterProp);
1181 d->origTopBinding = QDeclarativePropertyPrivate::binding(d->topProp);
1182 d->origBottomBinding = QDeclarativePropertyPrivate::binding(d->bottomProp);
1183 d->origVCenterBinding = QDeclarativePropertyPrivate::binding(d->vCenterProp);
1184 d->origBaselineBinding = QDeclarativePropertyPrivate::binding(d->baselineProp);
1186 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1187 if (targetPrivate->widthValid)
1188 d->origWidth = d->target->width();
1189 if (targetPrivate->heightValid)
1190 d->origHeight = d->target->height();
1191 d->origX = d->target->x();
1192 d->origY = d->target->y();
1194 d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
1195 = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false;
1197 saveCurrentValues();
1200 void QQuickAnchorChanges::copyOriginals(QDeclarativeActionEvent *other)
1202 Q_D(QQuickAnchorChanges);
1203 QQuickAnchorChanges *ac = static_cast<QQuickAnchorChanges*>(other);
1204 QQuickAnchorChangesPrivate *acp = ac->d_func();
1206 QQuickAnchors::Anchors combined = acp->anchorSet->d_func()->usedAnchors |
1207 acp->anchorSet->d_func()->resetAnchors;
1209 //probably also need to revert some things
1210 d->applyOrigLeft = (combined & QQuickAnchors::LeftAnchor);
1211 d->applyOrigRight = (combined & QQuickAnchors::RightAnchor);
1212 d->applyOrigHCenter = (combined & QQuickAnchors::HCenterAnchor);
1213 d->applyOrigTop = (combined & QQuickAnchors::TopAnchor);
1214 d->applyOrigBottom = (combined & QQuickAnchors::BottomAnchor);
1215 d->applyOrigVCenter = (combined & QQuickAnchors::VCenterAnchor);
1216 d->applyOrigBaseline = (combined & QQuickAnchors::BaselineAnchor);
1218 d->origLeftBinding = acp->origLeftBinding;
1219 d->origRightBinding = acp->origRightBinding;
1220 d->origHCenterBinding = acp->origHCenterBinding;
1221 d->origTopBinding = acp->origTopBinding;
1222 d->origBottomBinding = acp->origBottomBinding;
1223 d->origVCenterBinding = acp->origVCenterBinding;
1224 d->origBaselineBinding = acp->origBaselineBinding;
1226 d->origWidth = acp->origWidth;
1227 d->origHeight = acp->origHeight;
1228 d->origX = acp->origX;
1229 d->origY = acp->origY;
1231 d->oldBindings.clear();
1232 d->oldBindings << acp->leftBinding << acp->rightBinding << acp->hCenterBinding
1233 << acp->topBinding << acp->bottomBinding << acp->baselineBinding;
1235 saveCurrentValues();
1238 void QQuickAnchorChanges::clearBindings()
1240 Q_D(QQuickAnchorChanges);
1244 //### should this (saving "from" values) be moved to saveCurrentValues()?
1245 d->fromX = d->target->x();
1246 d->fromY = d->target->y();
1247 d->fromWidth = d->target->width();
1248 d->fromHeight = d->target->height();
1250 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1251 //reset any anchors with corresponding reverts
1252 //reset any anchors that have been specified as "undefined"
1253 //reset any anchors that we'll be setting in the state
1254 QQuickAnchors::Anchors combined = d->anchorSet->d_func()->resetAnchors |
1255 d->anchorSet->d_func()->usedAnchors;
1256 if (d->applyOrigLeft || (combined & QQuickAnchors::LeftAnchor)) {
1257 targetPrivate->anchors()->resetLeft();
1258 QDeclarativePropertyPrivate::setBinding(d->leftProp, 0);
1260 if (d->applyOrigRight || (combined & QQuickAnchors::RightAnchor)) {
1261 targetPrivate->anchors()->resetRight();
1262 QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
1264 if (d->applyOrigHCenter || (combined & QQuickAnchors::HCenterAnchor)) {
1265 targetPrivate->anchors()->resetHorizontalCenter();
1266 QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
1268 if (d->applyOrigTop || (combined & QQuickAnchors::TopAnchor)) {
1269 targetPrivate->anchors()->resetTop();
1270 QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
1272 if (d->applyOrigBottom || (combined & QQuickAnchors::BottomAnchor)) {
1273 targetPrivate->anchors()->resetBottom();
1274 QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
1276 if (d->applyOrigVCenter || (combined & QQuickAnchors::VCenterAnchor)) {
1277 targetPrivate->anchors()->resetVerticalCenter();
1278 QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
1280 if (d->applyOrigBaseline || (combined & QQuickAnchors::BaselineAnchor)) {
1281 targetPrivate->anchors()->resetBaseline();
1282 QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
1286 bool QQuickAnchorChanges::override(QDeclarativeActionEvent*other)
1288 if (other->typeName() != QLatin1String("AnchorChanges"))
1290 if (static_cast<QDeclarativeActionEvent*>(this) == other)
1292 if (static_cast<QQuickAnchorChanges*>(other)->object() == object())
1297 void QQuickAnchorChanges::rewind()
1299 Q_D(QQuickAnchorChanges);
1303 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1305 //restore previous values (but not previous bindings, i.e. anchors)
1306 d->target->setX(d->rewindX);
1307 d->target->setY(d->rewindY);
1308 if (targetPrivate->widthValid) {
1309 d->target->setWidth(d->rewindWidth);
1311 if (targetPrivate->heightValid) {
1312 d->target->setHeight(d->rewindHeight);
1316 void QQuickAnchorChanges::saveCurrentValues()
1318 Q_D(QQuickAnchorChanges);
1322 QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(d->target);
1323 d->rewindLeft = targetPrivate->anchors()->left();
1324 d->rewindRight = targetPrivate->anchors()->right();
1325 d->rewindHCenter = targetPrivate->anchors()->horizontalCenter();
1326 d->rewindTop = targetPrivate->anchors()->top();
1327 d->rewindBottom = targetPrivate->anchors()->bottom();
1328 d->rewindVCenter = targetPrivate->anchors()->verticalCenter();
1329 d->rewindBaseline = targetPrivate->anchors()->baseline();
1331 d->rewindX = d->target->x();
1332 d->rewindY = d->target->y();
1333 d->rewindWidth = d->target->width();
1334 d->rewindHeight = d->target->height();
1337 void QQuickAnchorChanges::saveTargetValues()
1339 Q_D(QQuickAnchorChanges);
1343 d->toX = d->target->x();
1344 d->toY = d->target->y();
1345 d->toWidth = d->target->width();
1346 d->toHeight = d->target->height();
1349 #include <moc_qquickstateoperations_p.cpp>