aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/util/qquickvaluetypes.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-09-21 10:40:27 +0200
committerUlf Hermann <ulf.hermann@qt.io>2020-10-02 13:21:09 +0200
commit45594322fe91eadcd9b2d7b1d76c1a6662bc1472 (patch)
treed14e743f40351ca7a660984616b2500aa83032f5 /src/quick/util/qquickvaluetypes.cpp
parentd621027babff9a30d56ab6af871a465108c9eaba (diff)
Use factory functions and ctors for creating value types
As you can extend value types with QML_EXTENDED we may as well allow a factory function in the extended type. Furthermore, if the original type allows construction from QJSValue, we may just use that. In turn, we can get rid of the value type providers now. Change-Id: I9124ea47537eab6c33d7451080ab2fff942eaa7b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/quick/util/qquickvaluetypes.cpp')
-rw-r--r--src/quick/util/qquickvaluetypes.cpp220
1 files changed, 220 insertions, 0 deletions
diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp
index 5bbfdbcbea..cbd641fecf 100644
--- a/src/quick/util/qquickvaluetypes.cpp
+++ b/src/quick/util/qquickvaluetypes.cpp
@@ -46,6 +46,11 @@
QT_BEGIN_NAMESPACE
+QVariant QQuickColorValueType::create(const QJSValue &params)
+{
+ return params.isString() ? QColor(params.toString()) : QVariant();
+}
+
QString QQuickColorValueType::toString() const
{
return v.name(v.alpha() != 255 ? QColor::HexArgb : QColor::HexRgb);
@@ -188,6 +193,53 @@ void QQuickColorValueType::setHslLightness(qreal hslLightness)
v.setHslF(hue, saturation, hslLightness, alpha);
}
+template<typename T, int NumParams>
+QVariant createValueTypeFromNumberString(const QString &s)
+{
+ Q_STATIC_ASSERT_X(NumParams == 2 || NumParams == 3 || NumParams == 4 || NumParams == 16,
+ "Unsupported number of params; add an additional case below if necessary.");
+
+ if (s.count(u',') != NumParams - 1)
+ return QVariant();
+
+ QVarLengthArray<float, NumParams> parameters;
+ bool ok = true;
+ for (qsizetype prev = 0, next = s.indexOf(u','), length = s.length(); ok && prev < length;) {
+ parameters.append(s.mid(prev, next - prev).toFloat(&ok));
+ prev = next + 1;
+ next = (parameters.length() == NumParams - 1) ? length : s.indexOf(u',', prev);
+ }
+
+ if (!ok)
+ return QVariant();
+
+ if constexpr (NumParams == 2) {
+ return T(parameters[0], parameters[1]);
+ } else if constexpr (NumParams == 3) {
+ return T(parameters[0], parameters[1], parameters[2]);
+ } else if constexpr (NumParams == 4) {
+ return T(parameters[0], parameters[1], parameters[2], parameters[3]);
+ } else if constexpr (NumParams == 16) {
+ return T(parameters[0], parameters[1], parameters[2], parameters[3],
+ parameters[4], parameters[5], parameters[6], parameters[7],
+ parameters[8], parameters[9], parameters[10], parameters[11],
+ parameters[12], parameters[13], parameters[14], parameters[15]);
+ } else {
+ Q_UNREACHABLE();
+ }
+
+ return QVariant();
+}
+
+QVariant QQuickVector2DValueType::create(const QJSValue &params)
+{
+ if (params.isString())
+ return createValueTypeFromNumberString<QVector2D, 2>(params.toString());
+ if (params.isArray())
+ return QVector2D(params.property(0).toNumber(), params.property(1).toNumber());
+ return QVariant();
+}
+
QString QQuickVector2DValueType::toString() const
{
return QString(QLatin1String("QVector2D(%1, %2)")).arg(v.x()).arg(v.y());
@@ -273,6 +325,18 @@ bool QQuickVector2DValueType::fuzzyEquals(const QVector2D &vec) const
return qFuzzyCompare(v, vec);
}
+QVariant QQuickVector3DValueType::create(const QJSValue &params)
+{
+ if (params.isString())
+ return createValueTypeFromNumberString<QVector3D, 3>(params.toString());
+
+ if (params.isArray()) {
+ return QVector3D(params.property(0).toNumber(), params.property(1).toNumber(),
+ params.property(2).toNumber());
+ }
+ return QVariant();
+}
+
QString QQuickVector3DValueType::toString() const
{
return QString(QLatin1String("QVector3D(%1, %2, %3)")).arg(v.x()).arg(v.y()).arg(v.z());
@@ -380,6 +444,19 @@ bool QQuickVector3DValueType::fuzzyEquals(const QVector3D &vec) const
return qFuzzyCompare(v, vec);
}
+QVariant QQuickVector4DValueType::create(const QJSValue &params)
+{
+ if (params.isString())
+ return createValueTypeFromNumberString<QVector4D, 4>(params.toString());
+
+ if (params.isArray()) {
+ return QVector4D(params.property(0).toNumber(), params.property(1).toNumber(),
+ params.property(2).toNumber(), params.property(3).toNumber());
+ }
+
+ return QVariant();
+}
+
QString QQuickVector4DValueType::toString() const
{
return QString(QLatin1String("QVector4D(%1, %2, %3, %4)")).arg(v.x()).arg(v.y()).arg(v.z()).arg(v.w());
@@ -494,6 +571,19 @@ bool QQuickVector4DValueType::fuzzyEquals(const QVector4D &vec) const
return qFuzzyCompare(v, vec);
}
+QVariant QQuickQuaternionValueType::create(const QJSValue &params)
+{
+ if (params.isString())
+ return createValueTypeFromNumberString<QQuaternion, 4>(params.toString());
+
+ if (params.isArray()) {
+ return QQuaternion(params.property(0).toNumber(), params.property(1).toNumber(),
+ params.property(2).toNumber(), params.property(3).toNumber());
+ }
+
+ return QVariant();
+}
+
QString QQuickQuaternionValueType::toString() const
{
return QString(QLatin1String("QQuaternion(%1, %2, %3, %4)")).arg(v.scalar()).arg(v.x()).arg(v.y()).arg(v.z());
@@ -539,6 +629,36 @@ void QQuickQuaternionValueType::setZ(qreal z)
v.setZ(z);
}
+QVariant QQuickMatrix4x4ValueType::create(const QJSValue &params)
+{
+ if (params.isNull() || params.isUndefined())
+ return QMatrix4x4();
+
+ if (params.isString())
+ return createValueTypeFromNumberString<QMatrix4x4, 16>(params.toString());
+
+ if (params.isArray() && params.property(QStringLiteral("length")).toInt() == 16) {
+ return QMatrix4x4(params.property(0).toNumber(),
+ params.property(1).toNumber(),
+ params.property(2).toNumber(),
+ params.property(3).toNumber(),
+ params.property(4).toNumber(),
+ params.property(5).toNumber(),
+ params.property(6).toNumber(),
+ params.property(7).toNumber(),
+ params.property(8).toNumber(),
+ params.property(9).toNumber(),
+ params.property(10).toNumber(),
+ params.property(11).toNumber(),
+ params.property(12).toNumber(),
+ params.property(13).toNumber(),
+ params.property(14).toNumber(),
+ params.property(15).toNumber());
+ }
+
+ return QVariant();
+}
+
QMatrix4x4 QQuickMatrix4x4ValueType::times(const QMatrix4x4 &m) const
{
return v * m;
@@ -612,6 +732,78 @@ bool QQuickMatrix4x4ValueType::fuzzyEquals(const QMatrix4x4 &m) const
return qFuzzyCompare(v, m);
}
+template<typename T>
+void setFontProperty(QFont &font, void (QFont::*setter)(T value), QString name,
+ const QJSValue &params, bool *ok)
+{
+ const QJSValue value = params.property(name);
+
+ if constexpr (std::is_same_v<T, bool>) {
+ if (value.isBool()) {
+ (font.*setter)(value.toBool());
+ *ok = true;
+ }
+ } else if constexpr (std::is_same_v<
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type,
+ QString>) {
+ if (value.isString()) {
+ (font.*setter)(value.toString());
+ *ok = true;
+ }
+ } else if constexpr (std::is_integral_v<T> || std::is_enum_v<T>) {
+ if (value.isNumber()) {
+ (font.*setter)(T(value.toInt()));
+ *ok = true;
+ }
+ } else if constexpr (std::is_floating_point_v<T>) {
+ if (value.isNumber()) {
+ (font.*setter)(value.toNumber());
+ *ok = true;
+ }
+ }
+}
+
+QVariant QQuickFontValueType::create(const QJSValue &params)
+{
+ if (!params.isObject())
+ return QVariant();
+
+ bool ok = false;
+ QFont ret;
+
+ setFontProperty(ret, &QFont::setBold, QStringLiteral("bold"), params, &ok);
+ setFontProperty(ret, &QFont::setCapitalization, QStringLiteral("capitalization"), params, &ok);
+ setFontProperty(ret, &QFont::setFamily, QStringLiteral("family"), params, &ok);
+ setFontProperty(ret, &QFont::setItalic, QStringLiteral("italic"), params, &ok);
+ setFontProperty(ret, &QFont::setPixelSize, QStringLiteral("pixelSize"), params, &ok);
+ setFontProperty(ret, &QFont::setPointSize, QStringLiteral("pointSize"), params, &ok);
+ setFontProperty(ret, &QFont::setStrikeOut, QStringLiteral("strikeout"), params, &ok);
+ setFontProperty(ret, &QFont::setUnderline, QStringLiteral("underline"), params, &ok);
+ setFontProperty(ret, &QFont::setWeight, QStringLiteral("weight"), params, &ok);
+ setFontProperty(ret, &QFont::setWordSpacing, QStringLiteral("wordSpacing"), params, &ok);
+ setFontProperty(ret, &QFont::setHintingPreference, QStringLiteral("hintingPreference"), params, &ok);
+ setFontProperty(ret, &QFont::setKerning, QStringLiteral("kerning"), params, &ok);
+
+ const QJSValue vlspac = params.property(QStringLiteral("letterSpacing"));
+ if (vlspac.isNumber()) {
+ ret.setLetterSpacing(QFont::AbsoluteSpacing, vlspac.toNumber());
+ ok = true;
+ }
+
+ const QJSValue vshaping = params.property(QStringLiteral("preferShaping"));
+ if (vshaping.isBool()) {
+ const bool enable = vshaping.toBool();
+ const QFont::StyleStrategy strategy = ret.styleStrategy();
+ if (enable)
+ ret.setStyleStrategy(QFont::StyleStrategy(strategy & ~QFont::PreferNoShaping));
+ else
+ ret.setStyleStrategy(QFont::StyleStrategy(strategy | QFont::PreferNoShaping));
+ ok = true;
+ }
+
+ return ok ? ret : QVariant();
+}
+
QString QQuickFontValueType::toString() const
{
return QString(QLatin1String("QFont(%1)")).arg(v.toString());
@@ -797,6 +989,34 @@ void QQuickFontValueType::setPreferShaping(bool enable)
v.setStyleStrategy(static_cast<QFont::StyleStrategy>(v.styleStrategy() | QFont::PreferNoShaping));
}
+QVariant QQuickColorSpaceValueType::create(const QJSValue &params)
+{
+ if (!params.isObject())
+ return QVariant();
+
+
+ const QJSValue vName = params.property(QStringLiteral("namedColorSpace"));
+ if (vName.isNumber())
+ return QColorSpace((QColorSpace::NamedColorSpace)vName.toInt());
+
+ const QJSValue vPri = params.property(QStringLiteral("primaries"));
+ const QJSValue vTra = params.property(QStringLiteral("transferFunction"));
+ if (!vPri.isNumber() || !vTra.isNumber())
+ return QVariant();
+
+ QColorSpace::Primaries pri = static_cast<QColorSpace::Primaries>(vPri.toInt());
+ QColorSpace::TransferFunction tra = static_cast<QColorSpace::TransferFunction>(vTra.toInt());
+ float gamma = 0.0f;
+ if (tra == QColorSpace::TransferFunction::Gamma) {
+ const QJSValue vGam = params.property(QStringLiteral("gamma"));
+ if (!vGam.isNumber())
+ return QVariant();
+ gamma = vGam.toNumber();
+ }
+
+ return QColorSpace(pri, tra, gamma);
+}
+
QQuickColorSpaceEnums::NamedColorSpace QQuickColorSpaceValueType::namedColorSpace() const noexcept
{
if (const auto *p = QColorSpacePrivate::get(v))