From 92970522b602844cbf932d5df6b62d6cf51e4416 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 2 May 2011 12:59:20 +0200 Subject: Fixed upside-down texture in QSGPaintedItem. --- src/declarative/scenegraph/util/qsgpainternode.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/declarative/scenegraph/util/qsgpainternode.cpp b/src/declarative/scenegraph/util/qsgpainternode.cpp index c7386d2fb9..569f1be19e 100644 --- a/src/declarative/scenegraph/util/qsgpainternode.cpp +++ b/src/declarative/scenegraph/util/qsgpainternode.cpp @@ -79,19 +79,13 @@ void QSGPainterTexture::bind() int w = m_dirty_rect.width(); int h = m_dirty_rect.height(); - int y = m_image.height() - m_dirty_rect.y() - h; #ifdef QT_OPENGL_ES - for (int i = 0; i < h; ++i) { - glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirty_rect.x(), y + i, w, 1, - GL_RGBA, GL_UNSIGNED_BYTE, subImage.constScanLine(h - 1 - i)); - } + glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirty_rect.x(), m_dirty_rect.y(), w, h, + GL_RGBA, GL_UNSIGNED_BYTE, subImage.constBits()); #else - for (int i = 0; i < h; ++i) { - glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirty_rect.x(), y + i, w, 1, - GL_BGRA, GL_UNSIGNED_BYTE, subImage.constScanLine(h - 1 - i)); - } - + glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirty_rect.x(), m_dirty_rect.y(), w, h, + GL_BGRA, GL_UNSIGNED_BYTE, subImage.constBits()); #endif m_dirty_texture = false; @@ -201,7 +195,7 @@ void QSGPainterNode::updateGeometry() { QRectF source; if (m_actualRenderTarget == QSGPaintedItem::Image) - source = QRectF(0, 1, 1, -1); + source = QRectF(0, 0, 1, 1); else source = QRectF(0, 1, qreal(m_size.width()) / m_fboSize.width(), qreal(-m_size.height()) / m_fboSize.height()); QSGGeometry::updateTexturedRectGeometry(&m_geometry, -- cgit v1.2.3 From fc345a6c356fdcdd28a67d212bb6750b2f494634 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 2 May 2011 16:58:33 +0200 Subject: Set ChildenDoNotOverlap flag on grids, lists and positioners. QSGGridView, QSGListView, QSGRow, QSGColumn, QSGGrid and QSGFlow now all set the ChildrenDoNotOverlap flag which allows the scene graph to render nodes in a more optimal order. --- src/declarative/items/qsggridview.cpp | 1 + src/declarative/items/qsgitem.cpp | 2 +- src/declarative/items/qsgitem_p.h | 4 +++- src/declarative/items/qsglistview.cpp | 1 + src/declarative/items/qsgpositioners_p_p.h | 1 + src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp | 2 +- src/declarative/scenegraph/coreapi/qsgnode.h | 2 +- 7 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/declarative/items/qsggridview.cpp b/src/declarative/items/qsggridview.cpp index 9beac05d72..4f00d3651f 100644 --- a/src/declarative/items/qsggridview.cpp +++ b/src/declarative/items/qsggridview.cpp @@ -488,6 +488,7 @@ public: void QSGGridViewPrivate::init() { Q_Q(QSGGridView); + QSGItemPrivate::get(contentItem)->childrenDoNotOverlap = true; QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped())); q->setFlag(QSGItem::ItemIsFocusScope); q->setFlickableDirection(QSGFlickable::VerticalFlick); diff --git a/src/declarative/items/qsgitem.cpp b/src/declarative/items/qsgitem.cpp index b0df6b1a04..f2d26955aa 100644 --- a/src/declarative/items/qsgitem.cpp +++ b/src/declarative/items/qsgitem.cpp @@ -1268,7 +1268,7 @@ QSGItemPrivate::QSGItemPrivate() notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true), effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false), inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true), - inheritMirrorFromParent(false), inheritMirrorFromItem(false), + inheritMirrorFromParent(false), inheritMirrorFromItem(false), childrenDoNotOverlap(false), canvas(0), parentItem(0), diff --git a/src/declarative/items/qsgitem_p.h b/src/declarative/items/qsgitem_p.h index a13fd6a85a..c76eceb674 100644 --- a/src/declarative/items/qsgitem_p.h +++ b/src/declarative/items/qsgitem_p.h @@ -254,7 +254,8 @@ public: bool isMirrorImplicit:1; bool inheritMirrorFromParent:1; bool inheritMirrorFromItem:1; - quint32 dummy:2; + bool childrenDoNotOverlap:1; + quint32 dummy:1; QSGCanvas *canvas; QSGContext *sceneGraphContext() const { return static_cast(QObjectPrivate::get(canvas))->context; } @@ -689,6 +690,7 @@ QSGNode *QSGItemPrivate::childContainerNode() opacityNode->appendChildNode(groupNode); else itemNode()->appendChildNode(groupNode); + groupNode->setFlag(QSGNode::ChildrenDoNotOverlap, childrenDoNotOverlap); #ifdef QML_RUNTIME_TESTING groupNode->description = QLatin1String("group"); #endif diff --git a/src/declarative/items/qsglistview.cpp b/src/declarative/items/qsglistview.cpp index 496fdaf4cc..80cc8be837 100644 --- a/src/declarative/items/qsglistview.cpp +++ b/src/declarative/items/qsglistview.cpp @@ -611,6 +611,7 @@ public: void QSGListViewPrivate::init() { Q_Q(QSGListView); + QSGItemPrivate::get(contentItem)->childrenDoNotOverlap = true; q->setFlag(QSGItem::ItemIsFocusScope); addItemChangeListener(this, Geometry); QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped())); diff --git a/src/declarative/items/qsgpositioners_p_p.h b/src/declarative/items/qsgpositioners_p_p.h index 241cbcfa3c..49de12a1fd 100644 --- a/src/declarative/items/qsgpositioners_p_p.h +++ b/src/declarative/items/qsgpositioners_p_p.h @@ -82,6 +82,7 @@ public: void init(QSGBasePositioner::PositionerType at) { type = at; + childrenDoNotOverlap = true; } int spacing; diff --git a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp index 05e502535a..901b84aa09 100644 --- a/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp +++ b/src/declarative/scenegraph/coreapi/qsgdefaultrenderer.cpp @@ -324,7 +324,7 @@ void QMLRenderer::buildLists(QSGNode *node) static bool reorder = !qApp->arguments().contains(QLatin1String("--no-reorder")); #endif - if (reorder && count > 1 && (node->flags() & QSGNode::ChildrenDoNotOverloap)) { + if (reorder && count > 1 && (node->flags() & QSGNode::ChildrenDoNotOverlap)) { QVarLengthArray beginIndices(count); QVarLengthArray endIndices(count); int baseCount = m_transparentNodes.size(); diff --git a/src/declarative/scenegraph/coreapi/qsgnode.h b/src/declarative/scenegraph/coreapi/qsgnode.h index fd2bc82b22..d6700af32e 100644 --- a/src/declarative/scenegraph/coreapi/qsgnode.h +++ b/src/declarative/scenegraph/coreapi/qsgnode.h @@ -99,7 +99,7 @@ public: // Lower 16 bites reserved for general node OwnedByParent = 0x0001, UsePreprocess = 0x0002, - ChildrenDoNotOverloap = 0x0004, + ChildrenDoNotOverlap = 0x0004, // Upper 16 bits reserved for node subclasses -- cgit v1.2.3 From 94c1a9d0e137a7c2adfd3ac86f3a439759306dc7 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 3 May 2011 10:23:21 +1000 Subject: Affector Augmentation Affectors gained shape and signal properties, and the affected(x,y) signal (turned on by the signal property, a theorized performance improvement). --- .../particles/allsmiles/smilefactory.qml | 1 + src/imports/particles/followemitter.cpp | 3 +- src/imports/particles/maskextruder.cpp | 15 +++++---- src/imports/particles/maskextruder.h | 2 ++ src/imports/particles/particleaffector.cpp | 10 ++++-- src/imports/particles/particleaffector.h | 38 ++++++++++++++++++++++ src/imports/particles/particlesystem.cpp | 2 ++ 7 files changed, 61 insertions(+), 10 deletions(-) diff --git a/examples/declarative/particles/allsmiles/smilefactory.qml b/examples/declarative/particles/allsmiles/smilefactory.qml index 1b43adb1da..47becb50fe 100644 --- a/examples/declarative/particles/allsmiles/smilefactory.qml +++ b/examples/declarative/particles/allsmiles/smilefactory.qml @@ -51,6 +51,7 @@ Rectangle{ particles: ["goingLeft", "goingRight"] image: "content/singlesmile.png" rotation: 90 + rotationSpeed: 90 autoRotation: true } DeformableParticle{ diff --git a/src/imports/particles/followemitter.cpp b/src/imports/particles/followemitter.cpp index 825b9ea69f..9e1ec7bbd2 100644 --- a/src/imports/particles/followemitter.cpp +++ b/src/imports/particles/followemitter.cpp @@ -46,6 +46,7 @@ QT_BEGIN_NAMESPACE FollowEmitter::FollowEmitter(QSGItem *parent) : ParticleEmitter(parent) + , m_particlesPerParticlePerSecond(0) , m_lastTimeStamp(0) , m_emitterXVariation(0) , m_emitterYVariation(0) @@ -66,7 +67,7 @@ void FollowEmitter::recalcParticlesPerSecond(){ return; m_followCount = m_system->m_groupData[m_system->m_groupIds[m_follow]]->size; if(!m_followCount){ - setParticlesPerSecond(1000);//XXX: Fix this horrendous hack, needed so they aren't turned off from start + setParticlesPerSecond(1000);//XXX: Fix this horrendous hack, needed so they aren't turned off from start (causes crashes - test that when gone you don't crash with 0 PPPS) }else{ setParticlesPerSecond(m_particlesPerParticlePerSecond * m_followCount); m_lastEmission.resize(m_followCount); diff --git a/src/imports/particles/maskextruder.cpp b/src/imports/particles/maskextruder.cpp index 16c64e0a70..2683010386 100644 --- a/src/imports/particles/maskextruder.cpp +++ b/src/imports/particles/maskextruder.cpp @@ -63,7 +63,8 @@ QPointF MaskExtruder::extrude(const QRectF &r) bool MaskExtruder::contains(const QRectF &bounds, const QPointF &point) { ensureInitialized(bounds);//###Current usage patterns WILL lead to different bounds/r calls. Separate list? - return m_mask.contains(QPointF(point.toPoint() - bounds.topLeft().toPoint())); + QPoint p = point.toPoint() - bounds.topLeft().toPoint(); + return m_img.rect().contains(p) && (bool)m_img.pixelIndex(p); } void MaskExtruder::ensureInitialized(const QRectF &r) @@ -76,14 +77,14 @@ void MaskExtruder::ensureInitialized(const QRectF &r) m_mask.clear(); if(m_source.isEmpty()) return; - - QImage img(m_source.toLocalFile()); - img = img.createAlphaMask(); - img = img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier - img = img.scaled(r.size().toSize());//TODO: Do they need aspect ratio stuff? Or tiling? + qDebug() << "Rebuild required"; + m_img = QImage(m_source.toLocalFile()); + m_img = m_img.createAlphaMask(); + m_img = m_img.convertToFormat(QImage::Format_Mono);//Else LSB, but I think that's easier + m_img = m_img.scaled(r.size().toSize());//TODO: Do they need aspect ratio stuff? Or tiling? for(int i=0; i +#include QT_BEGIN_HEADER @@ -85,6 +86,7 @@ private: void ensureInitialized(const QRectF &r); int m_lastWidth; int m_lastHeight; + QImage m_img; QList m_mask;//TODO: More memory efficient datastructures }; diff --git a/src/imports/particles/particleaffector.cpp b/src/imports/particles/particleaffector.cpp index 0d7bab577d..73564a940a 100644 --- a/src/imports/particles/particleaffector.cpp +++ b/src/imports/particles/particleaffector.cpp @@ -43,7 +43,8 @@ #include QT_BEGIN_NAMESPACE ParticleAffector::ParticleAffector(QSGItem *parent) : - QSGItem(parent), m_needsReset(false), m_system(0), m_active(true), m_updateIntSet(false) + QSGItem(parent), m_needsReset(false), m_system(0), m_active(true) + , m_updateIntSet(false), m_shape(new ParticleExtruder(this)), m_signal(false) { connect(this, SIGNAL(systemChanged(ParticleSystem*)), this, SLOT(updateOffsets())); @@ -82,11 +83,16 @@ void ParticleAffector::affectSystem(qreal dt) if(!d || (m_onceOff && m_onceOffed.contains(d->systemIndex))) continue; if(m_groups.isEmpty() || m_groups.contains(d->group)){ - if(width() == 0 || height() == 0 || QRectF(m_offset.x(), m_offset.y(), width(), height()).contains(d->curX(), d->curY())){ + //Need to have previous location for affected. if signal || shape might be faster? + QPointF curPos = QPointF(d->curX(), d->curY()); + if(width() == 0 || height() == 0 + || m_shape->contains(QRectF(m_offset.x(), m_offset.y(), width(), height()),curPos)){ if(affectParticle(d, dt)){ m_system->m_needsReset << d; if(m_onceOff) m_onceOffed << d->systemIndex; + if(m_signal) + emit affected(curPos.x(), curPos.y()); } } } diff --git a/src/imports/particles/particleaffector.h b/src/imports/particles/particleaffector.h index 1acb405f3e..3a92263092 100644 --- a/src/imports/particles/particleaffector.h +++ b/src/imports/particles/particleaffector.h @@ -44,6 +44,7 @@ #include #include "particlesystem.h" +#include "particleextruder.h" QT_BEGIN_HEADER @@ -59,6 +60,8 @@ class ParticleAffector : public QSGItem Q_PROPERTY(QStringList particles READ particles WRITE setParticles NOTIFY particlesChanged) Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged) Q_PROPERTY(bool onceOff READ onceOff WRITE setOnceOff NOTIFY onceOffChanged) + Q_PROPERTY(ParticleExtruder* shape READ shape WRITE setShape NOTIFY shapeChanged) + Q_PROPERTY(bool signal READ signal WRITE setSignal NOTIFY signalChanged) public: explicit ParticleAffector(QSGItem *parent = 0); @@ -84,6 +87,16 @@ public: return m_onceOff; } + ParticleExtruder* shape() const + { + return m_shape; + } + + bool signal() const + { + return m_signal; + } + signals: void systemChanged(ParticleSystem* arg); @@ -94,6 +107,11 @@ signals: void onceOffChanged(bool arg); + void shapeChanged(ParticleExtruder* arg); + + void affected(qreal x, qreal y);//###Idx too? + void signalChanged(bool arg); + public slots: void setSystem(ParticleSystem* arg) { @@ -129,6 +147,22 @@ void setOnceOff(bool arg) } } +void setShape(ParticleExtruder* arg) +{ + if (m_shape != arg) { + m_shape = arg; + emit shapeChanged(arg); + } +} + +void setSignal(bool arg) +{ + if (m_signal != arg) { + m_signal = arg; + emit signalChanged(arg); + } +} + protected: friend class ParticleSystem; virtual bool affectParticle(ParticleData *d, qreal dt); @@ -146,6 +180,10 @@ private: bool m_onceOff; + ParticleExtruder* m_shape; + + bool m_signal; + private slots: void updateOffsets(); }; diff --git a/src/imports/particles/particlesystem.cpp b/src/imports/particles/particlesystem.cpp index 571d33cb54..854d512630 100644 --- a/src/imports/particles/particlesystem.cpp +++ b/src/imports/particles/particlesystem.cpp @@ -186,6 +186,7 @@ void ParticleSystem::initializeSystem() m_timestamp.start(); m_initialized = true; emit systemInitialized(); + qDebug() << "System Initialized. Size:" << m_particle_count; } void ParticleSystem::reset() @@ -210,6 +211,7 @@ void ParticleSystem::reset() ParticleData* ParticleSystem::newDatum(int groupId) { Q_ASSERT(groupId < m_groupData.count());//XXX shouldn't really be an assert + Q_ASSERT(m_groupData[groupId]->size); int nextIdx = m_groupData[groupId]->start + m_groupData[groupId]->nextIdx++; if( m_groupData[groupId]->nextIdx >= m_groupData[groupId]->size) m_groupData[groupId]->nextIdx = 0; -- cgit v1.2.3 From d3be822c1bc167878ae75943c39dfb3f40bb3800 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 3 May 2011 15:13:50 +1000 Subject: Start QtQuick2 section of whats new. With the minor MouseArea behaviour change. --- doc/src/declarative/whatsnew.qdoc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/src/declarative/whatsnew.qdoc b/doc/src/declarative/whatsnew.qdoc index 6eb1548ab2..bf4b0df086 100644 --- a/doc/src/declarative/whatsnew.qdoc +++ b/doc/src/declarative/whatsnew.qdoc @@ -29,6 +29,12 @@ \title What's new in Qt Quick \page qtquick-whatsnew.html +\section1 Qt 5.0.0 includes QtQuick 2.0 + +QtQuick 2.0 is a major update. + +MouseArea now propagates clicked, doubleClicked and pressAndHold differently. + \section1 Qt 4.7.4 includes QtQuick 1.1 QtQuick 1.1 is a minor feature update. \e {import QtQuick 1.1} to use the new features. -- cgit v1.2.3 From 9267a7bce715924a96c8636a3110d90879e5927c Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 3 May 2011 14:41:52 +0200 Subject: Added antialiasing property to QSGPaintedItem. --- examples/declarative/painteditem/main.cpp | 5 +++++ src/declarative/items/qsgpainteditem.cpp | 33 ++++++++++++++++++++++++++++++- src/declarative/items/qsgpainteditem.h | 3 +++ src/declarative/items/qsgpainteditem_p.h | 1 + 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/examples/declarative/painteditem/main.cpp b/examples/declarative/painteditem/main.cpp index 1308325ca3..10bd4302c9 100644 --- a/examples/declarative/painteditem/main.cpp +++ b/examples/declarative/painteditem/main.cpp @@ -47,6 +47,11 @@ class MyPaintItem : public QSGPaintedItem { Q_OBJECT public: + MyPaintItem() : QSGPaintedItem() + { + setAntialiasing(true); + } + virtual void paint(QPainter *p) { QRectF rect(0, 0, width(), height()); diff --git a/src/declarative/items/qsgpainteditem.cpp b/src/declarative/items/qsgpainteditem.cpp index 8eb8afe8be..e0d63fa436 100644 --- a/src/declarative/items/qsgpainteditem.cpp +++ b/src/declarative/items/qsgpainteditem.cpp @@ -186,6 +186,37 @@ void QSGPaintedItem::setOpaquePainting(bool opaque) QSGItem::update(); } +/*! + Returns true if antialiased painting is enabled; otherwise, false is returned. + + By default, antialiasing is not enabled. + + \sa setAntialiasing() +*/ +bool QSGPaintedItem::antialiasing() const +{ + Q_D(const QSGPaintedItem); + return d->antialiasing; +} + +/*! + If \a enable is true, antialiased painting is enabled. + + By default, antialiasing is not enabled. + + \sa antialiasing() +*/ +void QSGPaintedItem::setAntialiasing(bool enable) +{ + Q_D(QSGPaintedItem); + + if (d->antialiasing == enable) + return; + + d->antialiasing = enable; + update(); +} + QSize QSGPaintedItem::contentsSize() const { // XXX todo @@ -337,7 +368,7 @@ QSGNode *QSGPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData * node->setPreferredRenderTarget(d->renderTarget); node->setSize(QSize(d->width, d->height)); - node->setSmoothPainting(d->smooth); + node->setSmoothPainting(d->antialiasing); node->setLinearFiltering(d->smooth); node->setOpaquePainting(d->opaquePainting); node->setFillColor(d->fillColor); diff --git a/src/declarative/items/qsgpainteditem.h b/src/declarative/items/qsgpainteditem.h index 23becfefa4..85255243c2 100644 --- a/src/declarative/items/qsgpainteditem.h +++ b/src/declarative/items/qsgpainteditem.h @@ -75,6 +75,9 @@ public: bool opaquePainting() const; void setOpaquePainting(bool opaque); + bool antialiasing() const; + void setAntialiasing(bool enable); + QSize contentsSize() const; void setContentsSize(const QSize &); void resetContentsSize(); diff --git a/src/declarative/items/qsgpainteditem_p.h b/src/declarative/items/qsgpainteditem_p.h index c49da5098f..ee76319a92 100644 --- a/src/declarative/items/qsgpainteditem_p.h +++ b/src/declarative/items/qsgpainteditem_p.h @@ -60,6 +60,7 @@ public: bool geometryDirty : 1; bool contentsDirty : 1; bool opaquePainting: 1; + bool antialiasing: 1; }; QT_END_NAMESPACE -- cgit v1.2.3 From b3bb9c795271e0b6a103e485873a88a395bdf9f8 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 3 May 2011 14:43:51 +0200 Subject: Removed unused properties in QSGPaintedItem. --- src/declarative/items/qsgpainteditem.cpp | 22 ---------------------- src/declarative/items/qsgpainteditem.h | 8 -------- 2 files changed, 30 deletions(-) diff --git a/src/declarative/items/qsgpainteditem.cpp b/src/declarative/items/qsgpainteditem.cpp index e0d63fa436..e9f4f73448 100644 --- a/src/declarative/items/qsgpainteditem.cpp +++ b/src/declarative/items/qsgpainteditem.cpp @@ -244,28 +244,6 @@ void QSGPaintedItem::setContentsScale(qreal) // XXX todo } -int QSGPaintedItem::pixelCacheSize() const -{ - // XXX todo - return 0; -} - -void QSGPaintedItem::setPixelCacheSize(int) -{ - // XXX todo -} - -bool QSGPaintedItem::smoothCache() const -{ - // XXX todo - return false; -} - -void QSGPaintedItem::setSmoothCache(bool) -{ - // XXX todo -} - /*! \property QSGPaintedItem::fillColor \brief The item's background fill color. diff --git a/src/declarative/items/qsgpainteditem.h b/src/declarative/items/qsgpainteditem.h index 85255243c2..8d4b466922 100644 --- a/src/declarative/items/qsgpainteditem.h +++ b/src/declarative/items/qsgpainteditem.h @@ -57,8 +57,6 @@ class Q_DECLARATIVE_EXPORT QSGPaintedItem : public QSGItem Q_PROPERTY(QSize contentsSize READ contentsSize WRITE setContentsSize NOTIFY contentsSizeChanged) Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor NOTIFY fillColorChanged) - Q_PROPERTY(int pixelCacheSize READ pixelCacheSize WRITE setPixelCacheSize) - Q_PROPERTY(bool smoothCache READ smoothCache WRITE setSmoothCache) Q_PROPERTY(qreal contentsScale READ contentsScale WRITE setContentsScale NOTIFY contentsScaleChanged) Q_PROPERTY(RenderTarget renderTarget READ renderTarget WRITE setRenderTarget NOTIFY renderTargetChanged) public: @@ -85,12 +83,6 @@ public: qreal contentsScale() const; void setContentsScale(qreal); - int pixelCacheSize() const; - void setPixelCacheSize(int pixels); - - bool smoothCache() const; - void setSmoothCache(bool on); - QColor fillColor() const; void setFillColor(const QColor&); -- cgit v1.2.3 From 79943c45bf22d28797afcd7a47bc98ad27b171ad Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Tue, 3 May 2011 16:50:51 +0200 Subject: Code cleanup in QSGShaderEffectTexture. --- src/declarative/items/qsgshadereffectsource.cpp | 24 +++++++++++++----------- src/declarative/items/qsgshadereffectsource_p.h | 8 ++------ 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/declarative/items/qsgshadereffectsource.cpp b/src/declarative/items/qsgshadereffectsource.cpp index e5b79a6d78..e7e248299d 100644 --- a/src/declarative/items/qsgshadereffectsource.cpp +++ b/src/declarative/items/qsgshadereffectsource.cpp @@ -65,6 +65,7 @@ QSGShaderEffectTexture::QSGShaderEffectTexture(QSGItem *shaderSource) #ifdef QSG_DEBUG_FBO_OVERLAY , m_debugOverlay(0) #endif + , m_mipmap(false) , m_live(true) , m_dirtyTexture(true) , m_multisamplingSupportChecked(false) @@ -95,7 +96,7 @@ bool QSGShaderEffectTexture::hasAlphaChannel() const bool QSGShaderEffectTexture::hasMipmaps() const { - return m_mipmapFiltering; + return m_mipmap; } @@ -114,12 +115,12 @@ bool QSGShaderEffectTexture::updateTexture() return false; } -void QSGShaderEffectTexture::setHasMipmaps(QSGTexture::Filtering filtering) +void QSGShaderEffectTexture::setHasMipmaps(bool mipmap) { - if (filtering == m_mipmapFiltering) + if (mipmap == m_mipmap) return; - m_mipmapFiltering = filtering; - if (filtering != None && m_fbo && !m_fbo->format().mipmap()) + m_mipmap = mipmap; + if (m_mipmap && m_fbo && !m_fbo->format().mipmap()) markDirtyTexture(); } @@ -196,9 +197,8 @@ void QSGShaderEffectTexture::grab() } m_renderer->setRootNode(static_cast(root)); - bool mipmap = m_mipmapFiltering != None; if (!m_fbo || m_fbo->size() != m_size || m_fbo->format().internalTextureFormat() != m_format - || (!m_fbo->format().mipmap() && mipmap)) + || (!m_fbo->format().mipmap() && m_mipmap)) { if (!m_multisamplingSupportChecked) { QList extensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' '); @@ -217,7 +217,7 @@ void QSGShaderEffectTexture::grab() m_multisampledFbo = new QGLFramebufferObject(m_size, format); format.setAttachment(QGLFramebufferObject::NoAttachment); - format.setMipmap(m_mipmapFiltering); + format.setMipmap(m_mipmap); format.setSamples(0); m_fbo = new QGLFramebufferObject(m_size, format); @@ -226,7 +226,7 @@ void QSGShaderEffectTexture::grab() QGLFramebufferObjectFormat format; format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); format.setInternalTextureFormat(m_format); - format.setMipmap(m_mipmapFiltering); + format.setMipmap(m_mipmap); m_fbo = new QGLFramebufferObject(m_size, format); } } @@ -267,7 +267,7 @@ void QSGShaderEffectTexture::grab() m_renderer->renderScene(BindableFbo(m_fbo)); } - if (mipmap) { + if (m_mipmap) { glBindTexture(GL_TEXTURE_2D, textureId()); ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D); } @@ -461,6 +461,8 @@ static void get_wrap_mode(QSGShaderEffectSource::WrapMode mode, QSGTexture::Wrap *hWrap = *vWrap = QSGTexture::Repeat; break; default: + // QSGShaderEffectSource::ClampToEdge + *hWrap = *vWrap = QSGTexture::ClampToEdge; break; } } @@ -504,12 +506,12 @@ QSGNode *QSGShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaintNod tex->setSize(textureSize); tex->setLive(m_live); tex->setFormat(GLenum(m_format)); + tex->setHasMipmaps(m_mipmap); QSGTexture::Filtering filtering = QSGItemPrivate::get(this)->smooth ? QSGTexture::Linear : QSGTexture::Nearest; QSGTexture::Filtering mmFiltering = m_mipmap ? filtering : QSGTexture::None; - tex->setHasMipmaps(mmFiltering); node->setMipmapFiltering(mmFiltering); node->setFiltering(filtering); diff --git a/src/declarative/items/qsgshadereffectsource_p.h b/src/declarative/items/qsgshadereffectsource_p.h index 1b6e1b5fe8..5d571ed42d 100644 --- a/src/declarative/items/qsgshadereffectsource_p.h +++ b/src/declarative/items/qsgshadereffectsource_p.h @@ -82,7 +82,7 @@ public: QSize size() const { return m_size; } void setSize(const QSize &size); - void setHasMipmaps(QSGTexture::Filtering filtering); + void setHasMipmaps(bool mipmap); void bind(); @@ -120,11 +120,7 @@ private: QSGRectangleNode *m_debugOverlay; #endif - uint m_hWrapMode : 1; - uint m_vWrapMode : 1; - uint m_filtering : 2; - uint m_mipmapFiltering : 2; - + uint m_mipmap : 1; uint m_live : 1; uint m_dirtyTexture : 1; uint m_multisamplingSupportChecked : 1; -- cgit v1.2.3 From a6a0dfc44e729f6a9e772beec1b7fd176051da4b Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 4 May 2011 14:43:16 +1000 Subject: Fix crashing QtQuick 1 Image elements. --- src/declarative/util/qdeclarativepixmapcache.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index dcce7db813..f0e999b46e 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -289,7 +289,7 @@ void QDeclarativePixmapReply::postReply(ReadError error, const QString &errorStr } QDeclarativePixmapReply::Event::Event(ReadError e, const QString &s, const QSize &iSize, const QImage &i) - : QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), image(i) + : QEvent(QEvent::User), error(e), errorString(s), implicitSize(iSize), image(i), texture(0), context(0) { } @@ -793,7 +793,7 @@ bool QDeclarativePixmapReply::event(QEvent *event) if (data) { Event *de = static_cast(event); data->pixmapStatus = (de->error == NoError) ? QDeclarativePixmap::Ready : QDeclarativePixmap::Error; - + if (data->pixmapStatus == QDeclarativePixmap::Ready) { if (de->texture) { data->texture = de->texture; -- cgit v1.2.3 From ff62dede7b8f4d211ad1de922ccb901ab9ae055c Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Wed, 4 May 2011 17:42:49 +1000 Subject: Fix QSGText autotests --- tests/auto/declarative/qsgtext/tst_qsgtext.cpp | 55 -------------------------- 1 file changed, 55 deletions(-) diff --git a/tests/auto/declarative/qsgtext/tst_qsgtext.cpp b/tests/auto/declarative/qsgtext/tst_qsgtext.cpp index 51184885db..2861dd9a9f 100644 --- a/tests/auto/declarative/qsgtext/tst_qsgtext.cpp +++ b/tests/auto/declarative/qsgtext/tst_qsgtext.cpp @@ -106,8 +106,6 @@ private slots: void QTBUG_12291(); void implicitSize_data(); void implicitSize(); - void testQtQuick11Attributes(); - void testQtQuick11Attributes_data(); void qtbug_14734(); private: @@ -1323,12 +1321,10 @@ void tst_qsgtext::lineHeight() qreal h2 = myText->height(); myText->setLineHeight(2.0); - QEXPECT_FAIL("", "QTBUG-17325", Continue); QVERIFY(myText->height() == h2 * 2.0); myText->setLineHeightMode(QSGText::FixedHeight); myText->setLineHeight(10); - QEXPECT_FAIL("", "QTBUG-17325", Continue); QCOMPARE(myText->height(), myText->lineCount() * 10.0); delete canvas; @@ -1363,57 +1359,6 @@ void tst_qsgtext::implicitSize() delete textObject; } -void tst_qsgtext::testQtQuick11Attributes() -{ - QFETCH(QString, code); - QFETCH(QString, warning); - QFETCH(QString, error); - - QDeclarativeEngine engine; - QObject *obj; - - QDeclarativeComponent valid(&engine); - valid.setData("import QtQuick 2.0; Text { " + code.toUtf8() + " }", QUrl("")); - obj = valid.create(); - QVERIFY(obj); - QVERIFY(valid.errorString().isEmpty()); - delete obj; - - QDeclarativeComponent invalid(&engine); - invalid.setData("import QtQuick 1.0; Text { " + code.toUtf8() + " }", QUrl("")); - QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); - obj = invalid.create(); - QCOMPARE(invalid.errorString(), error); - delete obj; -} - -void tst_qsgtext::testQtQuick11Attributes_data() -{ - QTest::addColumn("code"); - QTest::addColumn("warning"); - QTest::addColumn("error"); - - QTest::newRow("maximumLineCount") << "maximumLineCount: 4" - << "QDeclarativeComponent: Component is not ready" - << ":1 \"Text.maximumLineCount\" is not available in QtQuick 1.0.\n"; - - QTest::newRow("lineHeight") << "lineHeight: 2" - << "QDeclarativeComponent: Component is not ready" - << ":1 \"Text.lineHeight\" is not available in QtQuick 1.0.\n"; - - QTest::newRow("lineHeightMode") << "lineHeightMode: Text.ProportionalHeight" - << "QDeclarativeComponent: Component is not ready" - << ":1 \"Text.lineHeightMode\" is not available in QtQuick 1.0.\n"; - - QTest::newRow("lineCount") << "property int foo: lineCount" - << ":1: ReferenceError: Can't find variable: lineCount" - << ""; - - QTest::newRow("truncated") << "property bool foo: truncated" - << ":1: ReferenceError: Can't find variable: truncated" - << ""; -} - void tst_qsgtext::qtbug_14734() { QSGView *canvas = createView(SRCDIR "/data/qtbug_14734.qml"); -- cgit v1.2.3 From 1b7c1b6ef86d3d56ff01b2eab118062a229b0d19 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 4 May 2011 17:53:51 +1000 Subject: Update SG items with GV item changes. --- src/declarative/items/qsgflickable.cpp | 248 ++++++++++++++------- src/declarative/items/qsgflickable_p_p.h | 18 +- src/declarative/items/qsggridview.cpp | 34 ++- src/declarative/items/qsgimage.cpp | 22 +- src/declarative/items/qsgimagebase.cpp | 26 ++- src/declarative/items/qsgimagebase_p.h | 5 +- src/declarative/items/qsglistview.cpp | 42 +++- src/declarative/items/qsgmousearea.cpp | 31 ++- src/declarative/items/qsgmousearea_p.h | 5 +- src/declarative/items/qsgmousearea_p_p.h | 5 +- src/declarative/items/qsgpathview.cpp | 4 +- src/declarative/items/qsgpincharea.cpp | 230 ++++++++++--------- src/declarative/items/qsgpincharea_p.h | 9 +- src/declarative/items/qsgpincharea_p_p.h | 7 +- src/declarative/items/qsgtext.cpp | 24 +- src/declarative/items/qsgtext_p_p.h | 3 +- src/declarative/items/qsgtextedit.cpp | 17 +- src/declarative/items/qsgtextinput.cpp | 59 +++-- src/declarative/items/qsgtextinput_p.h | 7 +- src/declarative/items/qsgtextinput_p_p.h | 10 +- .../declarative/qsgflickable/tst_qsgflickable.cpp | 2 +- 21 files changed, 546 insertions(+), 262 deletions(-) diff --git a/src/declarative/items/qsgflickable.cpp b/src/declarative/items/qsgflickable.cpp index e2f6fff71b..ab3559bce9 100644 --- a/src/declarative/items/qsgflickable.cpp +++ b/src/declarative/items/qsgflickable.cpp @@ -1,4 +1,4 @@ -// Commit: ee767e8c16742316068e83323374ea54f2b939cb +// Commit: d4fa1878ff1e7628d3e984d54f8a93810353c71b /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -48,9 +48,41 @@ #include #include #include +#include "qplatformdefs.h" QT_BEGIN_NAMESPACE +// The maximum number of pixels a flick can overshoot +#ifndef QML_FLICK_OVERSHOOT +#define QML_FLICK_OVERSHOOT 200 +#endif + +// The number of samples to use in calculating the velocity of a flick +#ifndef QML_FLICK_SAMPLEBUFFER +#define QML_FLICK_SAMPLEBUFFER 3 +#endif + +// The number of samples to discard when calculating the flick velocity. +// Touch panels often produce inaccurate results as the finger is lifted. +#ifndef QML_FLICK_DISCARDSAMPLES +#define QML_FLICK_DISCARDSAMPLES 1 +#endif + +// The default maximum velocity of a flick. +#ifndef QML_FLICK_DEFAULTMAXVELOCITY +#define QML_FLICK_DEFAULTMAXVELOCITY 2500 +#endif + +// The default deceleration of a flick. +#ifndef QML_FLICK_DEFAULTDECELERATION +#define QML_FLICK_DEFAULTDECELERATION 1500 +#endif + +// How much faster to decelerate when overshooting +#ifndef QML_FLICK_OVERSHOOTFRICTION +#define QML_FLICK_OVERSHOOTFRICTION 8 +#endif + // FlickThreshold determines how far the "mouse" must have moved // before we perform a flick. static const int FlickThreshold = 20; @@ -143,8 +175,9 @@ QSGFlickablePrivate::QSGFlickablePrivate() , hMoved(false), vMoved(false) , movingHorizontally(false), movingVertically(false) , stealMouse(false), pressed(false), interactive(true), calcVelocity(false) - , deceleration(500), maxVelocity(2000), reportedVelocitySmoothing(100) - , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(600) + , deceleration(QML_FLICK_DEFAULTDECELERATION) + , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100) + , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(400) , fixupMode(Normal), vTime(0), visibleArea(0) , flickableDirection(QSGFlickable::AutoFlickDirection) , boundsBehavior(QSGFlickable::DragAndOvershootBounds) @@ -181,16 +214,36 @@ void QSGFlickablePrivate::init() Returns the amount to overshoot by given a velocity. Will be roughly in range 0 - size/4 */ -qreal QSGFlickablePrivate::overShootDistance(qreal velocity, qreal size) +qreal QSGFlickablePrivate::overShootDistance(qreal size) { if (maxVelocity <= 0) return 0.0; - velocity = qAbs(velocity); - if (velocity > maxVelocity) - velocity = maxVelocity; - qreal dist = size / 4 * velocity / maxVelocity; - return dist; + return qMin(qreal(QML_FLICK_OVERSHOOT), size/3); +} + +void QSGFlickablePrivate::AxisData::addVelocitySample(qreal v, qreal maxVelocity) +{ + if (v > maxVelocity) + v = maxVelocity; + else if (v < -maxVelocity) + v = -maxVelocity; + velocityBuffer.append(v); + if (velocityBuffer.count() > QML_FLICK_SAMPLEBUFFER) + velocityBuffer.remove(0); +} + +void QSGFlickablePrivate::AxisData::updateVelocity() +{ + if (velocityBuffer.count() > QML_FLICK_DISCARDSAMPLES) { + velocity = 0; + int count = velocityBuffer.count()-QML_FLICK_DISCARDSAMPLES; + for (int i = 0; i < count; ++i) { + qreal v = velocityBuffer.at(i); + velocity += v; + } + velocity /= count; + } } void QSGFlickablePrivate::itemGeometryChanged(QSGItem *item, const QRectF &newGeom, const QRectF &oldGeom) @@ -216,21 +269,18 @@ void QSGFlickablePrivate::flickY(qreal velocity) flick(vData, q->minYExtent(), q->maxYExtent(), q->height(), fixupY_callback, velocity); } -void QSGFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize, +void QSGFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal, QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity) { Q_Q(QSGFlickable); qreal maxDistance = -1; data.fixingUp = false; - bool overShoot = boundsBehavior == QSGFlickable::DragAndOvershootBounds; // -ve velocity means list is moving up if (velocity > 0) { - if (data.move.value() < minExtent) - maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity,vSize):0)); + maxDistance = qAbs(minExtent - data.move.value()); data.flickTarget = minExtent; } else { - if (data.move.value() > maxExtent) - maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity,vSize):0); + maxDistance = qAbs(maxExtent - data.move.value()); data.flickTarget = maxExtent; } if (maxDistance > 0) { @@ -242,7 +292,10 @@ void QSGFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent v = maxVelocity; } timeline.reset(data.move); - timeline.accel(data.move, v, deceleration, maxDistance); + if (boundsBehavior == QSGFlickable::DragAndOvershootBounds) + timeline.accel(data.move, v, deceleration); + else + timeline.accel(data.move, v, deceleration, maxDistance); timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); if (!flickingHorizontally && q->xflick()) { flickingHorizontally = true; @@ -329,6 +382,7 @@ void QSGFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent } } } + data.inOvershoot = false; fixupMode = Normal; vTime = timeline.time(); } @@ -537,16 +591,13 @@ void QSGFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) q->setKeepMouseGrab(stealMouse); pressed = true; timeline.clear(); - hData.velocity = 0; - vData.velocity = 0; - hData.dragStartOffset = 0; - vData.dragStartOffset = 0; + hData.reset(); + vData.reset(); hData.dragMinBound = q->minXExtent(); vData.dragMinBound = q->minYExtent(); hData.dragMaxBound = q->maxXExtent(); vData.dragMaxBound = q->maxYExtent(); - hData.fixingUp = false; - vData.fixingUp = false; + fixupMode = Normal; lastPos = QPoint(); QSGItemPrivate::start(lastPosTime); pressPos = event->pos(); @@ -638,33 +689,33 @@ void QSGFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) if (stealMouse) q->setKeepMouseGrab(true); - if (!lastPos.isNull()) { - qreal elapsed = qreal(QSGItemPrivate::restart(lastPosTime)) / 1000.; - if (elapsed <= 0) - elapsed = 1; - if (q->yflick()) { - qreal diff = event->pos().y() - lastPos.y(); - // average to reduce the effect of spurious moves - vData.velocity += diff / elapsed; - vData.velocity /= 2; - } - - if (q->xflick()) { - qreal diff = event->pos().x() - lastPos.x(); - // average to reduce the effect of spurious moves - hData.velocity += diff / elapsed; - hData.velocity /= 2; - } + if (rejectY) { + vData.velocityBuffer.clear(); + vData.velocity = 0; + } + if (rejectX) { + hData.velocityBuffer.clear(); + hData.velocity = 0; } - - if (rejectY) vData.velocity = 0; - if (rejectX) hData.velocity = 0; if (hMoved || vMoved) { q->movementStarting(); q->viewportMoved(); } + if (!lastPos.isNull()) { + qreal elapsed = qreal(QSGItemPrivate::elapsed(lastPosTime)) / 1000.; + if (elapsed <= 0) + return; + QSGItemPrivate::restart(lastPosTime); + qreal dy = event->pos().y()-lastPos.y(); + if (q->yflick() && !rejectY) + vData.addVelocitySample(dy/elapsed, maxVelocity); + qreal dx = event->pos().x()-lastPos.x(); + if (q->xflick() && !rejectX) + hData.addVelocitySample(dx/elapsed, maxVelocity); + } + lastPos = event->pos(); } @@ -677,25 +728,33 @@ void QSGFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *even if (!lastPosTime.isValid()) return; - if (QSGItemPrivate::elapsed(lastPosTime) > 100) { - // if we drag then pause before release we should not cause a flick. + // if we drag then pause before release we should not cause a flick. + if (QSGItemPrivate::elapsed(lastPosTime) < 100) { + vData.updateVelocity(); + hData.updateVelocity(); + } else { hData.velocity = 0.0; vData.velocity = 0.0; } vTime = timeline.time(); - if (qAbs(vData.velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) - flickY(vData.velocity); + + qreal velocity = vData.velocity; + if (vData.atBeginning || vData.atEnd) + velocity /= 2; + if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) + flickY(velocity); else fixupY(); - if (qAbs(hData.velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) - flickX(hData.velocity); + velocity = hData.velocity; + if (hData.atBeginning || hData.atEnd) + velocity /= 2; + if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) + flickX(velocity); else fixupX(); - lastPosTime.invalidate(); - if (!timeline.isActive()) q->movementEnding(); } @@ -742,29 +801,41 @@ void QSGFlickable::wheelEvent(QGraphicsSceneWheelEvent *event) if (!d->interactive) { QSGItem::wheelEvent(event); } else if (yflick() && event->orientation() == Qt::Vertical) { - if (event->delta() > 0) - d->vData.velocity = qMax(event->delta() - d->vData.smoothVelocity.value(), qreal(250.0)); - else - d->vData.velocity = qMin(event->delta() - d->vData.smoothVelocity.value(), qreal(-250.0)); - d->flickingVertically = false; - d->flickY(d->vData.velocity); - if (d->flickingVertically) { - d->vMoved = true; - movementStarting(); + bool valid = false; + if (event->delta() > 0 && contentY() > -minYExtent()) { + d->vData.velocity = qMax(event->delta()*2 - d->vData.smoothVelocity.value(), qreal(d->maxVelocity/4)); + valid = true; + } else if (event->delta() < 0 && contentY() < -maxYExtent()) { + d->vData.velocity = qMin(event->delta()*2 - d->vData.smoothVelocity.value(), qreal(-d->maxVelocity/4)); + valid = true; + } + if (valid) { + d->flickingVertically = false; + d->flickY(d->vData.velocity); + if (d->flickingVertically) { + d->vMoved = true; + movementStarting(); + } + event->accept(); } - event->accept(); } else if (xflick() && event->orientation() == Qt::Horizontal) { - if (event->delta() > 0) - d->hData.velocity = qMax(event->delta() - d->hData.smoothVelocity.value(), qreal(250.0)); - else - d->hData.velocity = qMin(event->delta() - d->hData.smoothVelocity.value(), qreal(-250.0)); - d->flickingHorizontally = false; - d->flickX(d->hData.velocity); - if (d->flickingHorizontally) { - d->hMoved = true; - movementStarting(); + bool valid = false; + if (event->delta() > 0 && contentX() > -minXExtent()) { + d->hData.velocity = qMax(event->delta()*2 - d->hData.smoothVelocity.value(), qreal(d->maxVelocity/4)); + valid = true; + } else if (event->delta() < 0 && contentX() < -maxXExtent()) { + d->hData.velocity = qMin(event->delta()*2 - d->hData.smoothVelocity.value(), qreal(-d->maxVelocity/4)); + valid = true; + } + if (valid) { + d->flickingHorizontally = false; + d->flickX(d->hData.velocity); + if (d->flickingHorizontally) { + d->hMoved = true; + movementStarting(); + } + event->accept(); } - event->accept(); } else { QSGItem::wheelEvent(event); } @@ -901,6 +972,27 @@ void QSGFlickable::viewportMoved() } } + if (!d->vData.inOvershoot && !d->vData.fixingUp && d->flickingVertically + && (d->vData.move.value() > minYExtent() || d->vData.move.value() < maxYExtent()) + && qAbs(d->vData.smoothVelocity.value()) > 100) { + // Increase deceleration if we've passed a bound + d->vData.inOvershoot = true; + qreal maxDistance = d->overShootDistance(height()); + d->timeline.reset(d->vData.move); + d->timeline.accel(d->vData.move, -d->vData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance); + d->timeline.callback(QDeclarativeTimeLineCallback(&d->vData.move, d->fixupY_callback, d)); + } + if (!d->hData.inOvershoot && !d->hData.fixingUp && d->flickingHorizontally + && (d->hData.move.value() > minXExtent() || d->hData.move.value() < maxXExtent()) + && qAbs(d->hData.smoothVelocity.value()) > 100) { + // Increase deceleration if we've passed a bound + d->hData.inOvershoot = true; + qreal maxDistance = d->overShootDistance(width()); + d->timeline.reset(d->hData.move); + d->timeline.accel(d->hData.move, -d->hData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance); + d->timeline.callback(QDeclarativeTimeLineCallback(&d->hData.move, d->fixupX_callback, d)); + } + d->lastFlickablePosition = QPointF(d->hData.move.value(), d->vData.move.value()); d->vTime = d->timeline.time(); @@ -1071,7 +1163,9 @@ void QSGFlickable::resizeContent(qreal w, qreal h, QPointF center) Q_D(QSGFlickable); if (w != d->hData.viewSize) { qreal oldSize = d->hData.viewSize; - setContentWidth(w); + d->hData.viewSize = w; + d->contentItem->setWidth(w); + emit contentWidthChanged(); if (center.x() != 0) { qreal pos = center.x() * w / oldSize; setContentX(contentX() + pos - center.x()); @@ -1079,12 +1173,15 @@ void QSGFlickable::resizeContent(qreal w, qreal h, QPointF center) } if (h != d->vData.viewSize) { qreal oldSize = d->vData.viewSize; - setContentHeight(h); + d->vData.viewSize = h; + d->contentItem->setHeight(h); + emit contentHeightChanged(); if (center.y() != 0) { qreal pos = center.y() * h / oldSize; setContentY(contentY() + pos - center.y()); } } + d->updateBeginningEnd(); } void QSGFlickable::returnToBounds() @@ -1148,8 +1245,9 @@ bool QSGFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) QSGCanvas *c = canvas(); QSGItem *grabber = c ? c->mouseGrabberItem() : 0; + bool disabledItem = grabber && !grabber->isEnabled(); bool stealThisEvent = d->stealMouse; - if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) { + if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab() || disabledItem)) { mouseEvent.setAccepted(false); for (int i = 0x1; i <= 0x10; i <<= 1) { if (event->buttons() & i) { @@ -1196,12 +1294,12 @@ bool QSGFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) break; } grabber = qobject_cast(c->mouseGrabberItem()); - if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) { + if ((grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) || disabledItem) { d->clearDelayedPress(); grabMouse(); } - return stealThisEvent || d->delayedPressEvent; + return stealThisEvent || d->delayedPressEvent || disabledItem; } else if (d->lastPosTime.isValid()) { d->lastPosTime.invalidate(); } diff --git a/src/declarative/items/qsgflickable_p_p.h b/src/declarative/items/qsgflickable_p_p.h index 2861bfd5b3..9f212ee038 100644 --- a/src/declarative/items/qsgflickable_p_p.h +++ b/src/declarative/items/qsgflickable_p_p.h @@ -1,4 +1,4 @@ -// Commit: cb0a6844705802564c81b581f24a76c5d5adf6d1 +// Commit: 160f1867868cdea916923652b00484ed11f90aaa /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -96,9 +96,19 @@ public: struct AxisData { AxisData(QSGFlickablePrivate *fp, void (QSGFlickablePrivate::*func)(qreal)) : move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true) - , fixingUp(false) + , fixingUp(false), inOvershoot(false) {} + void reset() { + velocityBuffer.clear(); + dragStartOffset = 0; + fixingUp = false; + inOvershoot = false; + } + + void addVelocitySample(qreal v, qreal maxVelocity); + void updateVelocity(); + QDeclarativeTimeLineValueProxy move; qreal viewSize; qreal pressPos; @@ -108,9 +118,11 @@ public: qreal velocity; qreal flickTarget; QSGFlickablePrivate::Velocity smoothVelocity; + QPODVector velocityBuffer; bool atEnd : 1; bool atBeginning : 1; bool fixingUp : 1; + bool inOvershoot : 1; }; void flickX(qreal velocity); @@ -131,7 +143,7 @@ public: void setRoundedViewportX(qreal x); void setRoundedViewportY(qreal y); - qreal overShootDistance(qreal velocity, qreal size); + qreal overShootDistance(qreal size); void itemGeometryChanged(QSGItem *, const QRectF &, const QRectF &); diff --git a/src/declarative/items/qsggridview.cpp b/src/declarative/items/qsggridview.cpp index 4f00d3651f..43f7f982a4 100644 --- a/src/declarative/items/qsggridview.cpp +++ b/src/declarative/items/qsggridview.cpp @@ -1,4 +1,4 @@ -// Commit: cc6408ccd5453d1bed9f98b9caa14861cea5742b +// Commit: fda9cc1d8a0e49817d1c6192c52d18dffcecf327 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -581,6 +581,26 @@ void QSGGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) --i; modelIndex = visibleItems.at(i)->index + 1; } + + if (visibleItems.count() && (fillFrom > rowPos + rowSize()*2 + || fillTo < rowPosAt(visibleIndex) - rowSize())) { + // We've jumped more than a page. Estimate which items are now + // visible and fill from there. + int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns; + for (int i = 0; i < visibleItems.count(); ++i) + releaseItem(visibleItems.at(i)); + visibleItems.clear(); + modelIndex += count; + if (modelIndex >= model->count()) + modelIndex = model->count() - 1; + else if (modelIndex < 0) + modelIndex = 0; + modelIndex = modelIndex / columns * columns; + visibleIndex = modelIndex; + colPos = colPosAt(visibleIndex); + rowPos = rowPosAt(visibleIndex); + } + int colNum = colPos / colSize(); FxGridItemSG *item = 0; @@ -1112,6 +1132,7 @@ void QSGGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) } else { QSGFlickablePrivate::fixup(data, minExtent, maxExtent); } + data.inOvershoot = false; fixupMode = Normal; } @@ -1190,7 +1211,7 @@ void QSGGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, accel = v2 / (2.0f * qAbs(dist)); } else { data.flickTarget = velocity > 0 ? minExtent : maxExtent; - overshootDist = overShoot ? overShootDistance(v, vSize) : 0; + overshootDist = overShoot ? overShootDistance(vSize) : 0; } timeline.reset(data.move); timeline.accel(data.move, v, accel, maxDistance + overshootDist); @@ -1869,7 +1890,7 @@ qreal QSGGridView::maxXExtent() const qreal extent; qreal highlightStart; qreal highlightEnd; - qreal lastItemPosition; + qreal lastItemPosition = 0; if (d->isRightToLeftTopToBottom()){ highlightStart = d->highlightRangeStartValid ? d->highlightRangeEnd : d->size(); highlightEnd = d->highlightRangeEndValid ? d->highlightRangeStart : d->size(); @@ -1877,6 +1898,7 @@ qreal QSGGridView::maxXExtent() const } else { highlightStart = d->highlightRangeStart; highlightEnd = d->highlightRangeEnd; + lastItemPosition = 0; if (d->model && d->model->count()) lastItemPosition = d->rowPosAt(d->model->count()-1); } @@ -2367,11 +2389,9 @@ void QSGGridView::itemsInserted(int modelIndex, int count) if (d->currentItem) { d->currentItem->index = d->currentIndex; d->currentItem->setPosition(d->colPosAt(d->currentIndex), d->rowPosAt(d->currentIndex)); - } else if (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared)) { - d->updateCurrent(0); } emit currentIndexChanged(); - } else if (d->itemCount == 0 && d->currentIndex == -1) { + } else if (d->itemCount == 0 && (!d->currentIndex || (d->currentIndex < 0 && !d->currentIndexCleared))) { setCurrentIndex(0); } @@ -2439,6 +2459,8 @@ void QSGGridView::itemsRemoved(int modelIndex, int count) d->currentIndex = -1; if (d->itemCount) d->updateCurrent(qMin(modelIndex, d->itemCount-1)); + else + emit currentIndexChanged(); } // update visibleIndex diff --git a/src/declarative/items/qsgimage.cpp b/src/declarative/items/qsgimage.cpp index d24db9f670..10670f4015 100644 --- a/src/declarative/items/qsgimage.cpp +++ b/src/declarative/items/qsgimage.cpp @@ -1,4 +1,4 @@ -// Commit: 695a39410c8ce186a2ce78cef51093c55fc32643 +// Commit: 051a76c1d65d698f71dc75c89f91ae9021357eae /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -77,12 +77,10 @@ void QSGImagePrivate::setPixmap(const QPixmap &pixmap) Q_Q(QSGImage); pix.setPixmap(pixmap); - q->setImplicitWidth(pix.width()); - q->setImplicitHeight(pix.height()); + q->pixmapChange(); status = pix.isNull() ? QSGImageBase::Null : QSGImageBase::Ready; q->update(); - q->pixmapChange(); } QSGImage::FillMode QSGImage::fillMode() const @@ -119,8 +117,11 @@ void QSGImage::updatePaintedGeometry() Q_D(QSGImage); if (d->fillMode == PreserveAspectFit) { - if (!d->pix.width() || !d->pix.height()) + if (!d->pix.width() || !d->pix.height()) { + setImplicitWidth(0); + setImplicitHeight(0); return; + } qreal w = widthValid() ? width() : d->pix.width(); qreal widthScale = w / qreal(d->pix.width()); qreal h = heightValid() ? height() : d->pix.height(); @@ -134,9 +135,13 @@ void QSGImage::updatePaintedGeometry() } if (widthValid() && !heightValid()) { setImplicitHeight(d->paintedHeight); + } else { + setImplicitHeight(d->pix.height()); } if (heightValid() && !widthValid()) { setImplicitWidth(d->paintedWidth); + } else { + setImplicitWidth(d->pix.width()); } } else if (d->fillMode == PreserveAspectCrop) { if (!d->pix.width() || !d->pix.height()) @@ -280,7 +285,12 @@ QSGNode *QSGImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) void QSGImage::pixmapChange() { Q_D(QSGImage); - + // PreserveAspectFit calculates the implicit size differently so we + // don't call our superclass pixmapChange(), since that would + // result in the implicit size being set incorrectly, then updated + // in updatePaintedGeometry() + if (d->fillMode != PreserveAspectFit) + QSGImageBase::pixmapChange(); updatePaintedGeometry(); d->pixmapChanged = true; } diff --git a/src/declarative/items/qsgimagebase.cpp b/src/declarative/items/qsgimagebase.cpp index bd8b24f735..9f2de03bbe 100644 --- a/src/declarative/items/qsgimagebase.cpp +++ b/src/declarative/items/qsgimagebase.cpp @@ -1,4 +1,4 @@ -// Commit: 462429f5692f810bdd4e04b916db5f9af428d9e4 +// Commit: 051a76c1d65d698f71dc75c89f91ae9021357eae /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -134,6 +134,18 @@ QSize QSGImageBase::sourceSize() const return QSize(width != -1 ? width : d->pix.width(), height != -1 ? height : d->pix.height()); } +void QSGImageBase::resetSourceSize() +{ + Q_D(QSGImageBase); + if (!d->explicitSourceSize) + return; + d->explicitSourceSize = false; + d->sourcesize = QSize(); + emit sourceSizeChanged(); + if (isComponentComplete()) + load(); +} + bool QSGImageBase::cache() const { Q_D(const QSGImageBase); @@ -180,11 +192,9 @@ void QSGImageBase::load() d->pix.clear(this); d->status = Null; d->progress = 0.0; - setImplicitWidth(0); - setImplicitHeight(0); + pixmapChange(); emit progressChanged(d->progress); emit statusChanged(d->status); - pixmapChange(); update(); } else { QDeclarativePixmap::Options options; @@ -235,8 +245,7 @@ void QSGImageBase::requestFinished() d->progress = 1.0; - setImplicitWidth(d->pix.width()); - setImplicitHeight(d->pix.height()); + pixmapChange(); if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height()) emit sourceSizeChanged(); @@ -245,7 +254,7 @@ void QSGImageBase::requestFinished() emit statusChanged(d->status); if (d->progress != oldProgress) emit progressChanged(d->progress); - pixmapChange(); + update(); } @@ -268,6 +277,9 @@ void QSGImageBase::componentComplete() void QSGImageBase::pixmapChange() { + Q_D(QSGImageBase); + setImplicitWidth(d->pix.width()); + setImplicitHeight(d->pix.height()); } QT_END_NAMESPACE diff --git a/src/declarative/items/qsgimagebase_p.h b/src/declarative/items/qsgimagebase_p.h index fe42854304..00b14525f2 100644 --- a/src/declarative/items/qsgimagebase_p.h +++ b/src/declarative/items/qsgimagebase_p.h @@ -1,4 +1,4 @@ -// Commit: ab71df83ba4eb9d749efc0f3a2d4a0fe5486023f +// Commit: af05f64d3edc860c3cf79c7f0bdf2377faae5f40 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -60,7 +60,7 @@ class Q_AUTOTEST_EXPORT QSGImageBase : public QSGImplicitSizeItem Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged) Q_PROPERTY(bool cache READ cache WRITE setCache NOTIFY cacheChanged) - Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize NOTIFY sourceSizeChanged) + Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize RESET resetSourceSize NOTIFY sourceSizeChanged) Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged) public: @@ -81,6 +81,7 @@ public: virtual void setSourceSize(const QSize&); QSize sourceSize() const; + void resetSourceSize(); virtual void setMirror(bool mirror); bool mirror() const; diff --git a/src/declarative/items/qsglistview.cpp b/src/declarative/items/qsglistview.cpp index 80cc8be837..3bc9026f8b 100644 --- a/src/declarative/items/qsglistview.cpp +++ b/src/declarative/items/qsglistview.cpp @@ -1,4 +1,4 @@ -// Commit: ce38c6e3a9b7eb336cbd9cd1e9520a5000c8f8ac +// Commit: cce89db1e2555cbca8fc28072e1c6dd737cec6c4 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -743,6 +743,27 @@ void QSGListViewPrivate::refill(qreal from, qreal to, bool doBuffer) modelIndex = visibleItems.at(i)->index + 1; } + if (visibleItems.count() && (fillFrom > itemEnd+averageSize+spacing + || fillTo < visiblePos - averageSize - spacing)) { + // We've jumped more than a page. Estimate which items are now + // visible and fill from there. + int count = (fillFrom - itemEnd) / (averageSize + spacing); + for (int i = 0; i < visibleItems.count(); ++i) + releaseItem(visibleItems.at(i)); + visibleItems.clear(); + modelIndex += count; + if (modelIndex >= model->count()) { + count -= modelIndex - model->count() + 1; + modelIndex = model->count() - 1; + } else if (modelIndex < 0) { + count -= modelIndex; + modelIndex = 0; + } + visibleIndex = modelIndex; + visiblePos = itemEnd + count * (averageSize + spacing) + 1; + itemEnd = visiblePos-1; + } + bool changed = false; FxListItemSG *item = 0; qreal pos = itemEnd + 1; @@ -1353,6 +1374,7 @@ void QSGListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) } else { QSGFlickablePrivate::fixup(data, minExtent, maxExtent); } + data.inOvershoot = false; fixupMode = Normal; } @@ -1425,10 +1447,10 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, data.flickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget; if (overShoot) { if (data.flickTarget >= minExtent) { - overshootDist = overShootDistance(v, vSize); + overshootDist = overShootDistance(vSize); data.flickTarget += overshootDist; } else if (data.flickTarget <= maxExtent) { - overshootDist = overShootDistance(v, vSize); + overshootDist = overShootDistance(vSize); data.flickTarget -= overshootDist; } } @@ -1448,10 +1470,10 @@ void QSGListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, } else if (overShoot) { data.flickTarget = data.move.value() - dist; if (data.flickTarget >= minExtent) { - overshootDist = overShootDistance(v, vSize); + overshootDist = overShootDistance(vSize); data.flickTarget += overshootDist; } else if (data.flickTarget <= maxExtent) { - overshootDist = overShootDistance(v, vSize); + overshootDist = overShootDistance(vSize); data.flickTarget -= overshootDist; } } @@ -1831,9 +1853,11 @@ void QSGListView::setOrientation(QSGListView::Orientation orientation) if (d->orient == QSGListView::Vertical) { setContentWidth(-1); setFlickableDirection(VerticalFlick); + setContentX(0); } else { setContentHeight(-1); setFlickableDirection(HorizontalFlick); + setContentY(0); } d->regenerate(); emit orientationChanged(); @@ -2131,7 +2155,7 @@ void QSGListView::viewportMoved() d->inFlickCorrection = true; // Near an end and it seems that the extent has changed? // Recalculate the flick so that we don't end up in an odd position. - if (yflick()) { + if (yflick() && !d->vData.inOvershoot) { if (d->vData.velocity > 0) { const qreal minY = minYExtent(); if ((minY - d->vData.move.value() < height()/2 || d->vData.flickTarget - d->vData.move.value() < height()/2) @@ -2147,7 +2171,7 @@ void QSGListView::viewportMoved() } } - if (xflick()) { + if (xflick() && !d->hData.inOvershoot) { if (d->hData.velocity > 0) { const qreal minX = minXExtent(); if ((minX - d->hData.move.value() < width()/2 || d->hData.flickTarget - d->hData.move.value() < width()/2) @@ -2311,7 +2335,7 @@ void QSGListView::keyPressEvent(QKeyEvent *event) { Q_D(QSGListView); if (d->model && d->model->count() && d->interactive) { - if ((!d->isRightToLeft() && event->key() == Qt::Key_Left) + if ((d->orient == QSGListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Left) || (d->orient == QSGListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Right) || (d->orient == QSGListView::Vertical && event->key() == Qt::Key_Up)) { if (currentIndex() > 0 || (d->wrap && !event->isAutoRepeat())) { @@ -2322,7 +2346,7 @@ void QSGListView::keyPressEvent(QKeyEvent *event) event->accept(); return; } - } else if ((!d->isRightToLeft() && event->key() == Qt::Key_Right) + } else if ((d->orient == QSGListView::Horizontal && !d->isRightToLeft() && event->key() == Qt::Key_Right) || (d->orient == QSGListView::Horizontal && d->isRightToLeft() && event->key() == Qt::Key_Left) || (d->orient == QSGListView::Vertical && event->key() == Qt::Key_Down)) { if (currentIndex() < d->model->count() - 1 || (d->wrap && !event->isAutoRepeat())) { diff --git a/src/declarative/items/qsgmousearea.cpp b/src/declarative/items/qsgmousearea.cpp index 1157a9a172..887d78a64d 100644 --- a/src/declarative/items/qsgmousearea.cpp +++ b/src/declarative/items/qsgmousearea.cpp @@ -1,4 +1,4 @@ -// Commit: f0f6deb9a5e8bd078047dd090a3857290c8b4ea4 +// Commit: e1ffbc04131dc6f76fa76821c297d08162e4b1ee /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -179,6 +179,8 @@ QSGMouseAreaPrivate::QSGMouseAreaPrivate() : absorb(true), hovered(false), pressed(false), longPress(false), moved(false), stealMouse(false), doubleClick(false), preventStealing(false), drag(0) { + Q_Q(QSGMouseArea); + forwardTo = QDeclarativeListProperty(q, forwardToList); } QSGMouseAreaPrivate::~QSGMouseAreaPrivate() @@ -202,6 +204,18 @@ void QSGMouseAreaPrivate::saveEvent(QGraphicsSceneMouseEvent *event) lastModifiers = event->modifiers(); } +void QSGMouseAreaPrivate::forwardEvent(QGraphicsSceneMouseEvent* event) +{ + Q_Q(QSGMouseArea); + for(int i=0; i < forwardToList.count(); i++){ + event->setPos(forwardToList[i]->mapFromScene(event->scenePos())); + forwardToList[i]->canvas()->sendEvent(forwardToList[i], event); + if(event->isAccepted()) + break; + } + event->setPos(q->mapFromScene(event->scenePos())); +} + bool QSGMouseAreaPrivate::isPressAndHoldConnected() { Q_Q(QSGMouseArea); @@ -382,6 +396,9 @@ void QSGMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event) d->pressAndHoldTimer.start(PressAndHoldDelay, this); setKeepMouseGrab(d->stealMouse); event->setAccepted(setPressed(true)); + + if(!event->isAccepted() && d->forwardToList.count()) + d->forwardEvent(event); } } @@ -459,6 +476,9 @@ void QSGMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event) me.setX(d->lastPos.x()); me.setY(d->lastPos.y()); emit positionChanged(&me); + + if(!event->isAccepted() && d->forwardToList.count()) + d->forwardEvent(event); } void QSGMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) @@ -479,6 +499,9 @@ void QSGMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if (c && c->mouseGrabberItem() == this) ungrabMouse(); setKeepMouseGrab(false); + + if(!event->isAccepted() && d->forwardToList.count()) + d->forwardEvent(event); } d->doubleClick = false; } @@ -768,4 +791,10 @@ QSGDrag *QSGMouseArea::drag() return d->drag; } +QDeclarativeListProperty QSGMouseArea::forwardTo() +{ + Q_D(QSGMouseArea); + return d->forwardTo; +} + QT_END_NAMESPACE diff --git a/src/declarative/items/qsgmousearea_p.h b/src/declarative/items/qsgmousearea_p.h index 24fb8389a6..469b9f7168 100644 --- a/src/declarative/items/qsgmousearea_p.h +++ b/src/declarative/items/qsgmousearea_p.h @@ -1,4 +1,4 @@ -// Commit: 57676c237992e0aa5a93a4e8fa66b3e7b90c2c90 +// Commit: c6e6a35aeb8794d68a3ca0c4e27a3a1181c066b5 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -131,6 +131,7 @@ class Q_AUTOTEST_EXPORT QSGMouseArea : public QSGItem Q_PROPERTY(bool hoverEnabled READ hoverEnabled WRITE setHoverEnabled NOTIFY hoverEnabledChanged) Q_PROPERTY(QSGDrag *drag READ drag CONSTANT) //### add flicking to QSGDrag or add a QDeclarativeFlick ??? Q_PROPERTY(bool preventStealing READ preventStealing WRITE setPreventStealing NOTIFY preventStealingChanged) + Q_PROPERTY(QDeclarativeListProperty forwardTo READ forwardTo); public: QSGMouseArea(QSGItem *parent=0); @@ -158,6 +159,8 @@ public: bool preventStealing() const; void setPreventStealing(bool prevent); + QDeclarativeListProperty forwardTo(); + Q_SIGNALS: void hoveredChanged(); void pressedChanged(); diff --git a/src/declarative/items/qsgmousearea_p_p.h b/src/declarative/items/qsgmousearea_p_p.h index b4b64c67e9..e736c059a2 100644 --- a/src/declarative/items/qsgmousearea_p_p.h +++ b/src/declarative/items/qsgmousearea_p_p.h @@ -1,4 +1,4 @@ -// Commit: 57676c237992e0aa5a93a4e8fa66b3e7b90c2c90 +// Commit: c6e6a35aeb8794d68a3ca0c4e27a3a1181c066b5 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -80,6 +80,7 @@ public: }; void propagate(QSGMouseEvent* event, PropagateType); bool propagateHelper(QSGMouseEvent*, QSGItem*,const QPointF &, PropagateType); + void forwardEvent(QGraphicsSceneMouseEvent* event); bool isPressAndHoldConnected(); bool isDoubleClickConnected(); @@ -105,6 +106,8 @@ public: Qt::MouseButtons lastButtons; Qt::KeyboardModifiers lastModifiers; QBasicTimer pressAndHoldTimer; + QDeclarativeListProperty forwardTo; + QList forwardToList; }; QT_END_NAMESPACE diff --git a/src/declarative/items/qsgpathview.cpp b/src/declarative/items/qsgpathview.cpp index f7dda6cb27..87e550b630 100644 --- a/src/declarative/items/qsgpathview.cpp +++ b/src/declarative/items/qsgpathview.cpp @@ -1,4 +1,4 @@ -// Commit: ac704e9f682378a5ec56e3f5c195dcf2f2dfa1ac +// Commit: 8878e2c53a0c9408d4b468e2dad485743c32f58b /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -1213,6 +1213,8 @@ void QSGPathView::itemsRemoved(int modelIndex, int count) } else { d->regenerate(); d->updateCurrent(); + if (!d->flicking && !d->moving && d->haveHighlightRange && d->highlightRangeMode == QSGPathView::StrictlyEnforceRange) + d->snapToCurrent(); } if (changedOffset) emit offsetChanged(); diff --git a/src/declarative/items/qsgpincharea.cpp b/src/declarative/items/qsgpincharea.cpp index e32f6bfe71..f21d873e5e 100644 --- a/src/declarative/items/qsgpincharea.cpp +++ b/src/declarative/items/qsgpincharea.cpp @@ -1,4 +1,4 @@ -// Commit: 2ec2dc55ddf424f5a7acd0a4729ddd9af2d7c398 +// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -121,7 +121,7 @@ void QSGPinchArea::touchEvent(QTouchEvent *event) void QSGPinchArea::updatePinch() { Q_D(QSGPinchArea); - if (d->touchPoints.count() != 2) { + if (d->touchPoints.count() == 0) { if (d->inPinch) { d->stealMouse = false; setKeepMouseGrab(false); @@ -134,127 +134,141 @@ void QSGPinchArea::updatePinch() pe.setPreviousScale(d->pinchLastScale); pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); - pe.setPoint1(d->lastPoint1); - pe.setPoint2(d->lastPoint2); + pe.setPoint1(mapFromScene(d->lastPoint1)); + pe.setPoint2(mapFromScene(d->lastPoint2)); emit pinchFinished(&pe); d->pinchStartDist = 0; + d->pinchActivated = false; if (d->pinch && d->pinch->target()) d->pinch->setActive(false); } return; } - if (d->touchPoints.at(0).state() & Qt::TouchPointPressed - || d->touchPoints.at(1).state() & Qt::TouchPointPressed) { - d->sceneStartPoint1 = d->touchPoints.at(0).scenePos(); - d->sceneStartPoint2 = d->touchPoints.at(1).scenePos(); + QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0); + QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0); + if (d->touchPoints.count() == 2 + && (touchPoint1.state() & Qt::TouchPointPressed || touchPoint2.state() & Qt::TouchPointPressed)) { + d->id1 = touchPoint1.id(); + d->sceneStartPoint1 = touchPoint1.scenePos(); + d->sceneStartPoint2 = touchPoint2.scenePos(); d->inPinch = false; d->pinchRejected = false; - } else if (!d->pinchRejected){ - QSGItem *grabber = canvas() ? canvas()->mouseGrabberItem() : 0; - if (grabber == this || !grabber || !grabber->keepMouseGrab()) { - const int dragThreshold = QApplication::startDragDistance(); - QPointF p1 = d->touchPoints.at(0).scenePos(); - QPointF p2 = d->touchPoints.at(1).scenePos(); - qreal dx = p1.x() - p2.x(); - qreal dy = p1.y() - p2.y(); - qreal dist = sqrt(dx*dx + dy*dy); - QPointF sceneCenter = (p1 + p2)/2; - qreal angle = QLineF(p1, p2).angle(); - if (angle > 180) - angle -= 360; - if (!d->inPinch) { - if (qAbs(p1.x()-d->sceneStartPoint1.x()) > dragThreshold - || qAbs(p1.y()-d->sceneStartPoint1.y()) > dragThreshold - || qAbs(p2.x()-d->sceneStartPoint2.x()) > dragThreshold - || qAbs(p2.y()-d->sceneStartPoint2.y()) > dragThreshold) { - d->sceneStartCenter = sceneCenter; - d->sceneLastCenter = sceneCenter; - d->pinchStartCenter = mapFromScene(sceneCenter); - d->pinchStartDist = dist; - d->pinchStartAngle = angle; - d->pinchLastScale = 1.0; - d->pinchLastAngle = angle; - d->pinchRotation = 0.0; - d->lastPoint1 = d->touchPoints.at(0).pos(); - d->lastPoint2 = d->touchPoints.at(1).pos(); - QSGPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0); - pe.setStartCenter(d->pinchStartCenter); - pe.setPreviousCenter(d->pinchStartCenter); - pe.setPreviousAngle(d->pinchLastAngle); - pe.setPreviousScale(d->pinchLastScale); - pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); - pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); - pe.setPoint1(d->lastPoint1); - pe.setPoint2(d->lastPoint2); - emit pinchStarted(&pe); - if (pe.accepted()) { - d->inPinch = true; - d->stealMouse = true; - QSGCanvas *c = canvas(); - if (c && c->mouseGrabberItem() != this) - grabMouse(); - setKeepMouseGrab(true); - if (d->pinch && d->pinch->target()) { - d->pinchStartPos = pinch()->target()->pos(); - d->pinchStartScale = d->pinch->target()->scale(); - d->pinchStartRotation = d->pinch->target()->rotation(); - d->pinch->setActive(true); - } - } else { - d->pinchRejected = true; - } - } - } else if (d->pinchStartDist > 0) { - qreal scale = dist / d->pinchStartDist; - qreal da = d->pinchLastAngle - angle; - if (da > 180) - da -= 360; - else if (da < -180) - da += 360; - d->pinchRotation += da; - QPointF pinchCenter = mapFromScene(sceneCenter); - QSGPinchEvent pe(pinchCenter, scale, angle, d->pinchRotation); + d->pinchActivated = true; + } else if (d->pinchActivated && !d->pinchRejected){ + const int dragThreshold = QApplication::startDragDistance(); + QPointF p1 = touchPoint1.scenePos(); + QPointF p2 = touchPoint2.scenePos(); + qreal dx = p1.x() - p2.x(); + qreal dy = p1.y() - p2.y(); + qreal dist = sqrt(dx*dx + dy*dy); + QPointF sceneCenter = (p1 + p2)/2; + qreal angle = QLineF(p1, p2).angle(); + if (d->touchPoints.count() == 1) { + // If we only have one point then just move the center + if (d->id1 == touchPoint1.id()) + sceneCenter = d->sceneLastCenter + touchPoint1.scenePos() - d->lastPoint1; + else + sceneCenter = d->sceneLastCenter + touchPoint2.scenePos() - d->lastPoint2; + angle = d->pinchLastAngle; + } + d->id1 = touchPoint1.id(); + if (angle > 180) + angle -= 360; + if (!d->inPinch) { + if (d->touchPoints.count() >= 2 + && (qAbs(p1.x()-d->sceneStartPoint1.x()) > dragThreshold + || qAbs(p1.y()-d->sceneStartPoint1.y()) > dragThreshold + || qAbs(p2.x()-d->sceneStartPoint2.x()) > dragThreshold + || qAbs(p2.y()-d->sceneStartPoint2.y()) > dragThreshold)) { + d->sceneStartCenter = sceneCenter; + d->sceneLastCenter = sceneCenter; + d->pinchStartCenter = mapFromScene(sceneCenter); + d->pinchStartDist = dist; + d->pinchStartAngle = angle; + d->pinchLastScale = 1.0; + d->pinchLastAngle = angle; + d->pinchRotation = 0.0; + d->lastPoint1 = p1; + d->lastPoint2 = p2; + QSGPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0); pe.setStartCenter(d->pinchStartCenter); - pe.setPreviousCenter(mapFromScene(d->sceneLastCenter)); + pe.setPreviousCenter(d->pinchStartCenter); pe.setPreviousAngle(d->pinchLastAngle); pe.setPreviousScale(d->pinchLastScale); pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); - pe.setPoint1(d->touchPoints.at(0).pos()); - pe.setPoint2(d->touchPoints.at(1).pos()); - d->pinchLastScale = scale; - d->sceneLastCenter = sceneCenter; - d->pinchLastAngle = angle; - d->lastPoint1 = d->touchPoints.at(0).pos(); - d->lastPoint2 = d->touchPoints.at(1).pos(); - emit pinchUpdated(&pe); - if (d->pinch && d->pinch->target()) { - qreal s = d->pinchStartScale * scale; - s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale()); - pinch()->target()->setScale(s); - QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos; - if (pinch()->axis() & QSGPinch::XAxis) { - qreal x = pos.x(); - if (x < pinch()->xmin()) - x = pinch()->xmin(); - else if (x > pinch()->xmax()) - x = pinch()->xmax(); - pinch()->target()->setX(x); - } - if (pinch()->axis() & QSGPinch::YAxis) { - qreal y = pos.y(); - if (y < pinch()->ymin()) - y = pinch()->ymin(); - else if (y > pinch()->ymax()) - y = pinch()->ymax(); - pinch()->target()->setY(y); - } - if (d->pinchStartRotation >= pinch()->minimumRotation() - && d->pinchStartRotation <= pinch()->maximumRotation()) { - qreal r = d->pinchRotation + d->pinchStartRotation; - r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation()); - pinch()->target()->setRotation(r); + pe.setPoint1(mapFromScene(d->lastPoint1)); + pe.setPoint2(mapFromScene(d->lastPoint2)); + pe.setPointCount(d->touchPoints.count()); + emit pinchStarted(&pe); + if (pe.accepted()) { + d->inPinch = true; + d->stealMouse = true; + QSGCanvas *c = canvas(); + if (c && c->mouseGrabberItem() != this) + grabMouse(); + setKeepMouseGrab(true); + if (d->pinch && d->pinch->target()) { + d->pinchStartPos = pinch()->target()->pos(); + d->pinchStartScale = d->pinch->target()->scale(); + d->pinchStartRotation = d->pinch->target()->rotation(); + d->pinch->setActive(true); } + } else { + d->pinchRejected = true; + } + } + } else if (d->pinchStartDist > 0) { + qreal scale = dist ? dist / d->pinchStartDist : d->pinchLastScale; + qreal da = d->pinchLastAngle - angle; + if (da > 180) + da -= 360; + else if (da < -180) + da += 360; + d->pinchRotation += da; + QPointF pinchCenter = mapFromScene(sceneCenter); + QSGPinchEvent pe(pinchCenter, scale, angle, d->pinchRotation); + pe.setStartCenter(d->pinchStartCenter); + pe.setPreviousCenter(mapFromScene(d->sceneLastCenter)); + pe.setPreviousAngle(d->pinchLastAngle); + pe.setPreviousScale(d->pinchLastScale); + pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); + pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); + pe.setPoint1(touchPoint1.pos()); + pe.setPoint2(touchPoint2.pos()); + pe.setPointCount(d->touchPoints.count()); + d->pinchLastScale = scale; + d->sceneLastCenter = sceneCenter; + d->pinchLastAngle = angle; + d->lastPoint1 = touchPoint1.scenePos(); + d->lastPoint2 = touchPoint2.scenePos(); + emit pinchUpdated(&pe); + if (d->pinch && d->pinch->target()) { + qreal s = d->pinchStartScale * scale; + s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale()); + pinch()->target()->setScale(s); + QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos; + if (pinch()->axis() & QSGPinch::XAxis) { + qreal x = pos.x(); + if (x < pinch()->xmin()) + x = pinch()->xmin(); + else if (x > pinch()->xmax()) + x = pinch()->xmax(); + pinch()->target()->setX(x); + } + if (pinch()->axis() & QSGPinch::YAxis) { + qreal y = pos.y(); + if (y < pinch()->ymin()) + y = pinch()->ymin(); + else if (y > pinch()->ymax()) + y = pinch()->ymax(); + pinch()->target()->setY(y); + } + if (d->pinchStartRotation >= pinch()->minimumRotation() + && d->pinchStartRotation <= pinch()->maximumRotation()) { + qreal r = d->pinchRotation + d->pinchStartRotation; + r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation()); + pinch()->target()->setRotation(r); } } } diff --git a/src/declarative/items/qsgpincharea_p.h b/src/declarative/items/qsgpincharea_p.h index 04fd815df3..4cba6367e1 100644 --- a/src/declarative/items/qsgpincharea_p.h +++ b/src/declarative/items/qsgpincharea_p.h @@ -1,4 +1,4 @@ -// Commit: ce59628ba366800fe2f3afdadc37be02f98480a7 +// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -204,11 +204,13 @@ class Q_AUTOTEST_EXPORT QSGPinchEvent : public QObject Q_PROPERTY(QPointF startPoint1 READ startPoint1) Q_PROPERTY(QPointF point2 READ point2) Q_PROPERTY(QPointF startPoint2 READ startPoint2) + Q_PROPERTY(int pointCount READ pointCount) Q_PROPERTY(bool accepted READ accepted WRITE setAccepted) public: QSGPinchEvent(QPointF c, qreal s, qreal a, qreal r) - : QObject(), m_center(c), m_scale(s), m_angle(a), m_rotation(r), m_accepted(true) {} + : QObject(), m_center(c), m_scale(s), m_angle(a), m_rotation(r) + , m_pointCount(0), m_accepted(true) {} QPointF center() const { return m_center; } QPointF startCenter() const { return m_startCenter; } @@ -230,6 +232,8 @@ public: void setPoint2(QPointF p) { m_point2 = p; } QPointF startPoint2() const { return m_startPoint2; } void setStartPoint2(QPointF p) { m_startPoint2 = p; } + int pointCount() const { return m_pointCount; } + void setPointCount(int count) { m_pointCount = count; } bool accepted() const { return m_accepted; } void setAccepted(bool a) { m_accepted = a; } @@ -247,6 +251,7 @@ private: QPointF m_point2; QPointF m_startPoint1; QPointF m_startPoint2; + int m_pointCount; bool m_accepted; }; diff --git a/src/declarative/items/qsgpincharea_p_p.h b/src/declarative/items/qsgpincharea_p_p.h index bdb3a51ef2..b93d095e0e 100644 --- a/src/declarative/items/qsgpincharea_p_p.h +++ b/src/declarative/items/qsgpincharea_p_p.h @@ -1,4 +1,4 @@ -// Commit: 2ec2dc55ddf424f5a7acd0a4729ddd9af2d7c398 +// Commit: f707672eb4c51ea82fbd98e1da16ece61a74c690 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -68,7 +68,8 @@ class QSGPinchAreaPrivate : public QSGItemPrivate public: QSGPinchAreaPrivate() : absorb(true), stealMouse(false), inPinch(false) - , pinchRejected(false), pinch(0), pinchStartDist(0), pinchStartScale(1.0) + , pinchRejected(false), pinchActivated(false) + , pinch(0), pinchStartDist(0), pinchStartScale(1.0) , pinchLastScale(1.0), pinchStartRotation(0.0), pinchStartAngle(0.0) , pinchLastAngle(0.0), pinchRotation(0.0) { @@ -87,6 +88,7 @@ public: bool stealMouse : 1; bool inPinch : 1; bool pinchRejected : 1; + bool pinchActivated : 1; QSGPinch *pinch; QPointF sceneStartPoint1; QPointF sceneStartPoint2; @@ -104,6 +106,7 @@ public: QPointF sceneLastCenter; QPointF pinchStartPos; QList touchPoints; + int id1; }; QT_END_NAMESPACE diff --git a/src/declarative/items/qsgtext.cpp b/src/declarative/items/qsgtext.cpp index f796006c18..f2ec7b21fa 100644 --- a/src/declarative/items/qsgtext.cpp +++ b/src/declarative/items/qsgtext.cpp @@ -1,4 +1,4 @@ -// Commit: a5c3c11e3e2204da6c8be9af98b38929366fafb8 +// Commit: cce89db1e2555cbca8fc28072e1c6dd737cec6c4 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -106,7 +106,7 @@ QSGTextPrivate::QSGTextPrivate() imageCacheDirty(true), updateOnComponentComplete(true), richText(false), singleline(false), cacheAllTextAsImage(true), internalWidthUpdate(false), requireImplicitWidth(false), truncated(false), hAlignImplicit(true), rightToLeftText(false), - naturalWidth(0), doc(0), nodeType(NodeIsNull) + layoutTextElided(false), naturalWidth(0), doc(0), nodeType(NodeIsNull) { cacheAllTextAsImage = enableImageCache(); } @@ -219,6 +219,7 @@ void QSGTextPrivate::updateLayout() return; } + layoutTextElided = false; // Setup instance of QTextLayout for all cases other than richtext if (!richText) { layout.clearLayout(); @@ -229,10 +230,13 @@ void QSGTextPrivate::updateLayout() singleline = !tmp.contains(QChar::LineSeparator); if (singleline && !maximumLineCountValid && elideMode != QSGText::ElideNone && q->widthValid()) { QFontMetrics fm(font); - tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width()); // XXX still worth layout...? - if (tmp != text && !truncated) { - truncated = true; - emit q->truncatedChanged(); + tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width()); + if (tmp != text) { + layoutTextElided = true; + if (!truncated) { + truncated = true; + emit q->truncatedChanged(); + } } } layout.setText(tmp); @@ -379,6 +383,12 @@ QRect QSGTextPrivate::setupTextLayout() if (requireImplicitWidth && q->widthValid()) { // requires an extra layout + QString elidedText; + if (layoutTextElided) { + // We have provided elided text to the layout, but we must calculate unelided width. + elidedText = layout.text(); + layout.setText(text); + } layout.beginLayout(); forever { QTextLine line = layout.createLine(); @@ -392,6 +402,8 @@ QRect QSGTextPrivate::setupTextLayout() br = br.united(line.naturalTextRect()); } naturalWidth = br.width(); + if (layoutTextElided) + layout.setText(elidedText); } if (maximumLineCountValid) { diff --git a/src/declarative/items/qsgtext_p_p.h b/src/declarative/items/qsgtext_p_p.h index 7df91f80d9..8d26394c3f 100644 --- a/src/declarative/items/qsgtext_p_p.h +++ b/src/declarative/items/qsgtext_p_p.h @@ -1,4 +1,4 @@ -// Commit: aeb330e3999ef3d7ae8d94b9330471f2a2a13554 +// Commit: 6e5a642c9484536fc173714f560f739944368cf5 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -119,6 +119,7 @@ public: bool truncated:1; bool hAlignImplicit:1; bool rightToLeftText:1; + bool layoutTextElided:1; QRect layedOutTextRect; QSize paintedSize; diff --git a/src/declarative/items/qsgtextedit.cpp b/src/declarative/items/qsgtextedit.cpp index 57f9135917..1c199ecc28 100644 --- a/src/declarative/items/qsgtextedit.cpp +++ b/src/declarative/items/qsgtextedit.cpp @@ -1,4 +1,4 @@ -// Commit: 6980bca15b411f86b9fadb7484a6dd782b9d1403 +// Commit: ec40dd2bb51868bca10dbd0c9116f3224ff2b29b /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -318,6 +318,7 @@ void QSGTextEdit::setVAlign(QSGTextEdit::VAlignment alignment) d->vAlign = alignment; d->updateDefaultTextOption(); updateSize(); + moveCursorDelegate(); emit verticalAlignmentChanged(d->vAlign); } @@ -496,8 +497,6 @@ void QSGTextEdit::setCursorDelegate(QDeclarativeComponent* c) Q_D(QSGTextEdit); if(d->cursorComponent){ if(d->cursor){ - disconnect(d->control, SIGNAL(cursorPositionChanged()), - this, SLOT(moveCursorDelegate())); d->control->setCursorWidth(-1); update(cursorRectangle()); delete d->cursor; @@ -523,8 +522,6 @@ void QSGTextEdit::loadCursorDelegate() return; d->cursor = qobject_cast(d->cursorComponent->create(qmlContext(this))); if(d->cursor){ - connect(d->control, SIGNAL(cursorPositionChanged()), - this, SLOT(moveCursorDelegate())); d->control->setCursorWidth(0); update(cursorRectangle()); QDeclarative_setParent_noEvent(d->cursor, this); @@ -696,7 +693,7 @@ Qt::TextInteractionFlags QSGTextEdit::textInteractionFlags() const QRect QSGTextEdit::cursorRectangle() const { Q_D(const QSGTextEdit); - return d->control->cursorRect().toRect().translated(0,-d->yoff); + return d->control->cursorRect().toRect().translated(0,d->yoff); } bool QSGTextEdit::event(QEvent *event) @@ -985,7 +982,7 @@ void QSGTextEditPrivate::init() QObject::connect(control, SIGNAL(selectionChanged()), q, SLOT(updateSelectionMarkers())); QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(updateSelectionMarkers())); QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged())); - QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorRectangleChanged())); + QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(moveCursorDelegate())); QObject::connect(control, SIGNAL(linkActivated(QString)), q, SIGNAL(linkActivated(QString))); #ifndef QT_NO_CLIPBOARD QObject::connect(q, SIGNAL(readOnlyChanged(bool)), q, SLOT(q_canPasteChanged())); @@ -1010,16 +1007,17 @@ void QSGTextEdit::q_textChanged() d->updateDefaultTextOption(); updateSize(); updateTotalLines(); - updateMicroFocus(); emit textChanged(d->text); } void QSGTextEdit::moveCursorDelegate() { Q_D(QSGTextEdit); + updateMicroFocus(); + emit cursorRectangleChanged(); if(!d->cursor) return; - QRectF cursorRect = d->control->cursorRect(); + QRectF cursorRect = cursorRectangle(); d->cursor->setX(cursorRect.x()); d->cursor->setY(cursorRect.y()); } @@ -1052,7 +1050,6 @@ void QSGTextEdit::updateSelectionMarkers() d->lastSelectionEnd = d->control->textCursor().selectionEnd(); emit selectionEndChanged(); } - updateMicroFocus(); } QRectF QSGTextEdit::boundingRect() const diff --git a/src/declarative/items/qsgtextinput.cpp b/src/declarative/items/qsgtextinput.cpp index 9631b3bafb..4eab28bbcf 100644 --- a/src/declarative/items/qsgtextinput.cpp +++ b/src/declarative/items/qsgtextinput.cpp @@ -1,4 +1,4 @@ -// Commit: b94176e69efc3948696c6774d5a228fc753b5b29 +// Commit: 47712d1f330e4b22ce6dd30e7557288ef7f7fca0 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -442,6 +442,20 @@ bool QSGTextInput::hasAcceptableInput() const return d->control->hasAcceptableInput(); } +void QSGTextInputPrivate::updateInputMethodHints() +{ + Q_Q(QSGTextInput); + Qt::InputMethodHints hints = inputMethodHints; + uint echo = control->echoMode(); + if (echo == QSGTextInput::Password || echo == QSGTextInput::NoEcho) + hints |= Qt::ImhHiddenText; + else if (echo == QSGTextInput::PasswordEchoOnEdit) + hints &= ~Qt::ImhHiddenText; + if (echo != QSGTextInput::Normal) + hints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); + q->setInputMethodHints(hints); +} + QSGTextInput::EchoMode QSGTextInput::echoMode() const { Q_D(const QSGTextInput); @@ -453,21 +467,27 @@ void QSGTextInput::setEchoMode(QSGTextInput::EchoMode echo) Q_D(QSGTextInput); if (echoMode() == echo) return; - Qt::InputMethodHints imHints = inputMethodHints(); - if (echo == Password || echo == NoEcho) - imHints |= Qt::ImhHiddenText; - else - imHints &= ~Qt::ImhHiddenText; - if (echo != Normal) - imHints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); - else - imHints &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); - setInputMethodHints(imHints); d->control->setEchoMode((uint)echo); + d->updateInputMethodHints(); q_textChanged(); emit echoModeChanged(echoMode()); } +Qt::InputMethodHints QSGTextInput::imHints() const +{ + Q_D(const QSGTextInput); + return d->inputMethodHints; +} + +void QSGTextInput::setIMHints(Qt::InputMethodHints hints) +{ + Q_D(QSGTextInput); + if (d->inputMethodHints == hints) + return; + d->inputMethodHints = hints; + d->updateInputMethodHints(); +} + QDeclarativeComponent* QSGTextInput::cursorDelegate() const { Q_D(const QSGTextInput); @@ -485,6 +505,8 @@ void QSGTextInput::setCursorDelegate(QDeclarativeComponent* c) //note that the components are owned by something else disconnect(d->control, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(moveCursor())); + disconnect(d->control, SIGNAL(updateMicroFocus()), + this, SLOT(moveCursor())); delete d->cursorItem; }else{ d->startCreatingCursor(); @@ -497,7 +519,9 @@ void QSGTextInputPrivate::startCreatingCursor() { Q_Q(QSGTextInput); q->connect(control, SIGNAL(cursorPositionChanged(int,int)), - q, SLOT(moveCursor())); + q, SLOT(moveCursor()), Qt::UniqueConnection); + q->connect(control, SIGNAL(updateMicroFocus()), + q, SLOT(moveCursor()), Qt::UniqueConnection); if(cursorComponent->isReady()){ q->createCursor(); }else if(cursorComponent->isLoading()){ @@ -648,9 +672,10 @@ void QSGTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) } if (d->selectByMouse) { setKeepMouseGrab(false); + d->selectPressed = true; d->pressPos = event->pos(); } - bool mark = event->modifiers() & Qt::ShiftModifier; + bool mark = (event->modifiers() & Qt::ShiftModifier) && d->selectByMouse; int cursor = d->xToPos(event->pos().x()); d->control->moveCursor(cursor, mark); event->setAccepted(true); @@ -661,7 +686,7 @@ void QSGTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event) Q_D(QSGTextInput); if (d->sendMouseEventToInputContext(event, QEvent::MouseMove)) return; - if (d->selectByMouse) { + if (d->selectPressed) { if (qAbs(int(event->pos().x() - d->pressPos.x())) > QApplication::startDragDistance()) setKeepMouseGrab(true); moveCursorSelection(d->xToPos(event->pos().x()), d->mouseSelectionMode); @@ -676,8 +701,10 @@ void QSGTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_D(QSGTextInput); if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonRelease)) return; - if (d->selectByMouse) + if (d->selectPressed) { + d->selectPressed = false; setKeepMouseGrab(false); + } if (!d->showInputPanelOnFocus) { // input panel on click if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->pos())) { if (canvas() && canvas() == qApp->focusWidget()) { @@ -731,6 +758,8 @@ bool QSGTextInputPrivate::sendMouseEventToInputContext( void QSGTextInput::mouseUngrabEvent() { + Q_D(QSGTextInput); + d->selectPressed = false; setKeepMouseGrab(false); } diff --git a/src/declarative/items/qsgtextinput_p.h b/src/declarative/items/qsgtextinput_p.h index ee04579a54..ccea485e99 100644 --- a/src/declarative/items/qsgtextinput_p.h +++ b/src/declarative/items/qsgtextinput_p.h @@ -1,4 +1,4 @@ -// Commit: 27e4302b7f45f22180693d26747f419177c81e27 +// Commit: 2f173e4945dd8414636c1061acfaf9c2d8b718d8 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -83,7 +83,7 @@ class Q_AUTOTEST_EXPORT QSGTextInput : public QSGImplicitSizePaintedItem Q_PROPERTY(QValidator* validator READ validator WRITE setValidator NOTIFY validatorChanged) #endif Q_PROPERTY(QString inputMask READ inputMask WRITE setInputMask NOTIFY inputMaskChanged) - Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints) + Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ imHints WRITE setIMHints) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged) Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged) @@ -212,6 +212,9 @@ public: bool isInputMethodComposing() const; + Qt::InputMethodHints imHints() const; + void setIMHints(Qt::InputMethodHints hints); + Q_SIGNALS: void textChanged(); void cursorPositionChanged(); diff --git a/src/declarative/items/qsgtextinput_p_p.h b/src/declarative/items/qsgtextinput_p_p.h index 00db1e995c..22c95a7b1d 100644 --- a/src/declarative/items/qsgtextinput_p_p.h +++ b/src/declarative/items/qsgtextinput_p_p.h @@ -1,4 +1,4 @@ -// Commit: 27e4302b7f45f22180693d26747f419177c81e27 +// Commit: 47712d1f330e4b22ce6dd30e7557288ef7f7fca0 /**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). @@ -72,10 +72,11 @@ public: QSGTextInputPrivate() : control(new QLineControl(QString())), color((QRgb)0), style(QSGText::Normal), styleColor((QRgb)0), hAlign(QSGTextInput::AlignLeft), - mouseSelectionMode(QSGTextInput::SelectCharacters), + mouseSelectionMode(QSGTextInput::SelectCharacters), inputMethodHints(Qt::ImhNone), hscroll(0), oldScroll(0), oldValidity(false), focused(false), focusOnPress(true), showInputPanelOnFocus(true), clickCausedFocus(false), cursorVisible(false), - autoScroll(true), selectByMouse(false), canPaste(false), hAlignImplicit(true) + autoScroll(true), selectByMouse(false), canPaste(false), hAlignImplicit(true), + selectPressed(false) { #ifdef Q_OS_SYMBIAN if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) { @@ -106,6 +107,7 @@ public: void mirrorChange(); int calculateTextWidth(); bool sendMouseEventToInputContext(QGraphicsSceneMouseEvent *event, QEvent::Type eventType); + void updateInputMethodHints(); QLineControl* control; @@ -118,6 +120,7 @@ public: QColor styleColor; QSGTextInput::HAlignment hAlign; QSGTextInput::SelectionMode mouseSelectionMode; + Qt::InputMethodHints inputMethodHints; QPointer cursorComponent; QPointer cursorItem; QPointF pressPos; @@ -139,6 +142,7 @@ public: bool selectByMouse:1; bool canPaste:1; bool hAlignImplicit:1; + bool selectPressed:1; static inline QSGTextInputPrivate *get(QSGTextInput *t) { return t->d_func(); diff --git a/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp b/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp index 1532281338..2cc6b3eac2 100644 --- a/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp +++ b/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp @@ -106,7 +106,7 @@ void tst_qsgflickable::create() QCOMPARE(obj->isInteractive(), true); QCOMPARE(obj->boundsBehavior(), QSGFlickable::DragAndOvershootBounds); QCOMPARE(obj->pressDelay(), 0); - QCOMPARE(obj->maximumFlickVelocity(), 2000.); + QCOMPARE(obj->maximumFlickVelocity(), 2500.); delete obj; } -- cgit v1.2.3