aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp6
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp2
-rw-r--r--src/quick/items/qquickgridview.cpp40
-rw-r--r--src/quick/items/qquickimage.cpp11
-rw-r--r--src/quick/items/qquickitem.cpp246
-rw-r--r--src/quick/items/qquickitem.h6
-rw-r--r--src/quick/items/qquickitem_p.h17
-rw-r--r--src/quick/items/qquickitemsmodule.cpp2
-rw-r--r--src/quick/items/qquickitemview.cpp40
-rw-r--r--src/quick/items/qquickitemview_p.h10
-rw-r--r--src/quick/items/qquickitemview_p_p.h2
-rw-r--r--src/quick/items/qquicklistview.cpp39
-rw-r--r--src/quick/items/qquickmousearea.cpp5
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp5
-rw-r--r--src/quick/items/qquickrectangle.cpp14
-rw-r--r--src/quick/items/qquicktext.cpp62
-rw-r--r--src/quick/items/qquicktext_p.h1
-rw-r--r--src/quick/items/qquicktext_p_p.h9
-rw-r--r--src/quick/items/qquicktextedit.cpp4
-rw-r--r--src/quick/items/qquicktranslate.cpp75
-rw-r--r--src/quick/items/qquicktranslate_p.h23
-rw-r--r--src/quick/items/qquickview.cpp27
-rw-r--r--src/quick/items/qquickview_p.h22
-rw-r--r--src/quick/items/qquickwindow.cpp119
-rw-r--r--src/quick/items/qquickwindow_p.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp4
-rw-r--r--src/quick/scenegraph/coreapi/qsggeometry.cpp10
-rw-r--r--src/quick/util/qquickbehavior.cpp11
-rw-r--r--src/quick/util/qquickglobal.cpp2
-rw-r--r--src/quick/util/qquickpropertychanges.cpp61
-rw-r--r--src/quick/util/qquickpropertychanges_p.h2
31 files changed, 649 insertions, 230 deletions
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index b3a2c9f46a..763dd5251b 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -180,7 +180,7 @@ QQuickCanvasItemPrivate::QQuickCanvasItemPrivate()
, renderTarget(QQuickCanvasItem::Image)
, renderStrategy(QQuickCanvasItem::Immediate)
{
- antialiasing = true;
+ implicitAntialiasing = true;
}
QQuickCanvasItemPrivate::~QQuickCanvasItemPrivate()
@@ -642,7 +642,7 @@ void QQuickCanvasItem::updatePolish()
Q_D(QQuickCanvasItem);
if (d->context && d->renderStrategy != QQuickCanvasItem::Cooperative)
- d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, d->antialiasing);
+ d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, antialiasing());
if (d->animationCallbacks.size() > 0 && isVisible()) {
QMap<int, QV4::PersistentValue> animationCallbacks = d->animationCallbacks;
@@ -705,7 +705,7 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
node->setFiltering(QSGTexture::Nearest);
if (d->renderStrategy == QQuickCanvasItem::Cooperative) {
- d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, d->antialiasing);
+ d->context->prepare(d->canvasSize.toSize(), d->tileSize, d->canvasWindow.toRect(), d->dirtyRect.toRect(), d->smooth, antialiasing());
d->context->flush();
}
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index b6d4f1073c..c8741335dd 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -871,7 +871,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object
: QV4::Object(engine)
{
setVTable(&static_vtbl);
- flags &= ~SimpleArray;
+ setArrayType(QV4::ArrayData::Custom);
}
static void destroy(QV4::Managed *that) {
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 1107425575..8587da5ac3 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -630,8 +630,8 @@ void QQuickGridViewPrivate::updateViewport()
void QQuickGridViewPrivate::layoutVisibleItems(int fromModelIndex)
{
if (visibleItems.count()) {
- const qreal from = isContentFlowReversed() ? -position() - size() : position();
- const qreal to = isContentFlowReversed() ? -position() : position() + size();
+ const qreal from = isContentFlowReversed() ? -position()-displayMarginBeginning-size() : position()-displayMarginBeginning;
+ const qreal to = isContentFlowReversed() ? -position()+displayMarginEnd : position()+size()+displayMarginEnd;
FxGridItemSG *firstItem = static_cast<FxGridItemSG*>(visibleItems.first());
qreal rowPos = firstItem->rowPos();
@@ -1534,7 +1534,35 @@ void QQuickGridView::setHighlightFollowsCurrentItem(bool autoHighlight)
of additional memory usage. It is not a substitute for creating efficient
delegates; the fewer objects and bindings in a delegate, the faster a view may be
scrolled.
+
+ The cacheBuffer operates outside of any display margins specified by
+ displayMarginBeginning or displayMarginEnd.
+*/
+
+/*!
+ \qmlproperty int QtQuick::GridView::displayMarginBeginning
+ \qmlproperty int QtQuick::GridView::displayMarginEnd
+ \since QtQuick 2.3
+
+ This property allows delegates to be displayed outside of the view geometry.
+
+ If this value is non-zero, the view will create extra delegates before the
+ start of the view, or after the end. The view will create as many delegates
+ as it can fit into the pixel size specified.
+
+ For example, if in a vertical view the delegate is 20 pixels high,
+ there are 3 columns, and
+ \c displayMarginBeginning and \c displayMarginEnd are both set to 40,
+ then 6 delegates above and 6 delegates below will be created and shown.
+
+ The default value is 0.
+
+ This property is meant for allowing certain UI configurations,
+ and not as a performance optimization. If you wish to create delegates
+ outside of the view geometry for performance reasons, you probably
+ want to use the cacheBuffer property instead.
*/
+
void QQuickGridView::setHighlightMoveDuration(int duration)
{
Q_D(QQuickGridView);
@@ -2000,8 +2028,8 @@ void QQuickGridView::viewportMoved(Qt::Orientations orient)
d->refillOrLayout();
// Set visibility of items to eliminate cost of items outside the visible area.
- qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
- qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size();
+ qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
+ qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
for (int i = 0; i < d->visibleItems.count(); ++i) {
FxGridItemSG *item = static_cast<FxGridItemSG*>(d->visibleItems.at(i));
QQuickItemPrivate::get(item->item)->setCulled(item->rowPos() + d->rowSize() < from || item->rowPos() > to);
@@ -2350,7 +2378,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
// Insert items before the visible item.
int insertionIdx = index;
int i = count - 1;
- int from = tempPos - buffer;
+ int from = tempPos - buffer - displayMarginBeginning;
while (i >= 0) {
if (rowPos > from && insertionIdx < visibleIndex) {
@@ -2387,7 +2415,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
}
} else {
int i = 0;
- int to = buffer+tempPos+size()-1;
+ int to = buffer+displayMarginEnd+tempPos+size()-1;
while (i < count && rowPos <= to + rowSize()*(columns - colNum)/qreal(columns+1)) {
FxViewItem *item = 0;
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index 0708304051..62ac72d244 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -62,6 +62,13 @@ public:
{
}
+ void updateTexture(QSGTexture *texture) {
+ if (m_texture == texture)
+ return;
+ m_texture = texture;
+ emit textureChanged();
+ }
+
QSGTexture *texture() const {
if (m_texture) {
m_texture->setFiltering(m_smooth ? QSGTexture::Linear : QSGTexture::Nearest);
@@ -542,7 +549,7 @@ QSGTextureProvider *QQuickImage::textureProvider() const
QQuickImagePrivate *dd = const_cast<QQuickImagePrivate *>(d);
dd->provider = new QQuickImageTextureProvider;
dd->provider->m_smooth = d->smooth;
- dd->provider->m_texture = d->sceneGraphRenderContext()->textureForFactory(d->pix.textureFactory(), window());
+ dd->provider->updateTexture(d->sceneGraphRenderContext()->textureForFactory(d->pix.textureFactory(), window()));
}
return d->provider;
@@ -557,7 +564,7 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
// Copy over the current texture state into the texture provider...
if (d->provider) {
d->provider->m_smooth = d->smooth;
- d->provider->m_texture = texture;
+ d->provider->updateTexture(texture);
}
if (!texture || width() <= 0 || height() <= 0) {
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 5739d6874e..2a507a27b1 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2707,6 +2707,8 @@ QQuickItemPrivate::QQuickItemPrivate()
, culled(false)
, hasCursor(false)
, activeFocusOnTab(false)
+ , implicitAntialiasing(false)
+ , antialiasingValid(false)
, dirtyAttributes(0)
, nextDirtyItem(0)
, prevDirtyItem(0)
@@ -4478,96 +4480,6 @@ void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
}
#endif // QT_NO_IM
-void QQuickItemPrivate::deliverFocusEvent(QFocusEvent *e)
-{
- Q_Q(QQuickItem);
-
- if (e->type() == QEvent::FocusIn) {
- q->focusInEvent(e);
- } else {
- q->focusOutEvent(e);
- }
-}
-
-void QQuickItemPrivate::deliverMouseEvent(QMouseEvent *e)
-{
- Q_Q(QQuickItem);
-
- Q_ASSERT(e->isAccepted());
-
- switch (e->type()) {
- default:
- Q_ASSERT(!"Unknown event type");
- case QEvent::MouseMove:
- q->mouseMoveEvent(e);
- break;
- case QEvent::MouseButtonPress:
- q->mousePressEvent(e);
- break;
- case QEvent::MouseButtonRelease:
- q->mouseReleaseEvent(e);
- break;
- case QEvent::MouseButtonDblClick:
- q->mouseDoubleClickEvent(e);
- break;
- }
-}
-
-#ifndef QT_NO_WHEELEVENT
-void QQuickItemPrivate::deliverWheelEvent(QWheelEvent *e)
-{
- Q_Q(QQuickItem);
- q->wheelEvent(e);
-}
-#endif
-
-void QQuickItemPrivate::deliverTouchEvent(QTouchEvent *e)
-{
- Q_Q(QQuickItem);
- q->touchEvent(e);
-}
-
-void QQuickItemPrivate::deliverHoverEvent(QHoverEvent *e)
-{
- Q_Q(QQuickItem);
- switch (e->type()) {
- default:
- Q_ASSERT(!"Unknown event type");
- case QEvent::HoverEnter:
- q->hoverEnterEvent(e);
- break;
- case QEvent::HoverLeave:
- q->hoverLeaveEvent(e);
- break;
- case QEvent::HoverMove:
- q->hoverMoveEvent(e);
- break;
- }
-}
-
-#ifndef QT_NO_DRAGANDDROP
-void QQuickItemPrivate::deliverDragEvent(QEvent *e)
-{
- Q_Q(QQuickItem);
- switch (e->type()) {
- default:
- Q_ASSERT(!"Unknown event type");
- case QEvent::DragEnter:
- q->dragEnterEvent(static_cast<QDragEnterEvent *>(e));
- break;
- case QEvent::DragLeave:
- q->dragLeaveEvent(static_cast<QDragLeaveEvent *>(e));
- break;
- case QEvent::DragMove:
- q->dragMoveEvent(static_cast<QDragMoveEvent *>(e));
- break;
- case QEvent::Drop:
- q->dropEvent(static_cast<QDropEvent *>(e));
- break;
- }
-}
-#endif // QT_NO_DRAGANDDROP
-
/*!
Called when \a change occurs for this item.
@@ -5573,6 +5485,9 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
}
}
break;
+ case QQuickItem::ItemAntialiasingHasChanged:
+ q->itemChange(change, data);
+ break;
}
}
@@ -5666,37 +5581,65 @@ void QQuickItem::setActiveFocusOnTab(bool activeFocusOnTab)
/*!
\qmlproperty bool QtQuick::Item::antialiasing
- Primarily used in Rectangle and image based elements to decide if the item should
- use antialiasing or not. Items with antialiasing enabled require more memory and
- are potentially slower to render.
+ Used by visual elements to decide if the item should use antialiasing or not.
+ In some cases items with antialiasing require more memory and are potentially
+ slower to render (see \l {Antialiasing} for more details).
- The default is false.
+ The default is false, but may be overridden by derived elements.
*/
/*!
\property QQuickItem::antialiasing
\brief Specifies whether the item is antialiased or not
- Primarily used in Rectangle and image based elements to decide if the item should
- use antialiasing or not. Items with antialiasing enabled require more memory and
- are potentially slower to render.
+ Used by visual elements to decide if the item should use antialiasing or not.
+ In some cases items with antialiasing require more memory and are potentially
+ slower to render (see \l {Antialiasing} for more details).
- The default is false.
+ The default is false, but may be overridden by derived elements.
*/
bool QQuickItem::antialiasing() const
{
Q_D(const QQuickItem);
- return d->antialiasing;
+ return d->antialiasingValid ? d->antialiasing : d->implicitAntialiasing;
}
-void QQuickItem::setAntialiasing(bool antialiasing)
+
+void QQuickItem::setAntialiasing(bool aa)
{
Q_D(QQuickItem);
- if (d->antialiasing == antialiasing)
+
+ bool changed = (aa != antialiasing());
+ d->antialiasingValid = true;
+
+ if (!changed)
return;
- d->antialiasing = antialiasing;
+ d->antialiasing = aa;
d->dirty(QQuickItemPrivate::Antialiasing);
- emit antialiasingChanged(antialiasing);
+ d->itemChange(ItemAntialiasingHasChanged, d->antialiasing);
+
+ emit antialiasingChanged(antialiasing());
+}
+
+void QQuickItem::resetAntialiasing()
+{
+ Q_D(QQuickItem);
+ if (!d->antialiasingValid)
+ return;
+
+ d->antialiasingValid = false;
+
+ if (d->implicitAntialiasing != d->antialiasing)
+ emit antialiasingChanged(antialiasing());
+}
+
+void QQuickItemPrivate::setImplicitAntialiasing(bool antialiasing)
+{
+ Q_Q(QQuickItem);
+ bool prev = q->antialiasing();
+ implicitAntialiasing = antialiasing;
+ if (componentComplete && (q->antialiasing() != prev))
+ emit q->antialiasingChanged(q->antialiasing());
}
/*!
@@ -6539,6 +6482,17 @@ void QQuickItemPrivate::incrementCursorCount(int delta)
#endif
}
+void QQuickItemPrivate::markObjects(QV4::ExecutionEngine *e)
+{
+ Q_Q(QQuickItem);
+ QQmlData *ddata = QQmlData::get(q);
+ if (ddata)
+ ddata->jsWrapper.markOnce(e);
+
+ foreach (QQuickItem *child, childItems)
+ QQuickItemPrivate::get(child)->markObjects(e);
+}
+
#ifndef QT_NO_CURSOR
/*!
@@ -6981,18 +6935,17 @@ QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const
*/
bool QQuickItem::event(QEvent *ev)
{
+ Q_D(QQuickItem);
+
+ switch (ev->type()) {
#if 0
- if (ev->type() == QEvent::PolishRequest) {
- Q_D(QQuickItem);
+ case QEvent::PolishRequest:
d->polishScheduled = false;
updatePolish();
- return true;
- } else {
- return QObject::event(ev);
- }
+ break;
#endif
#ifndef QT_NO_IM
- if (ev->type() == QEvent::InputMethodQuery) {
+ case QEvent::InputMethodQuery: {
QInputMethodQueryEvent *query = static_cast<QInputMethodQueryEvent *>(ev);
Qt::InputMethodQueries queries = query->queries();
for (uint i = 0; i < 32; ++i) {
@@ -7003,20 +6956,79 @@ bool QQuickItem::event(QEvent *ev)
}
}
query->accept();
- return true;
- } else if (ev->type() == QEvent::InputMethod) {
+ break;
+ }
+ case QEvent::InputMethod:
inputMethodEvent(static_cast<QInputMethodEvent *>(ev));
- return true;
- } else
+ break;
#endif // QT_NO_IM
- if (ev->type() == QEvent::StyleAnimationUpdate) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ case QEvent::TouchCancel:
+ touchEvent(static_cast<QTouchEvent*>(ev));
+ break;
+ case QEvent::StyleAnimationUpdate:
if (isVisible()) {
ev->accept();
update();
}
- return true;
+ break;
+ case QEvent::HoverEnter:
+ hoverEnterEvent(static_cast<QHoverEvent*>(ev));
+ break;
+ case QEvent::HoverLeave:
+ hoverLeaveEvent(static_cast<QHoverEvent*>(ev));
+ break;
+ case QEvent::HoverMove:
+ hoverMoveEvent(static_cast<QHoverEvent*>(ev));
+ break;
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ d->deliverKeyEvent(static_cast<QKeyEvent*>(ev));
+ break;
+ case QEvent::FocusIn:
+ focusInEvent(static_cast<QFocusEvent*>(ev));
+ break;
+ case QEvent::FocusOut:
+ focusOutEvent(static_cast<QFocusEvent*>(ev));
+ break;
+ case QEvent::MouseMove:
+ mouseMoveEvent(static_cast<QMouseEvent*>(ev));
+ break;
+ case QEvent::MouseButtonPress:
+ mousePressEvent(static_cast<QMouseEvent*>(ev));
+ break;
+ case QEvent::MouseButtonRelease:
+ mouseReleaseEvent(static_cast<QMouseEvent*>(ev));
+ break;
+ case QEvent::MouseButtonDblClick:
+ mouseDoubleClickEvent(static_cast<QMouseEvent*>(ev));
+ break;
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+ wheelEvent(static_cast<QWheelEvent*>(ev));
+ break;
+#endif
+#ifndef QT_NO_DRAGANDDROP
+ case QEvent::DragEnter:
+ dragEnterEvent(static_cast<QDragEnterEvent*>(ev));
+ break;
+ case QEvent::DragLeave:
+ dragLeaveEvent(static_cast<QDragLeaveEvent*>(ev));
+ break;
+ case QEvent::DragMove:
+ dragMoveEvent(static_cast<QDragMoveEvent*>(ev));
+ break;
+ case QEvent::Drop:
+ dropEvent(static_cast<QDropEvent*>(ev));
+ break;
+#endif // QT_NO_DRAGANDDROP
+ default:
+ return QObject::event(ev);
}
- return QObject::event(ev);
+
+ return true;
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 2500a2d33a..c666af2729 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -141,7 +141,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
Q_PROPERTY(QQmlListProperty<QQuickTransform> transform READ transform DESIGNABLE false FINAL)
Q_PROPERTY(bool smooth READ smooth WRITE setSmooth NOTIFY smoothChanged)
- Q_PROPERTY(bool antialiasing READ antialiasing WRITE setAntialiasing NOTIFY antialiasingChanged)
+ Q_PROPERTY(bool antialiasing READ antialiasing WRITE setAntialiasing NOTIFY antialiasingChanged RESET resetAntialiasing)
Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged)
Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged)
@@ -172,7 +172,8 @@ public:
ItemParentHasChanged, // value.item
ItemOpacityHasChanged, // value.realValue
ItemActiveFocusHasChanged, // value.boolValue
- ItemRotationHasChanged // value.realValue
+ ItemRotationHasChanged, // value.realValue
+ ItemAntialiasingHasChanged // value.boolValue
};
union ItemChangeData {
@@ -267,6 +268,7 @@ public:
bool antialiasing() const;
void setAntialiasing(bool);
+ void resetAntialiasing();
Flags flags() const;
void setFlag(Flag flag, bool enabled = true);
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index 44eabcf0d5..96cb9e8843 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -422,6 +422,8 @@ public:
bool hasCursor:1;
// Bit 32
bool activeFocusOnTab:1;
+ bool implicitAntialiasing:1;
+ bool antialiasingValid:1;
enum DirtyType {
TransformOrigin = 0x00000001,
@@ -521,6 +523,8 @@ public:
virtual void implicitWidthChanged();
virtual void implicitHeightChanged();
+ void setImplicitAntialiasing(bool antialiasing);
+
void resolveLayoutMirror();
void setImplicitLayoutMirror(bool mirror, bool inherit);
void setLayoutMirror(bool mirror);
@@ -540,16 +544,6 @@ public:
#ifndef QT_NO_IM
void deliverInputMethodEvent(QInputMethodEvent *);
#endif
- void deliverFocusEvent(QFocusEvent *);
- void deliverMouseEvent(QMouseEvent *);
-#ifndef QT_NO_WHEELEVENT
- void deliverWheelEvent(QWheelEvent *);
-#endif
- void deliverTouchEvent(QTouchEvent *);
- void deliverHoverEvent(QHoverEvent *);
-#ifndef QT_NO_DRAGANDDROP
- void deliverDragEvent(QEvent *);
-#endif
bool calcEffectiveVisible() const;
bool setEffectiveVisibleRecur(bool);
@@ -589,6 +583,9 @@ public:
virtual void mirrorChange() {}
void incrementCursorCount(int delta);
+
+ // recursive helper to let a visual parent mark its visual children
+ void markObjects(QV4::ExecutionEngine *e);
};
/*
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index a5b78b28e1..96746223ce 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -184,6 +184,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickTranslate>(uri,major,minor,"Translate");
qmlRegisterType<QQuickRotation>(uri,major,minor,"Rotation");
qmlRegisterType<QQuickScale>(uri,major,minor,"Scale");
+ qmlRegisterType<QQuickMatrix4x4>(uri,2,4,"Matrix4x4");
qmlRegisterType<QQuickText>(uri,major,minor,"Text");
qmlRegisterType<QQuickTextEdit>(uri,major,minor,"TextEdit");
qmlRegisterType<QQuickTextEdit,1>(uri,2,1,"TextEdit");
@@ -261,6 +262,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickItem, 1>(uri, 2, 1,"Item");
qmlRegisterType<QQuickGrid, 1>(uri, 2, 1, "Grid");
qmlRegisterUncreatableType<QQuickItemView, 1>(uri, 2, 1, "ItemView", QQuickItemView::tr("ItemView is an abstract base class"));
+ qmlRegisterUncreatableType<QQuickItemView, 2>(uri, 2, 3, "ItemView", QQuickItemView::tr("ItemView is an abstract base class"));
qmlRegisterType<QQuickListView, 1>(uri, 2, 1, "ListView");
qmlRegisterType<QQuickGridView, 1>(uri, 2, 1, "GridView");
qmlRegisterType<QQuickTextEdit, 1>(uri, 2, 1, "TextEdit");
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index d7b984788e..f5c0e3b8d2 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -459,6 +459,41 @@ void QQuickItemView::setCacheBuffer(int b)
}
}
+int QQuickItemView::displayMarginBeginning() const
+{
+ Q_D(const QQuickItemView);
+ return d->displayMarginBeginning;
+}
+
+void QQuickItemView::setDisplayMarginBeginning(int margin)
+{
+ Q_D(QQuickItemView);
+ if (d->displayMarginBeginning != margin) {
+ d->displayMarginBeginning = margin;
+ if (isComponentComplete()) {
+ d->refillOrLayout();
+ }
+ emit displayMarginBeginningChanged();
+ }
+}
+
+int QQuickItemView::displayMarginEnd() const
+{
+ Q_D(const QQuickItemView);
+ return d->displayMarginEnd;
+}
+
+void QQuickItemView::setDisplayMarginEnd(int margin)
+{
+ Q_D(QQuickItemView);
+ if (d->displayMarginEnd != margin) {
+ d->displayMarginEnd = margin;
+ if (isComponentComplete()) {
+ d->refillOrLayout();
+ }
+ emit displayMarginEndChanged();
+ }
+}
Qt::LayoutDirection QQuickItemView::layoutDirection() const
{
@@ -1443,6 +1478,7 @@ void QQuickItemView::componentComplete()
QQuickItemViewPrivate::QQuickItemViewPrivate()
: itemCount(0)
, buffer(QML_VIEW_DEFAULTCACHEBUFFER), bufferMode(BufferBefore | BufferAfter)
+ , displayMarginBeginning(0), displayMarginEnd(0)
, layoutDirection(Qt::LeftToRight), verticalLayoutDirection(QQuickItemView::TopToBottom)
, moveReason(Other)
, visibleIndex(0)
@@ -1682,9 +1718,9 @@ void QQuickItemViewPrivate::refill()
{
qreal s = qMax(size(), qreal(0.));
if (isContentFlowReversed())
- refill(-position()-s, -position());
+ refill(-position()-displayMarginBeginning-s, -position()+displayMarginEnd);
else
- refill(position(), position()+s);
+ refill(position()-displayMarginBeginning, position()+displayMarginEnd+s);
}
void QQuickItemViewPrivate::refill(qreal from, qreal to)
diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h
index 17d150f480..ad026a3152 100644
--- a/src/quick/items/qquickitemview_p.h
+++ b/src/quick/items/qquickitemview_p.h
@@ -63,6 +63,8 @@ class Q_AUTOTEST_EXPORT QQuickItemView : public QQuickFlickable
Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled NOTIFY keyNavigationWrapsChanged)
Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer NOTIFY cacheBufferChanged)
+ Q_PROPERTY(int displayMarginBeginning READ displayMarginBeginning WRITE setDisplayMarginBeginning NOTIFY displayMarginBeginningChanged REVISION 2)
+ Q_PROPERTY(int displayMarginEnd READ displayMarginEnd WRITE setDisplayMarginEnd NOTIFY displayMarginEndChanged REVISION 2)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
Q_PROPERTY(Qt::LayoutDirection effectiveLayoutDirection READ effectiveLayoutDirection NOTIFY effectiveLayoutDirectionChanged)
@@ -133,6 +135,12 @@ public:
int cacheBuffer() const;
void setCacheBuffer(int);
+ int displayMarginBeginning() const;
+ void setDisplayMarginBeginning(int);
+
+ int displayMarginEnd() const;
+ void setDisplayMarginEnd(int);
+
Qt::LayoutDirection layoutDirection() const;
void setLayoutDirection(Qt::LayoutDirection);
Qt::LayoutDirection effectiveLayoutDirection() const;
@@ -218,6 +226,8 @@ Q_SIGNALS:
void keyNavigationWrapsChanged();
void cacheBufferChanged();
+ void displayMarginBeginningChanged();
+ void displayMarginEndChanged();
void layoutDirectionChanged();
void effectiveLayoutDirectionChanged();
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index e0f08fd50f..af7c23c02e 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -257,6 +257,8 @@ public:
int itemCount;
int buffer;
int bufferMode;
+ int displayMarginBeginning;
+ int displayMarginEnd;
Qt::LayoutDirection layoutDirection;
QQuickItemView::VerticalLayoutDirection verticalLayoutDirection;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 06749be819..2dd61e386f 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -777,8 +777,8 @@ void QQuickListViewPrivate::visibleItemsChanged()
void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex)
{
if (!visibleItems.isEmpty()) {
- const qreal from = isContentFlowReversed() ? -position() - size() : position();
- const qreal to = isContentFlowReversed() ? -position() : position() + size();
+ const qreal from = isContentFlowReversed() ? -position()-displayMarginBeginning-size() : position()-displayMarginBeginning;
+ const qreal to = isContentFlowReversed() ? -position()+displayMarginEnd : position()+size()+displayMarginEnd;
FxViewItem *firstItem = *visibleItems.constBegin();
bool fixedCurrent = currentItem && firstItem->item == currentItem->item;
@@ -2145,8 +2145,33 @@ void QQuickListView::setOrientation(QQuickListView::Orientation orientation)
of additional memory usage. It is not a substitute for creating efficient
delegates; the fewer objects and bindings in a delegate, the faster a view can be
scrolled.
+
+ The cacheBuffer operates outside of any display margins specified by
+ displayMarginBeginning or displayMarginEnd.
*/
+/*!
+ \qmlproperty int QtQuick::ListView::displayMarginBeginning
+ \qmlproperty int QtQuick::ListView::displayMarginEnd
+ \since QtQuick 2.3
+
+ This property allows delegates to be displayed outside of the view geometry.
+
+ If this value is non-zero, the view will create extra delegates before the
+ start of the view, or after the end. The view will create as many delegates
+ as it can fit into the pixel size specified.
+
+ For example, if in a vertical view the delegate is 20 pixels high and
+ \c displayMarginBeginning and \c displayMarginEnd are both set to 40,
+ then 2 delegates above and 2 delegates below will be created and shown.
+
+ The default value is 0.
+
+ This property is meant for allowing certain UI configurations,
+ and not as a performance optimization. If you wish to create delegates
+ outside of the view geometry for performance reasons, you probably
+ want to use the cacheBuffer property instead.
+*/
/*!
\qmlpropertygroup QtQuick::ListView::section
@@ -2703,8 +2728,8 @@ void QQuickListView::viewportMoved(Qt::Orientations orient)
d->refillOrLayout();
// Set visibility of items to eliminate cost of items outside the visible area.
- qreal from = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
- qreal to = d->isContentFlowReversed() ? -d->position() : d->position()+d->size();
+ qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
+ qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
for (int i = 0; i < d->visibleItems.count(); ++i) {
FxViewItem *item = static_cast<FxListItemSG*>(d->visibleItems.at(i));
QQuickItemPrivate::get(item->item)->setCulled(item->endPosition() < from || item->position() > to);
@@ -2910,7 +2935,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
// there are no visible items except items marked for removal
index = visibleItems.count();
} else if (visibleItems.at(i)->index + 1 == modelIndex
- && visibleItems.at(i)->endPosition() <= buffer+tempPos+size()) {
+ && visibleItems.at(i)->endPosition() <= buffer+displayMarginEnd+tempPos+size()) {
// Special case of appending an item to the model.
index = visibleItems.count();
} else {
@@ -2939,7 +2964,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
// Insert items before the visible item.
int insertionIdx = index;
int i = 0;
- int from = tempPos - buffer;
+ int from = tempPos - displayMarginBeginning - buffer;
for (i = count-1; i >= 0; --i) {
if (pos > from && insertionIdx < visibleIndex) {
@@ -2970,7 +2995,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &ch
}
} else {
int i = 0;
- int to = buffer+tempPos+size();
+ int to = buffer+displayMarginEnd+tempPos+size();
for (i = 0; i < count && pos <= to; ++i) {
FxViewItem *item = 0;
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 7a4b359d91..f07571d3cc 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -49,6 +49,7 @@
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qevent.h>
+#include <QtGui/qstylehints.h>
#include <float.h>
@@ -56,8 +57,6 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlVisualTouchDebugging, QML_VISUAL_TOUCH_DEBUGGING)
-static const int PressAndHoldDelay = 800;
-
QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
: enabled(true), hovered(false), longPress(false),
moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
@@ -627,7 +626,7 @@ void QQuickMouseArea::mousePressEvent(QMouseEvent *event)
#endif
setHovered(true);
d->startScene = event->windowPos();
- d->pressAndHoldTimer.start(PressAndHoldDelay, this);
+ d->pressAndHoldTimer.start(qApp->styleHints()->mousePressAndHoldInterval(), this);
setKeepMouseGrab(d->stealMouse);
event->setAccepted(setPressed(event->button(), true));
}
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 8fe306b006..6b273dcd43 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -43,6 +43,7 @@
#include <QtQuick/qquickwindow.h>
#include <private/qsgadaptationlayer_p.h>
#include <private/qquickitem_p.h>
+#include <private/qguiapplication_p.h>
#include <QEvent>
#include <QMouseEvent>
#include <math.h>
@@ -675,6 +676,10 @@ bool QQuickMultiPointTouchArea::sendMouseEvent(QMouseEvent *event)
QMouseEvent mouseEvent(event->type(), localPos, event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers());
mouseEvent.setAccepted(false);
+ QGuiApplicationPrivate::setMouseEventCapsAndVelocity(&mouseEvent,
+ QGuiApplicationPrivate::mouseEventCaps(event),
+ QGuiApplicationPrivate::mouseEventVelocity(event));
+ QGuiApplicationPrivate::setMouseEventSource(&mouseEvent, Qt::MouseEventSynthesizedByQt);
switch (mouseEvent.type()) {
case QEvent::MouseMove:
diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp
index 48f79a2192..ee1b66f2b5 100644
--- a/src/quick/items/qquickrectangle.cpp
+++ b/src/quick/items/qquickrectangle.cpp
@@ -321,6 +321,16 @@ void QQuickRectangle::doUpdate()
}
/*!
+ \qmlproperty bool QtQuick::Rectangle::antialiasing
+
+ Used to decide if the Rectangle should use antialiasing or not.
+ \l {Antialiasing} provides information on the performance implications
+ of this property.
+
+ The default is true for Rectangles with a radius, and false otherwise.
+*/
+
+/*!
\qmlpropertygroup QtQuick::Rectangle::border
\qmlproperty int QtQuick::Rectangle::border.width
\qmlproperty color QtQuick::Rectangle::border.color
@@ -409,6 +419,8 @@ void QQuickRectangle::setRadius(qreal radius)
return;
d->radius = radius;
+ d->setImplicitAntialiasing(radius != 0.0);
+
update();
emit radiusChanged();
}
@@ -476,7 +488,7 @@ QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
}
rectangle->setRadius(d->radius);
- rectangle->setAntialiasing(d->antialiasing || d->radius > 0);
+ rectangle->setAntialiasing(antialiasing());
QGradientStops stops;
if (d->gradient) {
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index ad904a2579..beb2039924 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -88,6 +88,7 @@ QQuickTextPrivate::QQuickTextPrivate()
, truncated(false), hAlignImplicit(true), rightToLeftText(false)
, layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false)
{
+ implicitAntialiasing = true;
}
QQuickTextPrivate::ExtraData::ExtraData()
@@ -114,6 +115,7 @@ QQuickTextDocumentWithImageResources::QQuickTextDocumentWithImageResources(QQuic
{
setUndoRedoEnabled(false);
documentLayout()->registerHandler(QTextFormat::ImageObject, this);
+ connect(this, SIGNAL(baseUrlChanged(QUrl)), this, SLOT(reset()));
}
QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
@@ -125,14 +127,13 @@ QQuickTextDocumentWithImageResources::~QQuickTextDocumentWithImageResources()
QVariant QQuickTextDocumentWithImageResources::loadResource(int type, const QUrl &name)
{
QQmlContext *context = qmlContext(parent());
- QUrl url = m_baseUrl.resolved(name);
if (type == QTextDocument::ImageResource) {
- QQuickPixmap *p = loadPixmap(context, url);
+ QQuickPixmap *p = loadPixmap(context, name);
return p->image();
}
- return QTextDocument::loadResource(type,url); // The *resolved* URL
+ return QTextDocument::loadResource(type, name);
}
void QQuickTextDocumentWithImageResources::requestFinished()
@@ -144,14 +145,6 @@ void QQuickTextDocumentWithImageResources::requestFinished()
}
}
-void QQuickTextDocumentWithImageResources::clear()
-{
- clearResources();
-
- QTextDocument::clear();
-}
-
-
QSizeF QQuickTextDocumentWithImageResources::intrinsicSize(
QTextDocument *, int, const QTextFormat &format)
{
@@ -166,7 +159,7 @@ QSizeF QQuickTextDocumentWithImageResources::intrinsicSize(
QSizeF size(width, height);
if (!hasWidth || !hasHeight) {
QQmlContext *context = qmlContext(parent());
- QUrl url = m_baseUrl.resolved(QUrl(imageFormat.name()));
+ QUrl url = baseUrl().resolved(QUrl(imageFormat.name()));
QQuickPixmap *p = loadPixmap(context, url);
if (!p->isReady()) {
@@ -204,19 +197,16 @@ void QQuickTextDocumentWithImageResources::drawObject(
QImage QQuickTextDocumentWithImageResources::image(const QTextImageFormat &format)
{
QQmlContext *context = qmlContext(parent());
- QUrl url = m_baseUrl.resolved(QUrl(format.name()));
+ QUrl url = baseUrl().resolved(QUrl(format.name()));
QQuickPixmap *p = loadPixmap(context, url);
return p->image();
}
-void QQuickTextDocumentWithImageResources::setBaseUrl(const QUrl &url, bool clear)
+void QQuickTextDocumentWithImageResources::reset()
{
- m_baseUrl = url;
- if (clear) {
- clearResources();
- markContentsDirty(0, characterCount());
- }
+ clearResources();
+ markContentsDirty(0, characterCount());
}
QQuickPixmap *QQuickTextDocumentWithImageResources::loadPixmap(
@@ -297,6 +287,15 @@ qreal QQuickTextPrivate::getImplicitHeight() const
return implicitHeight;
}
+/*!
+ \qmlproperty bool QtQuick::Text::antialiasing
+
+ Used to decide if the Text should use antialiasing or not. Only Text
+ with renderType of Text.NativeRendering can disable antialiasing.
+
+ The default is true.
+*/
+
void QQuickText::q_imagesLoaded()
{
Q_D(QQuickText);
@@ -620,8 +619,9 @@ void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height,
textLine->setHeight(0);
textLine->setLineOffset(lineOffset);
- // use the text item's width by default if it has one and wrap is on
- if (q->widthValid() && q->wrapMode() != QQuickText::NoWrap)
+ // use the text item's width by default if it has one and wrap is on or text must be aligned
+ if (q->widthValid() && (q->wrapMode() != QQuickText::NoWrap ||
+ q->effectiveHAlign() != QQuickText::AlignLeft))
textLine->setWidth(q->width());
else
textLine->setWidth(INT_MAX);
@@ -959,7 +959,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
// If the horizontal alignment is not left and the width was not valid we need to relayout
// now that we know the maximum line width.
- if (!implicitWidthValid && lineCount > 1 && q->effectiveHAlign() != QQuickText::AlignLeft) {
+ if (!implicitWidthValid && unwrappedLineCount > 1 && q->effectiveHAlign() != QQuickText::AlignLeft) {
widthExceeded = false;
heightExceeded = false;
continue;
@@ -1415,6 +1415,9 @@ void QQuickText::setFont(const QFont &font)
QFont oldFont = d->font;
d->font = font;
+ if (!antialiasing())
+ d->font.setStyleStrategy(QFont::NoAntialias);
+
if (d->font.pointSizeF() != -1) {
// 0.5pt resolution
qreal size = qRound(d->font.pointSizeF()*2.0);
@@ -1434,6 +1437,21 @@ void QQuickText::setFont(const QFont &font)
emit fontChanged(d->sourceFont);
}
+void QQuickText::itemChange(ItemChange change, const ItemChangeData &value)
+{
+ Q_D(QQuickText);
+ Q_UNUSED(value);
+ if (change == ItemAntialiasingHasChanged) {
+ if (!antialiasing())
+ d->font.setStyleStrategy(QFont::NoAntialias);
+ else
+ d->font.setStyleStrategy(QFont::PreferAntialias);
+ d->implicitWidthValid = false;
+ d->implicitHeightValid = false;
+ d->updateLayout();
+ }
+}
+
/*!
\qmlproperty string QtQuick::Text::text
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 489ef58344..d55dc7e287 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -241,6 +241,7 @@ Q_SIGNALS:
protected:
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
+ virtual void itemChange(ItemChange change, const ItemChangeData &value);
virtual void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry);
virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 1f6cd3eab5..12113f416c 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -195,16 +195,13 @@ public:
void setText(const QString &);
int resourcesLoading() const { return outstanding; }
- void clearResources();
-
- void clear();
-
QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format);
void drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format);
QImage image(const QTextImageFormat &format);
- void setBaseUrl(const QUrl &url, bool clear = true);
+public Q_SLOTS:
+ void clearResources();
Q_SIGNALS:
void imagesLoaded();
@@ -215,11 +212,11 @@ protected:
QQuickPixmap *loadPixmap(QQmlContext *context, const QUrl &name);
private Q_SLOTS:
+ void reset();
void requestFinished();
private:
QHash<QUrl, QQuickPixmap *> m_resources;
- QUrl m_baseUrl;
int outstanding;
static QSet<QUrl> errors;
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index ffc732621d..c342c79ce5 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -830,7 +830,7 @@ void QQuickTextEdit::setBaseUrl(const QUrl &url)
if (baseUrl() != url) {
d->baseUrl = url;
- d->document->setBaseUrl(url, d->richText);
+ d->document->setBaseUrl(url);
emit baseUrlChanged();
}
}
@@ -1281,7 +1281,7 @@ void QQuickTextEdit::componentComplete()
Q_D(QQuickTextEdit);
QQuickImplicitSizeItem::componentComplete();
- d->document->setBaseUrl(baseUrl(), d->richText);
+ d->document->setBaseUrl(baseUrl());
#ifndef QT_NO_TEXTHTML_PARSER
if (d->richText)
d->control->setHtml(d->text);
diff --git a/src/quick/items/qquicktranslate.cpp b/src/quick/items/qquicktranslate.cpp
index f1b716cf5b..5c61fb33f8 100644
--- a/src/quick/items/qquicktranslate.cpp
+++ b/src/quick/items/qquicktranslate.cpp
@@ -458,4 +458,79 @@ void QQuickRotation::applyTo(QMatrix4x4 *matrix) const
matrix->translate(-d->origin);
}
+class QQuickMatrix4x4Private : public QQuickTransformPrivate
+{
+public:
+ QQuickMatrix4x4Private()
+ : matrix() {}
+ QMatrix4x4 matrix;
+};
+
+/*!
+ \qmltype Matrix4x4
+ \instantiates QQuickMatrix4x4
+ \inqmlmodule QtQuick
+ \ingroup qtquick-visual-transforms
+ \brief Provides a way to apply a 4x4 tranformation matrix to an \l Item
+
+ The Matrix4x4 type provides a way to apply a transformation to an
+ \l Item through a 4x4 matrix.
+
+ It allows for a combination of rotation, scale, translatation and shearing
+ by using just one tranformation provided in a 4x4-matrix.
+
+ The following example rotates a Rectangle 45 degress (PI/4):
+
+ \qml
+ Rectangle {
+ width: 100
+ height: 100
+ color: "red"
+
+ transform: Matrix4x4 {
+ property real a: Math.PI / 4
+ matrix: Qt.matrix4x4(Math.cos(a), -Math.sin(a), 0, 0,
+ Math.sin(a), Math.cos(a), 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1)
+ }
+ }
+ \endqml
+*/
+QQuickMatrix4x4::QQuickMatrix4x4(QObject *parent)
+ : QQuickTransform(*new QQuickMatrix4x4Private, parent)
+{
+}
+
+QQuickMatrix4x4::~QQuickMatrix4x4()
+{
+}
+
+/*!
+ \qmlproperty QMatrix4x4 QtQuick::Matrix4x4::matrix
+
+ 4x4-matrix which will be used in the tranformation of an \l Item
+*/
+QMatrix4x4 QQuickMatrix4x4::matrix() const
+{
+ Q_D(const QQuickMatrix4x4);
+ return d->matrix;
+}
+
+void QQuickMatrix4x4::setMatrix(const QMatrix4x4 &matrix)
+{
+ Q_D(QQuickMatrix4x4);
+ if (d->matrix == matrix)
+ return;
+ d->matrix = matrix;
+ update();
+ emit matrixChanged();
+}
+
+void QQuickMatrix4x4::applyTo(QMatrix4x4 *matrix) const
+{
+ Q_D(const QQuickMatrix4x4);
+ *matrix *= d->matrix;
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h
index d7843fe103..dd93275a28 100644
--- a/src/quick/items/qquicktranslate_p.h
+++ b/src/quick/items/qquicktranslate_p.h
@@ -148,6 +148,29 @@ private:
Q_DECLARE_PRIVATE(QQuickRotation)
};
+class QQuickMatrix4x4Private;
+class Q_AUTOTEST_EXPORT QQuickMatrix4x4 : public QQuickTransform
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY matrixChanged)
+public:
+ QQuickMatrix4x4(QObject *parent = 0);
+ ~QQuickMatrix4x4();
+
+ QMatrix4x4 matrix() const;
+ void setMatrix(const QMatrix4x4& matrix);
+
+ void applyTo(QMatrix4x4 *matrix) const;
+
+Q_SIGNALS:
+ void matrixChanged();
+
+private:
+ Q_DECLARE_PRIVATE(QQuickMatrix4x4)
+};
+
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickTranslate)
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index d1fe489dcb..61f0f9bec2 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -56,6 +56,26 @@
QT_BEGIN_NAMESPACE
+DEFINE_MANAGED_VTABLE(QQuickRootItemMarker);
+
+QQuickRootItemMarker::QQuickRootItemMarker(QQuickViewPrivate *view)
+ : QV4::Object(QQmlEnginePrivate::getV4Engine(view->engine.data()))
+ , view(view)
+{
+ setVTable(&static_vtbl);
+}
+
+void QQuickRootItemMarker::markObjects(QV4::Managed *that, QV4::ExecutionEngine *e)
+{
+ QQuickItem *root = static_cast<QQuickRootItemMarker*>(that)->view->root;
+ if (root) {
+ QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(root);
+ rootPrivate->markObjects(e);
+ }
+
+ QV4::Object::markObjects(that, e);
+}
+
void QQuickViewPrivate::init(QQmlEngine* e)
{
Q_Q(QQuickView);
@@ -68,6 +88,13 @@ void QQuickViewPrivate::init(QQmlEngine* e)
if (!engine.data()->incubationController())
engine.data()->setIncubationController(q->incubationController());
+ {
+ QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine.data());
+ QV4::Scope scope(v4);
+ QV4::Scoped<QQuickRootItemMarker> v(scope, new (v4->memoryManager) QQuickRootItemMarker(this));
+ rootItemMarker = v;
+ }
+
if (QQmlDebugService::isDebuggingEnabled())
QQmlInspectorService::instance()->addView(q);
}
diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h
index 170c93a6cf..e18b45dfbe 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -51,12 +51,17 @@
#include <QtCore/QWeakPointer>
#include <QtQml/qqmlengine.h>
+#include <private/qv4object_p.h>
#include "qquickwindow_p.h"
#include "qquickitemchangelistener_p.h"
QT_BEGIN_NAMESPACE
+namespace QV4 {
+struct ExecutionEngine;
+}
+
class QQmlContext;
class QQmlError;
class QQuickItem;
@@ -94,6 +99,23 @@ public:
QQuickView::ResizeMode resizeMode;
QSize initialSize;
QElapsedTimer frameTimer;
+ QV4::PersistentValue rootItemMarker;
+};
+
+struct QQuickRootItemMarker : public QV4::Object
+{
+ Q_MANAGED
+
+ QQuickRootItemMarker(QQuickViewPrivate *view);
+
+ static void destroy(Managed *that)
+ {
+ static_cast<QQuickRootItemMarker*>(that)->~QQuickRootItemMarker();
+ }
+
+ static void markObjects(Managed *that, QV4::ExecutionEngine *e);
+
+ QQuickViewPrivate *view;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index d286ccff0c..c57ca5e838 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -257,8 +257,10 @@ void QQuickWindowPrivate::polishItems()
for (QSet<QQuickItem *>::iterator it = itms.begin(); it != itms.end(); ++it) {
QQuickItem *item = *it;
- QQuickItemPrivate::get(item)->polishScheduled = false;
- item->updatePolish();
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->polishScheduled = false;
+ if (item->isVisible() || (itemPrivate->extra.isAllocated() && itemPrivate->extra->effectRefCount>0))
+ item->updatePolish();
}
}
@@ -470,6 +472,7 @@ static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::Touc
transformedVelocity = transformMatrix.mapVector(p.velocity()).toVector2D();
}
QGuiApplicationPrivate::setMouseEventCapsAndVelocity(me, event->device()->capabilities(), transformedVelocity);
+ QGuiApplicationPrivate::setMouseEventSource(me, Qt::MouseEventSynthesizedByQt);
return me;
}
@@ -523,7 +526,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
item->grabMouse();
item->grabTouchPoints(QVector<int>() << touchMouseId);
- QQuickItemPrivate::get(item)->deliverMouseEvent(mousePress.data());
+ QCoreApplication::sendEvent(item, mousePress.data());
event->setAccepted(mousePress->isAccepted());
if (!mousePress->isAccepted()) {
touchMouseId = -1;
@@ -536,7 +539,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
if (mousePress->isAccepted() && checkIfDoubleClicked(event->timestamp())) {
QScopedPointer<QMouseEvent> mouseDoubleClick(touchToMouseEvent(QEvent::MouseButtonDblClick, p, event, item));
- QQuickItemPrivate::get(item)->deliverMouseEvent(mouseDoubleClick.data());
+ QCoreApplication::sendEvent(item, mouseDoubleClick.data());
event->setAccepted(mouseDoubleClick->isAccepted());
if (mouseDoubleClick->isAccepted()) {
return true;
@@ -557,7 +560,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
if (p.state() & Qt::TouchPointMoved) {
if (mouseGrabberItem) {
QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event, mouseGrabberItem));
- QQuickItemPrivate::get(item)->deliverMouseEvent(me.data());
+ QCoreApplication::sendEvent(item, me.data());
event->setAccepted(me->isAccepted());
if (me->isAccepted()) {
itemForTouchPointId[p.id()] = mouseGrabberItem; // N.B. the mouseGrabberItem may be different after returning from sendEvent()
@@ -587,7 +590,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
touchMouseId = -1;
if (mouseGrabberItem) {
QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseButtonRelease, p, event, mouseGrabberItem));
- QQuickItemPrivate::get(item)->deliverMouseEvent(me.data());
+ QCoreApplication::sendEvent(item, me.data());
if (mouseGrabberItem) // might have ungrabbed due to event
mouseGrabberItem->ungrabMouse();
return me->isAccepted();
@@ -1296,24 +1299,43 @@ bool QQuickWindow::event(QEvent *e)
void QQuickWindow::keyPressEvent(QKeyEvent *e)
{
Q_D(QQuickWindow);
-
-#ifndef QT_NO_SHORTCUT
- // Try looking for a Shortcut before sending key events
- if (QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(focusObject(), e))
- return;
-#endif
-
- if (d->activeFocusItem)
- sendEvent(d->activeFocusItem, e);
+ d->deliverKeyEvent(e);
}
/*! \reimp */
void QQuickWindow::keyReleaseEvent(QKeyEvent *e)
{
Q_D(QQuickWindow);
+ d->deliverKeyEvent(e);
+}
- if (d->activeFocusItem)
- sendEvent(d->activeFocusItem, e);
+void QQuickWindowPrivate::deliverKeyEvent(QKeyEvent *e)
+{
+ Q_Q(QQuickWindow);
+
+#ifndef QT_NO_SHORTCUT
+ // Try looking for a Shortcut before sending key events
+ if (e->type() == QEvent::KeyPress
+ && QGuiApplicationPrivate::instance()->shortcutMap.tryShortcutEvent(q->focusObject(), e))
+ return;
+#endif
+
+ if (activeFocusItem)
+ q->sendEvent(activeFocusItem, e);
+#ifdef Q_OS_MAC
+ else {
+ // This is the case for popup windows on Mac, where popup windows get focus
+ // in Qt (after exposure) but they are not "key windows" in the Cocoa sense.
+ // Therefore, the will never receive key events from Cocoa. Instead, the
+ // toplevel non-popup window (the application current "key window") will
+ // receive them. (QWidgetWindow does something similar for widgets, by keeping
+ // a list of popup windows, and forwarding the key event to the top-most popup.)
+ QWindow *focusWindow = qApp->focusWindow();
+ if (focusWindow && focusWindow != q
+ && (focusWindow->flags() & Qt::Popup) == Qt::Popup)
+ QGuiApplication::sendEvent(focusWindow, e);
+ }
+#endif
}
QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos)
@@ -1325,6 +1347,7 @@ QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *t
event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers());
QGuiApplicationPrivate::setMouseEventCapsAndVelocity(me, caps, velocity);
+ QGuiApplicationPrivate::setMouseEventSource(me, QGuiApplicationPrivate::mouseEventSource(event));
me->setTimestamp(event->timestamp());
return me;
}
@@ -1401,6 +1424,12 @@ bool QQuickWindowPrivate::deliverMouseEvent(QMouseEvent *event)
void QQuickWindow::mousePressEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+
+ if (event->source() == Qt::MouseEventSynthesizedBySystem) {
+ event->accept();
+ return;
+ }
+
#ifdef MOUSE_DEBUG
qWarning() << "QQuickWindow::mousePressEvent()" << event->localPos() << event->button() << event->buttons();
#endif
@@ -1412,6 +1441,12 @@ void QQuickWindow::mousePressEvent(QMouseEvent *event)
void QQuickWindow::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+
+ if (event->source() == Qt::MouseEventSynthesizedBySystem) {
+ event->accept();
+ return;
+ }
+
#ifdef MOUSE_DEBUG
qWarning() << "QQuickWindow::mouseReleaseEvent()" << event->localPos() << event->button() << event->buttons();
#endif
@@ -1430,6 +1465,12 @@ void QQuickWindow::mouseReleaseEvent(QMouseEvent *event)
void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+
+ if (event->source() == Qt::MouseEventSynthesizedBySystem) {
+ event->accept();
+ return;
+ }
+
#ifdef MOUSE_DEBUG
qWarning() << "QQuickWindow::mouseDoubleClickEvent()" << event->localPos() << event->button() << event->buttons();
#endif
@@ -1465,6 +1506,12 @@ bool QQuickWindowPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item,
void QQuickWindow::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickWindow);
+
+ if (event->source() == Qt::MouseEventSynthesizedBySystem) {
+ event->accept();
+ return;
+ }
+
#ifdef MOUSE_DEBUG
qWarning() << "QQuickWindow::mouseMoveEvent()" << event->localPos() << event->button() << event->buttons();
#endif
@@ -1813,11 +1860,11 @@ bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QTouchEv
itemForTouchPointId[id] = item;
// Deliver the touch event to the given item
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- itemPrivate->deliverTouchEvent(touchEvent.data());
+ QCoreApplication::sendEvent(item, touchEvent.data());
touchEventAccepted = touchEvent->isAccepted();
// If the touch event wasn't accepted, synthesize a mouse event and see if the item wants it.
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
if (!touchEventAccepted && (itemPrivate->acceptedMouseButtons() & Qt::LeftButton)) {
// send mouse event
event->setAccepted(translateTouchToMouse(item, event));
@@ -2235,16 +2282,12 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e)
case QEvent::KeyPress:
case QEvent::KeyRelease:
e->accept();
- QQuickItemPrivate::get(item)->deliverKeyEvent(static_cast<QKeyEvent *>(e));
+ QCoreApplication::sendEvent(item, e);
while (!e->isAccepted() && (item = item->parentItem())) {
e->accept();
- QQuickItemPrivate::get(item)->deliverKeyEvent(static_cast<QKeyEvent *>(e));
+ QCoreApplication::sendEvent(item, e);
}
break;
- case QEvent::FocusIn:
- case QEvent::FocusOut:
- QQuickItemPrivate::get(item)->deliverFocusEvent(static_cast<QFocusEvent *>(e));
- break;
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
@@ -2253,7 +2296,7 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e)
if (!d->sendFilteredMouseEvent(item->parentItem(), item, e)) {
// accept because qml items by default accept and have to explicitly opt out of accepting
e->accept();
- QQuickItemPrivate::get(item)->deliverMouseEvent(static_cast<QMouseEvent *>(e));
+ QCoreApplication::sendEvent(item, e);
}
break;
case QEvent::UngrabMouse:
@@ -2264,30 +2307,26 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e)
break;
#ifndef QT_NO_WHEELEVENT
case QEvent::Wheel:
- QQuickItemPrivate::get(item)->deliverWheelEvent(static_cast<QWheelEvent *>(e));
- break;
#endif
+#ifndef QT_NO_DRAGANDDROP
+ case QEvent::DragEnter:
+ case QEvent::DragMove:
+ case QEvent::DragLeave:
+ case QEvent::Drop:
+#endif
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
case QEvent::HoverEnter:
case QEvent::HoverLeave:
case QEvent::HoverMove:
- QQuickItemPrivate::get(item)->deliverHoverEvent(static_cast<QHoverEvent *>(e));
+ case QEvent::TouchCancel:
+ QCoreApplication::sendEvent(item, e);
break;
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
d->sendFilteredTouchEvent(item->parentItem(), item, static_cast<QTouchEvent *>(e));
break;
- case QEvent::TouchCancel:
- QQuickItemPrivate::get(item)->deliverTouchEvent(static_cast<QTouchEvent *>(e));
- break;
-#ifndef QT_NO_DRAGANDDROP
- case QEvent::DragEnter:
- case QEvent::DragMove:
- case QEvent::DragLeave:
- case QEvent::Drop:
- QQuickItemPrivate::get(item)->deliverDragEvent(e);
- break;
-#endif
default:
break;
}
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 418633b6ac..d5c7b5d64c 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -111,6 +111,8 @@ public:
QQuickItem *activeFocusItem;
+ void deliverKeyEvent(QKeyEvent *e);
+
// Keeps track of the item currently receiving mouse events
QQuickItem *mouseGrabberItem;
#ifndef QT_NO_CURSOR
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index e9d883f248..eff8158335 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -2165,6 +2165,10 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
if (g->drawingMode() == GL_LINE_STRIP || g->drawingMode() == GL_LINE_LOOP || g->drawingMode() == GL_LINES)
glLineWidth(g->lineWidth());
+#if !defined(QT_OPENGL_ES_2)
+ else if (g->drawingMode() == GL_POINTS)
+ glPointSize(g->lineWidth());
+#endif
if (g->indexCount())
glDrawElements(g->drawingMode(), g->indexCount(), g->indexType(), iOffset);
diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp
index ffb11fc6fa..40e0a014ab 100644
--- a/src/quick/scenegraph/coreapi/qsggeometry.cpp
+++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp
@@ -525,8 +525,9 @@ void QSGGeometry::setDrawingMode(GLenum mode)
}
/*!
- Gets the current line width to be used for this geometry. This property only
- applies where the drawingMode is GL_LINES or a related value.
+ Gets the current line or point width or to be used for this geometry. This property
+ only applies to line width when the drawingMode is \c GL_LINES, \c GL_LINE_STRIP, or
+ \c GL_LINE_LOOP, and only applies to point size when the drawingMode is \c GL_POINTS.
The default value is \c 1.0
@@ -538,8 +539,9 @@ float QSGGeometry::lineWidth() const
}
/*!
- Sets the line width to be used for this geometry to \a width. The line width
- only applies where the drawingMode is \c GL_LINES or a related value.
+ Sets the line or point width to be used for this geometry to \a width. This property
+ only applies to line width when the drawingMode is \c GL_LINES, \c GL_LINE_STRIP, or
+ \c GL_LINE_LOOP, and only applies to point size when the drawingMode is \c GL_POINTS.
\sa lineWidth(), drawingMode()
*/
diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp
index 460e2ca554..407b80915d 100644
--- a/src/quick/util/qquickbehavior.cpp
+++ b/src/quick/util/qquickbehavior.cpp
@@ -185,7 +185,8 @@ void QQuickBehavior::write(const QVariant &value)
return;
}
- if (d->animation->isRunning() && value == d->targetValue)
+ bool behaviorActive = d->animation->isRunning();
+ if (behaviorActive && value == d->targetValue)
return;
d->targetValue = value;
@@ -201,6 +202,14 @@ void QQuickBehavior::write(const QVariant &value)
// to the item, so we need to read the value after.
const QVariant &currentValue = d->property.read();
+ // Don't unnecessarily wake up the animation system if no real animation
+ // is needed (value has not changed). If the Behavior was already
+ // running, let it continue as normal to ensure correct behavior and state.
+ if (!behaviorActive && d->targetValue == currentValue) {
+ QQmlPropertyPrivate::write(d->property, value, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding);
+ return;
+ }
+
QQuickStateOperation::ActionList actions;
QQuickStateAction action;
action.property = d->property;
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 152d1f34c9..5ae74c2fec 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -398,7 +398,7 @@ public:
if (!array)
return QMatrix4x4();
- if (array->arrayLength() != 16)
+ if (array->getLength() != 16)
return QMatrix4x4();
float matVals[16];
diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp
index 148c55bbcb..55ac85e64d 100644
--- a/src/quick/util/qquickpropertychanges.cpp
+++ b/src/quick/util/qquickpropertychanges.cpp
@@ -259,6 +259,29 @@ QQuickPropertyChangesParser::compileList(QList<QPair<QString, QVariant> > &list,
}
}
+void QQuickPropertyChangesParser::compileList(QList<QPair<QString, const QV4::CompiledData::Binding*> > &list, const QString &pre, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding)
+{
+ QString propName = pre + qmlUnit->header.stringAt(binding->propertyNameIndex);
+
+ if (binding->type == QV4::CompiledData::Binding::Type_Object) {
+ error(qmlUnit->objectAt(binding->value.objectIndex), QQuickPropertyChanges::tr("PropertyChanges does not support creating state-specific objects."));
+ return;
+ }
+
+ if (binding->type == QV4::CompiledData::Binding::Type_GroupProperty
+ || binding->type == QV4::CompiledData::Binding::Type_AttachedProperty) {
+ QString pre = propName + QLatin1Char('.');
+ const QV4::CompiledData::Object *subObj = qmlUnit->objectAt(binding->value.objectIndex);
+ const QV4::CompiledData::Binding *subBinding = subObj->bindingTable();
+ for (quint32 i = 0; i < subObj->nBindings; ++i, ++subBinding) {
+ compileList(list, pre, qmlUnit, subBinding);
+ }
+ return;
+ }
+
+ list << qMakePair(propName, binding);
+}
+
QByteArray
QQuickPropertyChangesParser::compile(const QList<QQmlCustomParserProperty> &props)
{
@@ -303,6 +326,44 @@ QQuickPropertyChangesParser::compile(const QList<QQmlCustomParserProperty> &prop
return rv;
}
+QByteArray QQuickPropertyChangesParser::compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props)
+{
+ QList<QPair<QString, const QV4::CompiledData::Binding *> > data;
+ for (int ii = 0; ii < props.count(); ++ii)
+ compileList(data, QString(), qmlUnit, props.at(ii));
+
+ QByteArray rv;
+ QDataStream ds(&rv, QIODevice::WriteOnly);
+
+ ds << data.count();
+ for (int ii = 0; ii < data.count(); ++ii) {
+ const QV4::CompiledData::Binding *binding = data.at(ii).second;
+ QVariant var;
+ bool isScript = binding->type == QV4::CompiledData::Binding::Type_Script;
+ QQmlBinding::Identifier id = QQmlBinding::Invalid;
+ switch (binding->type) {
+ case QV4::CompiledData::Binding::Type_Script:
+ // ### pre-compile binding
+ case QV4::CompiledData::Binding::Type_String:
+ var = binding->valueAsString(&qmlUnit->header);
+ break;
+ case QV4::CompiledData::Binding::Type_Number:
+ var = binding->valueAsNumber();
+ break;
+ case QV4::CompiledData::Binding::Type_Boolean:
+ var = binding->valueAsBoolean();
+ break;
+ default:
+ break;
+ }
+ ds << data.at(ii).first << isScript << var;
+ if (isScript)
+ ds << id;
+ }
+
+ return rv;
+}
+
void QQuickPropertyChangesPrivate::decode()
{
Q_Q(QQuickPropertyChanges);
diff --git a/src/quick/util/qquickpropertychanges_p.h b/src/quick/util/qquickpropertychanges_p.h
index 0236e4529b..081ea72862 100644
--- a/src/quick/util/qquickpropertychanges_p.h
+++ b/src/quick/util/qquickpropertychanges_p.h
@@ -93,8 +93,10 @@ public:
: QQmlCustomParser(AcceptsAttachedProperties) {}
void compileList(QList<QPair<QString, QVariant> > &list, const QString &pre, const QQmlCustomParserProperty &prop);
+ void compileList(QList<QPair<QString, const QV4::CompiledData::Binding *> > &list, const QString &pre, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::Binding *binding);
virtual QByteArray compile(const QList<QQmlCustomParserProperty> &);
+ virtual QByteArray compile(const QV4::CompiledData::QmlUnit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props);
virtual void setCustomData(QObject *, const QByteArray &);
};