diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-04-03 13:35:26 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-04-03 13:35:30 +0200 |
commit | 0eeb7ada04cc81d0ab1b61747bdf92fd7c33e1ec (patch) | |
tree | be4d0201b81b098a2976e857b5c6642f9c96e6ac /src/quick/items | |
parent | 349d3400c11c0ad1c9aaec01c44b174dbb6ebf9a (diff) | |
parent | e4894fe13d178b6aa8b5580b402df2d1b4f2615c (diff) |
Merge remote-tracking branch 'origin/dev' into wip/scenegraphng
Change-Id: I0cbb2ba4a00580e6a74a4e4085fc4eb06d0fadae
Diffstat (limited to 'src/quick/items')
-rw-r--r-- | src/quick/items/context2d/qquickcanvasitem.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/context2d/qquickcontext2d.cpp | 24 | ||||
-rw-r--r-- | src/quick/items/context2d/qquickcontext2dtexture.cpp | 7 | ||||
-rw-r--r-- | src/quick/items/qquickevents.cpp | 8 | ||||
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 18 | ||||
-rw-r--r-- | src/quick/items/qquickitem.cpp | 33 | ||||
-rw-r--r-- | src/quick/items/qquickitem.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquickitemanimation.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickitemsmodule.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickmousearea.cpp | 28 | ||||
-rw-r--r-- | src/quick/items/qquickopenglshadereffect.cpp | 10 | ||||
-rw-r--r-- | src/quick/items/qquickpainteditem_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquickpositioners_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffect.cpp | 7 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffect_p.h | 4 | ||||
-rw-r--r-- | src/quick/items/qquickstateoperations.cpp | 2 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 66 |
17 files changed, 156 insertions, 62 deletions
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 1167f408f5..da9379e7af 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> diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index b9b701313e..db9b1acbdf 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); @@ -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/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index 38b5f054bf..d90f527486 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -48,6 +48,7 @@ #include <QOpenGLFramebufferObject> #include <QOpenGLFramebufferObjectFormat> #include <QOpenGLFunctions> +#include <QtGui/private/qopenglextensions_p.h> #endif #include <QtCore/QThread> #include <QtGui/QGuiApplication> @@ -499,9 +500,9 @@ bool QQuickContext2DFBOTexture::doMultisampling() const static bool multisamplingSupported = false; if (!extensionsChecked) { - const QSet<QByteArray> extensions = QOpenGLContext::currentContext()->extensions(); - multisamplingSupported = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample")) - && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit")); + QOpenGLExtensions *e = static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions()); + multisamplingSupported = e->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample) + && e->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit); extensionsChecked = true; } diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index b6c45c40a8..f1f82f9e0e 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -193,8 +193,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. */ @@ -340,8 +340,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. */ diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 4ab604b30f..27d7072f03 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -642,8 +642,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. */ /*! @@ -2299,7 +2301,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); @@ -2319,7 +2322,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) { @@ -2335,7 +2338,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(); @@ -2349,8 +2352,11 @@ bool QQuickFlickable::filterMouseEvent(QQuickItem *receiver, QMouseEvent *event) bool QQuickFlickable::childMouseEventFilter(QQuickItem *i, QEvent *e) { Q_D(QQuickFlickable); - if (!isVisible() || !isEnabled() || !isInteractive()) + if (!isVisible() || !isEnabled() || !isInteractive()) { + d->cancelInteraction(); return QQuickItem::childMouseEventFilter(i, e); + } + switch (e->type()) { case QEvent::MouseButtonPress: case QEvent::MouseMove: diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 22ee3f39e4..539a374dd9 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2911,14 +2911,15 @@ void QQuickItemPrivate::addChild(QQuickItem *child) childItems.append(child); -#if QT_CONFIG(cursor) QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child); +#if QT_CONFIG(cursor) // if the added child has a cursor and we do not currently have any children // with cursors, bubble the notification up if (childPrivate->subtreeCursorEnabled && !subtreeCursorEnabled) setHasCursorInChild(true); #endif + if (childPrivate->subtreeHoverEnabled && !subtreeHoverEnabled) setHasHoverInChild(true); @@ -2939,13 +2940,14 @@ void QQuickItemPrivate::removeChild(QQuickItem *child) childItems.removeOne(child); Q_ASSERT(!childItems.contains(child)); -#if QT_CONFIG(cursor) QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child); +#if QT_CONFIG(cursor) // turn it off, if nothing else is using it if (childPrivate->subtreeCursorEnabled && subtreeCursorEnabled) setHasCursorInChild(false); #endif + if (childPrivate->subtreeHoverEnabled && subtreeHoverEnabled) setHasHoverInChild(false); @@ -3807,10 +3809,10 @@ QQuickItem::UpdatePaintNodeData::UpdatePaintNodeData() /*! This function is called when an item should release graphics - resources which are not already managed by the nodes returend from + resources which are not already managed by the nodes returned from QQuickItem::updatePaintNode(). - This happens when the item is about to be removed from window it + This happens when the item is about to be removed from the window it was previously rendering to. The item is guaranteed to have a \l {QQuickItem::window()}{window} when the function is called. @@ -6744,8 +6746,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); diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index c9494d91bd..f58946d01d 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 43f4b88833..6c0539bcc1 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -274,7 +274,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 diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index bb23b1fd54..c662efe40e 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -689,9 +689,10 @@ void QQuickMouseArea::mousePressEvent(QMouseEvent *event) #endif setHovered(true); d->startScene = event->windowPos(); - d->pressAndHoldTimer.start(pressAndHoldInterval(), this); setKeepMouseGrab(d->stealMouse); event->setAccepted(setPressed(event->button(), true, event->source())); + if (event->isAccepted()) + d->pressAndHoldTimer.start(pressAndHoldInterval(), this); } } @@ -738,23 +739,34 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event) bool dragY = drag()->axis() & QQuickDrag::YAxis; QPointF dragPos = d->drag->target()->position(); + QPointF boundedDragPos = dragPos; if (dragX) { - dragPos.setX(qBound( + dragPos.setX(startPos.x() + curLocalPos.x() - startLocalPos.x()); + boundedDragPos.setX(qBound( d->drag->xmin(), - startPos.x() + curLocalPos.x() - startLocalPos.x(), + dragPos.x(), d->drag->xmax())); } if (dragY) { - dragPos.setY(qBound( + dragPos.setY(startPos.y() + curLocalPos.y() - startLocalPos.y()); + boundedDragPos.setY(qBound( d->drag->ymin(), - startPos.y() + curLocalPos.y() - startLocalPos.y(), + dragPos.y(), d->drag->ymax())); } + + QPointF targetPos = d->drag->target()->position(); + if (d->drag->active()) - d->drag->target()->setPosition(dragPos); + d->drag->target()->setPosition(boundedDragPos); + + bool dragOverThresholdX = QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(), + Qt::XAxis, event, d->drag->threshold()); + bool dragOverThresholdY = QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(), + Qt::YAxis, event, d->drag->threshold()); - if (!d->overThreshold && (QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(), Qt::XAxis, event, d->drag->threshold()) - || QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(), Qt::YAxis, event, d->drag->threshold()))) + if (!d->overThreshold && (((targetPos.x() != boundedDragPos.x()) && dragOverThresholdX) || + ((targetPos.y() != boundedDragPos.y()) && dragOverThresholdY))) { d->overThreshold = true; if (d->drag->smoothed()) diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp index 42fcee3c0d..4f4c403483 100644 --- a/src/quick/items/qquickopenglshadereffect.cpp +++ b/src/quick/items/qquickopenglshadereffect.cpp @@ -256,10 +256,14 @@ void QQuickOpenGLShaderEffectCommon::connectPropertySignals(QQuickItem *item, qWarning("QQuickOpenGLShaderEffect: property '%s' does not have notification method!", d.name.constData()); } else { auto *mapper = signalMappers[shaderType].at(i); - mapper->setSignalIndex(pd->notifyIndex()); + mapper->setSignalIndex(itemMetaObject->property(d.propertyIndex).notifySignal().methodIndex()); Q_ASSERT(item->metaObject() == itemMetaObject); - QObjectPrivate::connectImpl(item, mapper->signalIndex(), item, nullptr, mapper, - Qt::AutoConnection, nullptr, itemMetaObject); + bool ok = QObjectPrivate::connectImpl(item, pd->notifyIndex(), item, nullptr, mapper, + Qt::AutoConnection, nullptr, itemMetaObject); + if (!ok) + qWarning() << "Failed to connect to property" << itemMetaObject->property(d.propertyIndex).name() + << "(" << d.propertyIndex << ", signal index" << pd->notifyIndex() + << ") of item" << item; } } else { // If the source is set via a dynamic property, like the layer is, then we need this 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_p.h b/src/quick/items/qquickpositioners_p.h index 8dc0d90a2f..cfe163b4c1 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 QQuickPositionerAttached : public QObject +class Q_QUICK_PRIVATE_EXPORT QQuickPositionerAttached : public QObject { Q_OBJECT diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index 7926607e33..d317c1d19b 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -873,4 +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 7885daffbb..30bd018098 100644 --- a/src/quick/items/qquickshadereffect_p.h +++ b/src/quick/items/qquickshadereffect_p.h @@ -117,6 +117,10 @@ public: bool isComponentComplete() const; QString parseLog(); +#if QT_CONFIG(opengl) + bool isOpenGLShaderEffect() const; +#endif + Q_SIGNALS: void fragmentShaderChanged(); void vertexShaderChanged(); 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/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 57810e4ec9..bd68f39e48 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -635,8 +635,8 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve // FIXME: make this work for mouse events too and get rid of the asTouchEvent in here. Q_ASSERT(pointerEvent->asPointerTouchEvent()); - QTouchEvent *event = pointerEvent->asPointerTouchEvent()->touchEventForItem(item); - if (!event) + QScopedPointer<QTouchEvent> event(pointerEvent->asPointerTouchEvent()->touchEventForItem(item)); + if (event.isNull()) return false; // For each point, check if it is accepted, if not, try the next point. @@ -653,7 +653,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve break; qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << p.id() << "->" << item; - QScopedPointer<QMouseEvent> mousePress(touchToMouseEvent(QEvent::MouseButtonPress, p, event, item, false)); + QScopedPointer<QMouseEvent> mousePress(touchToMouseEvent(QEvent::MouseButtonPress, p, event.data(), item, false)); // Send a single press and see if that's accepted QCoreApplication::sendEvent(item, mousePress.data()); @@ -667,7 +667,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve pointerEventPoint->setGrabber(item); if (checkIfDoubleClicked(event->timestamp())) { - QScopedPointer<QMouseEvent> mouseDoubleClick(touchToMouseEvent(QEvent::MouseButtonDblClick, p, event, item, false)); + QScopedPointer<QMouseEvent> mouseDoubleClick(touchToMouseEvent(QEvent::MouseButtonDblClick, p, event.data(), item, false)); QCoreApplication::sendEvent(item, mouseDoubleClick.data()); event->setAccepted(mouseDoubleClick->isAccepted()); if (!mouseDoubleClick->isAccepted()) { @@ -684,7 +684,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve } else if (touchMouseDevice == device && p.id() == touchMouseId) { if (p.state() & Qt::TouchPointMoved) { if (QQuickItem *mouseGrabberItem = q->mouseGrabberItem()) { - QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event, mouseGrabberItem, false)); + QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event.data(), mouseGrabberItem, false)); QCoreApplication::sendEvent(item, me.data()); event->setAccepted(me->isAccepted()); if (me->isAccepted()) { @@ -695,7 +695,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve // no grabber, check if we care about mouse hover // FIXME: this should only happen once, not recursively... I'll ignore it just ignore hover now. // hover for touch??? - QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event, item, false)); + QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseMove, p, event.data(), item, false)); if (lastMousePosition.isNull()) lastMousePosition = me->windowPos(); QPointF last = lastMousePosition; @@ -713,7 +713,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve } else if (p.state() & Qt::TouchPointReleased) { // currently handled point was released if (QQuickItem *mouseGrabberItem = q->mouseGrabberItem()) { - QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseButtonRelease, p, event, mouseGrabberItem, false)); + QScopedPointer<QMouseEvent> me(touchToMouseEvent(QEvent::MouseButtonRelease, p, event.data(), mouseGrabberItem, false)); QCoreApplication::sendEvent(item, me.data()); if (item->acceptHoverEvents() && p.screenPos() != QGuiApplicationPrivate::lastCursorPosition) { @@ -746,6 +746,7 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber) qCDebug(DBG_MOUSE_TARGET) << "grabber" << q->mouseGrabberItem() << "->" << grabber; QQuickItem *oldGrabber = q->mouseGrabberItem(); + bool fromTouch = false; if (grabber && touchMouseId != -1 && touchMouseDevice) { // update the touch item for mouse touch id to the new grabber @@ -753,6 +754,7 @@ void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber) auto point = touchMouseDevice->pointerEvent()->pointById(touchMouseId); if (point) point->setGrabber(grabber); + fromTouch = true; } else { QQuickPointerEvent *event = QQuickPointerDevice::genericMouseDevice()->pointerEvent(); Q_ASSERT(event->pointCount() == 1); @@ -762,8 +764,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(); + } } } @@ -811,6 +816,10 @@ void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVector<int void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool touch) { Q_Q(QQuickWindow); + if (Q_LIKELY(mouse) && q->mouseGrabberItem() == grabber) { + qCDebug(DBG_MOUSE_TARGET) << "removeGrabber" << q->mouseGrabberItem() << "-> null"; + setMouseGrabber(nullptr); + } if (Q_LIKELY(touch)) { const auto touchDevices = QQuickPointerDevice::touchDevices(); for (auto device : touchDevices) { @@ -824,10 +833,6 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to } } } - if (Q_LIKELY(mouse) && q->mouseGrabberItem() == grabber) { - qCDebug(DBG_MOUSE_TARGET) << "removeGrabber" << q->mouseGrabberItem() << "-> null"; - setMouseGrabber(nullptr); - } } /*! @@ -2397,7 +2402,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)) { @@ -2472,7 +2476,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); @@ -2583,23 +2590,39 @@ bool QQuickWindowPrivate::sendFilteredTouchEvent(QQuickItem *target, QQuickItem 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()) { // targetEvent is already transformed wrt local position, velocity, etc. // FIXME: remove asTouchEvent!!! QScopedPointer<QMouseEvent> mouseEvent(touchToMouseEvent(t, tp, event->asTouchEvent(), 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 (target->childMouseEventFilter(item, mouseEvent.data())) { qCDebug(DBG_TOUCH) << " - second chance intercepted on childMouseEventFilter by " << target; if (t != QEvent::MouseButtonRelease) { qCDebug(DBG_TOUCH_TARGET) << "TP" << tp.id() << "->" << target; - touchMouseId = tp.id(); - touchMouseDevice = event->device(); - touchMouseDevice->pointerEvent()->pointById(tp.id())->setGrabber(target); + if (touchMouseUnset) { + // the point was grabbed as a pure touch point before, now it will be treated as mouse + // but the old receiver still needs to be informed + if (auto oldGrabber = touchMouseDevice->pointerEvent()->pointById(tp.id())->grabber()) + oldGrabber->touchUngrabEvent(); + } + touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set target->grabMouse(); } filtered = 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 event can be filtered as a mouse event. break; } @@ -3392,6 +3415,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. @@ -4495,8 +4523,8 @@ QSGRendererInterface *QQuickWindow::rendererInterface() const \note The call to the function must happen before constructing the first QQuickWindow in the application. It cannot be changed afterwards. - If \a backend is invalid or an error occurs, the default backend (OpenGL or - software, depending on the Qt configuration) is used. + If the selected backend is invalid or an error occurs, the default backend + (OpenGL or software, depending on the Qt configuration) is used. \since 5.8 */ |