diff options
author | Joona Petrell <joona.t.petrell@nokia.com> | 2010-02-12 00:27:18 (GMT) |
---|---|---|
committer | Joona Petrell <joona.t.petrell@nokia.com> | 2010-02-12 00:53:22 (GMT) |
commit | 3aa16c105b7f9e55e804ee6bbb738dd267e484f2 (patch) | |
tree | 9be7555cf3ae8aef55155064ca027e64a6ce640d | |
parent | ba1fdd6e275ab6d22efe6329325b7cd6aa40a56e (diff) | |
download | Qt-3aa16c105b7f9e55e804ee6bbb738dd267e484f2.zip Qt-3aa16c105b7f9e55e804ee6bbb738dd267e484f2.tar.gz Qt-3aa16c105b7f9e55e804ee6bbb738dd267e484f2.tar.bz2 |
Decouple Loader from QmlGraphicsItem
Task-number: QT-2823
Reviewed-by: Aaron Kennedy
9 files changed, 231 insertions, 43 deletions
diff --git a/src/declarative/graphicsitems/qmlgraphicsloader.cpp b/src/declarative/graphicsitems/qmlgraphicsloader.cpp index 50267fc..d0b804b 100644 --- a/src/declarative/graphicsitems/qmlgraphicsloader.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsloader.cpp @@ -55,6 +55,14 @@ QmlGraphicsLoaderPrivate::~QmlGraphicsLoaderPrivate() { } +void QmlGraphicsLoaderPrivate::itemGeometryChanged(QmlGraphicsItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry) +{ + if (resizeItem == item && resizeMode == QmlGraphicsLoader::SizeLoaderToItem) { + _q_updateSize(); + } + QmlGraphicsItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry); +} + void QmlGraphicsLoaderPrivate::clear() { if (ownComponent) { @@ -65,10 +73,18 @@ void QmlGraphicsLoaderPrivate::clear() source = QUrl(); if (item) { + if (QmlGraphicsItem *qmlItem = qobject_cast<QmlGraphicsItem*>(item)) { + if (resizeMode == QmlGraphicsLoader::SizeLoaderToItem) { + QmlGraphicsItemPrivate *p = + static_cast<QmlGraphicsItemPrivate *>(QGraphicsItemPrivate::get(qmlItem)); + p->removeItemChangeListener(this, QmlGraphicsItemPrivate::Geometry); + } + } + // We can't delete immediately because our item may have triggered // the Loader to load a different item. item->setVisible(false); - static_cast<QGraphicsItem*>(item)->setParentItem(0); + item->setParentItem(0); item->deleteLater(); item = 0; } @@ -77,20 +93,22 @@ void QmlGraphicsLoaderPrivate::clear() void QmlGraphicsLoaderPrivate::initResize() { Q_Q(QmlGraphicsLoader); - QmlGraphicsItem *resizeItem = 0; - if (resizeMode == QmlGraphicsLoader::SizeLoaderToItem) - resizeItem = item; - else if (resizeMode == QmlGraphicsLoader::SizeItemToLoader) - resizeItem = q; - if (resizeItem) { - QObject::connect(resizeItem, SIGNAL(widthChanged()), q, SLOT(_q_updateSize())); - QObject::connect(resizeItem, SIGNAL(heightChanged()), q, SLOT(_q_updateSize())); + if (QmlGraphicsItem *qmlItem = qobject_cast<QmlGraphicsItem*>(item)) { + if (resizeMode == QmlGraphicsLoader::SizeLoaderToItem) { + QmlGraphicsItemPrivate *p = + static_cast<QmlGraphicsItemPrivate *>(QGraphicsItemPrivate::get(qmlItem)); + p->addItemChangeListener(this, QmlGraphicsItemPrivate::Geometry); + } + } else if (item && item->isWidget()) { + QGraphicsWidget *widget = static_cast<QGraphicsWidget*>(item); + if (resizeMode == QmlGraphicsLoader::SizeLoaderToItem) { + widget->installEventFilter(q); + } } _q_updateSize(); } - QML_DEFINE_TYPE(Qt,4,6,Loader,QmlGraphicsLoader) /*! @@ -270,9 +288,14 @@ void QmlGraphicsLoaderPrivate::_q_sourceLoaded() QObject *obj = component->create(ctxt); if (obj) { ctxt->setParent(obj); - item = qobject_cast<QmlGraphicsItem *>(obj); + item = qobject_cast<QGraphicsObject *>(obj); if (item) { - item->setParentItem(q); + if (QmlGraphicsItem* qmlItem = qobject_cast<QmlGraphicsItem *>(item)) { + qmlItem->setParentItem(q); + } else { + item->setParentItem(q); + item->setParent(q); + } // item->setFocus(true); initResize(); } @@ -366,16 +389,17 @@ void QmlGraphicsLoader::setResizeMode(ResizeMode mode) if (mode == d->resizeMode) return; - if (d->item) { - QmlGraphicsItem *resizeItem = 0; - if (d->resizeMode == SizeLoaderToItem) - resizeItem = d->item; - else if (d->resizeMode == SizeItemToLoader) - resizeItem = this; - if (resizeItem) { - disconnect(resizeItem, SIGNAL(widthChanged()), this, SLOT(_q_updateSize())); - disconnect(resizeItem, SIGNAL(heightChanged()), this, SLOT(_q_updateSize())); + QmlGraphicsItem *resizeItem = 0; + if (QmlGraphicsItem *qmlItem = qobject_cast<QmlGraphicsItem*>(d->item)) { + if (d->resizeMode == SizeLoaderToItem) { + QmlGraphicsItemPrivate *p = + static_cast<QmlGraphicsItemPrivate *>(QGraphicsItemPrivate::get(qmlItem)); + p->removeItemChangeListener(d, QmlGraphicsItemPrivate::Geometry); } + } else if (d->item && d->item->isWidget()) { + QGraphicsWidget *widget = static_cast<QGraphicsWidget*>(d->item); + if (d->resizeMode == SizeLoaderToItem) + d->item->removeEventFilter(this); } d->resizeMode = mode; @@ -387,17 +411,32 @@ void QmlGraphicsLoaderPrivate::_q_updateSize() Q_Q(QmlGraphicsLoader); if (!item) return; - switch (resizeMode) { - case QmlGraphicsLoader::SizeLoaderToItem: - q->setImplicitWidth(item->width()); - q->setImplicitHeight(item->height()); - break; - case QmlGraphicsLoader::SizeItemToLoader: - item->setWidth(q->width()); - item->setHeight(q->height()); - break; - default: - break; + if (QmlGraphicsItem *qmlItem = qobject_cast<QmlGraphicsItem*>(item)) { + if (resizeMode == QmlGraphicsLoader::SizeLoaderToItem) { + q->setWidth(qmlItem->width()); + q->setHeight(qmlItem->height()); + } else if (resizeMode == QmlGraphicsLoader::SizeItemToLoader) { + qmlItem->setWidth(q->width()); + qmlItem->setHeight(q->height()); + } + } else if (item && item->isWidget()) { + QGraphicsWidget *widget = static_cast<QGraphicsWidget*>(item); + if (resizeMode == QmlGraphicsLoader::SizeLoaderToItem) { + QSizeF newSize = widget->size(); + if (newSize.isValid()) { + q->setWidth(newSize.width()); + q->setHeight(newSize.height()); + } + } else if (resizeMode == QmlGraphicsLoader::SizeItemToLoader) { + QSizeF oldSize = widget->size(); + QSizeF newSize = oldSize; + if (q->heightValid()) + newSize.setHeight(q->height()); + if (q->widthValid()) + newSize.setWidth(q->width()); + if (oldSize != newSize) + widget->resize(newSize); + } } } @@ -405,12 +444,48 @@ void QmlGraphicsLoaderPrivate::_q_updateSize() \qmlproperty Item Loader::item This property holds the top-level item created from source. */ -QmlGraphicsItem *QmlGraphicsLoader::item() const +QGraphicsObject *QmlGraphicsLoader::item() const { Q_D(const QmlGraphicsLoader); return d->item; } +void QmlGraphicsLoader::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + Q_D(QmlGraphicsLoader); + if (newGeometry != oldGeometry) { + if (d->resizeMode == SizeItemToLoader) { + d->_q_updateSize(); + } + } + QmlGraphicsItem::geometryChanged(newGeometry, oldGeometry); +} + +QVariant QmlGraphicsLoader::itemChange(GraphicsItemChange change, const QVariant &value) +{ + Q_D(QmlGraphicsLoader); + if (change == ItemSceneHasChanged) { + if (d->item && d->item->isWidget()) { + if (d->resizeMode == SizeLoaderToItem) { + d->item->removeEventFilter(this); + d->item->installEventFilter(this); + } + } + } + return QmlGraphicsItem::itemChange(change, value); +} + +bool QmlGraphicsLoader::eventFilter(QObject *watched, QEvent *e) +{ + Q_D(QmlGraphicsLoader); + if (watched == d->item && e->type() == QEvent::GraphicsSceneResize) { + if (d->item && d->item->isWidget() && d->resizeMode == SizeLoaderToItem) { + d->_q_updateSize(); + } + } + return QmlGraphicsItem::eventFilter(watched, e); +} + #include <moc_qmlgraphicsloader_p.cpp> QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qmlgraphicsloader_p.h b/src/declarative/graphicsitems/qmlgraphicsloader_p.h index 88cc70d..87b6a52 100644 --- a/src/declarative/graphicsitems/qmlgraphicsloader_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsloader_p.h @@ -60,7 +60,7 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsLoader : public QmlGraphicsItem Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) Q_PROPERTY(QmlComponent *sourceComponent READ sourceComponent WRITE setSourceComponent NOTIFY sourceChanged) Q_PROPERTY(ResizeMode resizeMode READ resizeMode WRITE setResizeMode) - Q_PROPERTY(QmlGraphicsItem *item READ item NOTIFY itemChanged) + Q_PROPERTY(QGraphicsObject *item READ item NOTIFY itemChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) @@ -82,14 +82,17 @@ public: ResizeMode resizeMode() const; void setResizeMode(ResizeMode mode); - QmlGraphicsItem *item() const; + QGraphicsObject *item() const; Q_SIGNALS: void itemChanged(); void sourceChanged(); void statusChanged(); void progressChanged(); - +protected: + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + QVariant itemChange(GraphicsItemChange change, const QVariant &value); + bool eventFilter(QObject *watched, QEvent *e); private: Q_DISABLE_COPY(QmlGraphicsLoader) Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QmlGraphicsLoader) diff --git a/src/declarative/graphicsitems/qmlgraphicsloader_p_p.h b/src/declarative/graphicsitems/qmlgraphicsloader_p_p.h index 569e1a5..7f10eff 100644 --- a/src/declarative/graphicsitems/qmlgraphicsloader_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsloader_p_p.h @@ -56,11 +56,12 @@ #include "qmlgraphicsloader_p.h" #include "qmlgraphicsitem_p.h" +#include "qmlgraphicsitemchangelistener_p.h" QT_BEGIN_NAMESPACE class QmlContext; -class QmlGraphicsLoaderPrivate : public QmlGraphicsItemPrivate +class QmlGraphicsLoaderPrivate : public QmlGraphicsItemPrivate, public QmlGraphicsItemChangeListener { Q_DECLARE_PUBLIC(QmlGraphicsLoader) @@ -68,11 +69,12 @@ public: QmlGraphicsLoaderPrivate(); ~QmlGraphicsLoaderPrivate(); + void itemGeometryChanged(QmlGraphicsItem *item, const QRectF &newGeometry, const QRectF &oldGeometry); void clear(); void initResize(); QUrl source; - QmlGraphicsItem *item; + QGraphicsObject *item; QmlComponent *component; bool ownComponent : 1; QmlGraphicsLoader::ResizeMode resizeMode; diff --git a/src/declarative/widgets/graphicswidgets_p.h b/src/declarative/widgets/graphicswidgets_p.h index b15bffa..0de5c89 100644 --- a/src/declarative/widgets/graphicswidgets_p.h +++ b/src/declarative/widgets/graphicswidgets_p.h @@ -60,6 +60,7 @@ QT_END_NAMESPACE QML_DECLARE_TYPE(QGraphicsView) QML_DECLARE_TYPE_HASMETATYPE(QGraphicsScene) QML_DECLARE_TYPE(QGraphicsWidget) +QML_DECLARE_TYPE(QGraphicsObject) QML_DECLARE_INTERFACE_HASMETATYPE(QGraphicsItem) QT_END_HEADER diff --git a/tests/auto/declarative/qmlgraphicsloader/data/GraphicsWidget250x250.qml b/tests/auto/declarative/qmlgraphicsloader/data/GraphicsWidget250x250.qml new file mode 100644 index 0000000..627c7df --- /dev/null +++ b/tests/auto/declarative/qmlgraphicsloader/data/GraphicsWidget250x250.qml @@ -0,0 +1,5 @@ +import Qt 4.6 + +QGraphicsWidget { + size: "250x250" +} diff --git a/tests/auto/declarative/qmlgraphicsloader/data/NoResizeGraphicsWidget.qml b/tests/auto/declarative/qmlgraphicsloader/data/NoResizeGraphicsWidget.qml new file mode 100644 index 0000000..0704e18 --- /dev/null +++ b/tests/auto/declarative/qmlgraphicsloader/data/NoResizeGraphicsWidget.qml @@ -0,0 +1,8 @@ +import Qt 4.6
+
+Loader {
+ resizeMode: Loader.NoResize
+ source: "GraphicsWidget250x250.qml"
+ width: 200
+ height: 80
+}
diff --git a/tests/auto/declarative/qmlgraphicsloader/data/SizeGraphicsWidgetToLoader.qml b/tests/auto/declarative/qmlgraphicsloader/data/SizeGraphicsWidgetToLoader.qml new file mode 100644 index 0000000..97c72f4 --- /dev/null +++ b/tests/auto/declarative/qmlgraphicsloader/data/SizeGraphicsWidgetToLoader.qml @@ -0,0 +1,8 @@ +import Qt 4.6
+
+Loader {
+ resizeMode: Loader.SizeItemToLoader
+ width: 200
+ height: 80
+ source: "GraphicsWidget250x250.qml"
+}
diff --git a/tests/auto/declarative/qmlgraphicsloader/data/SizeLoaderToGraphicsWidget.qml b/tests/auto/declarative/qmlgraphicsloader/data/SizeLoaderToGraphicsWidget.qml new file mode 100644 index 0000000..cb72f05 --- /dev/null +++ b/tests/auto/declarative/qmlgraphicsloader/data/SizeLoaderToGraphicsWidget.qml @@ -0,0 +1,6 @@ +import Qt 4.6
+
+Loader {
+ resizeMode: Loader.SizeLoaderToItem
+ source: "GraphicsWidget250x250.qml"
+}
diff --git a/tests/auto/declarative/qmlgraphicsloader/tst_qmlgraphicsloader.cpp b/tests/auto/declarative/qmlgraphicsloader/tst_qmlgraphicsloader.cpp index 25543a9..43f58c1 100644 --- a/tests/auto/declarative/qmlgraphicsloader/tst_qmlgraphicsloader.cpp +++ b/tests/auto/declarative/qmlgraphicsloader/tst_qmlgraphicsloader.cpp @@ -39,6 +39,9 @@ ** ****************************************************************************/ #include <qtest.h> +#include <QtGui/QGraphicsWidget> +#include <QtGui/QGraphicsScene> + #include <QtDeclarative/qmlengine.h> #include <QtDeclarative/qmlcomponent.h> #include <private/qmlgraphicsloader_p.h> @@ -77,6 +80,9 @@ private slots: void sizeLoaderToItem(); void sizeItemToLoader(); void noResize(); + void sizeLoaderToGraphicsWidget(); + void sizeGraphicsWidgetToLoader(); + void noResizeGraphicsWidget(); void networkRequestUrl(); void failNetworkRequest(); // void networkComponent(); @@ -240,7 +246,7 @@ void tst_QmlGraphicsLoader::sizeLoaderToItem() QCOMPARE(loader->height(), 60.0); // Check resize - QmlGraphicsItem *rect = loader->item(); + QmlGraphicsItem *rect = qobject_cast<QmlGraphicsItem*>(loader->item()); QVERIFY(rect); rect->setWidth(150); rect->setHeight(45); @@ -264,7 +270,7 @@ void tst_QmlGraphicsLoader::sizeItemToLoader() QCOMPARE(loader->width(), 200.0); QCOMPARE(loader->height(), 80.0); - QmlGraphicsItem *rect = loader->item(); + QmlGraphicsItem *rect = qobject_cast<QmlGraphicsItem*>(loader->item()); QVERIFY(rect); QCOMPARE(rect->width(), 200.0); QCOMPARE(rect->height(), 80.0); @@ -279,8 +285,8 @@ void tst_QmlGraphicsLoader::sizeItemToLoader() loader->setResizeMode(QmlGraphicsLoader::SizeLoaderToItem); rect->setWidth(160); rect->setHeight(45); - QCOMPARE(rect->width(), 160.0); - QCOMPARE(rect->height(), 45.0); + QCOMPARE(loader->width(), 160.0); + QCOMPARE(loader->height(), 45.0); } void tst_QmlGraphicsLoader::noResize() @@ -291,12 +297,86 @@ void tst_QmlGraphicsLoader::noResize() QCOMPARE(loader->width(), 200.0); QCOMPARE(loader->height(), 80.0); - QmlGraphicsItem *rect = loader->item(); + QmlGraphicsItem *rect = qobject_cast<QmlGraphicsItem*>(loader->item()); QVERIFY(rect); QCOMPARE(rect->width(), 120.0); QCOMPARE(rect->height(), 60.0); } +void tst_QmlGraphicsLoader::sizeLoaderToGraphicsWidget() +{ + QmlComponent component(&engine, TEST_FILE("/SizeLoaderToGraphicsWidget.qml")); + QmlGraphicsLoader *loader = qobject_cast<QmlGraphicsLoader*>(component.create()); + QGraphicsScene scene; + scene.addItem(loader); + + QVERIFY(loader != 0); + QVERIFY(loader->resizeMode() == QmlGraphicsLoader::SizeLoaderToItem); + QCOMPARE(loader->width(), 250.0); + QCOMPARE(loader->height(), 250.0); + + // Check resize + QGraphicsWidget *widget = qobject_cast<QGraphicsWidget*>(loader->item()); + QVERIFY(widget); + widget->resize(QSizeF(150,45)); + QCOMPARE(loader->width(), 150.0); + QCOMPARE(loader->height(), 45.0); + + // Switch mode + loader->setResizeMode(QmlGraphicsLoader::SizeItemToLoader); + loader->setWidth(180); + loader->setHeight(30); + QCOMPARE(widget->size().width(), 180.0); + QCOMPARE(widget->size().height(), 30.0); +} + +void tst_QmlGraphicsLoader::sizeGraphicsWidgetToLoader() +{ + QmlComponent component(&engine, TEST_FILE("/SizeGraphicsWidgetToLoader.qml")); + QmlGraphicsLoader *loader = qobject_cast<QmlGraphicsLoader*>(component.create()); + QGraphicsScene scene; + scene.addItem(loader); + + QVERIFY(loader != 0); + QVERIFY(loader->resizeMode() == QmlGraphicsLoader::SizeItemToLoader); + QCOMPARE(loader->width(), 200.0); + QCOMPARE(loader->height(), 80.0); + + QGraphicsWidget *widget = qobject_cast<QGraphicsWidget*>(loader->item()); + QVERIFY(widget); + QCOMPARE(widget->size().width(), 200.0); + QCOMPARE(widget->size().height(), 80.0); + + // Check resize + loader->setWidth(180); + loader->setHeight(30); + QCOMPARE(widget->size().width(), 180.0); + QCOMPARE(widget->size().height(), 30.0); + + // Switch mode + loader->setResizeMode(QmlGraphicsLoader::SizeLoaderToItem); + widget->resize(QSizeF(160,45)); + QCOMPARE(loader->width(), 160.0); + QCOMPARE(loader->height(), 45.0); +} + +void tst_QmlGraphicsLoader::noResizeGraphicsWidget() +{ + QmlComponent component(&engine, TEST_FILE("/NoResizeGraphicsWidget.qml")); + QmlGraphicsLoader *loader = qobject_cast<QmlGraphicsLoader*>(component.create()); + QGraphicsScene scene; + scene.addItem(loader); + + QVERIFY(loader != 0); + QCOMPARE(loader->width(), 200.0); + QCOMPARE(loader->height(), 80.0); + + QGraphicsWidget *widget = qobject_cast<QGraphicsWidget*>(loader->item()); + QVERIFY(widget); + QCOMPARE(widget->size().width(), 250.0); + QCOMPARE(widget->size().height(), 250.0); +} + void tst_QmlGraphicsLoader::networkRequestUrl() { TestHTTPServer server(SERVER_PORT); |