1 // Commit: 726a8b16c52fe4608c89d740b47361a2b073ce01
2 /****************************************************************************
4 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
5 ** All rights reserved.
6 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 ** This file is part of the QtDeclarative module of the Qt Toolkit.
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
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.
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.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
41 ****************************************************************************/
43 #include "qsgstateoperations_p.h"
44 #include "qsgitem_p.h"
46 #include <private/qdeclarativestate_p_p.h>
48 #include <QtDeclarative/qdeclarativeinfo.h>
49 #include <QtCore/qmath.h>
53 class QSGParentChangePrivate : public QDeclarativeStateOperationPrivate
55 Q_DECLARE_PUBLIC(QSGParentChange)
57 QSGParentChangePrivate() : target(0), parent(0), origParent(0), origStackBefore(0),
58 rewindParent(0), rewindStackBefore(0) {}
61 QDeclarativeGuard<QSGItem> parent;
62 QDeclarativeGuard<QSGItem> origParent;
63 QDeclarativeGuard<QSGItem> origStackBefore;
64 QSGItem *rewindParent;
65 QSGItem *rewindStackBefore;
67 QDeclarativeNullableValue<QDeclarativeScriptString> xString;
68 QDeclarativeNullableValue<QDeclarativeScriptString> yString;
69 QDeclarativeNullableValue<QDeclarativeScriptString> widthString;
70 QDeclarativeNullableValue<QDeclarativeScriptString> heightString;
71 QDeclarativeNullableValue<QDeclarativeScriptString> scaleString;
72 QDeclarativeNullableValue<QDeclarativeScriptString> rotationString;
74 void doChange(QSGItem *targetParent, QSGItem *stackBefore = 0);
77 void QSGParentChangePrivate::doChange(QSGItem *targetParent, QSGItem *stackBefore)
79 if (targetParent && target && target->parentItem()) {
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");
90 bool isRotate = (transform.type() == QTransform::TxRotate) || (transform.m11() < 0);
91 if (ok && !isRotate) {
92 if (transform.m11() == transform.m22())
93 scale = transform.m11();
95 qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under non-uniform scale");
98 } else if (ok && isRotate) {
99 if (transform.m11() == transform.m22())
100 scale = qSqrt(transform.m11()*transform.m11() + transform.m12()*transform.m12());
102 qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under non-uniform scale");
107 rotation = atan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
109 qmlInfo(q) << QSGParentChange::tr("Unable to preserve appearance under scale of 0");
114 const QPointF &point = transform.map(QPointF(target->x(),target->y()));
118 // setParentItem will update the transformOriginPoint if needed
119 target->setParentItem(targetParent);
121 if (ok && target->transformOrigin() != QSGItem::TopLeft) {
122 qreal tempxt = target->transformOriginPoint().x();
123 qreal tempyt = target->transformOriginPoint().y();
125 t.translate(-tempxt, -tempyt);
127 t.scale(scale, scale);
128 t.translate(tempxt, tempyt);
129 const QPointF &offset = t.map(QPointF(0,0));
135 //qDebug() << x << y << rotation << scale;
138 target->setRotation(target->rotation() + rotation);
139 target->setScale(target->scale() * scale);
142 target->setParentItem(targetParent);
145 //restore the original stack position.
146 //### if stackBefore has also been reparented this won't work
148 target->stackBefore(stackBefore);
151 QSGParentChange::QSGParentChange(QObject *parent)
152 : QDeclarativeStateOperation(*(new QSGParentChangePrivate), parent)
156 QSGParentChange::~QSGParentChange()
160 QDeclarativeScriptString QSGParentChange::x() const
162 Q_D(const QSGParentChange);
163 return d->xString.value;
166 void QSGParentChange::setX(QDeclarativeScriptString x)
168 Q_D(QSGParentChange);
172 bool QSGParentChange::xIsSet() const
174 Q_D(const QSGParentChange);
175 return d->xString.isValid();
178 QDeclarativeScriptString QSGParentChange::y() const
180 Q_D(const QSGParentChange);
181 return d->yString.value;
184 void QSGParentChange::setY(QDeclarativeScriptString y)
186 Q_D(QSGParentChange);
190 bool QSGParentChange::yIsSet() const
192 Q_D(const QSGParentChange);
193 return d->yString.isValid();
196 QDeclarativeScriptString QSGParentChange::width() const
198 Q_D(const QSGParentChange);
199 return d->widthString.value;
202 void QSGParentChange::setWidth(QDeclarativeScriptString width)
204 Q_D(QSGParentChange);
205 d->widthString = width;
208 bool QSGParentChange::widthIsSet() const
210 Q_D(const QSGParentChange);
211 return d->widthString.isValid();
214 QDeclarativeScriptString QSGParentChange::height() const
216 Q_D(const QSGParentChange);
217 return d->heightString.value;
220 void QSGParentChange::setHeight(QDeclarativeScriptString height)
222 Q_D(QSGParentChange);
223 d->heightString = height;
226 bool QSGParentChange::heightIsSet() const
228 Q_D(const QSGParentChange);
229 return d->heightString.isValid();
232 QDeclarativeScriptString QSGParentChange::scale() const
234 Q_D(const QSGParentChange);
235 return d->scaleString.value;
238 void QSGParentChange::setScale(QDeclarativeScriptString scale)
240 Q_D(QSGParentChange);
241 d->scaleString = scale;
244 bool QSGParentChange::scaleIsSet() const
246 Q_D(const QSGParentChange);
247 return d->scaleString.isValid();
250 QDeclarativeScriptString QSGParentChange::rotation() const
252 Q_D(const QSGParentChange);
253 return d->rotationString.value;
256 void QSGParentChange::setRotation(QDeclarativeScriptString rotation)
258 Q_D(QSGParentChange);
259 d->rotationString = rotation;
262 bool QSGParentChange::rotationIsSet() const
264 Q_D(const QSGParentChange);
265 return d->rotationString.isValid();
268 QSGItem *QSGParentChange::originalParent() const
270 Q_D(const QSGParentChange);
271 return d->origParent;
274 QSGItem *QSGParentChange::object() const
276 Q_D(const QSGParentChange);
280 void QSGParentChange::setObject(QSGItem *target)
282 Q_D(QSGParentChange);
286 QSGItem *QSGParentChange::parent() const
288 Q_D(const QSGParentChange);
292 void QSGParentChange::setParent(QSGItem *parent)
294 Q_D(QSGParentChange);
298 QDeclarativeStateOperation::ActionList QSGParentChange::actions()
300 Q_D(QSGParentChange);
301 if (!d->target || !d->parent)
306 QDeclarativeAction a;
310 if (d->xString.isValid()) {
312 QString script = d->xString.value.script();
313 qreal x = script.toFloat(&ok);
315 QDeclarativeAction xa(d->target, QLatin1String("x"), x);
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;
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 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;
348 if (d->scaleString.isValid()) {
350 QString script = d->scaleString.value.script();
351 qreal scale = script.toFloat(&ok);
353 QDeclarativeAction sa(d->target, QLatin1String("scale"), scale);
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;
367 if (d->rotationString.isValid()) {
369 QString script = d->rotationString.value.script();
370 qreal rotation = script.toFloat(&ok);
372 QDeclarativeAction ra(d->target, QLatin1String("rotation"), rotation);
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;
386 if (d->widthString.isValid()) {
388 QString script = d->widthString.value.script();
389 qreal width = script.toFloat(&ok);
391 QDeclarativeAction wa(d->target, QLatin1String("width"), width);
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;
405 if (d->heightString.isValid()) {
407 QString script = d->heightString.value.script();
408 qreal height = script.toFloat(&ok);
410 QDeclarativeAction ha(d->target, QLatin1String("height"), height);
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;
427 void QSGParentChange::saveOriginals()
429 Q_D(QSGParentChange);
431 d->origParent = d->rewindParent;
432 d->origStackBefore = d->rewindStackBefore;
435 /*void QSGParentChange::copyOriginals(QDeclarativeActionEvent *other)
437 Q_D(QSGParentChange);
438 QSGParentChange *pc = static_cast<QSGParentChange*>(other);
440 d->origParent = pc->d_func()->rewindParent;
441 d->origStackBefore = pc->d_func()->rewindStackBefore;
446 void QSGParentChange::execute(Reason)
448 Q_D(QSGParentChange);
449 d->doChange(d->parent);
452 bool QSGParentChange::isReversable()
457 void QSGParentChange::reverse(Reason)
459 Q_D(QSGParentChange);
460 d->doChange(d->origParent, d->origStackBefore);
463 QString QSGParentChange::typeName() const
465 return QLatin1String("ParentChange");
468 bool QSGParentChange::override(QDeclarativeActionEvent*other)
470 Q_D(QSGParentChange);
471 if (other->typeName() != QLatin1String("ParentChange"))
473 if (QSGParentChange *otherPC = static_cast<QSGParentChange*>(other))
474 return (d->target == otherPC->object());
478 void QSGParentChange::saveCurrentValues()
480 Q_D(QSGParentChange);
483 d->rewindStackBefore = 0;
487 d->rewindParent = d->target->parentItem();
488 d->rewindStackBefore = 0;
490 if (!d->rewindParent)
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);
502 void QSGParentChange::rewind()
504 Q_D(QSGParentChange);
505 d->doChange(d->rewindParent, d->rewindStackBefore);
508 class QSGAnchorSetPrivate : public QObjectPrivate
510 Q_DECLARE_PUBLIC(QSGAnchorSet)
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)*/
519 QSGAnchors::Anchors usedAnchors;
520 QSGAnchors::Anchors resetAnchors;
525 QDeclarativeScriptString leftScript;
526 QDeclarativeScriptString rightScript;
527 QDeclarativeScriptString topScript;
528 QDeclarativeScriptString bottomScript;
529 QDeclarativeScriptString hCenterScript;
530 QDeclarativeScriptString vCenterScript;
531 QDeclarativeScriptString baselineScript;
540 qreal baselineOffset;*/
543 QSGAnchorSet::QSGAnchorSet(QObject *parent)
544 : QObject(*new QSGAnchorSetPrivate, parent)
548 QSGAnchorSet::~QSGAnchorSet()
552 QDeclarativeScriptString QSGAnchorSet::top() const
554 Q_D(const QSGAnchorSet);
558 void QSGAnchorSet::setTop(const QDeclarativeScriptString &edge)
561 d->usedAnchors |= QSGAnchors::TopAnchor;
563 if (edge.script() == QLatin1String("undefined"))
567 void QSGAnchorSet::resetTop()
570 d->usedAnchors &= ~QSGAnchors::TopAnchor;
571 d->topScript = QDeclarativeScriptString();
572 d->resetAnchors |= QSGAnchors::TopAnchor;
575 QDeclarativeScriptString QSGAnchorSet::bottom() const
577 Q_D(const QSGAnchorSet);
578 return d->bottomScript;
581 void QSGAnchorSet::setBottom(const QDeclarativeScriptString &edge)
584 d->usedAnchors |= QSGAnchors::BottomAnchor;
585 d->bottomScript = edge;
586 if (edge.script() == QLatin1String("undefined"))
590 void QSGAnchorSet::resetBottom()
593 d->usedAnchors &= ~QSGAnchors::BottomAnchor;
594 d->bottomScript = QDeclarativeScriptString();
595 d->resetAnchors |= QSGAnchors::BottomAnchor;
598 QDeclarativeScriptString QSGAnchorSet::verticalCenter() const
600 Q_D(const QSGAnchorSet);
601 return d->vCenterScript;
604 void QSGAnchorSet::setVerticalCenter(const QDeclarativeScriptString &edge)
607 d->usedAnchors |= QSGAnchors::VCenterAnchor;
608 d->vCenterScript = edge;
609 if (edge.script() == QLatin1String("undefined"))
610 resetVerticalCenter();
613 void QSGAnchorSet::resetVerticalCenter()
616 d->usedAnchors &= ~QSGAnchors::VCenterAnchor;
617 d->vCenterScript = QDeclarativeScriptString();
618 d->resetAnchors |= QSGAnchors::VCenterAnchor;
621 QDeclarativeScriptString QSGAnchorSet::baseline() const
623 Q_D(const QSGAnchorSet);
624 return d->baselineScript;
627 void QSGAnchorSet::setBaseline(const QDeclarativeScriptString &edge)
630 d->usedAnchors |= QSGAnchors::BaselineAnchor;
631 d->baselineScript = edge;
632 if (edge.script() == QLatin1String("undefined"))
636 void QSGAnchorSet::resetBaseline()
639 d->usedAnchors &= ~QSGAnchors::BaselineAnchor;
640 d->baselineScript = QDeclarativeScriptString();
641 d->resetAnchors |= QSGAnchors::BaselineAnchor;
644 QDeclarativeScriptString QSGAnchorSet::left() const
646 Q_D(const QSGAnchorSet);
647 return d->leftScript;
650 void QSGAnchorSet::setLeft(const QDeclarativeScriptString &edge)
653 d->usedAnchors |= QSGAnchors::LeftAnchor;
654 d->leftScript = edge;
655 if (edge.script() == QLatin1String("undefined"))
659 void QSGAnchorSet::resetLeft()
662 d->usedAnchors &= ~QSGAnchors::LeftAnchor;
663 d->leftScript = QDeclarativeScriptString();
664 d->resetAnchors |= QSGAnchors::LeftAnchor;
667 QDeclarativeScriptString QSGAnchorSet::right() const
669 Q_D(const QSGAnchorSet);
670 return d->rightScript;
673 void QSGAnchorSet::setRight(const QDeclarativeScriptString &edge)
676 d->usedAnchors |= QSGAnchors::RightAnchor;
677 d->rightScript = edge;
678 if (edge.script() == QLatin1String("undefined"))
682 void QSGAnchorSet::resetRight()
685 d->usedAnchors &= ~QSGAnchors::RightAnchor;
686 d->rightScript = QDeclarativeScriptString();
687 d->resetAnchors |= QSGAnchors::RightAnchor;
690 QDeclarativeScriptString QSGAnchorSet::horizontalCenter() const
692 Q_D(const QSGAnchorSet);
693 return d->hCenterScript;
696 void QSGAnchorSet::setHorizontalCenter(const QDeclarativeScriptString &edge)
699 d->usedAnchors |= QSGAnchors::HCenterAnchor;
700 d->hCenterScript = edge;
701 if (edge.script() == QLatin1String("undefined"))
702 resetHorizontalCenter();
705 void QSGAnchorSet::resetHorizontalCenter()
708 d->usedAnchors &= ~QSGAnchors::HCenterAnchor;
709 d->hCenterScript = QDeclarativeScriptString();
710 d->resetAnchors |= QSGAnchors::HCenterAnchor;
713 QSGItem *QSGAnchorSet::fill() const
715 Q_D(const QSGAnchorSet);
719 void QSGAnchorSet::setFill(QSGItem *f)
725 void QSGAnchorSet::resetFill()
730 QSGItem *QSGAnchorSet::centerIn() const
732 Q_D(const QSGAnchorSet);
736 void QSGAnchorSet::setCenterIn(QSGItem* c)
742 void QSGAnchorSet::resetCenterIn()
748 class QSGAnchorChangesPrivate : public QDeclarativeStateOperationPrivate
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)
761 ~QSGAnchorChangesPrivate() { delete anchorSet; }
764 QSGAnchorSet *anchorSet;
766 QDeclarativeBinding *leftBinding;
767 QDeclarativeBinding *rightBinding;
768 QDeclarativeBinding *hCenterBinding;
769 QDeclarativeBinding *topBinding;
770 QDeclarativeBinding *bottomBinding;
771 QDeclarativeBinding *vCenterBinding;
772 QDeclarativeBinding *baselineBinding;
774 QDeclarativeAbstractBinding *origLeftBinding;
775 QDeclarativeAbstractBinding *origRightBinding;
776 QDeclarativeAbstractBinding *origHCenterBinding;
777 QDeclarativeAbstractBinding *origTopBinding;
778 QDeclarativeAbstractBinding *origBottomBinding;
779 QDeclarativeAbstractBinding *origVCenterBinding;
780 QDeclarativeAbstractBinding *origBaselineBinding;
782 QSGAnchorLine rewindLeft;
783 QSGAnchorLine rewindRight;
784 QSGAnchorLine rewindHCenter;
785 QSGAnchorLine rewindTop;
786 QSGAnchorLine rewindBottom;
787 QSGAnchorLine rewindVCenter;
788 QSGAnchorLine rewindBaseline;
807 bool applyOrigHCenter;
809 bool applyOrigBottom;
810 bool applyOrigVCenter;
811 bool applyOrigBaseline;
813 QDeclarativeNullableValue<qreal> origWidth;
814 QDeclarativeNullableValue<qreal> origHeight;
818 QList<QDeclarativeAbstractBinding*> oldBindings;
820 QDeclarativeProperty leftProp;
821 QDeclarativeProperty rightProp;
822 QDeclarativeProperty hCenterProp;
823 QDeclarativeProperty topProp;
824 QDeclarativeProperty bottomProp;
825 QDeclarativeProperty vCenterProp;
826 QDeclarativeProperty baselineProp;
829 QSGAnchorChanges::QSGAnchorChanges(QObject *parent)
830 : QDeclarativeStateOperation(*(new QSGAnchorChangesPrivate), parent)
834 QSGAnchorChanges::~QSGAnchorChanges()
838 QSGAnchorChanges::ActionList QSGAnchorChanges::actions()
840 Q_D(QSGAnchorChanges);
841 d->leftBinding = d->rightBinding = d->hCenterBinding = d->topBinding
842 = d->bottomBinding = d->vCenterBinding = d->baselineBinding = 0;
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"));
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);
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);
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);
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);
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);
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);
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);
881 QDeclarativeAction a;
883 return ActionList() << a;
886 QSGAnchorSet *QSGAnchorChanges::anchors()
888 Q_D(QSGAnchorChanges);
892 QSGItem *QSGAnchorChanges::object() const
894 Q_D(const QSGAnchorChanges);
898 void QSGAnchorChanges::setObject(QSGItem *target)
900 Q_D(QSGAnchorChanges);
904 void QSGAnchorChanges::execute(Reason reason)
906 Q_D(QSGAnchorChanges);
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);
917 if (d->applyOrigRight) {
918 if (!d->origRightBinding)
919 targetPrivate->anchors()->resetRight();
920 QDeclarativePropertyPrivate::setBinding(d->rightProp, d->origRightBinding);
922 if (d->applyOrigHCenter) {
923 if (!d->origHCenterBinding)
924 targetPrivate->anchors()->resetHorizontalCenter();
925 QDeclarativePropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding);
927 if (d->applyOrigTop) {
928 if (!d->origTopBinding)
929 targetPrivate->anchors()->resetTop();
930 QDeclarativePropertyPrivate::setBinding(d->topProp, d->origTopBinding);
932 if (d->applyOrigBottom) {
933 if (!d->origBottomBinding)
934 targetPrivate->anchors()->resetBottom();
935 QDeclarativePropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding);
937 if (d->applyOrigVCenter) {
938 if (!d->origVCenterBinding)
939 targetPrivate->anchors()->resetVerticalCenter();
940 QDeclarativePropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding);
942 if (d->applyOrigBaseline) {
943 if (!d->origBaselineBinding)
944 targetPrivate->anchors()->resetBaseline();
945 QDeclarativePropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding);
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);
955 d->oldBindings.clear();
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);
963 if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::RightAnchor) {
964 targetPrivate->anchors()->resetRight();
965 QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
967 if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::HCenterAnchor) {
968 targetPrivate->anchors()->resetHorizontalCenter();
969 QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
971 if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::TopAnchor) {
972 targetPrivate->anchors()->resetTop();
973 QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
975 if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::BottomAnchor) {
976 targetPrivate->anchors()->resetBottom();
977 QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
979 if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::VCenterAnchor) {
980 targetPrivate->anchors()->resetVerticalCenter();
981 QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
983 if (d->anchorSet->d_func()->resetAnchors & QSGAnchors::BaselineAnchor) {
984 targetPrivate->anchors()->resetBaseline();
985 QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
988 //set any anchors that have been specified
990 QDeclarativePropertyPrivate::setBinding(d->leftBinding->property(), d->leftBinding);
992 QDeclarativePropertyPrivate::setBinding(d->rightBinding->property(), d->rightBinding);
993 if (d->hCenterBinding)
994 QDeclarativePropertyPrivate::setBinding(d->hCenterBinding->property(), d->hCenterBinding);
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);
1005 bool QSGAnchorChanges::isReversable()
1010 void QSGAnchorChanges::reverse(Reason reason)
1012 Q_D(QSGAnchorChanges);
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;
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;
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;
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;
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;
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;
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;
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);
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;
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);
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);
1114 if (stateHAnchors && !origHAnchors)
1115 d->target->setX(d->origX);
1117 if (stateVAnchors && !origVAnchors)
1118 d->target->setY(d->origY);
1121 QString QSGAnchorChanges::typeName() const
1123 return QLatin1String("AnchorChanges");
1126 QList<QDeclarativeAction> QSGAnchorChanges::additionalActions()
1128 Q_D(QSGAnchorChanges);
1129 QList<QDeclarativeAction> extra;
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;
1136 QDeclarativeAction a;
1137 if (hChange && d->fromX != d->toX) {
1138 a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
1142 if (vChange && d->fromY != d->toY) {
1143 a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
1147 if (hChange && d->fromWidth != d->toWidth) {
1148 a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
1149 a.toValue = d->toWidth;
1152 if (vChange && d->fromHeight != d->toHeight) {
1153 a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
1154 a.toValue = d->toHeight;
1162 bool QSGAnchorChanges::changesBindings()
1167 void QSGAnchorChanges::saveOriginals()
1169 Q_D(QSGAnchorChanges);
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);
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();
1189 d->applyOrigLeft = d->applyOrigRight = d->applyOrigHCenter = d->applyOrigTop
1190 = d->applyOrigBottom = d->applyOrigVCenter = d->applyOrigBaseline = false;
1192 saveCurrentValues();
1195 void QSGAnchorChanges::copyOriginals(QDeclarativeActionEvent *other)
1197 Q_D(QSGAnchorChanges);
1198 QSGAnchorChanges *ac = static_cast<QSGAnchorChanges*>(other);
1199 QSGAnchorChangesPrivate *acp = ac->d_func();
1201 QSGAnchors::Anchors combined = acp->anchorSet->d_func()->usedAnchors |
1202 acp->anchorSet->d_func()->resetAnchors;
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);
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;
1221 d->origWidth = acp->origWidth;
1222 d->origHeight = acp->origHeight;
1223 d->origX = acp->origX;
1224 d->origY = acp->origY;
1226 d->oldBindings.clear();
1227 d->oldBindings << acp->leftBinding << acp->rightBinding << acp->hCenterBinding
1228 << acp->topBinding << acp->bottomBinding << acp->baselineBinding;
1230 saveCurrentValues();
1233 void QSGAnchorChanges::clearBindings()
1235 Q_D(QSGAnchorChanges);
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();
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);
1255 if (d->applyOrigRight || (combined & QSGAnchors::RightAnchor)) {
1256 targetPrivate->anchors()->resetRight();
1257 QDeclarativePropertyPrivate::setBinding(d->rightProp, 0);
1259 if (d->applyOrigHCenter || (combined & QSGAnchors::HCenterAnchor)) {
1260 targetPrivate->anchors()->resetHorizontalCenter();
1261 QDeclarativePropertyPrivate::setBinding(d->hCenterProp, 0);
1263 if (d->applyOrigTop || (combined & QSGAnchors::TopAnchor)) {
1264 targetPrivate->anchors()->resetTop();
1265 QDeclarativePropertyPrivate::setBinding(d->topProp, 0);
1267 if (d->applyOrigBottom || (combined & QSGAnchors::BottomAnchor)) {
1268 targetPrivate->anchors()->resetBottom();
1269 QDeclarativePropertyPrivate::setBinding(d->bottomProp, 0);
1271 if (d->applyOrigVCenter || (combined & QSGAnchors::VCenterAnchor)) {
1272 targetPrivate->anchors()->resetVerticalCenter();
1273 QDeclarativePropertyPrivate::setBinding(d->vCenterProp, 0);
1275 if (d->applyOrigBaseline || (combined & QSGAnchors::BaselineAnchor)) {
1276 targetPrivate->anchors()->resetBaseline();
1277 QDeclarativePropertyPrivate::setBinding(d->baselineProp, 0);
1281 bool QSGAnchorChanges::override(QDeclarativeActionEvent*other)
1283 if (other->typeName() != QLatin1String("AnchorChanges"))
1285 if (static_cast<QDeclarativeActionEvent*>(this) == other)
1287 if (static_cast<QSGAnchorChanges*>(other)->object() == object())
1292 void QSGAnchorChanges::rewind()
1294 Q_D(QSGAnchorChanges);
1298 QSGItemPrivate *targetPrivate = QSGItemPrivate::get(d->target);
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);
1306 if (targetPrivate->heightValid) {
1307 d->target->setHeight(d->rewindHeight);
1311 void QSGAnchorChanges::saveCurrentValues()
1313 Q_D(QSGAnchorChanges);
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();
1326 d->rewindX = d->target->x();
1327 d->rewindY = d->target->y();
1328 d->rewindWidth = d->target->width();
1329 d->rewindHeight = d->target->height();
1332 void QSGAnchorChanges::saveTargetValues()
1334 Q_D(QSGAnchorChanges);
1338 d->toX = d->target->x();
1339 d->toY = d->target->y();
1340 d->toWidth = d->target->width();
1341 d->toHeight = d->target->height();
1344 #include <moc_qsgstateoperations_p.cpp>