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 <private/qquickvaluetypes_p.h>
43 #include <private/qquickapplication_p.h>
44 #include <private/qqmlglobal_p.h>
46 #include <QtGui/QGuiApplication>
47 #include <QtGui/qdesktopservices.h>
48 #include <QtGui/qfontdatabase.h>
53 class QQuickColorProvider : public QQmlColorProvider
56 static inline QColor QColorFromString(const QString &s)
58 // Should we also handle #rrggbb here?
59 if (s.length() == 9 && s.startsWith(QLatin1Char('#'))) {
60 uchar a = fromHex(s, 1);
61 uchar r = fromHex(s, 3);
62 uchar g = fromHex(s, 5);
63 uchar b = fromHex(s, 7);
64 return QColor(r, g, b, a);
70 QVariant colorFromString(const QString &s, bool *ok)
72 QColor c(QColorFromString(s));
82 unsigned rgbaFromString(const QString &s, bool *ok)
84 QColor c(QColorFromString(s));
94 QString stringFromRgba(unsigned rgba)
96 QColor c(QColor::fromRgba(rgba));
98 return QVariant(c).toString();
104 QVariant fromRgbF(double r, double g, double b, double a)
106 return QVariant(QColor::fromRgbF(r, g, b, a));
109 QVariant fromHslF(double h, double s, double l, double a)
111 return QVariant(QColor::fromHslF(h, s, l, a));
114 QVariant lighter(const QVariant &var, qreal factor)
116 QColor color = var.value<QColor>();
117 color = color.lighter(int(qRound(factor*100.)));
118 return QVariant::fromValue(color);
121 QVariant darker(const QVariant &var, qreal factor)
123 QColor color = var.value<QColor>();
124 color = color.darker(int(qRound(factor*100.)));
125 return QVariant::fromValue(color);
128 QVariant tint(const QVariant &baseVar, const QVariant &tintVar)
130 QColor tintColor = tintVar.value<QColor>();
132 int tintAlpha = tintColor.alpha();
133 if (tintAlpha == 0xFF) {
135 } else if (tintAlpha == 0x00) {
139 // tint the base color and return the final color
140 QColor baseColor = baseVar.value<QColor>();
141 qreal a = tintColor.alphaF();
142 qreal inv_a = 1.0 - a;
144 qreal r = tintColor.redF() * a + baseColor.redF() * inv_a;
145 qreal g = tintColor.greenF() * a + baseColor.greenF() * inv_a;
146 qreal b = tintColor.blueF() * a + baseColor.blueF() * inv_a;
148 return QVariant::fromValue(QColor::fromRgbF(r, g, b, a + inv_a * baseColor.alphaF()));
152 static uchar fromHex(const uchar c, const uchar c2)
155 if (c >= '0' && c <= '9')
156 rv += (c - '0') * 16;
157 else if (c >= 'A' && c <= 'F')
158 rv += (c - 'A' + 10) * 16;
159 else if (c >= 'a' && c <= 'f')
160 rv += (c - 'a' + 10) * 16;
162 if (c2 >= '0' && c2 <= '9')
164 else if (c2 >= 'A' && c2 <= 'F')
165 rv += (c2 - 'A' + 10);
166 else if (c2 >= 'a' && c2 <= 'f')
167 rv += (c2 - 'a' + 10);
172 static inline uchar fromHex(const QString &s, int idx)
174 uchar c = s.at(idx).toLatin1();
175 uchar c2 = s.at(idx + 1).toLatin1();
176 return fromHex(c, c2);
181 // Note: The functions in this class provide handling only for the types
182 // that the QML engine will currently actually call them for, so many
183 // appear incompletely implemented. For some functions, the implementation
184 // would be obvious, but for others (particularly create and createFromString)
185 // the exact semantics are unknown. For this reason unused functionality
188 class QQuickValueTypeProvider : public QQmlValueTypeProvider
191 static QVector3D vector3DFromString(const QString &s, bool *ok)
193 if (s.count(QLatin1Char(',')) == 2) {
194 int index = s.indexOf(QLatin1Char(','));
195 int index2 = s.indexOf(QLatin1Char(','), index+1);
197 bool xGood, yGood, zGood;
198 qreal xCoord = s.left(index).toDouble(&xGood);
199 qreal yCoord = s.mid(index+1, index2-index-1).toDouble(&yGood);
200 qreal zCoord = s.mid(index2+1).toDouble(&zGood);
202 if (xGood && yGood && zGood) {
204 return QVector3D(xCoord, yCoord, zCoord);
212 static QVector4D vector4DFromString(const QString &s, bool *ok)
214 if (s.count(QLatin1Char(',')) == 3) {
215 int index = s.indexOf(QLatin1Char(','));
216 int index2 = s.indexOf(QLatin1Char(','), index+1);
217 int index3 = s.indexOf(QLatin1Char(','), index2+1);
219 bool xGood, yGood, zGood, wGood;
220 qreal xCoord = s.left(index).toDouble(&xGood);
221 qreal yCoord = s.mid(index+1, index2-index-1).toDouble(&yGood);
222 qreal zCoord = s.mid(index2+1, index3-index2-1).toDouble(&zGood);
223 qreal wCoord = s.mid(index3+1).toDouble(&wGood);
225 if (xGood && yGood && zGood && wGood) {
227 return QVector4D(xCoord, yCoord, zCoord, wCoord);
235 bool create(int type, QQmlValueType *&v)
238 case QMetaType::QColor:
239 v = new QQuickColorValueType;
241 case QMetaType::QVector2D:
242 v = new QQuickVector2DValueType;
244 case QMetaType::QVector3D:
245 v = new QQuickVector3DValueType;
247 case QMetaType::QVector4D:
248 v = new QQuickVector4DValueType;
250 case QMetaType::QQuaternion:
251 v = new QQuickQuaternionValueType;
253 case QMetaType::QMatrix4x4:
254 v = new QQuickMatrix4x4ValueType;
256 case QMetaType::QFont:
257 v = new QQuickFontValueType;
264 bool init(int type, void *data, size_t n)
266 if (type == QMetaType::QColor) {
267 Q_ASSERT(n >= sizeof(QColor));
268 QColor *color = reinterpret_cast<QColor *>(data);
269 new (color) QColor();
276 bool destroy(int type, void *data, size_t n)
278 if (type == QMetaType::QColor) {
279 Q_ASSERT(n >= sizeof(QColor));
280 QColor *color = reinterpret_cast<QColor *>(data);
288 bool copy(int type, const void *src, void *dst, size_t n)
290 if (type == QMetaType::QColor) {
291 Q_ASSERT(n >= sizeof(QColor));
292 const QColor *srcColor = reinterpret_cast<const QColor *>(src);
293 QColor *dstColor = reinterpret_cast<QColor *>(dst);
294 new (dstColor) QColor(*srcColor);
301 bool create(int type, int argc, const void *argv[], QVariant *v)
304 case QMetaType::QVector3D:
306 const float *xyz = reinterpret_cast<const float*>(argv[0]);
307 QVector3D v3(xyz[0], xyz[1], xyz[2]);
312 case QMetaType::QVector4D:
314 const float *xyzw = reinterpret_cast<const float*>(argv[0]);
315 QVector4D v4(xyzw[0], xyzw[1], xyzw[2], xyzw[3]);
325 bool createFromString(int type, const QString &s, void *data, size_t n)
330 case QMetaType::QColor:
332 Q_ASSERT(n >= sizeof(QColor));
333 QColor *color = reinterpret_cast<QColor *>(data);
334 new (color) QColor(QQuickColorProvider::QColorFromString(s));
337 case QMetaType::QVector3D:
339 Q_ASSERT(n >= sizeof(QVector3D));
340 QVector3D *v3 = reinterpret_cast<QVector3D *>(data);
341 new (v3) QVector3D(vector3DFromString(s, &ok));
344 case QMetaType::QVector4D:
346 Q_ASSERT(n >= sizeof(QVector4D));
347 QVector4D *v4 = reinterpret_cast<QVector4D *>(data);
348 new (v4) QVector4D(vector4DFromString(s, &ok));
356 bool createStringFrom(int type, const void *data, QString *s)
358 if (type == QMetaType::QColor) {
359 const QColor *color = reinterpret_cast<const QColor *>(data);
360 new (s) QString(QVariant(*color).toString());
367 bool variantFromString(const QString &s, QVariant *v)
369 QColor c(QQuickColorProvider::QColorFromString(s));
371 *v = QVariant::fromValue(c);
377 QVector3D v3 = vector3DFromString(s, &ok);
379 *v = QVariant::fromValue(v3);
383 QVector4D v4 = vector4DFromString(s, &ok);
385 *v = QVariant::fromValue(v4);
392 bool variantFromString(int type, const QString &s, QVariant *v)
397 case QMetaType::QColor:
399 QColor c(QQuickColorProvider::QColorFromString(s));
400 *v = QVariant::fromValue(c);
403 case QMetaType::QVector3D:
404 *v = QVariant::fromValue(vector3DFromString(s, &ok));
406 case QMetaType::QVector4D:
407 *v = QVariant::fromValue(vector4DFromString(s, &ok));
415 bool typedEqual(const void *lhs, const void *rhs)
417 return (*(reinterpret_cast<const T *>(lhs)) == *(reinterpret_cast<const T *>(rhs)));
420 bool equal(int type, const void *lhs, const void *rhs)
423 case QMetaType::QColor:
424 return typedEqual<QColor>(lhs, rhs);
425 case QMetaType::QVector3D:
426 return typedEqual<QVector3D>(lhs, rhs);
427 case QMetaType::QVector4D:
428 return typedEqual<QVector4D>(lhs, rhs);
434 bool store(int type, const void *src, void *dst, size_t n)
437 case QMetaType::QColor:
439 Q_ASSERT(n >= sizeof(QColor));
440 const QRgb *rgb = reinterpret_cast<const QRgb *>(src);
441 QColor *color = reinterpret_cast<QColor *>(dst);
442 new (color) QColor(QColor::fromRgba(*rgb));
445 case QMetaType::QVector3D:
447 Q_ASSERT(n >= sizeof(QVector3D));
448 const QVector3D *srcVector = reinterpret_cast<const QVector3D *>(src);
449 QVector3D *dstVector = reinterpret_cast<QVector3D *>(dst);
450 new (dstVector) QVector3D(*srcVector);
453 case QMetaType::QVector4D:
455 Q_ASSERT(n >= sizeof(QVector4D));
456 const QVector4D *srcVector = reinterpret_cast<const QVector4D *>(src);
457 QVector4D *dstVector = reinterpret_cast<QVector4D *>(dst);
458 new (dstVector) QVector4D(*srcVector);
466 bool read(int srcType, const void *src, int dstType, void *dst)
468 if (dstType == QMetaType::QColor) {
469 QColor *dstColor = reinterpret_cast<QColor *>(dst);
470 if (srcType == QMetaType::QColor) {
471 const QColor *srcColor = reinterpret_cast<const QColor *>(src);
472 *dstColor = *srcColor;
474 *dstColor = QColor();
482 bool write(int type, const void *src, void *dst, size_t n)
484 if (type == QMetaType::QColor) {
485 Q_ASSERT(n >= sizeof(QColor));
486 const QColor *srcColor = reinterpret_cast<const QColor *>(src);
487 QColor *dstColor = reinterpret_cast<QColor *>(dst);
488 if (*dstColor != *srcColor) {
489 *dstColor = *srcColor;
499 class QQuickGuiProvider : public QQmlGuiProvider
502 QQuickApplication *application(QObject *parent)
504 return new QQuickApplication(parent);
507 QInputMethod *inputMethod()
509 return qGuiApp->inputMethod();
512 QStringList fontFamilies()
514 QFontDatabase database;
515 return database.families();
518 bool openUrlExternally(QUrl &url)
520 #ifndef QT_NO_DESKTOPSERVICES
521 return QDesktopServices::openUrl(url);
529 static QQuickValueTypeProvider *getValueTypeProvider()
531 static QQuickValueTypeProvider valueTypeProvider;
532 return &valueTypeProvider;
535 static QQuickColorProvider *getColorProvider()
537 static QQuickColorProvider colorProvider;
538 return &colorProvider;
541 static QQuickGuiProvider *getGuiProvider()
543 static QQuickGuiProvider guiProvider;
547 static bool initializeProviders()
549 QQml_addValueTypeProvider(getValueTypeProvider());
550 QQml_setColorProvider(getColorProvider());
551 QQml_setGuiProvider(getGuiProvider());
555 static bool initialized = initializeProviders();