aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2020-02-17 01:01:00 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-02-17 10:21:59 +0100
commit3e758800b4daf8fbc870a2ff5d54fce9d4402ce8 (patch)
treeba237b9da1c7dfd08bf13e71c5dbd6b3c2e77633 /src/quick/items
parent925a0e499a5dbdb180fd9969a79abf96006ce4fd (diff)
parent55546991e24ca6799709cbe0171b9ab87216c35f (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: src/imports/qtqml/plugin.cpp src/qml/qml/qqml.h src/qml/qml/qqmlmetatype.cpp src/qml/qml/qqmlmetatype_p.h src/qml/qml/qqmltypeloader.cpp src/qml/types/qqmlbind.cpp src/quick/items/qquickitemsmodule.cpp tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp Change-Id: I52548938a582cb6510271ed4bc3a9aa0c3c11df6
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickevents.cpp162
-rw-r--r--src/quick/items/qquickevents_p_p.h71
-rw-r--r--src/quick/items/qquickflickable.cpp19
-rw-r--r--src/quick/items/qquickflickable_p_p.h2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp7
-rw-r--r--src/quick/items/qquickitemsmodule_p.h12
-rw-r--r--src/quick/items/qquickitemview.cpp2
-rw-r--r--src/quick/items/qquicklistview.cpp168
-rw-r--r--src/quick/items/qquickloader.cpp93
-rw-r--r--src/quick/items/qquickloader_p_p.h7
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp28
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h4
-rw-r--r--src/quick/items/qquickshadereffectsource.cpp4
-rw-r--r--src/quick/items/qquickspriteengine_p.h12
-rw-r--r--src/quick/items/qquickspritesequence.cpp4
-rw-r--r--src/quick/items/qquicktableview.cpp20
-rw-r--r--src/quick/items/qquicktableview_p_p.h2
-rw-r--r--src/quick/items/qquicktext.cpp7
-rw-r--r--src/quick/items/qquickwindow.cpp60
-rw-r--r--src/quick/items/qquickwindow.h3
-rw-r--r--src/quick/items/qquickwindow_p.h2
21 files changed, 562 insertions, 127 deletions
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 469dc3cb4d..3c01bd2cb1 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -658,14 +658,73 @@ QQuickPointerDevice *QQuickPointerDevice::genericMouseDevice()
return g_genericMouseDevice;
}
-QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id)
-{
- auto it = g_tabletDevices->find(id);
+QQuickPointerDevice *QQuickPointerDevice::tabletDevice(const QTabletEvent *event)
+{
+ // QTabletEvent::uniqueId() is the same for the pointy end and the eraser end of the stylus.
+ // We need to make those unique. QTabletEvent::PointerType only needs 2 bits' worth of storage.
+ // The key into g_tabletDevices just needs to be unique; we don't need to extract uniqueId
+ // back out of it, because QQuickPointerDevice stores that separately anyway.
+ // So the shift-and-add can be thought of as a sort of hash function, even though
+ // most of the time the result will be recognizable because the uniqueId MSBs are often 0.
+ qint64 key = event->uniqueId() + (qint64(event->pointerType()) << 60);
+ auto it = g_tabletDevices->find(key);
if (it != g_tabletDevices->end())
return it.value();
- // ### Figure out how to populate the tablet devices
- return nullptr;
+ DeviceType type = UnknownDevice;
+ int buttonCount = 0;
+ Capabilities caps = Position | Pressure | Hover;
+ // TODO Qt 6: we can't know for sure about XTilt or YTilt until we have a
+ // QTabletDevice populated with capabilities provided by QPA plugins
+
+ switch (event->device()) {
+ case QTabletEvent::Stylus:
+ type = QQuickPointerDevice::Stylus;
+ buttonCount = 3;
+ break;
+ case QTabletEvent::RotationStylus:
+ type = QQuickPointerDevice::Stylus;
+ caps |= QQuickPointerDevice::Rotation;
+ buttonCount = 1;
+ break;
+ case QTabletEvent::Airbrush:
+ type = QQuickPointerDevice::Airbrush;
+ buttonCount = 2;
+ break;
+ case QTabletEvent::Puck:
+ type = QQuickPointerDevice::Puck;
+ buttonCount = 3;
+ break;
+ case QTabletEvent::FourDMouse:
+ type = QQuickPointerDevice::Mouse;
+ caps |= QQuickPointerDevice::Rotation;
+ buttonCount = 3;
+ break;
+ default:
+ type = QQuickPointerDevice::UnknownDevice;
+ break;
+ }
+
+ PointerType ptype = GenericPointer;
+ switch (event->pointerType()) {
+ case QTabletEvent::Pen:
+ ptype = Pen;
+ break;
+ case QTabletEvent::Eraser:
+ ptype = Eraser;
+ break;
+ case QTabletEvent::Cursor:
+ ptype = Cursor;
+ break;
+ case QTabletEvent::UnknownPointer:
+ break;
+ }
+
+ QQuickPointerDevice *device = new QQuickPointerDevice(type, ptype, caps, 1, buttonCount,
+ QLatin1String("tablet tool ") + QString::number(event->uniqueId()), event->uniqueId());
+
+ g_tabletDevices->insert(key, device);
+ return device;
}
/*!
@@ -1284,6 +1343,12 @@ QVector2D QQuickEventPoint::estimatedVelocity() const
QQuickPointerEvent::~QQuickPointerEvent()
{}
+QQuickPointerMouseEvent::QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerMouseEvent::reset(QEvent *event)
{
auto ev = static_cast<QMouseEvent*>(event);
@@ -1398,6 +1463,12 @@ void QQuickPointerTouchEvent::localize(QQuickItem *target)
}
#if QT_CONFIG(gestures)
+QQuickPointerNativeGestureEvent::QQuickPointerNativeGestureEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerNativeGestureEvent::reset(QEvent *event)
{
auto ev = static_cast<QNativeGestureEvent*>(event);
@@ -1560,6 +1631,12 @@ QQuickEventPoint *QQuickSinglePointEvent::point(int i) const
\note Many platforms provide no such information. On such platforms,
\c inverted always returns false.
*/
+QQuickPointerScrollEvent::QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventPoint(this);
+}
+
QQuickPointerEvent *QQuickPointerScrollEvent::reset(QEvent *event)
{
m_event = static_cast<QInputEvent*>(event);
@@ -1832,6 +1909,81 @@ QMouseEvent *QQuickPointerTouchEvent::syntheticMouseEvent(int pointID, QQuickIte
return &m_synthMouseEvent;
}
+#if QT_CONFIG(tabletevent)
+QQuickPointerTabletEvent::QQuickPointerTabletEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickSinglePointEvent(parent, device)
+{
+ m_point = new QQuickEventTabletPoint(this);
+}
+
+QQuickPointerEvent *QQuickPointerTabletEvent::reset(QEvent *event)
+{
+ auto ev = static_cast<QTabletEvent*>(event);
+ m_event = ev;
+ if (!event)
+ return this;
+
+ Q_ASSERT(m_device == QQuickPointerDevice::tabletDevice(ev));
+ m_device->eventDeliveryTargets().clear();
+ m_button = ev->button();
+ m_pressedButtons = ev->buttons();
+ static_cast<QQuickEventTabletPoint *>(m_point)->reset(ev);
+ return this;
+}
+
+QQuickEventTabletPoint::QQuickEventTabletPoint(QQuickPointerTabletEvent *parent)
+ : QQuickEventPoint(parent)
+{
+}
+
+void QQuickEventTabletPoint::reset(const QTabletEvent *ev)
+{
+ Qt::TouchPointState state = Qt::TouchPointStationary;
+ switch (ev->type()) {
+ case QEvent::TabletPress:
+ state = Qt::TouchPointPressed;
+ clearPassiveGrabbers();
+ break;
+ case QEvent::TabletRelease:
+ state = Qt::TouchPointReleased;
+ break;
+ case QEvent::TabletMove:
+ state = Qt::TouchPointMoved;
+ break;
+ default:
+ break;
+ }
+ QQuickEventPoint::reset(state, ev->posF(), 1, ev->timestamp());
+ m_rotation = ev->rotation();
+ m_pressure = ev->pressure();
+ m_tangentialPressure = ev->tangentialPressure();
+ m_tilt = QVector2D(ev->xTilt(), ev->yTilt());
+}
+
+bool QQuickPointerTabletEvent::isPressEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletPress;
+}
+
+bool QQuickPointerTabletEvent::isUpdateEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletMove;
+}
+
+bool QQuickPointerTabletEvent::isReleaseEvent() const
+{
+ auto me = static_cast<QTabletEvent *>(m_event);
+ return me->type() == QEvent::TabletRelease;
+}
+
+QTabletEvent *QQuickPointerTabletEvent::asTabletEvent() const
+{
+ return static_cast<QTabletEvent *>(m_event);
+}
+#endif // QT_CONFIG(tabletevent)
+
#if QT_CONFIG(gestures)
bool QQuickPointerNativeGestureEvent::isPressEvent() const
{
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 94b61fd364..84450e060a 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -478,8 +478,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickSinglePointEvent : public QQuickPointerEvent
{
Q_OBJECT
public:
- QQuickSinglePointEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickPointerEvent(parent, device), m_point(new QQuickEventPoint(this)) { }
+ QQuickSinglePointEvent(QObject *parent, QQuickPointerDevice *device)
+ : QQuickPointerEvent(parent, device) { }
void localize(QQuickItem *target) override;
int pointCount() const override { return 1; }
@@ -493,7 +493,7 @@ public:
bool hasExclusiveGrabber(const QQuickPointerHandler *handler) const override;
protected:
- QQuickEventPoint *m_point;
+ QQuickEventPoint *m_point = nullptr;
Q_DISABLE_COPY(QQuickSinglePointEvent)
};
@@ -507,8 +507,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerMouseEvent : public QQuickSinglePointE
QML_ADDED_IN_MINOR_VERSION(12)
public:
- QQuickPointerMouseEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerMouseEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
bool isPressEvent() const override;
@@ -570,6 +569,60 @@ private:
Q_DISABLE_COPY(QQuickPointerTouchEvent)
};
+#if QT_CONFIG(tabletevent)
+class Q_QUICK_PRIVATE_EXPORT QQuickEventTabletPoint : public QQuickEventPoint
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal rotation READ rotation)
+ Q_PROPERTY(qreal pressure READ pressure)
+ Q_PROPERTY(qreal tangentialPressure READ tangentialPressure)
+ Q_PROPERTY(QVector2D tilt READ tilt)
+
+ QML_NAMED_ELEMENT(EventTabletPoint)
+ QML_UNCREATABLE("EventTouchPoint is only available as a member of PointerEvent.")
+ QML_ADDED_IN_MINOR_VERSION(15)
+
+public:
+ QQuickEventTabletPoint(QQuickPointerTabletEvent *parent);
+
+ void reset(const QTabletEvent *e);
+
+ qreal rotation() const { return m_rotation; }
+ qreal pressure() const { return m_pressure; }
+ qreal tangentialPressure() const { return m_tangentialPressure; }
+ QVector2D tilt() const { return m_tilt; }
+
+private:
+ qreal m_rotation;
+ qreal m_pressure;
+ qreal m_tangentialPressure;
+ QVector2D m_tilt;
+
+ friend class QQuickPointerTouchEvent;
+
+ Q_DISABLE_COPY(QQuickEventTabletPoint)
+};
+
+class Q_QUICK_PRIVATE_EXPORT QQuickPointerTabletEvent : public QQuickSinglePointEvent
+{
+ Q_OBJECT
+public:
+ QQuickPointerTabletEvent(QObject *parent, QQuickPointerDevice *device);
+
+ QQuickPointerEvent *reset(QEvent *) override;
+ bool isPressEvent() const override;
+ bool isUpdateEvent() const override;
+ bool isReleaseEvent() const override;
+ QQuickPointerTabletEvent *asPointerTabletEvent() override { return this; }
+ const QQuickPointerTabletEvent *asPointerTabletEvent() const override { return this; }
+ const QQuickEventTabletPoint *tabletPoint() const { return static_cast<QQuickEventTabletPoint *>(m_point); }
+
+ QTabletEvent *asTabletEvent() const;
+
+ Q_DISABLE_COPY(QQuickPointerTabletEvent)
+};
+#endif // QT_CONFIG(tabletevent)
+
#if QT_CONFIG(gestures)
class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickSinglePointEvent
{
@@ -578,8 +631,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickSing
Q_PROPERTY(qreal value READ value CONSTANT)
public:
- QQuickPointerNativeGestureEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerNativeGestureEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
bool isPressEvent() const override;
@@ -608,8 +660,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerScrollEvent : public QQuickSinglePoint
QML_ADDED_IN_MINOR_VERSION(14)
public:
- QQuickPointerScrollEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
- : QQuickSinglePointEvent(parent, device) { }
+ QQuickPointerScrollEvent(QObject *parent, QQuickPointerDevice *device);
QQuickPointerEvent *reset(QEvent *) override;
void localize(QQuickItem *target) override;
@@ -714,7 +765,7 @@ public:
static QQuickPointerDevice *touchDevice(const QTouchDevice *d);
static QList<QQuickPointerDevice *> touchDevices();
static QQuickPointerDevice *genericMouseDevice();
- static QQuickPointerDevice *tabletDevice(qint64);
+ static QQuickPointerDevice *tabletDevice(const QTabletEvent *event);
QVector<QQuickPointerHandler *> &eventDeliveryTargets() { return m_eventDeliveryTargets; }
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 8ade5b7e37..27c57e147a 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -128,8 +128,13 @@ void QQuickFlickableVisibleArea::updateVisible()
// Vertical
const qreal viewheight = flickable->height();
const qreal maxyextent = -flickable->maxYExtent() + flickable->minYExtent();
- qreal pagePos = (-p->vData.move.value() + flickable->minYExtent()) / (maxyextent + viewheight);
- qreal pageSize = viewheight / (maxyextent + viewheight);
+ const qreal maxYBounds = maxyextent + viewheight;
+ qreal pagePos = 0;
+ qreal pageSize = 0;
+ if (!qFuzzyIsNull(maxYBounds)) {
+ pagePos = (-p->vData.move.value() + flickable->minYExtent()) / maxYBounds;
+ pageSize = viewheight / maxYBounds;
+ }
if (pageSize != m_heightRatio) {
m_heightRatio = pageSize;
@@ -143,8 +148,14 @@ void QQuickFlickableVisibleArea::updateVisible()
// Horizontal
const qreal viewwidth = flickable->width();
const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent();
- pagePos = (-p->hData.move.value() + flickable->minXExtent()) / (maxxextent + viewwidth);
- pageSize = viewwidth / (maxxextent + viewwidth);
+ const qreal maxXBounds = maxxextent + viewwidth;
+ if (!qFuzzyIsNull(maxXBounds)) {
+ pagePos = (-p->hData.move.value() + flickable->minXExtent()) / maxXBounds;
+ pageSize = viewwidth / maxXBounds;
+ } else {
+ pagePos = 0;
+ pageSize = 0;
+ }
if (pageSize != m_widthRatio) {
m_widthRatio = pageSize;
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 1ff55dae90..3f5f11effd 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -73,7 +73,7 @@ class QQuickFlickableVisibleArea;
class QQuickTransition;
class QQuickFlickableReboundTransition;
-class Q_AUTOTEST_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
+class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
{
Q_DECLARE_PUBLIC(QQuickFlickable)
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index bd6b9d741e..125518e51b 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -183,13 +183,6 @@ static void qt_quickitems_defineModule()
qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine");
qRegisterMetaType<QPointingDeviceUniqueId>("QPointingDeviceUniqueId");
qRegisterMetaType<QQuickHandlerPoint>();
-
-#if !QT_CONFIG(quick_animatedimage)
- qmlRegisterTypeNotAvailable(
- "QtQuick", 2, 15, "AnimatedImage",
- QCoreApplication::translate("QQuickAnimatedImage",
- "Qt was built without support for QMovie"));
-#endif
}
static void initResources()
diff --git a/src/quick/items/qquickitemsmodule_p.h b/src/quick/items/qquickitemsmodule_p.h
index 6ceb0d56e6..28dff65dff 100644
--- a/src/quick/items/qquickitemsmodule_p.h
+++ b/src/quick/items/qquickitemsmodule_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <private/qtquickglobal_p.h>
#include <QtGui/qevent.h>
#include <qqml.h>
@@ -71,6 +72,17 @@ struct QPointingDeviceUniqueIdForeign
QML_UNCREATABLE("PointingDeviceUniqueId is only available via read-only properties.")
};
+#if !QT_CONFIG(quick_animatedimage)
+struct QQuickAnimatedImageNotAvailable
+{
+ Q_GADGET
+ QML_UNAVAILABLE
+ QML_NAMED_ELEMENT(AnimatedImage)
+ QML_ADDED_IN_VERSION(2, 0)
+ QML_UNCREATABLE("Qt was built without support for QMovie.")
+};
+#endif
+
QT_END_NAMESPACE
#endif // QQUICKITEMSMODULE_P_H
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 7fb392233e..3e3a2c262b 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -2419,7 +2419,7 @@ void QQuickItemView::destroyingItem(QObject *object)
Q_D(QQuickItemView);
QQuickItem* item = qmlobject_cast<QQuickItem*>(object);
if (item) {
- item->setParentItem(nullptr);
+ QQuickItemPrivate::get(item)->setCulled(true);
d->unrequestedItems.remove(item);
}
}
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index badd2efe29..b91e705ad0 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -141,6 +141,8 @@ public:
QQuickItemViewAttached *getAttachedObject(const QObject *object) const override;
+ void fixupHeader();
+ void fixupHeaderCompleted();
QQuickListView::Orientation orient;
qreal visiblePos;
qreal averageSize;
@@ -169,6 +171,12 @@ public:
QString nextSection;
qreal overshootDist;
+
+ qreal desiredViewportPosition;
+ qreal fixupHeaderPosition;
+ bool headerNeedsSeparateFixup : 1;
+ bool desiredHeaderVisible : 1;
+
bool correctFlick : 1;
bool inFlickCorrection : 1;
@@ -182,7 +190,9 @@ public:
, highlightPosAnimator(nullptr), highlightWidthAnimator(nullptr), highlightHeightAnimator(nullptr)
, highlightMoveVelocity(400), highlightResizeVelocity(400), highlightResizeDuration(-1)
, sectionCriteria(nullptr), currentSectionItem(nullptr), nextSectionItem(nullptr)
- , overshootDist(0.0), correctFlick(false), inFlickCorrection(false)
+ , overshootDist(0.0), desiredViewportPosition(0.0), fixupHeaderPosition(0.0)
+ , headerNeedsSeparateFixup(false), desiredHeaderVisible(false)
+ , correctFlick(false), inFlickCorrection(false)
{
highlightMoveDuration = -1; //override default value set in base class
}
@@ -1402,6 +1412,31 @@ void QQuickListViewPrivate::updateFooter()
emit q->footerItemChanged();
}
+void QQuickListViewPrivate::fixupHeaderCompleted()
+{
+ headerNeedsSeparateFixup = false;
+ QObjectPrivate::disconnect(&timeline, &QQuickTimeLine::updated, this, &QQuickListViewPrivate::fixupHeader);
+}
+
+void QQuickListViewPrivate::fixupHeader()
+{
+ FxListItemSG *listItem = static_cast<FxListItemSG*>(header);
+ const bool fixingUp = (orient == QQuickListView::Vertical ? vData : hData).fixingUp;
+ if (fixingUp && headerPositioning == QQuickListView::PullBackHeader && visibleItems.count()) {
+ int fixupDura = timeline.duration();
+ if (fixupDura < 0)
+ fixupDura = fixupDuration/2;
+ const int t = timeline.time();
+
+ const qreal progress = qreal(t)/fixupDura;
+ const qreal ultimateHeaderPosition = desiredHeaderVisible ? desiredViewportPosition : desiredViewportPosition - headerSize();
+ const qreal headerPosition = fixupHeaderPosition * (1 - progress) + ultimateHeaderPosition * progress;
+ const qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
+ const qreal clampedPos = qBound(originPosition() - headerSize(), headerPosition, lastPosition() - size());
+ listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos));
+ }
+}
+
void QQuickListViewPrivate::updateHeader()
{
Q_Q(QQuickListView);
@@ -1419,9 +1454,14 @@ void QQuickListViewPrivate::updateHeader()
if (headerPositioning == QQuickListView::OverlayHeader) {
listItem->setPosition(isContentFlowReversed() ? -position() - size() : position());
} else if (visibleItems.count()) {
+ const bool fixingUp = (orient == QQuickListView::Vertical ? vData : hData).fixingUp;
if (headerPositioning == QQuickListView::PullBackHeader) {
- qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
- qreal clampedPos = qBound(originPosition() - headerSize(), listItem->position(), lastPosition() - headerSize() - size());
+ qreal headerPosition = listItem->position();
+ const qreal viewPos = isContentFlowReversed() ? -position() - size() : position();
+ // Make sure the header is not shown if we absolutely do not have any plans to show it
+ if (fixingUp && !headerNeedsSeparateFixup)
+ headerPosition = viewPos - headerSize();
+ qreal clampedPos = qBound(originPosition() - headerSize(), headerPosition, lastPosition() - size());
listItem->setPosition(qBound(viewPos - headerSize(), clampedPos, viewPos));
} else {
qreal startPos = originPosition();
@@ -1539,13 +1579,46 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
bias = -bias;
tempPosition -= bias;
}
- FxViewItem *topItem = snapItemAt(tempPosition+highlightRangeStart);
+
+ qreal snapOffset = 0;
+ qreal overlayHeaderOffset = 0;
+ bool isHeaderWithinBounds = false;
+ if (header) {
+ qreal visiblePartOfHeader = header->position() + header->size() - tempPosition;
+ isHeaderWithinBounds = visiblePartOfHeader > 0;
+ switch (headerPositioning) {
+ case QQuickListView::OverlayHeader:
+ snapOffset = header->size();
+ overlayHeaderOffset = header->size();
+ break;
+ case QQuickListView::InlineHeader:
+ if (isHeaderWithinBounds && tempPosition < originPosition())
+ // For the inline header, we want to snap to the first item
+ // if we're more than halfway down the inline header.
+ // So if we look for an item halfway down of the header
+ snapOffset = header->size() / 2;
+ break;
+ case QQuickListView::PullBackHeader:
+ desiredHeaderVisible = visiblePartOfHeader > header->size()/2;
+ if (qFuzzyCompare(header->position(), tempPosition)) {
+ // header was pulled down; make sure it remains visible and snap items to bottom of header
+ snapOffset = header->size();
+ } else if (desiredHeaderVisible) {
+ // More than 50% of the header is shown. Show it fully.
+ // Scroll the view so the next item snaps to the header.
+ snapOffset = header->size();
+ overlayHeaderOffset = header->size();
+ }
+ break;
+ }
+ }
+ FxViewItem *topItem = snapItemAt(tempPosition + snapOffset + highlightRangeStart);
if (strictHighlightRange && currentItem && (!topItem || (topItem->index != currentIndex && fixupMode == Immediate))) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
topItem = currentItem;
}
- FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
+ FxViewItem *bottomItem = snapItemAt(tempPosition + snapOffset + highlightRangeEnd);
if (strictHighlightRange && currentItem && (!bottomItem || (bottomItem->index != currentIndex && fixupMode == Immediate))) {
// StrictlyEnforceRange always keeps an item in range
updateHighlight();
@@ -1553,27 +1626,92 @@ void QQuickListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExte
}
qreal pos;
bool isInBounds = -position() > maxExtent && -position() <= minExtent;
- if (topItem && (isInBounds || strictHighlightRange)) {
- if (topItem->index == 0 && header && tempPosition+highlightRangeStart < header->position()+header->size()/2 && !strictHighlightRange) {
- pos = isContentFlowReversed() ? - header->position() + highlightRangeStart - size() : header->position() - highlightRangeStart;
+
+ if (header && !topItem && isInBounds) {
+ // We are trying to pull back further than needed
+ switch (headerPositioning) {
+ case QQuickListView::OverlayHeader:
+ pos = startPosition() - overlayHeaderOffset;
+ break;
+ case QQuickListView::InlineHeader:
+ pos = isContentFlowReversed() ? header->size() - size() : header->position();
+ break;
+ case QQuickListView::PullBackHeader:
+ pos = isContentFlowReversed() ? -size() : startPosition();
+ break;
+ }
+ } else if (topItem && (isInBounds || strictHighlightRange)) {
+ if (topItem->index == 0 && header && !hasStickyHeader() && tempPosition+highlightRangeStart < header->position()+header->size()/2 && !strictHighlightRange) {
+ pos = isContentFlowReversed() ? -header->position() + highlightRangeStart - size() : (header->position() - highlightRangeStart + header->size());
} else {
- if (isContentFlowReversed())
- pos = qMax(qMin(-static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size(), -maxExtent), -minExtent);
- else
- pos = qMax(qMin(static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart, -maxExtent), -minExtent);
+ if (header && headerPositioning == QQuickListView::PullBackHeader) {
+ // We pulled down the header. If it isn't pulled all way down, we need to snap
+ // the header.
+ if (qFuzzyCompare(tempPosition, header->position())) {
+ // It is pulled all way down. Scroll-snap the content, but not the header.
+ if (isContentFlowReversed())
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size() + snapOffset;
+ else
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart - snapOffset;
+ } else {
+ // Header is not pulled all way down, make it completely visible or hide it.
+ // Depends on how much of the header is visible.
+ if (desiredHeaderVisible) {
+ // More than half of the header is visible - show it.
+ // Scroll so that the topItem is aligned to a fully visible header
+ if (isContentFlowReversed())
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size() + headerSize();
+ else
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart - headerSize();
+ } else {
+ // Less than half is visible - hide the header. Scroll so
+ // that the topItem is aligned to the top of the view
+ if (isContentFlowReversed())
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size();
+ else
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart;
+ }
+ }
+
+ headerNeedsSeparateFixup = isHeaderWithinBounds || desiredHeaderVisible;
+ if (headerNeedsSeparateFixup) {
+ // We need to animate the header independently if it starts visible or should end as visible,
+ // since the header should not necessarily follow the content.
+ // Store the desired viewport position.
+ // Also store the header position so we know where to animate the header from (fixupHeaderPosition).
+ // We deduce the desired header position from the desiredViewportPosition variable.
+ pos = qBound(-minExtent, pos, -maxExtent);
+ desiredViewportPosition = isContentFlowReversed() ? -pos - size() : pos;
+
+ FxListItemSG *headerItem = static_cast<FxListItemSG*>(header);
+ fixupHeaderPosition = headerItem->position();
+
+ // follow the same fixup timeline
+ QObjectPrivate::connect(&timeline, &QQuickTimeLine::updated, this, &QQuickListViewPrivate::fixupHeader);
+ QObjectPrivate::connect(&timeline, &QQuickTimeLine::completed, this, &QQuickListViewPrivate::fixupHeaderCompleted);
+ }
+ } else if (isContentFlowReversed()) {
+ pos = -static_cast<FxListItemSG*>(topItem)->itemPosition() + highlightRangeStart - size() + overlayHeaderOffset;
+ } else {
+ pos = static_cast<FxListItemSG*>(topItem)->itemPosition() - highlightRangeStart - overlayHeaderOffset;
+ }
}
} else if (bottomItem && isInBounds) {
if (isContentFlowReversed())
- pos = qMax(qMin(-static_cast<FxListItemSG*>(bottomItem)->itemPosition() + highlightRangeEnd - size(), -maxExtent), -minExtent);
+ pos = -static_cast<FxListItemSG*>(bottomItem)->itemPosition() + highlightRangeEnd - size() + overlayHeaderOffset;
else
- pos = qMax(qMin(static_cast<FxListItemSG*>(bottomItem)->itemPosition() - highlightRangeEnd, -maxExtent), -minExtent);
+ pos = static_cast<FxListItemSG*>(bottomItem)->itemPosition() - highlightRangeEnd - overlayHeaderOffset;
} else {
QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
return;
}
+ pos = qBound(-minExtent, pos, -maxExtent);
qreal dist = qAbs(data.move + pos);
- if (dist > 0) {
+ if (dist >= 0) {
+ // Even if dist == 0 we still start the timeline, because we use the same timeline for
+ // moving the header. And we might need to move the header while the content does not
+ // need moving
timeline.reset(data.move);
if (fixupMode != Immediate) {
timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index 8722a45373..1fb71272b1 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -56,7 +56,7 @@ static const QQuickItemPrivate::ChangeTypes watchedChanges
QQuickLoaderPrivate::QQuickLoaderPrivate()
: item(nullptr), object(nullptr), itemContext(nullptr), incubator(nullptr), updatingSize(false),
- active(true), loadingFromSource(false), asynchronous(false)
+ active(true), loadingFromSource(false), asynchronous(false), status(computeStatus())
{
}
@@ -379,7 +379,7 @@ void QQuickLoader::setActive(bool newVal)
d->object = nullptr;
emit itemChanged();
}
- emit statusChanged();
+ d->updateStatus();
}
emit activeChanged();
}
@@ -432,7 +432,7 @@ void QQuickLoader::loadFromSource()
Q_D(QQuickLoader);
if (d->source.isEmpty()) {
emit sourceChanged();
- emit statusChanged();
+ d->updateStatus();
emit progressChanged();
emit itemChanged();
return;
@@ -503,7 +503,7 @@ void QQuickLoader::loadFromSourceComponent()
Q_D(QQuickLoader);
if (!d->component) {
emit sourceComponentChanged();
- emit statusChanged();
+ d->updateStatus();
emit progressChanged();
emit itemChanged();
return;
@@ -619,7 +619,7 @@ void QQuickLoaderPrivate::load()
q, SLOT(_q_sourceLoaded()));
QObject::connect(component, SIGNAL(progressChanged(qreal)),
q, SIGNAL(progressChanged()));
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
if (loadingFromSource)
emit q->sourceChanged();
@@ -707,7 +707,7 @@ void QQuickLoaderPrivate::incubatorStateChanged(QQmlIncubator::Status status)
emit q->sourceChanged();
else
emit q->sourceComponentChanged();
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
if (status == QQmlIncubator::Ready)
emit q->loaded();
@@ -724,7 +724,7 @@ void QQuickLoaderPrivate::_q_sourceLoaded()
emit q->sourceChanged();
else
emit q->sourceComponentChanged();
- emit q->statusChanged();
+ updateStatus();
emit q->progressChanged();
emit q->itemChanged(); //Like clearing source, emit itemChanged even if previous item was also null
disposeInitialPropertyValues(); // cleanup
@@ -742,7 +742,7 @@ void QQuickLoaderPrivate::_q_sourceLoaded()
component->create(*incubator, itemContext);
if (incubator && incubator->status() == QQmlIncubator::Loading)
- emit q->statusChanged();
+ updateStatus();
}
/*!
@@ -789,37 +789,7 @@ QQuickLoader::Status QQuickLoader::status() const
{
Q_D(const QQuickLoader);
- if (!d->active)
- return Null;
-
- if (d->component) {
- switch (d->component->status()) {
- case QQmlComponent::Loading:
- return Loading;
- case QQmlComponent::Error:
- return Error;
- case QQmlComponent::Null:
- return Null;
- default:
- break;
- }
- }
-
- if (d->incubator) {
- switch (d->incubator->status()) {
- case QQmlIncubator::Loading:
- return Loading;
- case QQmlIncubator::Error:
- return Error;
- default:
- break;
- }
- }
-
- if (d->object)
- return Ready;
-
- return d->source.isEmpty() ? Null : Error;
+ return static_cast<Status>(d->status);
}
void QQuickLoader::componentComplete()
@@ -1020,6 +990,51 @@ QV4::ReturnedValue QQuickLoaderPrivate::extractInitialPropertyValues(QQmlV4Funct
return valuemap->asReturnedValue();
}
+QQuickLoader::Status QQuickLoaderPrivate::computeStatus() const
+{
+ if (!active)
+ return QQuickLoader::Status::Null;
+
+ if (component) {
+ switch (component->status()) {
+ case QQmlComponent::Loading:
+ return QQuickLoader::Status::Loading;
+ case QQmlComponent::Error:
+ return QQuickLoader::Status::Error;
+ case QQmlComponent::Null:
+ return QQuickLoader::Status::Null;
+ default:
+ break;
+ }
+ }
+
+ if (incubator) {
+ switch (incubator->status()) {
+ case QQmlIncubator::Loading:
+ return QQuickLoader::Status::Loading;
+ case QQmlIncubator::Error:
+ return QQuickLoader::Status::Error;
+ default:
+ break;
+ }
+ }
+
+ if (object)
+ return QQuickLoader::Status::Ready;
+
+ return source.isEmpty() ? QQuickLoader::Status::Null : QQuickLoader::Status::Error;
+}
+
+void QQuickLoaderPrivate::updateStatus()
+{
+ Q_Q(QQuickLoader);
+ auto newStatus = computeStatus();
+ if (status != newStatus) {
+ status = newStatus;
+ emit q->statusChanged();
+ }
+}
+
#include <moc_qquickloader_p.cpp>
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index 349b5c6c06..39d50280c5 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -96,6 +96,8 @@ public:
void disposeInitialPropertyValues();
static QUrl resolveSourceUrl(QQmlV4Function *args);
QV4::ReturnedValue extractInitialPropertyValues(QQmlV4Function *args, QObject *loader, bool *error);
+ QQuickLoader::Status computeStatus() const;
+ void updateStatus();
qreal getImplicitWidth() const override;
qreal getImplicitHeight() const override;
@@ -112,6 +114,11 @@ public:
bool active : 1;
bool loadingFromSource : 1;
bool asynchronous : 1;
+ // We need to use char instead of QQuickLoader::Status
+ // as otherwise the size of the class would increase
+ // on 32-bit systems, as sizeof(Status) == sizeof(int)
+ // and sizeof(int) > remaining padding on 32 bit
+ char status;
void _q_sourceLoaded();
void _q_updateSize(bool loaderGeometryChanged = true);
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 9a371207ce..3a807d3c66 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -88,20 +88,18 @@ void QQuickTouchPoint::setPointId(int id)
These properties hold the current position of the touch point.
*/
-void QQuickTouchPoint::setX(qreal x)
+void QQuickTouchPoint::setPosition(QPointF p)
{
- if (_x == x)
+ bool xch = (_x != p.x());
+ bool ych = (_y != p.y());
+ if (!xch && !ych)
return;
- _x = x;
- emit xChanged();
-}
-
-void QQuickTouchPoint::setY(qreal y)
-{
- if (_y == y)
- return;
- _y = y;
- emit yChanged();
+ _x = p.x();
+ _y = p.y();
+ if (xch)
+ emit xChanged();
+ if (ych)
+ emit yChanged();
}
/*!
@@ -798,8 +796,7 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QT
//TODO: if !qmlDefined, could bypass setters.
// also, should only emit signals after all values have been set
dtp->setUniqueId(p->uniqueId());
- dtp->setX(p->pos().x());
- dtp->setY(p->pos().y());
+ dtp->setPosition(p->pos());
dtp->setEllipseDiameters(p->ellipseDiameters());
dtp->setPressure(p->pressure());
dtp->setRotation(p->rotation());
@@ -817,8 +814,7 @@ void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QM
{
dtp->setPreviousX(dtp->x());
dtp->setPreviousY(dtp->y());
- dtp->setX(e->localPos().x());
- dtp->setY(e->localPos().y());
+ dtp->setPosition(e->localPos());
if (e->type() == QEvent::MouseButtonPress) {
dtp->setStartX(e->localPos().x());
dtp->setStartY(e->localPos().y());
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index 363e62593b..e34a3faad6 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -97,10 +97,8 @@ public:
void setUniqueId(const QPointingDeviceUniqueId &id);
qreal x() const { return _x; }
- void setX(qreal x);
-
qreal y() const { return _y; }
- void setY(qreal y);
+ void setPosition(QPointF pos);
QSizeF ellipseDiameters() const { return _ellipseDiameters; }
void setEllipseDiameters(const QSizeF &d);
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index f9f3e5cfa3..b298ed74da 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -161,10 +161,6 @@ public:
\l sourceItem while still handling input. For this, you can use
the \l hideSource property.
- \note If \l sourceItem is a \l Rectangle with border, by default half the
- border width falls outside the texture. To get the whole border, you can
- extend the \l sourceRect.
-
\note The ShaderEffectSource relies on FBO multisampling support
to antialias edges. If the underlying hardware does not support this,
which is the case for most embedded graphics chips, edges rendered
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index d76055c831..5ad33389de 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -330,6 +330,18 @@ inline int spriteCount(QQmlListProperty<QQuickSprite> *p)
return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->count();
}
+inline void spriteReplace(QQmlListProperty<QQuickSprite> *p, int idx, QQuickSprite *s)
+{
+ reinterpret_cast<QList<QQuickSprite *> *>(p->data)->replace(idx, s);
+ p->object->metaObject()->invokeMethod(p->object, "createEngine");
+}
+
+inline void spriteRemoveLast(QQmlListProperty<QQuickSprite> *p)
+{
+ reinterpret_cast<QList<QQuickSprite *> *>(p->data)->removeLast();
+ p->object->metaObject()->invokeMethod(p->object, "createEngine");
+}
+
QT_END_NAMESPACE
#endif // QQUICKSPRITEENGINE_P_H
diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp
index eb4b5335e7..c29938a1bb 100644
--- a/src/quick/items/qquickspritesequence.cpp
+++ b/src/quick/items/qquickspritesequence.cpp
@@ -162,7 +162,9 @@ void QQuickSpriteSequence::setInterpolate(bool arg)
QQmlListProperty<QQuickSprite> QQuickSpriteSequence::sprites()
{
Q_D(QQuickSpriteSequence);
- return QQmlListProperty<QQuickSprite>(this, &d->m_sprites, spriteAppend, spriteCount, spriteAt, spriteClear);
+ return QQmlListProperty<QQuickSprite>(this, &d->m_sprites,
+ spriteAppend, spriteCount, spriteAt,
+ spriteClear, spriteReplace, spriteRemoveLast);
}
bool QQuickSpriteSequence::running() const
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 496aea73d1..56c5bedd4d 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -2352,14 +2352,11 @@ void QQuickTableViewPrivate::connectToModel()
QObjectPrivate::connect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
QObjectPrivate::connect(model, &QQmlInstanceModel::initItem, this, &QQuickTableViewPrivate::initItemCallback);
+ QObjectPrivate::connect(model, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
+ QObjectPrivate::connect(model, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- if (tableModel) {
- const auto tm = tableModel.data();
- QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
- QObjectPrivate::connect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- // Connect atYEndChanged to a function that fetches data if more is available
- QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
- }
+ // Connect atYEndChanged to a function that fetches data if more is available
+ QObjectPrivate::connect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
if (auto const aim = model->abstractItemModel()) {
// When the model exposes a QAIM, we connect to it directly. This means that if the current model is
@@ -2387,13 +2384,10 @@ void QQuickTableViewPrivate::disconnectFromModel()
QObjectPrivate::disconnect(model, &QQmlInstanceModel::createdItem, this, &QQuickTableViewPrivate::itemCreatedCallback);
QObjectPrivate::disconnect(model, &QQmlInstanceModel::initItem, this, &QQuickTableViewPrivate::initItemCallback);
+ QObjectPrivate::disconnect(model, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
+ QObjectPrivate::disconnect(model, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- if (tableModel) {
- const auto tm = tableModel.data();
- QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemPooled, this, &QQuickTableViewPrivate::itemPooledCallback);
- QObjectPrivate::disconnect(tm, &QQmlTableInstanceModel::itemReused, this, &QQuickTableViewPrivate::itemReusedCallback);
- QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
- }
+ QObjectPrivate::disconnect(q, &QQuickTableView::atYEndChanged, this, &QQuickTableViewPrivate::fetchMoreData);
if (auto const aim = model->abstractItemModel()) {
disconnect(aim, &QAbstractItemModel::rowsMoved, this, &QQuickTableViewPrivate::rowsMovedCallback);
diff --git a/src/quick/items/qquicktableview_p_p.h b/src/quick/items/qquicktableview_p_p.h
index 03fe019916..a3cc39419f 100644
--- a/src/quick/items/qquicktableview_p_p.h
+++ b/src/quick/items/qquicktableview_p_p.h
@@ -91,7 +91,7 @@ private:
Q_DECLARE_PRIVATE(QQuickTableSectionSizeProvider)
};
-class Q_QML_AUTOTEST_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickTableViewPrivate : public QQuickFlickablePrivate
{
Q_DECLARE_PUBLIC(QQuickTableView)
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index f89e7d970f..816b48b190 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -40,6 +40,9 @@
#include "qquicktext_p.h"
#include "qquicktext_p_p.h"
+#include <private/qqmldebugserviceinterfaces_p.h>
+#include <private/qqmldebugconnector_p.h>
+
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qsgadaptationlayer_p.h>
@@ -1146,6 +1149,10 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
elideLayout->setFont(layout.font());
elideLayout->setTextOption(layout.textOption());
+ if (QQmlDebugTranslationService *service
+ = QQmlDebugConnector::service<QQmlDebugTranslationService>()) {
+ elideText = service->foundElidedText(q, layoutText, elideText);
+ }
elideLayout->setText(elideText);
elideLayout->beginLayout();
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 491334f439..5832242961 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -93,6 +93,7 @@ Q_LOGGING_CATEGORY(DBG_TOUCH, "qt.quick.touch")
Q_LOGGING_CATEGORY(DBG_TOUCH_TARGET, "qt.quick.touch.target")
Q_LOGGING_CATEGORY(DBG_MOUSE, "qt.quick.mouse")
Q_LOGGING_CATEGORY(DBG_MOUSE_TARGET, "qt.quick.mouse.target")
+Q_LOGGING_CATEGORY(lcTablet, "qt.quick.tablet")
Q_LOGGING_CATEGORY(lcWheelTarget, "qt.quick.wheel.target")
Q_LOGGING_CATEGORY(lcGestureTarget, "qt.quick.gesture.target")
Q_LOGGING_CATEGORY(DBG_HOVER_TRACE, "qt.quick.hover.trace")
@@ -547,7 +548,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfa
else
context->endNextFrame(renderer);
- if (renderer->hasCustomRenderModeWithContinuousUpdate()) {
+ if (renderer && renderer->hasCustomRenderModeWithContinuousUpdate()) {
// For the overdraw visualizer. This update is not urgent so avoid a
// direct update() call, this is only here to keep the overdraw
// visualization box rotating even when the scene is static.
@@ -682,10 +683,13 @@ void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state)
QQmlListProperty<QObject> QQuickWindowPrivate::data()
{
- return QQmlListProperty<QObject>(q_func(), nullptr, QQuickWindowPrivate::data_append,
- QQuickWindowPrivate::data_count,
- QQuickWindowPrivate::data_at,
- QQuickWindowPrivate::data_clear);
+ return QQmlListProperty<QObject>(q_func(), nullptr,
+ QQuickWindowPrivate::data_append,
+ QQuickWindowPrivate::data_count,
+ QQuickWindowPrivate::data_at,
+ QQuickWindowPrivate::data_clear,
+ QQuickWindowPrivate::data_replace,
+ QQuickWindowPrivate::data_removeLast);
}
static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true)
@@ -2119,6 +2123,17 @@ void QQuickWindow::wheelEvent(QWheelEvent *event)
}
#endif // wheelevent
+#if QT_CONFIG(tabletevent)
+/*! \reimp */
+void QQuickWindow::tabletEvent(QTabletEvent *event)
+{
+ Q_D(QQuickWindow);
+ qCDebug(lcTablet) << event;
+ // TODO Qt 6: make sure TabletEnterProximity and TabletLeaveProximity are delivered here
+ d->deliverPointerEvent(d->pointerEventInstance(event));
+}
+#endif // tabletevent
+
bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
{
qCDebug(DBG_TOUCH) << event;
@@ -2397,8 +2412,12 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevic
#endif
ev = new QQuickPointerTouchEvent(q, device);
break;
+ case QQuickPointerDevice::Stylus:
+ case QQuickPointerDevice::Airbrush:
+ case QQuickPointerDevice::Puck:
+ ev = new QQuickPointerTabletEvent(q, device);
+ break;
default:
- // TODO tablet event types
break;
}
pointerEventInstances << ev;
@@ -2429,7 +2448,15 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) con
case QEvent::TouchCancel:
dev = QQuickPointerDevice::touchDevice(static_cast<QTouchEvent *>(event)->device());
break;
- // TODO tablet event types
+#if QT_CONFIG(tabletevent)
+ case QEvent::TabletPress:
+ case QEvent::TabletMove:
+ case QEvent::TabletRelease:
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ dev = QQuickPointerDevice::tabletDevice(static_cast<QTabletEvent *>(event));
+ break;
+#endif
#if QT_CONFIG(gestures)
case QEvent::NativeGesture:
dev = QQuickPointerDevice::touchDevice(static_cast<QNativeGestureEvent *>(event)->device());
@@ -2464,6 +2491,11 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
deliverTouchEvent(event->asPointerTouchEvent());
} else {
deliverSinglePointEventUntilAccepted(event);
+ // If any handler got interested in the tablet event, we don't want to receive a synth-mouse event from QtGui
+ // TODO Qt 6: QTabletEvent will be accepted by default, like other events
+ if (event->asPointerTabletEvent() &&
+ (!event->point(0)->passiveGrabbers().isEmpty() || event->point(0)->exclusiveGrabber()))
+ event->setAccepted(true);
}
event->reset(nullptr);
@@ -3257,6 +3289,20 @@ void QQuickWindowPrivate::data_clear(QQmlListProperty<QObject> *property)
itemProperty.clear(&itemProperty);
}
+void QQuickWindowPrivate::data_replace(QQmlListProperty<QObject> *property, int i, QObject *o)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ itemProperty.replace(&itemProperty, i, o);
+}
+
+void QQuickWindowPrivate::data_removeLast(QQmlListProperty<QObject> *property)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ itemProperty.removeLast(&itemProperty);
+}
+
bool QQuickWindowPrivate::isRenderable() const
{
Q_Q(const QQuickWindow);
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index d22bba4512..097627374c 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -252,6 +252,9 @@ protected:
#if QT_CONFIG(wheelevent)
void wheelEvent(QWheelEvent *) override;
#endif
+#if QT_CONFIG(tabletevent)
+ void tabletEvent(QTabletEvent *) override;
+#endif
private Q_SLOTS:
void maybeUpdate();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 6e6dc7a400..86bdaf6396 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -299,6 +299,8 @@ public:
static int data_count(QQmlListProperty<QObject> *);
static QObject *data_at(QQmlListProperty<QObject> *, int);
static void data_clear(QQmlListProperty<QObject> *);
+ static void data_replace(QQmlListProperty<QObject> *, int, QObject *);
+ static void data_removeLast(QQmlListProperty<QObject> *);
static void contextCreationFailureMessage(const QSurfaceFormat &format,
QString *translatedMessage,