aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickpathview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items/qquickpathview.cpp')
-rw-r--r--src/quick/items/qquickpathview.cpp109
1 files changed, 62 insertions, 47 deletions
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index 6de81470c4..ce61543f42 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -10,7 +10,7 @@
#include <private/qqmlglobal_p.h>
#include <private/qqmlopenmetaobject_p.h>
#include <private/qqmlchangeset_p.h>
-#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformtheme.h>
#include <QtQml/qqmlinfo.h>
@@ -26,10 +26,11 @@
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcItemViewDelegateLifecycle)
+#if !QT_CONFIG(quick_itemview)
+Q_LOGGING_CATEGORY(lcItemViewDelegateLifecycle, "qt.quick.itemview.lifecycle")
+#endif
Q_LOGGING_CATEGORY(lcPathView, "qt.quick.pathview")
-static const qreal MinimumFlickVelocity = 75;
-
static QQmlOpenMetaObjectType *qPathViewAttachedType = nullptr;
QQuickPathViewAttached::QQuickPathViewAttached(QObject *parent)
@@ -64,9 +65,9 @@ QQuickPathViewPrivate::QQuickPathViewPrivate()
, moving(false), flicking(false), dragging(false), inRequest(false), delegateValidated(false)
, inRefill(false)
, dragMargin(0), deceleration(100)
- , maximumFlickVelocity(QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::FlickMaximumVelocity).toReal())
+ , maximumFlickVelocity(QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::FlickMaximumVelocity).toReal())
, moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0)
- , pathItems(-1), requestedIndex(-1), cacheSize(0), requestedZ(0)
+ , pathItems(-1), requestedIndex(-1), cacheSize(0), requestedCacheSize(0), requestedZ(0)
, moveReason(Other), movementDirection(QQuickPathView::Shortest), moveDirection(QQuickPathView::Shortest)
, attType(nullptr), highlightComponent(nullptr), highlightItem(nullptr)
, moveHighlight(this, &QQuickPathViewPrivate::setHighlightPosition)
@@ -75,6 +76,7 @@ QQuickPathViewPrivate::QQuickPathViewPrivate()
, highlightRangeMode(QQuickPathView::StrictlyEnforceRange)
, highlightMoveDuration(300), modelCount(0), snapMode(QQuickPathView::NoSnap)
{
+ setSizePolicy(QLayoutPolicy::Preferred, QLayoutPolicy::Preferred);
}
void QQuickPathViewPrivate::init()
@@ -231,6 +233,10 @@ void QQuickPathViewPrivate::clear()
void QQuickPathViewPrivate::updateMappedRange()
{
+ // Update the actual cache size to be at max
+ // the available non-visible items.
+ cacheSize = qMax(0, qMin(requestedCacheSize, modelCount - pathItems));
+
if (model && pathItems != -1 && pathItems < modelCount) {
mappedRange = qreal(modelCount)/pathItems;
mappedCache = qreal(cacheSize)/pathItems/2; // Half of cache at each end
@@ -265,9 +271,10 @@ qreal QQuickPathViewPrivate::positionOfIndex(qreal index) const
// returns true if position is between lower and upper, taking into
// account the circular space.
-bool QQuickPathViewPrivate::isInBound(qreal position, qreal lower, qreal upper) const
+bool QQuickPathViewPrivate::isInBound(qreal position, qreal lower,
+ qreal upper, bool emptyRangeCheck) const
{
- if (qFuzzyCompare(lower, upper))
+ if (emptyRangeCheck && qFuzzyCompare(lower, upper))
return true;
if (lower > upper) {
if (position > upper && position > lower)
@@ -530,6 +537,8 @@ QQuickPathView::~QQuickPathView()
/*!
\qmlattachedproperty PathView QtQuick::PathView::view
+ \readonly
+
This attached property holds the view that manages this delegate instance.
It is attached to each instance of the delegate.
@@ -537,6 +546,8 @@ QQuickPathView::~QQuickPathView()
/*!
\qmlattachedproperty bool QtQuick::PathView::onPath
+ \readonly
+
This attached property holds whether the item is currently on the path.
If a pathItemCount has been set, it is possible that some items may
@@ -557,6 +568,8 @@ QQuickPathView::~QQuickPathView()
/*!
\qmlattachedproperty bool QtQuick::PathView::isCurrentItem
+ \readonly
+
This attached property is true if this delegate is the current item; otherwise false.
It is attached to each instance of the delegate.
@@ -894,18 +907,16 @@ QQuickItem *QQuickPathView::highlightItem() const
Valid values for \c highlightRangeMode are:
- \list
- \li \e PathView.NoHighlightRange - no range is applied and the
- highlight will move freely within the view.
- \li \e PathView.ApplyRange - the view will attempt to maintain
- the highlight within the range, however the highlight can
- move outside of the range at the ends of the path or due to
- a mouse interaction.
- \li \e PathView.StrictlyEnforceRange - the highlight will never
- move outside of the range. This means that the current item
- will change if a keyboard or mouse action would cause the
- highlight to move outside of the range.
- \endlist
+ \value PathView.NoHighlightRange no range is applied: the highlight
+ will move freely within the view.
+ \value PathView.ApplyRange the view will attempt to maintain the highlight
+ within the range, however the highlight can move
+ outside of the range at the ends of the path or
+ due to a mouse interaction.
+ \value PathView.StrictlyEnforceRange the highlight will never move outside of the range.
+ This means that the current item will change if a
+ keyboard or mouse action would cause the highlight
+ to move outside of the range.
The default value is \e PathView.StrictlyEnforceRange.
@@ -1291,16 +1302,16 @@ void QQuickPathView::resetPathItemCount()
int QQuickPathView::cacheItemCount() const
{
Q_D(const QQuickPathView);
- return d->cacheSize;
+ return d->requestedCacheSize;
}
void QQuickPathView::setCacheItemCount(int i)
{
Q_D(QQuickPathView);
- if (i == d->cacheSize || i < 0)
+ if (i == d->requestedCacheSize || i < 0)
return;
- d->cacheSize = i;
+ d->requestedCacheSize = i;
d->updateMappedRange();
refill();
emit cacheItemCountChanged();
@@ -1312,13 +1323,11 @@ void QQuickPathView::setCacheItemCount(int i)
This property determines how the items will settle following a drag or flick.
The possible values are:
- \list
- \li PathView.NoSnap (default) - the items stop anywhere along the path.
- \li PathView.SnapToItem - the items settle with an item aligned with the \l preferredHighlightBegin.
- \li PathView.SnapOneItem - the items settle no more than one item away from the item nearest
+ \value PathView.NoSnap (default) the items stop anywhere along the path.
+ \value PathView.SnapToItem the items settle with an item aligned with the \l preferredHighlightBegin.
+ \value PathView.SnapOneItem the items settle no more than one item away from the item nearest
\l preferredHighlightBegin at the time the press is released. This mode is particularly
useful for moving one page at a time.
- \endlist
\c snapMode does not affect the \l currentIndex. To update the
\l currentIndex as the view is moved, set \l highlightRangeMode
@@ -1348,12 +1357,10 @@ void QQuickPathView::setSnapMode(SnapMode mode)
This property determines the direction in which items move when setting the current index.
The possible values are:
- \list
- \li PathView.Shortest (default) - the items move in the direction that requires the least
- movement, which could be either \c Negative or \c Positive.
- \li PathView.Negative - the items move backwards towards their destination.
- \li PathView.Positive - the items move forwards towards their destination.
- \endlist
+ \value PathView.Shortest (default) the items move in the direction that requires the least
+ movement, which could be either \c Negative or \c Positive.
+ \value PathView.Negative the items move backwards towards their destination.
+ \value PathView.Positive the items move forwards towards their destination.
For example, suppose that there are 5 items in the model, and \l currentIndex is \c 0.
If currentIndex is set to \c 2,
@@ -1389,15 +1396,13 @@ void QQuickPathView::setMovementDirection(QQuickPathView::MovementDirection dir)
Positions the view such that the \a index is at the position specified by
\a mode:
- \list
- \li PathView.Beginning - position item at the beginning of the path.
- \li PathView.Center - position item in the center of the path.
- \li PathView.End - position item at the end of the path.
- \li PathView.Contain - ensure the item is positioned on the path.
- \li PathView.SnapPosition - position the item at \l preferredHighlightBegin. This mode
- is only valid if \l highlightRangeMode is StrictlyEnforceRange or snapping is enabled
- via \l snapMode.
- \endlist
+ \value PathView.Beginning position item at the beginning of the path.
+ \value PathView.Center position item in the center of the path.
+ \value PathView.End position item at the end of the path.
+ \value PathView.Contain ensure the item is positioned on the path.
+ \value PathView.SnapPosition position the item at \l preferredHighlightBegin. This mode
+ is only valid if \l highlightRangeMode is StrictlyEnforceRange or snapping is enabled
+ via \l snapMode.
\b Note: methods should only be called after the Component has completed. To position
the view at startup, this method should be called by Component.onCompleted. For
@@ -1510,7 +1515,7 @@ QQuickItem *QQuickPathView::itemAt(qreal x, qreal y) const
}
/*!
- \qmlmethod Item QtQuick::QQuickPathView::itemAtIndex(int index)
+ \qmlmethod Item QtQuick::PathView::itemAtIndex(int index)
Returns the item for \a index. If there is no item for that index, for example
because it has not been created yet, or because it has been panned out of
@@ -1536,6 +1541,14 @@ QQuickItem *QQuickPathView::itemAtIndex(int index) const
return nullptr;
}
+/*!
+ \internal
+
+ Returns a point in the path, that has the closest distance from \a point.
+ A value in the range 0-1 will be written to \a nearPercent if given, which
+ represents where on the path the \a point is closest to. \c 0 means the very
+ beginning of the path, and \c 1 means the very end.
+*/
QPointF QQuickPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) const
{
const auto pathLength = path->path().length();
@@ -1751,7 +1764,7 @@ void QQuickPathViewPrivate::handleMouseReleaseEvent(QMouseEvent *event)
qreal count = pathItems == -1 ? modelCount : qMin(pathItems, modelCount);
const auto averageItemLength = path->path().length() / count;
qreal pixelVelocity = averageItemLength * velocity;
- if (qAbs(pixelVelocity) > MinimumFlickVelocity) {
+ if (qAbs(pixelVelocity) > _q_MinimumFlickVelocity) {
if (qAbs(pixelVelocity) > maximumFlickVelocity || snapMode == QQuickPathView::SnapOneItem) {
// limit velocity
qreal maxVel = velocity < 0 ? -maximumFlickVelocity : maximumFlickVelocity;
@@ -1855,7 +1868,8 @@ bool QQuickPathView::childMouseEventFilter(QQuickItem *i, QEvent *e)
const bool filtered = stealThisEvent || grabberDisabled;
if (filtered)
- pe->setAccepted(false);
+ pe->setAccepted(stealThisEvent && grabber == this && grabber->isEnabled());
+
return filtered;
} else if (d->timer.isValid()) {
d->timer.invalidate();
@@ -2011,6 +2025,7 @@ void QQuickPathView::refill()
startPos = d->highlightRangeStart;
// With no items, then "end" is just off the top so we populate via append
endIdx = (qRound(d->modelCount - d->offset) - 1) % d->modelCount;
+ endIdx = qMax(-1, endIdx); // endIdx shouldn't be smaller than -1
endPos = d->positionOfIndex(endIdx);
}
//Append
@@ -2018,8 +2033,8 @@ void QQuickPathView::refill()
if (idx >= d->modelCount)
idx = 0;
qreal nextPos = d->positionOfIndex(idx);
- while ((d->isInBound(nextPos, endPos, 1 + d->mappedCache) || !d->items.size())
- && d->items.size() < count+d->cacheSize) {
+ while ((d->isInBound(nextPos, endPos, 1 + d->mappedCache, false) || !d->items.size())
+ && d->items.size() < count + d->cacheSize) {
qCDebug(lcItemViewDelegateLifecycle) << "append" << idx << "@" << nextPos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.size();
QQuickItem *item = d->getItem(idx, idx+1, nextPos >= 1);
if (!item) {