aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp19
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp32
-rw-r--r--src/quick/items/qquickdrag_p.h2
-rw-r--r--src/quick/items/qquickevents.cpp25
-rw-r--r--src/quick/items/qquickflickable.cpp123
-rw-r--r--src/quick/items/qquickflickable_p.h11
-rw-r--r--src/quick/items/qquickflickable_p_p.h1
-rw-r--r--src/quick/items/qquickimage.cpp3
-rw-r--r--src/quick/items/qquickitem.cpp31
-rw-r--r--src/quick/items/qquickitem.h1
-rw-r--r--src/quick/items/qquickitemanimation.cpp2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp4
-rw-r--r--src/quick/items/qquickpainteditem_p.h2
-rw-r--r--src/quick/items/qquickpositioners.cpp100
-rw-r--r--src/quick/items/qquickpositioners_p.h35
-rw-r--r--src/quick/items/qquickpositioners_p_p.h41
-rw-r--r--src/quick/items/qquickrendercontrol.cpp3
-rw-r--r--src/quick/items/qquickshadereffect.cpp2
-rw-r--r--src/quick/items/qquickshadereffect_p.h2
-rw-r--r--src/quick/items/qquickstateoperations.cpp2
-rw-r--r--src/quick/items/qquicktextcontrol.cpp46
-rw-r--r--src/quick/items/qquickwindow.cpp36
22 files changed, 280 insertions, 243 deletions
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 1167f408f5..dab35f2a54 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -44,8 +44,10 @@
#include <private/qquickcontext2d_p.h>
#include <private/qquickcontext2dtexture_p.h>
#include <private/qsgadaptationlayer_p.h>
+#include <qsgtextureprovider.h>
#include <QtQuick/private/qquickpixmapcache_p.h>
#include <QtGui/QGuiApplication>
+#include <qsgtextureprovider.h>
#include <qqmlinfo.h>
#include <private/qqmlengine_p.h>
@@ -1102,14 +1104,17 @@ bool QQuickCanvasItem::isImageLoaded(const QUrl& url) const
QImage QQuickCanvasItem::toImage(const QRectF& rect) const
{
Q_D(const QQuickCanvasItem);
- if (d->context) {
- if (rect.isEmpty())
- return d->context->toImage(canvasWindow());
- else
- return d->context->toImage(rect);
- }
- return QImage();
+ if (!d->context)
+ return QImage();
+
+ const QRectF &rectSource = rect.isEmpty() ? canvasWindow() : rect;
+ const qreal dpr = window() ? window()->effectiveDevicePixelRatio() : qreal(1);
+ const QRectF rectScaled(rectSource.topLeft() * dpr, rectSource.size() * dpr);
+
+ QImage image = d->context->toImage(rectScaled);
+ image.setDevicePixelRatio(dpr);
+ return image;
}
static const char* mimeToType(const QString &mime)
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index b9b701313e..1a6f530bfa 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -42,13 +42,16 @@
#include "qquickcanvasitem_p.h"
#include <private/qquickcontext2dtexture_p.h>
#include <private/qquickitem_p.h>
+#if QT_CONFIG(quick_shadereffect)
#include <QtQuick/private/qquickshadereffectsource_p.h>
+#endif
#include <qsgrendererinterface.h>
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qquicksvgparser_p.h>
+#if QT_CONFIG(quick_path)
#include <private/qquickpath_p.h>
-
+#endif
#include <private/qquickimage_p_p.h>
#include <qqmlinfo.h>
@@ -126,8 +129,6 @@ QT_BEGIN_NAMESPACE
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
-#define DEGREES(t) ((t) * 180.0 / M_PI)
-
#define CHECK_CONTEXT(r) if (!r || !r->d()->context || !r->d()->context->bufferValid()) \
THROW_GENERIC_ERROR("Not a Context2D object");
@@ -567,9 +568,10 @@ struct QQuickJSContext2D : public QV4::Object
static void method_set_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
// should these two be on the proto?
+#if QT_CONFIG(quick_path)
static void method_get_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
static void method_set_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-
+#endif
static void method_get_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
static void method_set_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
static void method_get_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
@@ -925,9 +927,9 @@ struct QQuickJSContext2DImageData : public QV4::Object
static void method_get_height(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
static void method_get_data(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *engine) {
- static_cast<QQuickJSContext2DImageData::Data *>(that)->pixelData.mark(engine);
- QV4::Object::markObjects(that, engine);
+ static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack) {
+ static_cast<QQuickJSContext2DImageData::Data *>(that)->pixelData.mark(markStack);
+ QV4::Object::markObjects(that, markStack);
}
};
@@ -958,7 +960,7 @@ static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionE
*pixelData->d()->image = QImage(w, h, QImage::Format_ARGB32);
pixelData->d()->image->fill(0x00000000);
} else {
- Q_ASSERT(image.width() == qRound(w) && image.height() == qRound(h));
+ Q_ASSERT(image.width()== qRound(w * image.devicePixelRatio()) && image.height() == qRound(h * image.devicePixelRatio()));
*pixelData->d()->image = image.format() == QImage::Format_ARGB32 ? image : image.convertToFormat(QImage::Format_ARGB32);
}
@@ -1639,7 +1641,7 @@ void QQuickJSContext2DPrototype::method_createConicalGradient(const QV4::Builtin
if (callData->argc >= 3) {
qreal x = callData->args[0].toNumber();
qreal y = callData->args[1].toNumber();
- qreal angle = DEGREES(callData->args[2].toNumber());
+ qreal angle = qRadiansToDegrees(callData->args[2].toNumber());
if (!qt_is_finite(x) || !qt_is_finite(y)) {
THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createConicalGradient(): Incorrect arguments");
}
@@ -2032,6 +2034,7 @@ void QQuickJSContext2D::method_set_shadowOffsetY(const QV4::BuiltinFunction *, Q
RETURN_UNDEFINED();
}
+#if QT_CONFIG(quick_path)
void QQuickJSContext2D::method_get_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
@@ -2058,6 +2061,7 @@ void QQuickJSContext2D::method_set_path(const QV4::BuiltinFunction *, QV4::Scope
r->d()->context->m_v4path.set(scope.engine, value);
RETURN_UNDEFINED();
}
+#endif // QT_CONFIG(quick_path)
//rects
/*!
@@ -3364,7 +3368,7 @@ void QQuickContext2D::rotate(qreal angle)
return;
QTransform newTransform =state.matrix;
- newTransform.rotate(DEGREES(angle));
+ newTransform.rotate(qRadiansToDegrees(angle));
if (!newTransform.isInvertible()) {
state.invertibleCTM = false;
@@ -3373,7 +3377,7 @@ void QQuickContext2D::rotate(qreal angle)
state.matrix = newTransform;
buffer()->updateMatrix(state.matrix);
- m_path = QTransform().rotate(-DEGREES(angle)).map(m_path);
+ m_path = QTransform().rotate(-qRadiansToDegrees(angle)).map(m_path);
}
void QQuickContext2D::shear(qreal h, qreal v)
@@ -3770,8 +3774,8 @@ void QQuickContext2D::arc(qreal xc, qreal yc, qreal radius, qreal sar, qreal ear
antiClockWise = !antiClockWise;
//end hack
- float sa = DEGREES(sar);
- float ea = DEGREES(ear);
+ float sa = qRadiansToDegrees(sar);
+ float ea = qRadiansToDegrees(ear);
double span = 0;
@@ -4208,7 +4212,9 @@ QQuickContext2DEngineData::QQuickContext2DEngineData(QV4::ExecutionEngine *v4)
proto->defineAccessorProperty(QStringLiteral("fillStyle"), QQuickJSContext2D::method_get_fillStyle, QQuickJSContext2D::method_set_fillStyle);
proto->defineAccessorProperty(QStringLiteral("shadowColor"), QQuickJSContext2D::method_get_shadowColor, QQuickJSContext2D::method_set_shadowColor);
proto->defineAccessorProperty(QStringLiteral("textBaseline"), QQuickJSContext2D::method_get_textBaseline, QQuickJSContext2D::method_set_textBaseline);
+#if QT_CONFIG(quick_path)
proto->defineAccessorProperty(QStringLiteral("path"), QQuickJSContext2D::method_get_path, QQuickJSContext2D::method_set_path);
+#endif
proto->defineAccessorProperty(QStringLiteral("lineJoin"), QQuickJSContext2D::method_get_lineJoin, QQuickJSContext2D::method_set_lineJoin);
proto->defineAccessorProperty(QStringLiteral("lineWidth"), QQuickJSContext2D::method_get_lineWidth, QQuickJSContext2D::method_set_lineWidth);
proto->defineAccessorProperty(QStringLiteral("textAlign"), QQuickJSContext2D::method_get_textAlign, QQuickJSContext2D::method_set_textAlign);
diff --git a/src/quick/items/qquickdrag_p.h b/src/quick/items/qquickdrag_p.h
index 357f72b3e7..17e9d8c690 100644
--- a/src/quick/items/qquickdrag_p.h
+++ b/src/quick/items/qquickdrag_p.h
@@ -248,7 +248,7 @@ class QQuickDragAttached : public QObject
Q_PROPERTY(QObject *source READ source WRITE setSource NOTIFY sourceChanged RESET resetSource)
Q_PROPERTY(QObject *target READ target NOTIFY targetChanged)
Q_PROPERTY(QPointF hotSpot READ hotSpot WRITE setHotSpot NOTIFY hotSpotChanged)
- Q_PROPERTY(QUrl imageSource READ imageSource WRITE setImageSource NOTIFY imageSourceChanged REVISION 8)
+ Q_PROPERTY(QUrl imageSource READ imageSource WRITE setImageSource NOTIFY imageSourceChanged)
Q_PROPERTY(QStringList keys READ keys WRITE setKeys NOTIFY keysChanged)
Q_PROPERTY(QVariantMap mimeData READ mimeData WRITE setMimeData NOTIFY mimeDataChanged)
Q_PROPERTY(Qt::DropActions supportedActions READ supportedActions WRITE setSupportedActions NOTIFY supportedActionsChanged)
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 2671b9c9a2..19dd81b6fc 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -195,8 +195,8 @@ Item {
*/
/*!
- \qmlproperty int QtQuick::MouseEvent::x
- \qmlproperty int QtQuick::MouseEvent::y
+ \qmlproperty real QtQuick::MouseEvent::x
+ \qmlproperty real QtQuick::MouseEvent::y
These properties hold the coordinates of the position supplied by the mouse event.
*/
@@ -342,8 +342,8 @@ Item {
*/
/*!
- \qmlproperty int QtQuick::WheelEvent::x
- \qmlproperty int QtQuick::WheelEvent::y
+ \qmlproperty real QtQuick::WheelEvent::x
+ \qmlproperty real QtQuick::WheelEvent::y
These properties hold the coordinates of the position supplied by the wheel event.
*/
@@ -1225,9 +1225,24 @@ QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool i
auto p = m_touchPoints.at(i);
if (p->isAccepted())
continue;
+ // include points where item is the grabber
bool isGrabber = p->exclusiveGrabber() == item;
+ // include newly pressed points inside the bounds
bool isPressInside = p->state() == QQuickEventPoint::Pressed && item->contains(item->mapFromScene(p->scenePos()));
- if (!(isGrabber || isPressInside || isFiltering))
+
+ // filtering: (childMouseEventFilter) include points that are grabbed by children of the target item
+ bool grabberIsChild = false;
+ auto parent = p->grabberItem();
+ while (isFiltering && parent) {
+ if (parent == item) {
+ grabberIsChild = true;
+ break;
+ }
+ parent = parent->parentItem();
+ }
+ bool filterRelevant = isFiltering && grabberIsChild;
+
+ if (!(isGrabber || isPressInside || filterRelevant))
continue;
const QTouchEvent::TouchPoint *tp = touchPointById(p->pointId());
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 6306a48d48..40719c6324 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -255,6 +255,7 @@ QQuickFlickablePrivate::QQuickFlickablePrivate()
, flickBoost(1.0), fixupMode(Normal), vTime(0), visibleArea(0)
, flickableDirection(QQuickFlickable::AutoFlickDirection)
, boundsBehavior(QQuickFlickable::DragAndOvershootBounds)
+ , boundsMovement(QQuickFlickable::FollowBoundsBehavior)
, rebound(0)
{
}
@@ -643,8 +644,10 @@ is finished.
\section1 Limitations
- \note Due to an implementation detail, items placed inside a Flickable cannot anchor to it by
- \c id. Use \c parent instead.
+ \note Due to an implementation detail, items placed inside a Flickable
+ cannot anchor to the Flickable. Instead, use \l {Item::}{parent}, which
+ refers to the Flickable's \l contentItem. The size of the content item is
+ determined by \l contentWidth and \l contentHeight.
*/
/*!
@@ -1575,16 +1578,18 @@ void QQuickFlickablePrivate::replayDelayedPress()
void QQuickFlickablePrivate::setViewportX(qreal x)
{
Q_Q(QQuickFlickable);
- if (pixelAligned)
- x = -Round(-x);
-
- contentItem->setX(x);
- if (contentItem->x() != x)
- return; // reentered
+ qreal effectiveX = pixelAligned ? -Round(-x) : x;
const qreal maxX = q->maxXExtent();
const qreal minX = q->minXExtent();
+ if (boundsMovement == int(QQuickFlickable::StopAtBounds))
+ effectiveX = qBound(maxX, effectiveX, minX);
+
+ contentItem->setX(effectiveX);
+ if (contentItem->x() != effectiveX)
+ return; // reentered
+
qreal overshoot = 0.0;
if (x <= maxX)
overshoot = maxX - x;
@@ -1600,16 +1605,18 @@ void QQuickFlickablePrivate::setViewportX(qreal x)
void QQuickFlickablePrivate::setViewportY(qreal y)
{
Q_Q(QQuickFlickable);
- if (pixelAligned)
- y = -Round(-y);
-
- contentItem->setY(y);
- if (contentItem->y() != y)
- return; // reentered
+ qreal effectiveY = pixelAligned ? -Round(-y) : y;
const qreal maxY = q->maxYExtent();
const qreal minY = q->minYExtent();
+ if (boundsMovement == int(QQuickFlickable::StopAtBounds))
+ effectiveY = qBound(maxY, effectiveY, minY);
+
+ contentItem->setY(effectiveY);
+ if (contentItem->y() != effectiveY)
+ return; // reentered
+
qreal overshoot = 0.0;
if (y <= maxY)
overshoot = maxY - y;
@@ -1869,8 +1876,9 @@ QQmlListProperty<QQuickItem> QQuickFlickable::flickableChildren()
beyond the Flickable's boundaries, or overshoot the
Flickable's boundaries when flicked.
- This enables the feeling that the edges of the view are soft,
- rather than a hard physical boundary.
+ When the \l boundsMovement is \c Flickable.FollowBoundsBehavior, a value
+ other than \c Flickable.StopAtBounds will give a feeling that the edges of
+ the view are soft, rather than a hard physical boundary.
The \c boundsBehavior can be one of:
@@ -1886,7 +1894,7 @@ QQmlListProperty<QQuickItem> QQuickFlickable::flickableChildren()
boundary when flicked.
\endlist
- \sa horizontalOvershoot, verticalOvershoot
+ \sa horizontalOvershoot, verticalOvershoot, boundsMovement
*/
QQuickFlickable::BoundsBehavior QQuickFlickable::boundsBehavior() const
{
@@ -2303,7 +2311,8 @@ bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event)
bool receiverDisabled = receiver && !receiver->isEnabled();
bool stealThisEvent = d->stealMouse;
- if ((stealThisEvent || contains(localPos)) && (!receiver || !receiver->keepMouseGrab() || receiverDisabled)) {
+ bool receiverKeepsGrab = receiver && (receiver->keepMouseGrab() || receiver->keepTouchGrab());
+ if ((stealThisEvent || contains(localPos)) && (!receiver || !receiverKeepsGrab || receiverDisabled)) {
QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos));
mouseEvent->setAccepted(false);
@@ -2323,7 +2332,7 @@ bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event)
default:
break;
}
- if ((receiver && stealThisEvent && !receiver->keepMouseGrab() && receiver != this) || receiverDisabled) {
+ if ((receiver && stealThisEvent && !receiverKeepsGrab && receiver != this) || receiverDisabled) {
d->clearDelayedPress();
grabMouse();
} else if (d->delayedPressEvent) {
@@ -2339,7 +2348,7 @@ bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event)
d->lastPosTime = -1;
returnToBounds();
}
- if (event->type() == QEvent::MouseButtonRelease || (receiver && receiver->keepMouseGrab() && !receiverDisabled)) {
+ if (event->type() == QEvent::MouseButtonRelease || (receiverKeepsGrab && !receiverDisabled)) {
// mouse released, or another item has claimed the grab
d->lastPosTime = -1;
d->clearDelayedPress();
@@ -2696,7 +2705,11 @@ void QQuickFlickablePrivate::updateVelocity()
The value is negative when the content is dragged or flicked beyond the beginning,
and positive when beyond the end; \c 0.0 otherwise.
- \sa verticalOvershoot, boundsBehavior
+ Whether the values are reported for dragging and/or flicking is determined by
+ \l boundsBehavior. The overshoot distance is reported even when \l boundsMovement
+ is \c Flickable.StopAtBounds.
+
+ \sa verticalOvershoot, boundsBehavior, boundsMovement
*/
qreal QQuickFlickable::horizontalOvershoot() const
{
@@ -2713,7 +2726,11 @@ qreal QQuickFlickable::horizontalOvershoot() const
The value is negative when the content is dragged or flicked beyond the beginning,
and positive when beyond the end; \c 0.0 otherwise.
- \sa horizontalOvershoot, boundsBehavior
+ Whether the values are reported for dragging and/or flicking is determined by
+ \l boundsBehavior. The overshoot distance is reported even when \l boundsMovement
+ is \c Flickable.StopAtBounds.
+
+ \sa horizontalOvershoot, boundsBehavior, boundsMovement
*/
qreal QQuickFlickable::verticalOvershoot() const
{
@@ -2721,4 +2738,66 @@ qreal QQuickFlickable::verticalOvershoot() const
return d->vData.overshoot;
}
+/*!
+ \qmlproperty enumeration QtQuick::Flickable::boundsMovement
+ \since 5.10
+
+ This property holds whether the flickable will give a feeling that the edges of the
+ view are soft, rather than a hard physical boundary.
+
+ The \c boundsMovement can be one of:
+
+ \list
+ \li Flickable.StopAtBounds - this allows implementing custom edge effects where the
+ contents do not follow drags or flicks beyond the bounds of the flickable. The values
+ of \l horizontalOvershoot and \l verticalOvershoot can be utilized to implement custom
+ edge effects.
+ \li Flickable.FollowBoundsBehavior (default) - whether the contents follow drags or
+ flicks beyond the bounds of the flickable is determined by \l boundsBehavior.
+ \endlist
+
+ The following example keeps the contents within bounds and instead applies a flip
+ effect when flicked over horizontal bounds:
+ \code
+ Flickable {
+ id: flickable
+ boundsMovement: Flickable.StopAtBounds
+ boundsBehavior: Flickable.DragAndOvershootBounds
+ transform: Rotation {
+ axis { x: 0; y: 1; z: 0 }
+ origin.x: flickable.width / 2
+ origin.y: flickable.height / 2
+ angle: Math.min(30, Math.max(-30, flickable.horizontalOvershoot))
+ }
+ }
+ \endcode
+
+ The following example keeps the contents within bounds and instead applies an opacity
+ effect when dragged over vertical bounds:
+ \code
+ Flickable {
+ boundsMovement: Flickable.StopAtBounds
+ boundsBehavior: Flickable.DragOverBounds
+ opacity: Math.max(0.5, 1.0 - Math.abs(verticalOvershoot) / height)
+ }
+ \endcode
+
+ \sa boundsBehavior, verticalOvershoot, horizontalOvershoot
+*/
+QQuickFlickable::BoundsMovement QQuickFlickable::boundsMovement() const
+{
+ Q_D(const QQuickFlickable);
+ return d->boundsMovement;
+}
+
+void QQuickFlickable::setBoundsMovement(BoundsMovement movement)
+{
+ Q_D(QQuickFlickable);
+ if (d->boundsMovement == movement)
+ return;
+
+ d->boundsMovement = movement;
+ emit boundsMovementChanged();
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index 52cade1472..7558ee7df8 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -80,6 +80,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem
Q_PROPERTY(qreal verticalVelocity READ verticalVelocity NOTIFY verticalVelocityChanged)
Q_PROPERTY(BoundsBehavior boundsBehavior READ boundsBehavior WRITE setBoundsBehavior NOTIFY boundsBehaviorChanged)
+ Q_PROPERTY(BoundsMovement boundsMovement READ boundsMovement WRITE setBoundsMovement NOTIFY boundsMovementChanged REVISION 10)
Q_PROPERTY(QQuickTransition *rebound READ rebound WRITE setRebound NOTIFY reboundChanged)
Q_PROPERTY(qreal maximumFlickVelocity READ maximumFlickVelocity WRITE setMaximumFlickVelocity NOTIFY maximumFlickVelocityChanged)
Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged)
@@ -132,6 +133,15 @@ public:
BoundsBehavior boundsBehavior() const;
void setBoundsBehavior(BoundsBehavior);
+ enum BoundsMovement {
+ // StopAtBounds = 0x0,
+ FollowBoundsBehavior = 0x1
+ };
+ Q_ENUM(BoundsMovement)
+
+ BoundsMovement boundsMovement() const;
+ void setBoundsMovement(BoundsMovement movement);
+
QQuickTransition *rebound() const;
void setRebound(QQuickTransition *transition);
@@ -237,6 +247,7 @@ Q_SIGNALS:
void flickableDirectionChanged();
void interactiveChanged();
void boundsBehaviorChanged();
+ Q_REVISION(10) void boundsMovementChanged();
void reboundChanged();
void maximumFlickVelocityChanged();
void flickDecelerationChanged();
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 1ceff22dfc..8609a15fcd 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -247,6 +247,7 @@ public:
QQuickFlickableVisibleArea *visibleArea;
QQuickFlickable::FlickableDirection flickableDirection;
QQuickFlickable::BoundsBehavior boundsBehavior;
+ QQuickFlickable::BoundsMovement boundsMovement;
QQuickTransition *rebound;
void viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index f3d7dc4b56..bf982117e8 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -559,7 +559,8 @@ void QQuickImage::updatePaintedGeometry()
void QQuickImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
QQuickImageBase::geometryChanged(newGeometry, oldGeometry);
- updatePaintedGeometry();
+ if (newGeometry.size() != oldGeometry.size())
+ updatePaintedGeometry();
}
QRectF QQuickImage::boundingRect() const
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 1edc54aca2..bfc4a59851 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -6780,8 +6780,27 @@ bool QQuickItem::heightValid() const
}
/*!
- \internal
- */
+ \since 5.10
+
+ Returns the size of the item.
+
+ \sa setSize, width, height
+ */
+
+QSizeF QQuickItem::size() const
+{
+ Q_D(const QQuickItem);
+ return QSizeF(d->width, d->height);
+}
+
+
+/*!
+ \since 5.10
+
+ Sets the size of the item to \a size.
+
+ \sa size, setWidth, setHeight
+ */
void QQuickItem::setSize(const QSizeF &size)
{
Q_D(QQuickItem);
@@ -8456,19 +8475,19 @@ struct QQuickItemWrapper : public QObjectWrapper {
struct QQuickItemWrapper : public QV4::QObjectWrapper {
V4_OBJECT2(QQuickItemWrapper, QV4::QObjectWrapper)
- static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e);
+ static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack);
};
DEFINE_OBJECT_VTABLE(QQuickItemWrapper);
-void QQuickItemWrapper::markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e)
+void QQuickItemWrapper::markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack)
{
QObjectWrapper::Data *This = static_cast<QObjectWrapper::Data *>(that);
if (QQuickItem *item = static_cast<QQuickItem*>(This->object())) {
for (QQuickItem *child : qAsConst(QQuickItemPrivate::get(item)->childItems))
- QV4::QObjectWrapper::markWrapper(child, e);
+ QV4::QObjectWrapper::markWrapper(child, markStack);
}
- QV4::QObjectWrapper::markObjects(that, e);
+ QV4::QObjectWrapper::markObjects(that, markStack);
}
quint64 QQuickItemPrivate::_q_createJSWrapper(QV4::ExecutionEngine *engine)
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 279d052db9..1d174ca979 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -237,6 +237,7 @@ public:
void setImplicitHeight(qreal);
qreal implicitHeight() const;
+ QSizeF size() const;
void setSize(const QSizeF &size);
TransformOrigin transformOrigin() const;
diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp
index 9873622f41..874130b137 100644
--- a/src/quick/items/qquickitemanimation.cpp
+++ b/src/quick/items/qquickitemanimation.cpp
@@ -327,7 +327,7 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act
}
if (scale != 0)
- rotation = qAtan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
+ rotation = qRadiansToDegrees(qAtan2(transform.m12() / scale, transform.m11() / scale));
else {
qmlWarning(this) << QQuickParentAnimation::tr("Unable to preserve appearance under scale of 0");
ok = false;
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index eeffe1ee48..13f23c918a 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -273,7 +273,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickAnchorSet>();
qmlRegisterType<QQuickAnchorAnimation>(uri, major, minor,"AnchorAnimation");
qmlRegisterType<QQuickParentAnimation>(uri, major, minor,"ParentAnimation");
-#if QT_CONFIG(quick_canvas)
+#if QT_CONFIG(quick_path)
qmlRegisterType<QQuickPathAnimation>("QtQuick",2,0,"PathAnimation");
qmlRegisterType<QQuickPathInterpolator>("QtQuick",2,0,"PathInterpolator");
#endif
@@ -389,6 +389,8 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#if QT_CONFIG(quick_shadereffect)
qmlRegisterType<QQuickShaderEffectSource, 2>(uri, 2, 9, "ShaderEffectSource");
#endif
+
+ qmlRegisterType<QQuickFlickable, 10>(uri, 2, 10, "Flickable");
}
static void initResources()
diff --git a/src/quick/items/qquickpainteditem_p.h b/src/quick/items/qquickpainteditem_p.h
index 742e786335..3e160ed55a 100644
--- a/src/quick/items/qquickpainteditem_p.h
+++ b/src/quick/items/qquickpainteditem_p.h
@@ -51,7 +51,9 @@
// We mean it.
//
+#include "qquickpainteditem.h"
#include "qquickitem_p.h"
+#include "qquickpainteditem.h"
#include <QtGui/qcolor.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp
index 70fc5fa65f..05882d0464 100644
--- a/src/quick/items/qquickpositioners.cpp
+++ b/src/quick/items/qquickpositioners.cpp
@@ -48,19 +48,8 @@
QT_BEGIN_NAMESPACE
-// The default item change types that positioners are interested in.
-static const QQuickItemPrivate::ChangeTypes explicitSizeItemChangeTypes =
- QQuickItemPrivate::Geometry
- | QQuickItemPrivate::SiblingOrder
- | QQuickItemPrivate::Visibility
- | QQuickItemPrivate::Destroyed;
-
-// The item change types for positioners that are only interested in the implicit
-// size of the items they manage. These are used if useImplicitSize is true.
-// useImplicitSize should be set in the constructor, before any items are added.
-static const QQuickItemPrivate::ChangeTypes implicitSizeItemChangeTypes =
- QQuickItemPrivate::ImplicitWidth
- | QQuickItemPrivate::ImplicitHeight
+static const QQuickItemPrivate::ChangeTypes watchedChanges
+ = QQuickItemPrivate::Geometry
| QQuickItemPrivate::SiblingOrder
| QQuickItemPrivate::Visibility
| QQuickItemPrivate::Destroyed;
@@ -68,15 +57,13 @@ static const QQuickItemPrivate::ChangeTypes implicitSizeItemChangeTypes =
void QQuickBasePositionerPrivate::watchChanges(QQuickItem *other)
{
QQuickItemPrivate *otherPrivate = QQuickItemPrivate::get(other);
- otherPrivate->addItemChangeListener(this, useImplicitSize
- ? implicitSizeItemChangeTypes : explicitSizeItemChangeTypes);
+ otherPrivate->addItemChangeListener(this, watchedChanges);
}
void QQuickBasePositionerPrivate::unwatchChanges(QQuickItem* other)
{
QQuickItemPrivate *otherPrivate = QQuickItemPrivate::get(other);
- otherPrivate->removeItemChangeListener(this, useImplicitSize
- ? implicitSizeItemChangeTypes : explicitSizeItemChangeTypes);
+ otherPrivate->removeItemChangeListener(this, watchedChanges);
}
@@ -336,7 +323,7 @@ void QQuickBasePositioner::prePositioning()
if (wIdx < 0) {
d->watchChanges(child);
posItem.isNew = true;
- if (!childPrivate->explicitVisible || !d->itemWidth(child) || !d->itemHeight(child)) {
+ if (!childPrivate->explicitVisible || !child->width() || !child->height()) {
posItem.isVisible = false;
posItem.index = -1;
unpositionedItems.append(posItem);
@@ -358,7 +345,7 @@ void QQuickBasePositioner::prePositioning()
PositionedItem *item = &oldItems[wIdx];
// Items are only omitted from positioning if they are explicitly hidden
// i.e. their positioning is not affected if an ancestor is hidden.
- if (!childPrivate->explicitVisible || !d->itemWidth(child) || !d->itemHeight(child)) {
+ if (!childPrivate->explicitVisible || !child->width() || !child->height()) {
item->isVisible = false;
item->index = -1;
unpositionedItems.append(*item);
@@ -957,7 +944,6 @@ QQuickColumn::QQuickColumn(QQuickItem *parent)
void QQuickColumn::doPositioning(QSizeF *contentSize)
{
//Precondition: All items in the positioned list have a valid item pointer and should be positioned
- QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate*>(QQuickBasePositionerPrivate::get(this));
qreal voffset = topPadding();
const qreal padding = leftPadding() + rightPadding();
contentSize->setWidth(qMax(contentSize->width(), padding));
@@ -966,9 +952,9 @@ void QQuickColumn::doPositioning(QSizeF *contentSize)
PositionedItem &child = positionedItems[ii];
positionItem(child.itemX() + leftPadding() - child.leftPadding, voffset, &child);
child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
- contentSize->setWidth(qMax(contentSize->width(), d->itemWidth(child.item) + padding));
+ contentSize->setWidth(qMax(contentSize->width(), child.item->width() + padding));
- voffset += d->itemHeight(child.item);
+ voffset += child.item->height();
voffset += spacing();
}
@@ -1236,9 +1222,9 @@ void QQuickRow::doPositioning(QSizeF *contentSize)
hoffsets << hoffset;
}
- contentSize->setHeight(qMax(contentSize->height(), d->itemHeight(child.item) + padding));
+ contentSize->setHeight(qMax(contentSize->height(), child.item->height() + padding));
- hoffset += d->itemWidth(child.item);
+ hoffset += child.item->width();
hoffset += spacing();
}
@@ -1259,7 +1245,7 @@ void QQuickRow::doPositioning(QSizeF *contentSize)
int acc = 0;
for (int ii = 0; ii < positionedItems.count(); ++ii) {
PositionedItem &child = positionedItems[ii];
- hoffset = end - hoffsets[acc++] - d->itemWidth(child.item);
+ hoffset = end - hoffsets[acc++] - child.item->width();
positionItem(hoffset, child.itemY() + topPadding() - child.topPadding, &child);
child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
}
@@ -1760,12 +1746,10 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
break;
const PositionedItem &child = positionedItems.at(childIndex++);
- const qreal childWidth = d->itemWidth(child.item);
- const qreal childHeight = d->itemHeight(child.item);
- if (childWidth > maxColWidth[j])
- maxColWidth[j] = childWidth;
- if (childHeight > maxRowHeight[i])
- maxRowHeight[i] = childHeight;
+ if (child.item->width() > maxColWidth[j])
+ maxColWidth[j] = child.item->width();
+ if (child.item->height() > maxRowHeight[i])
+ maxRowHeight[i] = child.item->height();
}
}
} else {
@@ -1780,12 +1764,10 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
break;
const PositionedItem &child = positionedItems.at(childIndex++);
- const qreal childWidth = d->itemWidth(child.item);
- const qreal childHeight = d->itemHeight(child.item);
- if (childWidth > maxColWidth[j])
- maxColWidth[j] = childWidth;
- if (childHeight > maxRowHeight[i])
- maxRowHeight[i] = childHeight;
+ if (child.item->width() > maxColWidth[j])
+ maxColWidth[j] = child.item->width();
+ if (child.item->height() > maxRowHeight[i])
+ maxRowHeight[i] = child.item->height();
}
}
}
@@ -1827,22 +1809,20 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
for (int i = 0; i < positionedItems.count(); ++i) {
PositionedItem &child = positionedItems[i];
qreal childXOffset = xoffset;
- const qreal childWidth = d->itemWidth(child.item);
- const qreal childHeight = d->itemHeight(child.item);
if (effectiveHAlign() == AlignRight)
- childXOffset += maxColWidth[curCol] - childWidth;
+ childXOffset += maxColWidth[curCol] - child.item->width();
else if (hItemAlign() == AlignHCenter)
- childXOffset += (maxColWidth[curCol] - childWidth)/2.0;
+ childXOffset += (maxColWidth[curCol] - child.item->width())/2.0;
if (!d->isLeftToRight())
childXOffset -= maxColWidth[curCol];
qreal alignYOffset = yoffset;
if (m_vItemAlign == AlignVCenter)
- alignYOffset += (maxRowHeight[curRow] - childHeight)/2.0;
+ alignYOffset += (maxRowHeight[curRow] - child.item->height())/2.0;
else if (m_vItemAlign == AlignBottom)
- alignYOffset += maxRowHeight[curRow] - childHeight;
+ alignYOffset += maxRowHeight[curRow] - child.item->height();
positionItem(childXOffset, alignYOffset, &child);
child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
@@ -2160,17 +2140,15 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
for (int i = 0; i < positionedItems.count(); ++i) {
PositionedItem &child = positionedItems[i];
- const qreal childWidth = d->itemWidth(child.item);
- const qreal childHeight = d->itemHeight(child.item);
if (d->flow == LeftToRight) {
- if (widthValid() && hoffset != hoffset1 && hoffset + childWidth + hoffset2 > width()) {
+ if (widthValid() && hoffset != hoffset1 && hoffset + child.item->width() + hoffset2 > width()) {
hoffset = hoffset1;
voffset += linemax + spacing();
linemax = 0;
}
} else {
- if (heightValid() && voffset != voffset1 && voffset + childHeight + bottomPadding() > height()) {
+ if (heightValid() && voffset != voffset1 && voffset + child.item->height() + bottomPadding() > height()) {
voffset = voffset1;
hoffset += linemax + spacing();
linemax = 0;
@@ -2187,17 +2165,17 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
child.bottomPadding = bottomPadding();
}
- contentSize->setWidth(qMax(contentSize->width(), hoffset + childWidth + hoffset2));
- contentSize->setHeight(qMax(contentSize->height(), voffset + childHeight + bottomPadding()));
+ contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width() + hoffset2));
+ contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height() + bottomPadding()));
if (d->flow == LeftToRight) {
- hoffset += childWidth;
+ hoffset += child.item->width();
hoffset += spacing();
- linemax = qMax(linemax, childHeight);
+ linemax = qMax(linemax, child.item->height());
} else {
- voffset += childHeight;
+ voffset += child.item->height();
voffset += spacing();
- linemax = qMax(linemax, childWidth);
+ linemax = qMax(linemax, child.item->width());
}
}
@@ -2212,7 +2190,7 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
int acc = 0;
for (int i = 0; i < positionedItems.count(); ++i) {
PositionedItem &child = positionedItems[i];
- hoffset = end - hoffsets[acc++] - d->itemWidth(child.item);
+ hoffset = end - hoffsets[acc++] - child.item->width();
positionItemX(hoffset, &child);
child.leftPadding = leftPadding();
child.rightPadding = rightPadding();
@@ -2236,18 +2214,4 @@ void QQuickFlow::reportConflictingAnchors()
qmlWarning(this) << "Cannot specify anchors for items inside Flow." << " Flow will not function.";
}
-QQuickImplicitRow::QQuickImplicitRow(QQuickItem *parent)
- : QQuickRow(parent)
-{
- QQuickBasePositionerPrivate *d = QQuickBasePositioner::get(this);
- d->useImplicitSize = true;
-}
-
-QQuickImplicitGrid::QQuickImplicitGrid(QQuickItem *parent)
- : QQuickGrid(parent)
-{
- QQuickBasePositionerPrivate *d = QQuickBasePositioner::get(this);
- d->useImplicitSize = true;
-}
-
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h
index cfe163b4c1..9ae7029d69 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE
class QQuickBasePositionerPrivate;
-class Q_QUICK_PRIVATE_EXPORT QQuickPositionerAttached : public QObject
+class QQuickPositionerAttached : public QObject
{
Q_OBJECT
@@ -132,11 +132,6 @@ public:
static QQuickPositionerAttached *qmlAttachedProperties(QObject *obj);
- static QQuickBasePositionerPrivate* get(QQuickBasePositioner *positioner)
- {
- return positioner->d_func();
- }
-
void updateAttachedProperties(QQuickPositionerAttached *specificProperty = 0, QQuickItem *specificPropertyOwner = 0) const;
qreal padding() const;
@@ -187,7 +182,7 @@ protected:
virtual void doPositioning(QSizeF *contentSize)=0;
virtual void reportConflictingAnchors()=0;
- class Q_QUICK_PRIVATE_EXPORT PositionedItem
+ class PositionedItem
{
public :
PositionedItem(QQuickItem *i);
@@ -232,7 +227,7 @@ private:
Q_DECLARE_PRIVATE(QQuickBasePositioner)
};
-class Q_QUICK_PRIVATE_EXPORT QQuickColumn : public QQuickBasePositioner
+class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner
{
Q_OBJECT
public:
@@ -246,7 +241,7 @@ private:
};
class QQuickRowPrivate;
-class Q_QUICK_PRIVATE_EXPORT QQuickRow: public QQuickBasePositioner
+class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner
{
Q_OBJECT
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
@@ -271,7 +266,7 @@ private:
};
class QQuickGridPrivate;
-class Q_QUICK_PRIVATE_EXPORT QQuickGrid : public QQuickBasePositioner
+class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner
{
Q_OBJECT
Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
@@ -358,7 +353,7 @@ private:
};
class QQuickFlowPrivate;
-class Q_QUICK_PRIVATE_EXPORT QQuickFlow: public QQuickBasePositioner
+class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner
{
Q_OBJECT
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
@@ -391,22 +386,6 @@ private:
Q_DECLARE_PRIVATE(QQuickFlow)
};
-class Q_QUICK_PRIVATE_EXPORT QQuickImplicitRow : public QQuickRow
-{
- Q_OBJECT
-
-public:
- QQuickImplicitRow(QQuickItem *parent = nullptr);
-};
-
-class Q_QUICK_PRIVATE_EXPORT QQuickImplicitGrid : public QQuickGrid
-{
- Q_OBJECT
-
-public:
- QQuickImplicitGrid(QQuickItem *parent = nullptr);
-};
-
QT_END_NAMESPACE
@@ -414,8 +393,6 @@ QML_DECLARE_TYPE(QQuickColumn)
QML_DECLARE_TYPE(QQuickRow)
QML_DECLARE_TYPE(QQuickGrid)
QML_DECLARE_TYPE(QQuickFlow)
-QML_DECLARE_TYPE(QQuickImplicitRow)
-QML_DECLARE_TYPE(QQuickImplicitGrid)
QML_DECLARE_TYPE(QQuickBasePositioner)
QML_DECLARE_TYPEINFO(QQuickBasePositioner, QML_HAS_ATTACHED_PROPERTIES)
diff --git a/src/quick/items/qquickpositioners_p_p.h b/src/quick/items/qquickpositioners_p_p.h
index 1a7051615c..0be4c56df6 100644
--- a/src/quick/items/qquickpositioners_p_p.h
+++ b/src/quick/items/qquickpositioners_p_p.h
@@ -89,14 +89,10 @@ public:
QLazilyAllocated<ExtraData> extra;
QQuickBasePositionerPrivate()
- : spacing(0)
- , type(QQuickBasePositioner::None)
- , transitioner(0)
- , positioningDirty(false)
- , doingPositioning(false)
- , anchorConflict(false)
- , useImplicitSize(false)
- , layoutDirection(Qt::LeftToRight)
+ : spacing(0), type(QQuickBasePositioner::None)
+ , transitioner(0), positioningDirty(false)
+ , doingPositioning(false), anchorConflict(false), layoutDirection(Qt::LeftToRight)
+
{
}
@@ -123,7 +119,6 @@ public:
bool positioningDirty : 1;
bool doingPositioning : 1;
bool anchorConflict : 1;
- bool useImplicitSize : 1;
Qt::LayoutDirection layoutDirection;
@@ -179,34 +174,6 @@ public:
{
}
- void itemImplicitWidthChanged(QQuickItem *) override
- {
- Q_ASSERT(useImplicitSize);
- setPositioningDirty();
- }
-
- void itemImplicitHeightChanged(QQuickItem *) override
- {
- Q_ASSERT(useImplicitSize);
- setPositioningDirty();
- }
-
- qreal itemWidth(QQuickItem *item) const
- {
- if (Q_LIKELY(!useImplicitSize))
- return item->width();
-
- return item->implicitWidth();
- }
-
- qreal itemHeight(QQuickItem *item) const
- {
- if (Q_LIKELY(!useImplicitSize))
- return item->height();
-
- return item->implicitHeight();
- }
-
inline qreal padding() const { return extra.isAllocated() ? extra->padding : 0.0; }
void setTopPadding(qreal value, bool reset = false);
void setLeftPadding(qreal value, bool reset = false);
diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
index 03d96aea1f..e2a20f9e7e 100644
--- a/src/quick/items/qquickrendercontrol.cpp
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -385,6 +385,9 @@ QImage QQuickRenderControl::grab()
cd->syncSceneGraph();
render();
grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), false, false);
+ if (QQuickRenderControl::renderWindowFor(d->window)) {
+ grabContent.setDevicePixelRatio(d->window->effectiveDevicePixelRatio());
+ }
#endif
} else if (d->window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) {
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 436d7b33ce..d317c1d19b 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -873,9 +873,11 @@ void QQuickShaderEffectPrivate::updatePolish()
q->m_impl->maybeUpdateShaders();
}
+#if QT_CONFIG(opengl)
bool QQuickShaderEffect::isOpenGLShaderEffect() const
{
return m_glImpl != Q_NULLPTR;
}
+#endif
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickshadereffect_p.h b/src/quick/items/qquickshadereffect_p.h
index d269dc5e50..30bd018098 100644
--- a/src/quick/items/qquickshadereffect_p.h
+++ b/src/quick/items/qquickshadereffect_p.h
@@ -117,7 +117,9 @@ public:
bool isComponentComplete() const;
QString parseLog();
+#if QT_CONFIG(opengl)
bool isOpenGLShaderEffect() const;
+#endif
Q_SIGNALS:
void fragmentShaderChanged();
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index b40a9e2843..a4ce13a199 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -101,7 +101,7 @@ void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *s
}
if (scale != 0)
- rotation = qAtan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
+ rotation = qRadiansToDegrees(qAtan2(transform.m12() / scale, transform.m11() / scale));
else {
qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under scale of 0");
ok = false;
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 555fd233b3..2dce3e9ec8 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -769,52 +769,8 @@ void QQuickTextControl::processEvent(QEvent *e, const QMatrix &matrix)
case QEvent::ShortcutOverride:
if (d->interactionFlags & Qt::TextEditable) {
QKeyEvent* ke = static_cast<QKeyEvent *>(e);
- if (ke->modifiers() == Qt::NoModifier
- || ke->modifiers() == Qt::ShiftModifier
- || ke->modifiers() == Qt::KeypadModifier) {
- if (ke->key() < Qt::Key_Escape) {
- ke->accept();
- } else {
- switch (ke->key()) {
- case Qt::Key_Return:
- case Qt::Key_Enter:
- case Qt::Key_Delete:
- case Qt::Key_Home:
- case Qt::Key_End:
- case Qt::Key_Backspace:
- case Qt::Key_Left:
- case Qt::Key_Right:
- case Qt::Key_Up:
- case Qt::Key_Down:
- case Qt::Key_Tab:
- ke->accept();
- default:
- break;
- }
- }
-#if QT_CONFIG(shortcut)
- } else if (ke == QKeySequence::Copy
- || ke == QKeySequence::Paste
- || ke == QKeySequence::Cut
- || ke == QKeySequence::Redo
- || ke == QKeySequence::Undo
- || ke == QKeySequence::MoveToNextWord
- || ke == QKeySequence::MoveToPreviousWord
- || ke == QKeySequence::MoveToStartOfDocument
- || ke == QKeySequence::MoveToEndOfDocument
- || ke == QKeySequence::SelectNextWord
- || ke == QKeySequence::SelectPreviousWord
- || ke == QKeySequence::SelectStartOfLine
- || ke == QKeySequence::SelectEndOfLine
- || ke == QKeySequence::SelectStartOfBlock
- || ke == QKeySequence::SelectEndOfBlock
- || ke == QKeySequence::SelectStartOfDocument
- || ke == QKeySequence::SelectEndOfDocument
- || ke == QKeySequence::SelectAll
- ) {
+ if (isCommonTextEditShortcut(ke))
ke->accept();
-#endif
- }
}
break;
default:
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 0105e84cd6..888b0cde85 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -748,6 +748,7 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber)
QQuickItem *oldGrabber = q->mouseGrabberItem();
qCDebug(DBG_MOUSE_TARGET) << "grabber" << oldGrabber << "->" << grabber;
+ bool fromTouch = false;
if (grabber && touchMouseId != -1 && touchMouseDevice) {
// update the touch item for mouse touch id to the new grabber
@@ -758,6 +759,7 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber)
for (auto handler : point->passiveGrabbers())
point->cancelPassiveGrab(handler);
}
+ fromTouch = true;
} else {
QQuickPointerEvent *event = QQuickPointerDevice::genericMouseDevice()->pointerEvent();
Q_ASSERT(event->pointCount() == 1);
@@ -771,8 +773,11 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber)
if (oldGrabber) {
QEvent e(QEvent::UngrabMouse);
QSet<QQuickItem *> hasFiltered;
- if (!sendFilteredMouseEvent(oldGrabber->parentItem(), oldGrabber, &e, &hasFiltered))
+ if (!sendFilteredMouseEvent(oldGrabber->parentItem(), oldGrabber, &e, &hasFiltered)) {
oldGrabber->mouseUngrabEvent();
+ if (fromTouch)
+ oldGrabber->touchUngrabEvent();
+ }
}
}
@@ -2503,7 +2508,6 @@ void QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QEvent *e
} else for (; grabItem != grabber->end(); grabItem = grabber->release(grabItem)) {
QDragMoveEvent *moveEvent = static_cast<QDragMoveEvent *>(event);
if (deliverDragEvent(grabber, **grabItem, moveEvent)) {
- moveEvent->setAccepted(true);
for (++grabItem; grabItem != grabber->end();) {
QPointF p = (**grabItem)->mapFromScene(moveEvent->pos());
if ((**grabItem)->contains(p)) {
@@ -2578,7 +2582,10 @@ bool QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickIte
event->keyboardModifiers(),
event->type());
QQuickDropEventEx::copyActions(&translatedEvent, *event);
+ translatedEvent.setAccepted(event->isAccepted());
QCoreApplication::sendEvent(item, &translatedEvent);
+ event->setAccepted(translatedEvent.isAccepted());
+ event->setDropAction(translatedEvent.dropAction());
if (event->type() == QEvent::DragEnter) {
if (translatedEvent.isAccepted()) {
grabber->grab(item);
@@ -2726,18 +2733,23 @@ bool QQuickWindowPrivate::sendFilteredPointerEvent(QQuickPointerEvent *event, QQ
break;
}
+ bool touchMouseUnset = (touchMouseId == -1);
// Only deliver mouse event if it is the touchMouseId or it could become the touchMouseId
- if (touchMouseId == -1 || touchMouseId == tp.id()) {
+ if (touchMouseUnset || touchMouseId == tp.id()) {
// convert filteringParentTouchEvent (which is already transformed wrt local position, velocity, etc.)
// into a synthetic mouse event, and let childMouseEventFilter() have another chance with that
QScopedPointer<QMouseEvent> mouseEvent(touchToMouseEvent(t, tp, filteringParentTouchEvent.data(), item, false));
+ // If a filtering item calls QQuickWindow::mouseGrabberItem(), it should
+ // report the touchpoint's grabber. Whenever we send a synthetic mouse event,
+ // touchMouseId and touchMouseDevice must be set, even if it's only temporarily and isn't grabbed.
+ touchMouseId = tp.id();
+ touchMouseDevice = event->device();
if (filteringParent->childMouseEventFilter(item, mouseEvent.data())) {
qCDebug(DBG_TOUCH) << "touch event intercepted as synth mouse event by childMouseEventFilter of " << filteringParent;
if (t != QEvent::MouseButtonRelease) {
qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << tp.id() << "->" << filteringParent;
- touchMouseId = tp.id();
- touchMouseDevice = event->device();
touchMouseDevice->pointerEvent()->pointById(tp.id())->setGrabberItem(filteringParent);
+ touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set
filteringParent->grabMouse();
auto pointerEventPoint = pte->pointById(tp.id());
for (auto handler : pointerEventPoint->passiveGrabbers()) {
@@ -2748,9 +2760,15 @@ bool QQuickWindowPrivate::sendFilteredPointerEvent(QQuickPointerEvent *event, QQ
}
ret = true;
}
+ if (touchMouseUnset) {
+ // Now that we're done sending a synth mouse event, and it wasn't grabbed,
+ // the touchpoint is no longer acting as a synthetic mouse. Restore previous state.
+ touchMouseId = -1;
+ touchMouseDevice = nullptr;
+ }
// Only one touchpoint can be treated as a synthetic mouse, so after childMouseEventFilter
// has been called once, we're done with this loop over the touchpoints.
- break;
+ break;
}
}
}
@@ -3542,6 +3560,11 @@ void QQuickWindow::setRenderTarget(QOpenGLFramebufferObject *fbo)
The specified FBO must be created in the context of the window
or one that shares with it.
+ \note \a fboId can also be set to 0. In this case rendering will target the
+ default framebuffer of whichever surface is current when the scenegraph
+ renders. \a size must still be valid, specifying the dimensions of the
+ surface.
+
\note
This function only has an effect when using the default OpenGL scene
graph adaptation.
@@ -3648,6 +3671,7 @@ QImage QQuickWindow::grabWindow()
bool alpha = format().alphaBufferSize() > 0 && color().alpha() < 255;
QImage image = qt_gl_read_framebuffer(size() * effectiveDevicePixelRatio(), alpha, alpha);
+ image.setDevicePixelRatio(effectiveDevicePixelRatio());
d->cleanupNodesOnShutdown();
d->context->invalidate();
context.doneCurrent();