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 QtQml 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 "qqmlvaluetype_p.h"
43 #include "qqmlmetatype_p.h"
45 #include <private/qqmlglobal_p.h>
46 #include <QtCore/qdebug.h>
52 struct QQmlValueTypeFactoryImpl
54 QQmlValueTypeFactoryImpl();
55 ~QQmlValueTypeFactoryImpl();
57 bool isValueType(int idx);
59 QQmlValueType *createValueType(int);
60 QQmlValueType *valueType(int);
62 QQmlValueType *valueTypes[QVariant::UserType];
63 QHash<int, QQmlValueType *> userTypes;
67 QQmlValueTypeFactoryImpl::QQmlValueTypeFactoryImpl()
69 for (unsigned int ii = 0; ii < QVariant::UserType; ++ii)
73 QQmlValueTypeFactoryImpl::~QQmlValueTypeFactoryImpl()
75 qDeleteAll(valueTypes, valueTypes + QVariant::UserType);
76 qDeleteAll(userTypes);
79 bool QQmlValueTypeFactoryImpl::isValueType(int idx)
81 if (idx >= QVariant::UserType) {
82 return (valueType(idx) != 0);
84 && idx != QVariant::StringList
85 && idx != QMetaType::QObjectStar
86 && idx != QMetaType::VoidStar
87 && idx != QMetaType::QVariant) {
94 QQmlValueType *QQmlValueTypeFactoryImpl::createValueType(int t)
96 QQmlValueType *rv = 0;
100 rv = new QQmlPointValueType;
102 case QVariant::PointF:
103 rv = new QQmlPointFValueType;
106 rv = new QQmlSizeValueType;
108 case QVariant::SizeF:
109 rv = new QQmlSizeFValueType;
112 rv = new QQmlRectValueType;
114 case QVariant::RectF:
115 rv = new QQmlRectFValueType;
117 case QVariant::EasingCurve:
118 rv = new QQmlEasingValueType;
121 rv = QQml_valueTypeProvider()->createValueType(t);
125 Q_ASSERT(!rv || rv->metaObject()->propertyCount() < 32);
129 QQmlValueType *QQmlValueTypeFactoryImpl::valueType(int idx)
131 if (idx >= (int)QVariant::UserType) {
132 // Protect the hash with a mutex
135 QHash<int, QQmlValueType *>::iterator it = userTypes.find(idx);
136 if (it == userTypes.end()) {
137 it = userTypes.insert(idx, createValueType(idx));
144 QQmlValueType *rv = valueTypes[idx];
146 // No need for mutex protection - the most we can lose is a valueType instance
148 // TODO: Investigate the performance/memory characteristics of
149 // removing the preallocated array
150 if ((rv = createValueType(idx))) {
151 valueTypes[idx] = rv;
160 Q_GLOBAL_STATIC(QQmlValueTypeFactoryImpl, factoryImpl);
162 bool QQmlValueTypeFactory::isValueType(int idx)
164 return factoryImpl()->isValueType(idx);
167 QQmlValueType *QQmlValueTypeFactory::valueType(int idx)
169 return factoryImpl()->valueType(idx);
172 void QQmlValueTypeFactory::registerValueTypes(const char *uri, int versionMajor, int versionMinor)
174 qmlRegisterValueTypeEnums<QQmlEasingValueType>(uri, versionMajor, versionMinor, "Easing");
178 QQmlValueType::QQmlValueType(int userType, QObject *parent)
179 : QObject(parent), m_userType(userType)
183 QQmlPointFValueType::QQmlPointFValueType(QObject *parent)
184 : QQmlValueTypeBase<QPointF>(QMetaType::QPointF, parent)
188 QString QQmlPointFValueType::toString() const
190 return QString(QLatin1String("QPointF(%1, %2)")).arg(v.x()).arg(v.y());
193 qreal QQmlPointFValueType::x() const
198 qreal QQmlPointFValueType::y() const
203 void QQmlPointFValueType::setX(qreal x)
208 void QQmlPointFValueType::setY(qreal y)
214 QQmlPointValueType::QQmlPointValueType(QObject *parent)
215 : QQmlValueTypeBase<QPoint>(QMetaType::QPoint, parent)
219 QString QQmlPointValueType::toString() const
221 return QString(QLatin1String("QPoint(%1, %2)")).arg(v.x()).arg(v.y());
224 int QQmlPointValueType::x() const
229 int QQmlPointValueType::y() const
234 void QQmlPointValueType::setX(int x)
239 void QQmlPointValueType::setY(int y)
245 QQmlSizeFValueType::QQmlSizeFValueType(QObject *parent)
246 : QQmlValueTypeBase<QSizeF>(QMetaType::QSizeF, parent)
250 QString QQmlSizeFValueType::toString() const
252 return QString(QLatin1String("QSizeF(%1, %2)")).arg(v.width()).arg(v.height());
255 qreal QQmlSizeFValueType::width() const
260 qreal QQmlSizeFValueType::height() const
265 void QQmlSizeFValueType::setWidth(qreal w)
270 void QQmlSizeFValueType::setHeight(qreal h)
276 QQmlSizeValueType::QQmlSizeValueType(QObject *parent)
277 : QQmlValueTypeBase<QSize>(QMetaType::QSize, parent)
281 QString QQmlSizeValueType::toString() const
283 return QString(QLatin1String("QSize(%1, %2)")).arg(v.width()).arg(v.height());
286 int QQmlSizeValueType::width() const
291 int QQmlSizeValueType::height() const
296 void QQmlSizeValueType::setWidth(int w)
301 void QQmlSizeValueType::setHeight(int h)
307 QQmlRectFValueType::QQmlRectFValueType(QObject *parent)
308 : QQmlValueTypeBase<QRectF>(QMetaType::QRectF, parent)
312 QString QQmlRectFValueType::toString() const
314 return QString(QLatin1String("QRectF(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.width()).arg(v.height());
317 qreal QQmlRectFValueType::x() const
322 qreal QQmlRectFValueType::y() const
327 void QQmlRectFValueType::setX(qreal x)
332 void QQmlRectFValueType::setY(qreal y)
337 qreal QQmlRectFValueType::width() const
342 qreal QQmlRectFValueType::height() const
347 void QQmlRectFValueType::setWidth(qreal w)
352 void QQmlRectFValueType::setHeight(qreal h)
358 QQmlRectValueType::QQmlRectValueType(QObject *parent)
359 : QQmlValueTypeBase<QRect>(QMetaType::QRect, parent)
363 QString QQmlRectValueType::toString() const
365 return QString(QLatin1String("QRect(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.width()).arg(v.height());
368 int QQmlRectValueType::x() const
373 int QQmlRectValueType::y() const
378 void QQmlRectValueType::setX(int x)
383 void QQmlRectValueType::setY(int y)
388 int QQmlRectValueType::width() const
393 int QQmlRectValueType::height() const
398 void QQmlRectValueType::setWidth(int w)
403 void QQmlRectValueType::setHeight(int h)
409 QQmlEasingValueType::QQmlEasingValueType(QObject *parent)
410 : QQmlValueTypeBase<QEasingCurve>(QMetaType::QEasingCurve, parent)
414 QString QQmlEasingValueType::toString() const
416 return QString(QLatin1String("QEasingCurve(%1, %2, %3, %4)")).arg(v.type()).arg(v.amplitude()).arg(v.overshoot()).arg(v.period());
419 QQmlEasingValueType::Type QQmlEasingValueType::type() const
421 return (QQmlEasingValueType::Type)v.type();
424 qreal QQmlEasingValueType::amplitude() const
426 return v.amplitude();
429 qreal QQmlEasingValueType::overshoot() const
431 return v.overshoot();
434 qreal QQmlEasingValueType::period() const
439 void QQmlEasingValueType::setType(QQmlEasingValueType::Type type)
441 v.setType((QEasingCurve::Type)type);
444 void QQmlEasingValueType::setAmplitude(qreal amplitude)
446 v.setAmplitude(amplitude);
449 void QQmlEasingValueType::setOvershoot(qreal overshoot)
451 v.setOvershoot(overshoot);
454 void QQmlEasingValueType::setPeriod(qreal period)
459 void QQmlEasingValueType::setBezierCurve(const QVariantList &customCurveVariant)
461 if (customCurveVariant.isEmpty())
464 QVariantList variantList = customCurveVariant;
465 if ((variantList.count() % 6) == 0) {
466 bool allRealsOk = true;
468 for (int i = 0; i < variantList.count(); i++) {
470 const qreal real = variantList.at(i).toReal(&ok);
476 QEasingCurve newEasingCurve(QEasingCurve::BezierSpline);
477 for (int i = 0; i < reals.count() / 6; i++) {
478 const qreal c1x = reals.at(i * 6);
479 const qreal c1y = reals.at(i * 6 + 1);
480 const qreal c2x = reals.at(i * 6 + 2);
481 const qreal c2y = reals.at(i * 6 + 3);
482 const qreal c3x = reals.at(i * 6 + 4);
483 const qreal c3y = reals.at(i * 6 + 5);
485 const QPointF c1(c1x, c1y);
486 const QPointF c2(c2x, c2y);
487 const QPointF c3(c3x, c3y);
489 newEasingCurve.addCubicBezierSegment(c1, c2, c3);
496 QVariantList QQmlEasingValueType::bezierCurve() const
499 QVector<QPointF> points = v.toCubicSpline();
500 for (int ii = 0; ii < points.count(); ++ii)
501 rv << QVariant(points.at(ii).x()) << QVariant(points.at(ii).y());