From 11e54d7349b14a3fa4cd7faf1bae584cee6503f6 Mon Sep 17 00:00:00 2001 From: Ian Walters Date: Fri, 8 May 2009 14:23:10 +1000 Subject: Current item highlight Unfortunatley the color doesn't animate. A 'Behavior' doesn't work (still snaps) and using states and transitions causes a crash within the ListView code. --- demos/declarative/contacts/contacts.qml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/demos/declarative/contacts/contacts.qml b/demos/declarative/contacts/contacts.qml index b38e02e..42ea2b1 100644 --- a/demos/declarative/contacts/contacts.qml +++ b/demos/declarative/contacts/contacts.qml @@ -34,14 +34,14 @@ Rect { y: 12 width: parent.width-30 text: model.label - color: "white" + color: wrapper.ListView.isCurrentItem ? "black" : "white" font.bold: true children: [ MouseRegion { anchors.fill: parent onClicked: { Details.qml = 'Contact.qml'; - wrapper.state='opened'; + wrapper.state ='opened'; contacts.mode = 'edit'; } } @@ -190,10 +190,26 @@ Rect { anchors.left: parent.left anchors.right: parent.right anchors.top: cancelEditButton.bottom - anchors.bottom: searchBarWrapper.bottom + anchors.bottom: searchBarWrapper.top + anchors.topMargin: 5 clip: true model: contactList delegate: contactDelegate + highlight: [ + Rect { + id: contactHighlight + pen.width: 0 + color: 'white' + opacity: contacts.mode == 'list' ? 1 : 0 + opacity: Behaviour { + NumericAnimation { + property: "opacity" + duration: 250 + } + } + } + ] + autoHighlight: true focus: false } FocusRealm { -- cgit v0.12 From fae073096e027bbf079efac7fdd8e3f34ba0a4ab Mon Sep 17 00:00:00 2001 From: Ian Walters Date: Tue, 26 May 2009 10:06:40 +1000 Subject: fade text accross white to black Prior to this change, when the highlight moved the text would blink from white to black. This was a little disconcerting. Add in a smooth blend for the color change. --- demos/declarative/contacts/contacts.qml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/demos/declarative/contacts/contacts.qml b/demos/declarative/contacts/contacts.qml index 42ea2b1..9b6d321 100644 --- a/demos/declarative/contacts/contacts.qml +++ b/demos/declarative/contacts/contacts.qml @@ -34,7 +34,7 @@ Rect { y: 12 width: parent.width-30 text: model.label - color: wrapper.ListView.isCurrentItem ? "black" : "white" + color: "white" font.bold: true children: [ MouseRegion { @@ -46,6 +46,25 @@ Rect { } } ] + states: [ + State { + name: "currentItem" + when: wrapper.ListView.isCurrentItem + SetProperty { + target: label + property: "color" + value: "black" + } + } + ] + transitions: [ + Transition { + ColorAnimation { + duration: 250 + property: "color" + } + } + ] } Item { id: Details -- cgit v0.12 From aa0ef24ecdd2007d90ec4086a267a2ae930ae01e Mon Sep 17 00:00:00 2001 From: Ian Walters Date: Thu, 18 Jun 2009 10:29:55 +1000 Subject: Use QContiguousCache for cached queries By using QContiguousCache, and upper limit on cache size is assured. Also caching is set to occur in the background when possible. This should reduce any impact on animation performance. --- src/declarative/extra/qmlsqlquery.cpp | 142 +++++++++++++++++++++++++++++----- src/declarative/extra/qmlsqlquery.h | 3 + 2 files changed, 124 insertions(+), 21 deletions(-) diff --git a/src/declarative/extra/qmlsqlquery.cpp b/src/declarative/extra/qmlsqlquery.cpp index 0e2e91b..82ac50062 100644 --- a/src/declarative/extra/qmlsqlquery.cpp +++ b/src/declarative/extra/qmlsqlquery.cpp @@ -51,6 +51,9 @@ #include #include +#include +#include + QT_BEGIN_NAMESPACE QML_DEFINE_TYPE(QmlSqlBind, SqlBind) QML_DEFINE_TYPE(QmlSqlQuery, SqlQuery) @@ -192,12 +195,21 @@ class QmlSqlQueryPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QmlSqlQuery) public: - QmlSqlQueryPrivate(QmlSqlQuery *owner) : isSel(false), query(NULL), requireCache(false), count(-1), binds(owner) {} + QmlSqlQueryPrivate(QmlSqlQuery *owner) + : isSel(false), query(NULL), requireCache(false), count(-1), + cacheNear(100), cacheRetain(100), cacheSize(1000), + cacheInterval(250), scheduledRow(-1), cacheTimer(-1), + binds(owner) {} void prepareQuery() const; void bindQuery() const; - void cacheQuery() const; void grabRoles() const; + void clearCache(); + void initCache() const; + void hitCache(int row) const; + + void enactShift(int row) const; + QString queryText; bool isSel; QVariant connectionVariant; @@ -206,7 +218,14 @@ public: mutable int count; mutable QList roles; mutable QStringList roleNames; - mutable QVector< QVector< QVariant > > cache; + + typedef QContiguousCache Column; + mutable QVector< Column * > cache; + + int cacheNear, cacheRetain, cacheSize, cacheInterval; + + mutable int scheduledRow; + mutable int cacheTimer; class QmlSqlBindList : public QmlList { @@ -408,12 +427,13 @@ QHash QmlSqlQuery::data(int row, const QList &roles) const if (!d->requireCache) d->query->seek(row); + else + d->hitCache(row); for (int i = 0; i < roles.count(); ++i) { int column = roles[i]; - Q_ASSERT(column >= 0 && column < d->cache.size()); if (d->requireCache) - result.insert(column, d->cache[column].at(row)); + result.insert(column, d->cache[column]->at(row)); else result.insert(column, d->query->value(column)); } @@ -511,7 +531,7 @@ void QmlSqlQuery::resetBinds() if (!d->query) return; int oldcount = d->count; - d->cache.resize(0); + d->clearCache(); d->roles.clear(); d->roleNames.clear(); d->bindQuery(); @@ -520,7 +540,7 @@ void QmlSqlQuery::resetBinds() if (!d->query->exec()) qWarning() << "failed to execute query" << d->query->lastQuery() << d->query->boundValues() << d->query->lastError().text(); } - d->cacheQuery(); // may finish query + d->initCache(); // may finish query emitChanges(oldcount); } } @@ -540,12 +560,12 @@ void QmlSqlQuery::exec() if (d->isSel) { int oldcount = d->count; - d->cache.resize(0); + d->clearCache(); d->roles.clear(); d->roleNames.clear(); if (!d->query->exec()) qWarning() << "failed to execute query" << d->query->lastQuery() << d->query->boundValues() << d->query->lastError().text(); - d->cacheQuery(); // may finish query + d->initCache(); // may finish query emitChanges(oldcount); } else { if (!d->query->exec()) @@ -565,7 +585,7 @@ void QmlSqlQuery::resetQuery() Q_ASSERT(d->query != 0); delete d->query; d->query = 0; - d->cache.resize(0); + d->clearCache(); d->roles.clear(); d->roleNames.clear(); int oldcount = d->count; @@ -591,6 +611,22 @@ void QmlSqlQuery::emitChanges(int oldcount) } /* + \internal + + Handles delayed caching of the query. +*/ +void QmlSqlQuery::timerEvent(QTimerEvent *event) +{ + Q_D(QmlSqlQuery); + if (event->timerId() == d->cacheTimer) { + killTimer(d->cacheTimer); + d->cacheTimer = -1; + d->enactShift(d->scheduledRow); + d->scheduledRow = -1; + } +} + +/* Prepares the query. If the query starts with SELECT it is assumed to be a SELECT statement and the query is also executed. */ @@ -625,7 +661,7 @@ void QmlSqlQueryPrivate::prepareQuery() const if (isSel) { if (!query->exec()) qWarning() << "failed to execute query" << query->lastQuery() << query->boundValues() << query->lastError().text(); - cacheQuery(); + initCache(); } } @@ -645,26 +681,39 @@ void QmlSqlQueryPrivate::bindQuery() const } /* - If the query is connected to a database with simple locking or - that cannot ask for the count of a result set, caches the required - data of the query and finishes the query to release locks. + Clears cached query results +*/ +void QmlSqlQueryPrivate::clearCache() +{ + for (int i = 0; i < cache.size(); ++i) + delete cache[i]; + cache.resize(0); +} + +/* + If caching is required, initializes the cache with + column definitions and initial rows. - Otherwise just caches the count of the query. + Otherwise caches the count for the query. */ -void QmlSqlQueryPrivate::cacheQuery() const +void QmlSqlQueryPrivate::initCache() const { if (requireCache) { int row = 0; - while (query->next()) { + if (query->next()) { if (roleNames.isEmpty()) { grabRoles(); cache.resize(roleNames.count()); + for (int i = 0; i < cache.size(); ++i) + cache[i] = new Column(cacheSize); } Q_ASSERT(cache.size() > 0); - for (int i = 0; i < cache.size(); ++i) { - cache[i].append(query->value(i)); - } - row++; + do { + for (int i = 0; i < cache.size(); ++i) + cache[i]->insert(row, query->value(i)); + row++; + } while (!cache[0]->isFull() && query->next()); + while(query->next()) row++; } count = row; query->finish(); @@ -674,6 +723,57 @@ void QmlSqlQueryPrivate::cacheQuery() const } /* + Schedules future background cache loading based of + the given row. + + Should only be called if caching is active. +*/ +void QmlSqlQueryPrivate::hitCache(int row) const +{ + Q_Q(const QmlSqlQuery); + + Q_ASSERT(cache.size() > 0 && requireCache); + if (cache[0]->containsIndex(row)) { + int fi = cache[0]->firstIndex(); + int li = cache[0]->lastIndex(); + if (fi > 0 && row < fi + cacheNear) + scheduledRow = qMax(0, row + cacheRetain - cacheSize); + else if (li < count-1 && row > li - cacheNear) + scheduledRow = qMax(0, row - cacheRetain); + + if (scheduledRow != -1 && cacheTimer == -1) + cacheTimer = ((QmlSqlQuery *)q)->startTimer(cacheInterval); + } else { + if (cacheTimer != -1) { + ((QmlSqlQuery *)q)->killTimer(cacheTimer); + cacheTimer = -1; + } + scheduledRow = -1; + qDebug() << "cache miss for row:" << row << "count:" << count; + enactShift(row); + } +} + +/* + Load items from sql centered around row. +*/ +void QmlSqlQueryPrivate::enactShift(int targetRow) const +{ + Q_ASSERT(query && cache.size()); + query->exec(); + int row = targetRow < cache[0]->firstIndex() ? targetRow : qMax(targetRow, cache[0]->lastIndex()+1); + + if (query->seek(row)) { + do { + for (int i = 0; i < cache.size(); ++i) { + cache[i]->insert(row, query->value(i)); + } + row++; + } while(row < targetRow + cacheSize && query->next()); + } +} + +/* Gets the column names for the roles of the SqlQuery element. The query must be active and on a valid row. diff --git a/src/declarative/extra/qmlsqlquery.h b/src/declarative/extra/qmlsqlquery.h index dca3596..7aa0709 100644 --- a/src/declarative/extra/qmlsqlquery.h +++ b/src/declarative/extra/qmlsqlquery.h @@ -123,6 +123,9 @@ public: public slots: void exec(); +protected: + void timerEvent(QTimerEvent *); + private slots: void resetBinds(); void resetQuery(); -- cgit v0.12 From ff93dcfdb3e279771b65fff8f245ac8d76cda15d Mon Sep 17 00:00:00 2001 From: Ian Walters Date: Thu, 18 Jun 2009 11:05:13 +1000 Subject: Keyword name change Behaviour was renamed Behavior. Was Australian spelling, now US spelling. --- demos/declarative/contacts/Button.qml | 2 +- demos/declarative/contacts/FieldText.qml | 2 +- demos/declarative/contacts/RemoveButton.qml | 2 +- demos/declarative/contacts/contacts.qml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/demos/declarative/contacts/Button.qml b/demos/declarative/contacts/Button.qml index d9f1236..3b76a13 100644 --- a/demos/declarative/contacts/Button.qml +++ b/demos/declarative/contacts/Button.qml @@ -48,7 +48,7 @@ Item { } ] } - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 diff --git a/demos/declarative/contacts/FieldText.qml b/demos/declarative/contacts/FieldText.qml index eb18ef2..39e45d4 100644 --- a/demos/declarative/contacts/FieldText.qml +++ b/demos/declarative/contacts/FieldText.qml @@ -73,7 +73,7 @@ Rect { font.bold: true text: fieldText.label opacity: textEdit.text == '' ? 1 : 0 - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 diff --git a/demos/declarative/contacts/RemoveButton.qml b/demos/declarative/contacts/RemoveButton.qml index 59e3fcb..8f46fcb 100644 --- a/demos/declarative/contacts/RemoveButton.qml +++ b/demos/declarative/contacts/RemoveButton.qml @@ -76,7 +76,7 @@ Rect { text: "Remove" opacity: 0 } - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 diff --git a/demos/declarative/contacts/contacts.qml b/demos/declarative/contacts/contacts.qml index 9b6d321..0ce9948 100644 --- a/demos/declarative/contacts/contacts.qml +++ b/demos/declarative/contacts/contacts.qml @@ -220,7 +220,7 @@ Rect { pen.width: 0 color: 'white' opacity: contacts.mode == 'list' ? 1 : 0 - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 -- cgit v0.12 From 1e6a8054cfcd5217fbea390fc2395fcb5af588e7 Mon Sep 17 00:00:00 2001 From: Ian Walters Date: Thu, 18 Jun 2009 11:13:13 +1000 Subject: more keword change fixes. Behaviour -> Behavior --- examples/declarative/minehunt/minehunt.qml | 2 +- .../declarative/tutorials/contacts/1_Drawing_and_Animation/GroupBox.qml | 2 +- examples/declarative/tutorials/contacts/2_Reuse/3/FieldText.qml | 2 +- examples/declarative/tutorials/contacts/2_Reuse/4/FieldText.qml | 2 +- examples/declarative/tutorials/contacts/2_Reuse/GroupBox.qml | 2 +- examples/declarative/tutorials/contacts/3_Collections/GroupBox.qml | 2 +- examples/declarative/tutorials/contacts/3_Collections/lib/Button.qml | 2 +- examples/declarative/tutorials/contacts/3_Collections/lib/FieldText.qml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/declarative/minehunt/minehunt.qml b/examples/declarative/minehunt/minehunt.qml index bf31c3d..db826a3 100644 --- a/examples/declarative/minehunt/minehunt.qml +++ b/examples/declarative/minehunt/minehunt.qml @@ -28,7 +28,7 @@ Item { anchors.verticalCenter: parent.verticalCenter source: "pics/flag.png" opacity: modelData.hasFlag - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 diff --git a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/GroupBox.qml b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/GroupBox.qml index edaae72..0d607a9 100644 --- a/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/GroupBox.qml +++ b/examples/declarative/tutorials/contacts/1_Drawing_and_Animation/GroupBox.qml @@ -47,7 +47,7 @@ FocusRealm { anchors.fill: parent onClicked: { parent.parent.focus=true } } - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 diff --git a/examples/declarative/tutorials/contacts/2_Reuse/3/FieldText.qml b/examples/declarative/tutorials/contacts/2_Reuse/3/FieldText.qml index f6cc1e4..8bf5317 100644 --- a/examples/declarative/tutorials/contacts/2_Reuse/3/FieldText.qml +++ b/examples/declarative/tutorials/contacts/2_Reuse/3/FieldText.qml @@ -70,7 +70,7 @@ Rect { font.italic: true text: fieldText.label opacity: textEdit.text == '' ? 1 : 0 - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 diff --git a/examples/declarative/tutorials/contacts/2_Reuse/4/FieldText.qml b/examples/declarative/tutorials/contacts/2_Reuse/4/FieldText.qml index e969f7b..d4fbc20 100644 --- a/examples/declarative/tutorials/contacts/2_Reuse/4/FieldText.qml +++ b/examples/declarative/tutorials/contacts/2_Reuse/4/FieldText.qml @@ -72,7 +72,7 @@ Rect { font.italic: true text: fieldText.label opacity: textEdit.text == '' ? 1 : 0 - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 diff --git a/examples/declarative/tutorials/contacts/2_Reuse/GroupBox.qml b/examples/declarative/tutorials/contacts/2_Reuse/GroupBox.qml index edaae72..0d607a9 100644 --- a/examples/declarative/tutorials/contacts/2_Reuse/GroupBox.qml +++ b/examples/declarative/tutorials/contacts/2_Reuse/GroupBox.qml @@ -47,7 +47,7 @@ FocusRealm { anchors.fill: parent onClicked: { parent.parent.focus=true } } - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 diff --git a/examples/declarative/tutorials/contacts/3_Collections/GroupBox.qml b/examples/declarative/tutorials/contacts/3_Collections/GroupBox.qml index edaae72..0d607a9 100644 --- a/examples/declarative/tutorials/contacts/3_Collections/GroupBox.qml +++ b/examples/declarative/tutorials/contacts/3_Collections/GroupBox.qml @@ -47,7 +47,7 @@ FocusRealm { anchors.fill: parent onClicked: { parent.parent.focus=true } } - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 diff --git a/examples/declarative/tutorials/contacts/3_Collections/lib/Button.qml b/examples/declarative/tutorials/contacts/3_Collections/lib/Button.qml index d9f1236..3b76a13 100644 --- a/examples/declarative/tutorials/contacts/3_Collections/lib/Button.qml +++ b/examples/declarative/tutorials/contacts/3_Collections/lib/Button.qml @@ -48,7 +48,7 @@ Item { } ] } - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 diff --git a/examples/declarative/tutorials/contacts/3_Collections/lib/FieldText.qml b/examples/declarative/tutorials/contacts/3_Collections/lib/FieldText.qml index 427e2b0..111d9c5 100644 --- a/examples/declarative/tutorials/contacts/3_Collections/lib/FieldText.qml +++ b/examples/declarative/tutorials/contacts/3_Collections/lib/FieldText.qml @@ -72,7 +72,7 @@ Rect { font.italic: true text: fieldText.label opacity: textEdit.text == '' ? 1 : 0 - opacity: Behaviour { + opacity: Behavior { NumericAnimation { property: "opacity" duration: 250 -- cgit v0.12 From 10771f86a99588196304b94bcba3aea7f3dc1fb8 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 18 Jun 2009 12:08:20 +1000 Subject: Allow synthesized and extension meta objects to work together --- src/declarative/qml/qmlvmemetaobject.cpp | 16 +++++++++++++--- src/declarative/qml/qmlvmemetaobject_p.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/declarative/qml/qmlvmemetaobject.cpp b/src/declarative/qml/qmlvmemetaobject.cpp index 0117448..4b2c64c 100644 --- a/src/declarative/qml/qmlvmemetaobject.cpp +++ b/src/declarative/qml/qmlvmemetaobject.cpp @@ -55,14 +55,18 @@ QmlVMEMetaObject::QmlVMEMetaObject(QObject *obj, QList *strData, int slotData, QmlRefCount *rc) -: object(obj), ref(rc), slotData(strData), slotDataIdx(slotData) +: object(obj), ref(rc), slotData(strData), slotDataIdx(slotData), parent(0) { if (ref) ref->addref(); *static_cast(this) = *other; this->d.superdata = obj->metaObject(); - QObjectPrivate::get(obj)->metaObject = this; + + QObjectPrivate *op = QObjectPrivate::get(obj); + if (op->metaObject) + parent = static_cast(op->metaObject); + op->metaObject = this; baseProp = propertyOffset(); baseSig = methodOffset(); @@ -101,6 +105,8 @@ QmlVMEMetaObject::~QmlVMEMetaObject() { if (ref) ref->release(); + if (parent) + delete parent; delete [] data; } @@ -172,6 +178,10 @@ int QmlVMEMetaObject::metaCall(QMetaObject::Call c, int id, void **a) } } - return object->qt_metacall(c, id, a); + if (parent) + return parent->metaCall(c, id, a); + else + return object->qt_metacall(c, id, a); } + QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlvmemetaobject_p.h b/src/declarative/qml/qmlvmemetaobject_p.h index 6f1e31b..17140ef 100644 --- a/src/declarative/qml/qmlvmemetaobject_p.h +++ b/src/declarative/qml/qmlvmemetaobject_p.h @@ -69,6 +69,7 @@ private: QBitArray vTypes; QList *slotData; int slotDataIdx; + QAbstractDynamicMetaObject *parent; }; QT_END_NAMESPACE -- cgit v0.12