From: Chris Adams Date: Tue, 2 Aug 2011 23:20:18 +0000 (+1000) Subject: Make QColor a value type X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=36767e3fe1f0038441ae06ef5b5e1cb19a3738fa;p=konrad%2Fqtdeclarative.git Make QColor a value type This commit allows direct access to the r, g, b and a components of a color (in floating point format: 0 <= v <= 1). Since conversion from color to string is a common operation, this commit also adds unit tests to ensure that the previous behaviour is maintained in other cases (comparison with toString value, etc). Task-number: QTBUG-14731 Change-Id: I87b521dd4f9c1e96dfe5b20cf8053293cb14cfe4 Reviewed-on: http://codereview.qt.nokia.com/2527 Reviewed-by: Qt Sanity Bot Reviewed-by: Aaron Kennedy --- diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index 4aedf3e..3e77f4b 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -152,6 +152,9 @@ QDeclarativeValueType *QDeclarativeValueTypeFactory::valueType(int t) case QVariant::Font: rv = new QDeclarativeFontValueType; break; + case QVariant::Color: + rv = new QDeclarativeColorValueType; + break; default: break; } @@ -1143,4 +1146,83 @@ void QDeclarativeFontValueType::setWordSpacing(qreal size) font.setWordSpacing(size); } +QDeclarativeColorValueType::QDeclarativeColorValueType(QObject *parent) +: QDeclarativeValueType(parent) +{ +} + +void QDeclarativeColorValueType::read(QObject *obj, int idx) +{ + void *a[] = { &color, 0 }; + QMetaObject::metacall(obj, QMetaObject::ReadProperty, idx, a); +} + +void QDeclarativeColorValueType::write(QObject *obj, int idx, QDeclarativePropertyPrivate::WriteFlags flags) +{ + int status = -1; + void *a[] = { &color, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, idx, a); +} + +QVariant QDeclarativeColorValueType::value() +{ + return QVariant(color); +} + +void QDeclarativeColorValueType::setValue(QVariant value) +{ + color = qvariant_cast(value); +} + +QString QDeclarativeColorValueType::toString() const +{ + // special case - to maintain behaviour with QtQuick 1.0, we just output normal toString() value. + return QVariant(color).toString(); +} + +bool QDeclarativeColorValueType::isEqual(const QVariant &value) const +{ + return (QVariant(color) == value); +} + +qreal QDeclarativeColorValueType::r() const +{ + return color.redF(); +} + +qreal QDeclarativeColorValueType::g() const +{ + return color.greenF(); +} + +qreal QDeclarativeColorValueType::b() const +{ + return color.blueF(); +} + +qreal QDeclarativeColorValueType::a() const +{ + return color.alphaF(); +} + +void QDeclarativeColorValueType::setR(qreal r) +{ + color.setRedF(r); +} + +void QDeclarativeColorValueType::setG(qreal g) +{ + color.setGreenF(g); +} + +void QDeclarativeColorValueType::setB(qreal b) +{ + color.setBlueF(b); +} + +void QDeclarativeColorValueType::setA(qreal a) +{ + color.setAlphaF(a); +} + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativevaluetype_p.h b/src/declarative/qml/qdeclarativevaluetype_p.h index 01a1765..03cb83f 100644 --- a/src/declarative/qml/qdeclarativevaluetype_p.h +++ b/src/declarative/qml/qdeclarativevaluetype_p.h @@ -582,6 +582,36 @@ private: mutable QDeclarativeNullableValue dpi; }; +class Q_AUTOTEST_EXPORT QDeclarativeColorValueType : public QDeclarativeValueType +{ + Q_PROPERTY(qreal r READ r WRITE setR) + Q_PROPERTY(qreal g READ g WRITE setG) + Q_PROPERTY(qreal b READ b WRITE setB) + Q_PROPERTY(qreal a READ a WRITE setA) + Q_OBJECT +public: + QDeclarativeColorValueType(QObject *parent = 0); + + virtual void read(QObject *, int); + virtual void write(QObject *, int, QDeclarativePropertyPrivate::WriteFlags); + virtual QVariant value(); + virtual void setValue(QVariant value); + virtual QString toString() const; + virtual bool isEqual(const QVariant &value) const; + + qreal r() const; + qreal g() const; + qreal b() const; + qreal a() const; + void setR(qreal); + void setG(qreal); + void setB(qreal); + void setA(qreal); + +private: + QColor color; +}; + QT_END_NAMESPACE #endif // QDECLARATIVEVALUETYPE_P_H diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/color_compare.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/color_compare.qml new file mode 100644 index 0000000..8701dae --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/color_compare.qml @@ -0,0 +1,37 @@ +import Test 1.0 + +MyTypeObject { + property real v_r: color.r + property real v_g: color.g + property real v_b: color.b + property real v_a: color.a + property variant copy: color + property string colorToString: color.toString() + + // compare different colors + property bool colorEqualsIdenticalRgba: (color == Qt.rgba(0.2, 0.88, 0.6, 0.34)) // true + property bool colorEqualsDifferentAlpha: (color == Qt.rgba(0.2, 0.88, 0.6, 0.44)) // false + property bool colorEqualsDifferentRgba: (color == Qt.rgba(0.3, 0.98, 0.7, 0.44)) // false + + // compare different color.toString()s + property bool colorToStringEqualsColorString: (color.toString() == colorToString) // true + property bool colorToStringEqualsDifferentAlphaString: (color.toString() == Qt.rgba(0.2, 0.88, 0.6, 0.44).toString()) // true + property bool colorToStringEqualsDifferentRgbaString: (color.toString() == Qt.rgba(0.3, 0.98, 0.7, 0.44).toString()) // false + + // compare colors to strings + property bool colorEqualsColorString: (color == colorToString) // false + property bool colorEqualsDifferentAlphaString: (color == Qt.rgba(0.2, 0.88, 0.6, 0.44).toString()) // false + property bool colorEqualsDifferentRgbaString: (color == Qt.rgba(0.3, 0.98, 0.7, 0.44).toString()) // false + + // compare colors to various value types + property bool equalsColor: (color == Qt.rgba(0.2, 0.88, 0.6, 0.34)) // true + property bool equalsVector3d: (color == Qt.vector3d(1, 2, 3)) // false + property bool equalsSize: (color == Qt.size(1912, 1913)) // false + property bool equalsPoint: (color == Qt.point(10, 4)) // false + property bool equalsRect: (color == Qt.rect(2, 3, 109, 102)) // false + + // ensure comparison directionality doesn't matter + property bool equalsColorRHS: (Qt.rgba(0.2, 0.88, 0.6, 0.34) == color) // true + property bool colorEqualsCopy: (color == copy) // true + property bool copyEqualsColor: (copy == color) // true +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/color_read.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/color_read.qml new file mode 100644 index 0000000..bc92b1e --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/color_read.qml @@ -0,0 +1,9 @@ +import Test 1.0 + +MyTypeObject { + property real v_r: color.r + property real v_g: color.g + property real v_b: color.b + property real v_a: color.a + property variant copy: color +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/data/color_write.qml b/tests/auto/declarative/qdeclarativevaluetypes/data/color_write.qml new file mode 100644 index 0000000..3f1bad4 --- /dev/null +++ b/tests/auto/declarative/qdeclarativevaluetypes/data/color_write.qml @@ -0,0 +1,8 @@ +import Test 1.0 + +MyTypeObject { + color.r: if (true) 0.5 + color.g: if (true) 0.38 + color.b: if (true) 0.3 + color.a: if (true) 0.7 +} diff --git a/tests/auto/declarative/qdeclarativevaluetypes/testtypes.h b/tests/auto/declarative/qdeclarativevaluetypes/testtypes.h index 1efab0c..5eb6bf6 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/testtypes.h +++ b/tests/auto/declarative/qdeclarativevaluetypes/testtypes.h @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -79,6 +80,7 @@ class MyTypeObject : public QObject Q_PROPERTY(QQuaternion quaternion READ quaternion WRITE setQuaternion NOTIFY changed) Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY changed) Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY changed) + Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY changed) Q_PROPERTY(QVariant variant READ variant NOTIFY changed) public: @@ -109,6 +111,10 @@ public: m_font.setCapitalization(QFont::AllLowercase); m_font.setLetterSpacing(QFont::AbsoluteSpacing, 10.2); m_font.setWordSpacing(19.7); + m_color.setRedF(0.2); + m_color.setGreenF(0.88); + m_color.setBlueF(0.6); + m_color.setAlphaF(0.34); } QPoint m_point; @@ -171,6 +177,10 @@ public: QFont font() const { return m_font; } void setFont(const QFont &v) { m_font = v; emit changed(); } + QColor m_color; + QColor color() const { return m_color; } + void setColor(const QColor &v) { m_color = v; emit changed(); } + QVariant variant() const { return sizef(); } void emitRunScript() { emit runScript(); } diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp index 5869310..89d0e7e 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp +++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp @@ -77,6 +77,7 @@ private slots: void quaternion(); void matrix4x4(); void font(); + void color(); void variant(); void bindingAssignment(); @@ -807,6 +808,73 @@ void tst_qdeclarativevaluetypes::font() } } +void tst_qdeclarativevaluetypes::color() +{ + { + QDeclarativeComponent component(&engine, TEST_FILE("color_read.qml")); + MyTypeObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + + QCOMPARE((float)object->property("v_r").toDouble(), (float)0.2); + QCOMPARE((float)object->property("v_g").toDouble(), (float)0.88); + QCOMPARE((float)object->property("v_b").toDouble(), (float)0.6); + QCOMPARE((float)object->property("v_a").toDouble(), (float)0.34); + QColor comparison; + comparison.setRedF(0.2); + comparison.setGreenF(0.88); + comparison.setBlueF(0.6); + comparison.setAlphaF(0.34); + QCOMPARE(object->property("copy"), QVariant(comparison)); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("color_write.qml")); + MyTypeObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + + QColor newColor; + newColor.setRedF(0.5); + newColor.setGreenF(0.38); + newColor.setBlueF(0.3); + newColor.setAlphaF(0.7); + QCOMPARE(object->color(), newColor); + + delete object; + } + + { + QDeclarativeComponent component(&engine, TEST_FILE("color_compare.qml")); + MyTypeObject *object = qobject_cast(component.create()); + QVERIFY(object != 0); + QString colorString("#33e199"); + QCOMPARE(object->property("colorToString").toString(), colorString); + QCOMPARE(object->property("colorEqualsIdenticalRgba").toBool(), true); + QCOMPARE(object->property("colorEqualsDifferentAlpha").toBool(), false); + QCOMPARE(object->property("colorEqualsDifferentRgba").toBool(), false); + QCOMPARE(object->property("colorToStringEqualsColorString").toBool(), true); + QCOMPARE(object->property("colorToStringEqualsDifferentAlphaString").toBool(), true); + QCOMPARE(object->property("colorToStringEqualsDifferentRgbaString").toBool(), false); + QCOMPARE(object->property("colorEqualsColorString").toBool(), true); // maintaining behaviour with QtQuick 1.0 + QCOMPARE(object->property("colorEqualsDifferentAlphaString").toBool(), true); // maintaining behaviour with QtQuick 1.0 + QCOMPARE(object->property("colorEqualsDifferentRgbaString").toBool(), false); + + QCOMPARE(object->property("equalsColor").toBool(), true); + QCOMPARE(object->property("equalsVector3d").toBool(), false); + QCOMPARE(object->property("equalsSize").toBool(), false); + QCOMPARE(object->property("equalsPoint").toBool(), false); + QCOMPARE(object->property("equalsRect").toBool(), false); + + // Color == Property and Property == Color should return the same result. + QCOMPARE(object->property("equalsColorRHS").toBool(), object->property("equalsColor").toBool()); + QCOMPARE(object->property("colorEqualsCopy").toBool(), true); + QCOMPARE(object->property("copyEqualsColor").toBool(), object->property("colorEqualsCopy").toBool()); + + delete object; + } +} + // Test bindings can write to value types void tst_qdeclarativevaluetypes::bindingAssignment() {