diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-03-01 11:54:30 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-03-01 11:54:35 +0100 |
commit | 87aebe39ae80c0752695b21b5b7508d220035b85 (patch) | |
tree | a60bd61dd81b5e79532762ae014cb7612d619da2 /src/quick/items | |
parent | a48244d5aa1d14c286b7cd39afebcfff9c9dcb60 (diff) | |
parent | afec9016d0fd51345ea93a1bbadb99b5c3fdf629 (diff) |
Merge remote-tracking branch 'origin/dev' into wip/scenegraphng
Change-Id: Iba540adaeffb0098fc4e1923050eb611bf47287b
Diffstat (limited to 'src/quick/items')
27 files changed, 449 insertions, 140 deletions
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index b772ed97d2..1167f408f5 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -640,6 +640,17 @@ void QQuickCanvasItem::releaseResources() } } +bool QQuickCanvasItem::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::PolishRequest: + polish(); + return true; + default: + return QQuickItem::event(event); + } +} + void QQuickCanvasItem::invalidateSceneGraph() { Q_D(QQuickCanvasItem); @@ -651,6 +662,12 @@ void QQuickCanvasItem::invalidateSceneGraph() d->textureProvider = 0; } +void QQuickCanvasItem::schedulePolish() +{ + auto polishRequestEvent = new QEvent(QEvent::PolishRequest); + QCoreApplication::postEvent(this, polishRequestEvent); +} + void QQuickCanvasItem::componentComplete() { QQuickItem::componentComplete(); @@ -892,8 +909,9 @@ void QQuickCanvasItem::requestAnimationFrame(QQmlV4Function *args) d->animationCallbacks.insert(++id, QV4::PersistentValue(scope.engine, f->asReturnedValue())); + // QTBUG-55778: Calling polish directly here can lead to a polish loop if (isVisible()) - polish(); + schedulePolish(); args->setReturnValue(QV4::Encode(id)); } diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h index 8af84d0e7c..217ae9bb69 100644 --- a/src/quick/items/context2d/qquickcanvasitem_p.h +++ b/src/quick/items/context2d/qquickcanvasitem_p.h @@ -182,6 +182,7 @@ private Q_SLOTS: void sceneGraphInitialized(); void checkAnimationCallbacks(); void invalidateSceneGraph(); + void schedulePolish(); protected: void componentComplete() Q_DECL_OVERRIDE; @@ -190,6 +191,7 @@ protected: QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE; void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; void releaseResources() Q_DECL_OVERRIDE; + bool event(QEvent *event) Q_DECL_OVERRIDE; private: Q_DECLARE_PRIVATE(QQuickCanvasItem) Q_INVOKABLE void delayedCreate(); diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index b0c1d50907..b9b701313e 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -901,7 +901,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object V4_NEEDS_DESTROY static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty); - static void putIndexed(QV4::Managed *m, uint index, const QV4::Value &value); + static bool putIndexed(QV4::Managed *m, uint index, const QV4::Value &value); static void proto_get_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData); }; @@ -1879,7 +1879,7 @@ void QQuickJSContext2D::method_get_lineWidth(const QV4::BuiltinFunction *, QV4:: QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); CHECK_CONTEXT(r) - RETURN_RESULT(r->d()->context->state.lineWidth); + RETURN_RESULT(QV4::Encode(r->d()->context->state.lineWidth)); } void QQuickJSContext2D::method_set_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) @@ -1906,7 +1906,7 @@ void QQuickJSContext2D::method_get_miterLimit(const QV4::BuiltinFunction *, QV4: QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); CHECK_CONTEXT(r) - RETURN_RESULT(r->d()->context->state.miterLimit); + RETURN_RESULT(QV4::Encode(r->d()->context->state.miterLimit)); } void QQuickJSContext2D::method_set_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) @@ -1933,7 +1933,7 @@ void QQuickJSContext2D::method_get_shadowBlur(const QV4::BuiltinFunction *, QV4: QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); CHECK_CONTEXT(r) - RETURN_RESULT(r->d()->context->state.shadowBlur); + RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowBlur)); } void QQuickJSContext2D::method_set_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) @@ -1990,7 +1990,7 @@ void QQuickJSContext2D::method_get_shadowOffsetX(const QV4::BuiltinFunction *, Q QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); CHECK_CONTEXT(r) - RETURN_RESULT(r->d()->context->state.shadowOffsetX); + RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowOffsetX)); } void QQuickJSContext2D::method_set_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) @@ -2016,7 +2016,7 @@ void QQuickJSContext2D::method_get_shadowOffsetY(const QV4::BuiltinFunction *, Q QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject); CHECK_CONTEXT(r) - RETURN_RESULT(r->d()->context->state.shadowOffsetY); + RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowOffsetY)); } void QQuickJSContext2D::method_set_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) @@ -3043,7 +3043,7 @@ void QQuickJSContext2DPixelData::proto_get_length(const QV4::BuiltinFunction *, if (!r || r->d()->image->isNull()) RETURN_UNDEFINED(); - RETURN_RESULT(r->d()->image->width() * r->d()->image->height() * 4); + RETURN_RESULT(QV4::Encode(r->d()->image->width() * r->d()->image->height() * 4)); } QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m, uint index, bool *hasProperty) @@ -3077,13 +3077,13 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m, return QV4::Encode::undefined(); } -void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const QV4::Value &value) +bool QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const QV4::Value &value) { Q_ASSERT(m->as<QQuickJSContext2DPixelData>()); QV4::ExecutionEngine *v4 = static_cast<QQuickJSContext2DPixelData *>(m)->engine(); QV4::Scope scope(v4); if (scope.hasException()) - return; + return false; QV4::Scoped<QQuickJSContext2DPixelData> r(scope, static_cast<QQuickJSContext2DPixelData *>(m)); @@ -3109,7 +3109,10 @@ void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const Q *pixel = qRgba(qRed(*pixel), qGreen(*pixel), qBlue(*pixel), v); break; } + return true; } + + return false; } /*! \qmlmethod CanvasImageData QtQuick::Context2D::createImageData(real sw, real sh) diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index a1833081c8..22ea4774be 100644 --- a/src/quick/items/qquickanimatedimage.cpp +++ b/src/quick/items/qquickanimatedimage.cpp @@ -67,7 +67,7 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine .arg(current)); } if (!requestedUrl.isEmpty()) { - if (QQuickPixmap::isCached(requestedUrl, QSize())) + if (QQuickPixmap::isCached(requestedUrl, QSize(), QQuickImageProviderOptions())) pixmap = new QQuickPixmap(engine, requestedUrl); else pixmap = new QQuickPixmap(requestedUrl, _movie->currentImage()); diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index 7b281623fe..cf6f83e5b1 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -108,7 +108,9 @@ public: bool isAccepted() { return event.isAccepted(); } void setAccepted(bool accepted) { event.setAccepted(accepted); } +#if QT_CONFIG(shortcut) Q_REVISION(2) Q_INVOKABLE bool matches(QKeySequence::StandardKey key) const { return event.matches(key); } +#endif private: QKeyEvent event; diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp index f71a2fbdbd..f3d7dc4b56 100644 --- a/src/quick/items/qquickimage.cpp +++ b/src/quick/items/qquickimage.cpp @@ -514,37 +514,41 @@ void QQuickImage::updatePaintedGeometry() setImplicitSize(0, 0); return; } - qreal w = widthValid() ? width() : d->pix.width(); - qreal widthScale = w / qreal(d->pix.width()); - qreal h = heightValid() ? height() : d->pix.height(); - qreal heightScale = h / qreal(d->pix.height()); + const qreal pixWidth = d->pix.width() / d->devicePixelRatio; + const qreal pixHeight = d->pix.height() / d->devicePixelRatio; + const qreal w = widthValid() ? width() : pixWidth; + const qreal widthScale = w / pixWidth; + const qreal h = heightValid() ? height() : pixHeight; + const qreal heightScale = h / pixHeight; if (widthScale <= heightScale) { d->paintedWidth = w; - d->paintedHeight = widthScale * qreal(d->pix.height()); + d->paintedHeight = widthScale * pixHeight; } else if (heightScale < widthScale) { - d->paintedWidth = heightScale * qreal(d->pix.width()); + d->paintedWidth = heightScale * pixWidth; d->paintedHeight = h; } - qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : d->pix.height(); - qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : d->pix.width(); + const qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : pixHeight; + const qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : pixWidth; setImplicitSize(iWidth, iHeight); } else if (d->fillMode == PreserveAspectCrop) { if (!d->pix.width() || !d->pix.height()) return; - qreal widthScale = width() / qreal(d->pix.width()); - qreal heightScale = height() / qreal(d->pix.height()); + const qreal pixWidth = d->pix.width() / d->devicePixelRatio; + const qreal pixHeight = d->pix.height() / d->devicePixelRatio; + qreal widthScale = width() / pixWidth; + qreal heightScale = height() / pixHeight; if (widthScale < heightScale) { widthScale = heightScale; } else if (heightScale < widthScale) { heightScale = widthScale; } - d->paintedHeight = heightScale * qreal(d->pix.height()); - d->paintedWidth = widthScale * qreal(d->pix.width()); + d->paintedHeight = heightScale * pixHeight; + d->paintedWidth = widthScale * pixWidth; } else if (d->fillMode == Pad) { - d->paintedWidth = d->pix.width(); - d->paintedHeight = d->pix.height(); + d->paintedWidth = d->pix.width() / d->devicePixelRatio; + d->paintedHeight = d->pix.height() / d->devicePixelRatio; } else { d->paintedWidth = width(); d->paintedHeight = height(); diff --git a/src/quick/items/qquickimage_p_p.h b/src/quick/items/qquickimage_p_p.h index 522dbca803..afc33def0f 100644 --- a/src/quick/items/qquickimage_p_p.h +++ b/src/quick/items/qquickimage_p_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE class QQuickImageTextureProvider; -class QQuickImagePrivate : public QQuickImageBasePrivate +class Q_QUICK_PRIVATE_EXPORT QQuickImagePrivate : public QQuickImageBasePrivate { Q_DECLARE_PUBLIC(QQuickImage) diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp index 22d631e917..33d69f5032 100644 --- a/src/quick/items/qquickimagebase.cpp +++ b/src/quick/items/qquickimagebase.cpp @@ -49,6 +49,30 @@ QT_BEGIN_NAMESPACE +// This function gives derived classes the chance set the devicePixelRatio +// if they're not happy with our implementation of it. +bool QQuickImageBasePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio) +{ + // QQuickImageProvider and SVG can generate a high resolution image when + // sourceSize is set (this function is only called if it's set). + // If sourceSize is not set then the provider default size will be used, as usual. + bool setDevicePixelRatio = false; + if (url.scheme() == QLatin1String("image")) { + setDevicePixelRatio = true; + } else { + QString stringUrl = url.path(QUrl::PrettyDecoded); + if (stringUrl.endsWith(QLatin1String("svg")) || + stringUrl.endsWith(QLatin1String("svgz"))) { + setDevicePixelRatio = true; + } + } + + if (setDevicePixelRatio) + devicePixelRatio = targetDevicePixelRatio; + + return setDevicePixelRatio; +} + QQuickImageBase::QQuickImageBase(QQuickItem *parent) : QQuickImplicitSizeItem(*(new QQuickImageBasePrivate), parent) { @@ -221,26 +245,11 @@ void QQuickImageBase::load() QUrl loadUrl = d->url; - // QQuickImageProvider and SVG can generate a high resolution image when - // sourceSize is set. If sourceSize is not set then the provider default size - // will be used, as usual. - bool setDevicePixelRatio = false; - if (d->sourcesize.isValid()) { - if (loadUrl.scheme() == QLatin1String("image")) { - setDevicePixelRatio = true; - } else { - QString stringUrl = loadUrl.path(QUrl::PrettyDecoded); - if (stringUrl.endsWith(QLatin1String("svg")) || - stringUrl.endsWith(QLatin1String("svgz"))) { - setDevicePixelRatio = true; - } - } - - if (setDevicePixelRatio) - d->devicePixelRatio = targetDevicePixelRatio; - } + bool updatedDevicePixelRatio = false; + if (d->sourcesize.isValid()) + updatedDevicePixelRatio = d->updateDevicePixelRatio(targetDevicePixelRatio); - if (!setDevicePixelRatio) { + if (!updatedDevicePixelRatio) { // (possible) local file: loadUrl and d->devicePixelRatio will be modified if // an "@2x" file is found. resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio); diff --git a/src/quick/items/qquickimagebase_p_p.h b/src/quick/items/qquickimagebase_p_p.h index d9b609c7fe..1b771166a2 100644 --- a/src/quick/items/qquickimagebase_p_p.h +++ b/src/quick/items/qquickimagebase_p_p.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE class QNetworkReply; -class QQuickImageBasePrivate : public QQuickImplicitSizeItemPrivate +class Q_QUICK_PRIVATE_EXPORT QQuickImageBasePrivate : public QQuickImplicitSizeItemPrivate { Q_DECLARE_PUBLIC(QQuickImageBase) @@ -75,6 +75,8 @@ public: { } + virtual bool updateDevicePixelRatio(qreal targetDevicePixelRatio); + QQuickPixmap pix; QQuickImageBase::Status status; QUrl url; diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index f7b9a58329..22ee3f39e4 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -7865,6 +7865,7 @@ QQuickItemLayer::QQuickItemLayer(QQuickItem *item) , m_effect(0) , m_effectSource(0) , m_textureMirroring(QQuickShaderEffectSource::MirrorVertically) + , m_samples(0) { } @@ -7939,6 +7940,7 @@ void QQuickItemLayer::activate() m_effectSource->setWrapMode(m_wrapMode); m_effectSource->setFormat(m_format); m_effectSource->setTextureMirroring(m_textureMirroring); + m_effectSource->setSamples(m_samples); if (m_effectComponent) activateEffect(); @@ -8232,6 +8234,44 @@ void QQuickItemLayer::setTextureMirroring(QQuickShaderEffectSource::TextureMirro } /*! + \qmlproperty enumeration QtQuick::Item::layer.samples + \since 5.10 + + This property allows requesting multisampled rendering in the layer. + + By default multisampling is enabled whenever multisampling is + enabled for the entire window, assuming the scenegraph renderer in + use and the underlying graphics API supports this. + + By setting the value to 2, 4, etc. multisampled rendering can be requested + for a part of the scene without enabling multisampling for the entire + scene. This way multisampling is applied only to a given subtree, which can + lead to significant performance gains since multisampling is not applied to + other parts of the scene. + + \note Enabling multisampling can be potentially expensive regardless of the + layer's size, as it incurs a hardware and driver dependent performance and + memory cost. + + \note This property is only functional when support for multisample + renderbuffers and framebuffer blits is available. Otherwise the value is + silently ignored. + */ + +void QQuickItemLayer::setSamples(int count) +{ + if (m_samples == count) + return; + + m_samples = count; + + if (m_effectSource) + m_effectSource->setSamples(m_samples); + + emit samplesChanged(count); +} + +/*! \qmlproperty string QtQuick::Item::layer.samplerName Holds the name of the effect's source texture property. diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index c0c9bd46bd..797ba42781 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -152,6 +152,8 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener Q_PROPERTY(QByteArray samplerName READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QQmlComponent *effect READ effect WRITE setEffect NOTIFY effectChanged) Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged) + Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged) + public: QQuickItemLayer(QQuickItem *item); ~QQuickItemLayer(); @@ -189,6 +191,9 @@ public: QQuickShaderEffectSource::TextureMirroring textureMirroring() const { return m_textureMirroring; } void setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring); + int samples() const { return m_samples; } + void setSamples(int count); + QQuickShaderEffectSource *effectSource() const { return m_effectSource; } void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) Q_DECL_OVERRIDE; @@ -213,6 +218,7 @@ Q_SIGNALS: void formatChanged(QQuickShaderEffectSource::Format format); void sourceRectChanged(const QRectF &sourceRect); void textureMirroringChanged(QQuickShaderEffectSource::TextureMirroring mirroring); + void samplesChanged(int count); private: friend class QQuickTransformAnimatorJob; @@ -237,6 +243,7 @@ private: QQuickItem *m_effect; QQuickShaderEffectSource *m_effectSource; QQuickShaderEffectSource::TextureMirroring m_textureMirroring; + int m_samples; }; #endif diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp index 07c2cb607c..12bcd43076 100644 --- a/src/quick/items/qquickitemgrabresult.cpp +++ b/src/quick/items/qquickitemgrabresult.cpp @@ -75,7 +75,7 @@ public: void ensureImageInCache() const { if (url.isEmpty() && !image.isNull()) { - url.setScheme(QStringLiteral("ItemGrabber")); + url.setScheme(QQuickPixmap::itemGrabberScheme); url.setPath(QVariant::fromValue(item.data()).toString()); static uint counter = 0; url.setFragment(QString::number(++counter)); diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 65143f3e9b..43f4b88833 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -397,6 +397,10 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterUncreatableType<QQuickBasePositioner, 9>(uri, 2, 9, "Positioner", QStringLiteral("Positioner is an abstract type that is only available as an attached property.")); #endif + +#if QT_CONFIG(quick_shadereffect) + qmlRegisterType<QQuickShaderEffectSource, 2>(uri, 2, 9, "ShaderEffectSource"); +#endif } static void initResources() diff --git a/src/quick/items/qquickopenglshadereffect_p.h b/src/quick/items/qquickopenglshadereffect_p.h index 64e79a9343..bc2e2975ee 100644 --- a/src/quick/items/qquickopenglshadereffect_p.h +++ b/src/quick/items/qquickopenglshadereffect_p.h @@ -70,7 +70,6 @@ QT_REQUIRE_CONFIG(quick_shadereffect); QT_BEGIN_NAMESPACE class QSGContext; -class QSignalMapper; class QFileSelector; class QQuickOpenGLCustomMaterialShader; diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp index 05d3ae0191..70fc5fa65f 100644 --- a/src/quick/items/qquickpositioners.cpp +++ b/src/quick/items/qquickpositioners.cpp @@ -44,15 +44,23 @@ #include <QtQml/qqmlinfo.h> #include <QtCore/qcoreapplication.h> -#include <QtQuick/private/qquickstate_p.h> -#include <QtQuick/private/qquickstategroup_p.h> -#include <private/qquickstatechangescript_p.h> #include <QtQuick/private/qquicktransition_p.h> QT_BEGIN_NAMESPACE -static const QQuickItemPrivate::ChangeTypes watchedChanges - = QQuickItemPrivate::Geometry +// 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 | QQuickItemPrivate::SiblingOrder | QQuickItemPrivate::Visibility | QQuickItemPrivate::Destroyed; @@ -60,13 +68,15 @@ static const QQuickItemPrivate::ChangeTypes watchedChanges void QQuickBasePositionerPrivate::watchChanges(QQuickItem *other) { QQuickItemPrivate *otherPrivate = QQuickItemPrivate::get(other); - otherPrivate->addItemChangeListener(this, watchedChanges); + otherPrivate->addItemChangeListener(this, useImplicitSize + ? implicitSizeItemChangeTypes : explicitSizeItemChangeTypes); } void QQuickBasePositionerPrivate::unwatchChanges(QQuickItem* other) { QQuickItemPrivate *otherPrivate = QQuickItemPrivate::get(other); - otherPrivate->removeItemChangeListener(this, watchedChanges); + otherPrivate->removeItemChangeListener(this, useImplicitSize + ? implicitSizeItemChangeTypes : explicitSizeItemChangeTypes); } @@ -326,7 +336,7 @@ void QQuickBasePositioner::prePositioning() if (wIdx < 0) { d->watchChanges(child); posItem.isNew = true; - if (!childPrivate->explicitVisible || !child->width() || !child->height()) { + if (!childPrivate->explicitVisible || !d->itemWidth(child) || !d->itemHeight(child)) { posItem.isVisible = false; posItem.index = -1; unpositionedItems.append(posItem); @@ -348,7 +358,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 || !child->width() || !child->height()) { + if (!childPrivate->explicitVisible || !d->itemWidth(child) || !d->itemHeight(child)) { item->isVisible = false; item->index = -1; unpositionedItems.append(*item); @@ -947,6 +957,7 @@ 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)); @@ -955,9 +966,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(), child.item->width() + padding)); + contentSize->setWidth(qMax(contentSize->width(), d->itemWidth(child.item) + padding)); - voffset += child.item->height(); + voffset += d->itemHeight(child.item); voffset += spacing(); } @@ -1137,7 +1148,7 @@ public: : QQuickBasePositionerPrivate() {} - void effectiveLayoutDirectionChange() + void effectiveLayoutDirectionChange() override { Q_Q(QQuickRow); // For RTL layout the positioning changes when the width changes. @@ -1225,9 +1236,9 @@ void QQuickRow::doPositioning(QSizeF *contentSize) hoffsets << hoffset; } - contentSize->setHeight(qMax(contentSize->height(), child.item->height() + padding)); + contentSize->setHeight(qMax(contentSize->height(), d->itemHeight(child.item) + padding)); - hoffset += child.item->width(); + hoffset += d->itemWidth(child.item); hoffset += spacing(); } @@ -1248,7 +1259,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++] - child.item->width(); + hoffset = end - hoffsets[acc++] - d->itemWidth(child.item); positionItem(hoffset, child.itemY() + topPadding() - child.topPadding, &child); child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding()); } @@ -1436,7 +1447,7 @@ public: : QQuickBasePositionerPrivate() {} - void effectiveLayoutDirectionChange() + void effectiveLayoutDirectionChange() override { Q_Q(QQuickGrid); // For RTL layout the positioning changes when the width changes. @@ -1749,10 +1760,12 @@ void QQuickGrid::doPositioning(QSizeF *contentSize) break; const PositionedItem &child = positionedItems.at(childIndex++); - if (child.item->width() > maxColWidth[j]) - maxColWidth[j] = child.item->width(); - if (child.item->height() > maxRowHeight[i]) - maxRowHeight[i] = child.item->height(); + 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; } } } else { @@ -1767,10 +1780,12 @@ void QQuickGrid::doPositioning(QSizeF *contentSize) break; const PositionedItem &child = positionedItems.at(childIndex++); - if (child.item->width() > maxColWidth[j]) - maxColWidth[j] = child.item->width(); - if (child.item->height() > maxRowHeight[i]) - maxRowHeight[i] = child.item->height(); + 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; } } } @@ -1812,20 +1827,22 @@ 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] - child.item->width(); + childXOffset += maxColWidth[curCol] - childWidth; else if (hItemAlign() == AlignHCenter) - childXOffset += (maxColWidth[curCol] - child.item->width())/2.0; + childXOffset += (maxColWidth[curCol] - childWidth)/2.0; if (!d->isLeftToRight()) childXOffset -= maxColWidth[curCol]; qreal alignYOffset = yoffset; if (m_vItemAlign == AlignVCenter) - alignYOffset += (maxRowHeight[curRow] - child.item->height())/2.0; + alignYOffset += (maxRowHeight[curRow] - childHeight)/2.0; else if (m_vItemAlign == AlignBottom) - alignYOffset += maxRowHeight[curRow] - child.item->height(); + alignYOffset += maxRowHeight[curRow] - childHeight; positionItem(childXOffset, alignYOffset, &child); child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding()); @@ -2023,7 +2040,7 @@ public: : QQuickBasePositionerPrivate(), flow(QQuickFlow::LeftToRight) {} - void effectiveLayoutDirectionChange() + void effectiveLayoutDirectionChange() override { Q_Q(QQuickFlow); // Don't postpone, as it might be the only trigger for visible changes. @@ -2143,15 +2160,17 @@ 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 + child.item->width() + hoffset2 > width()) { + if (widthValid() && hoffset != hoffset1 && hoffset + childWidth + hoffset2 > width()) { hoffset = hoffset1; voffset += linemax + spacing(); linemax = 0; } } else { - if (heightValid() && voffset != voffset1 && voffset + child.item->height() + bottomPadding() > height()) { + if (heightValid() && voffset != voffset1 && voffset + childHeight + bottomPadding() > height()) { voffset = voffset1; hoffset += linemax + spacing(); linemax = 0; @@ -2168,17 +2187,17 @@ void QQuickFlow::doPositioning(QSizeF *contentSize) child.bottomPadding = bottomPadding(); } - contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width() + hoffset2)); - contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height() + bottomPadding())); + contentSize->setWidth(qMax(contentSize->width(), hoffset + childWidth + hoffset2)); + contentSize->setHeight(qMax(contentSize->height(), voffset + childHeight + bottomPadding())); if (d->flow == LeftToRight) { - hoffset += child.item->width(); + hoffset += childWidth; hoffset += spacing(); - linemax = qMax(linemax, child.item->height()); + linemax = qMax(linemax, childHeight); } else { - voffset += child.item->height(); + voffset += childHeight; voffset += spacing(); - linemax = qMax(linemax, child.item->width()); + linemax = qMax(linemax, childWidth); } } @@ -2193,7 +2212,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++] - child.item->width(); + hoffset = end - hoffsets[acc++] - d->itemWidth(child.item); positionItemX(hoffset, &child); child.leftPadding = leftPadding(); child.rightPadding = rightPadding(); @@ -2217,4 +2236,18 @@ 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 ae6e795794..8dc0d90a2f 100644 --- a/src/quick/items/qquickpositioners_p.h +++ b/src/quick/items/qquickpositioners_p.h @@ -58,7 +58,6 @@ QT_REQUIRE_CONFIG(quick_positioners); #include "qquickimplicitsizeitem_p.h" #include "qquickitemviewtransition_p.h" -#include <QtQuick/private/qquickstate_p.h> #include <private/qpodvector_p.h> #include <QtCore/qobject.h> @@ -133,6 +132,11 @@ 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; @@ -183,7 +187,7 @@ protected: virtual void doPositioning(QSizeF *contentSize)=0; virtual void reportConflictingAnchors()=0; - class PositionedItem + class Q_QUICK_PRIVATE_EXPORT PositionedItem { public : PositionedItem(QQuickItem *i); @@ -228,7 +232,7 @@ private: Q_DECLARE_PRIVATE(QQuickBasePositioner) }; -class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner +class Q_QUICK_PRIVATE_EXPORT QQuickColumn : public QQuickBasePositioner { Q_OBJECT public: @@ -242,7 +246,7 @@ private: }; class QQuickRowPrivate; -class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner +class Q_QUICK_PRIVATE_EXPORT QQuickRow: public QQuickBasePositioner { Q_OBJECT Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged) @@ -267,7 +271,7 @@ private: }; class QQuickGridPrivate; -class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner +class Q_QUICK_PRIVATE_EXPORT QQuickGrid : public QQuickBasePositioner { Q_OBJECT Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged) @@ -354,7 +358,7 @@ private: }; class QQuickFlowPrivate; -class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner +class Q_QUICK_PRIVATE_EXPORT QQuickFlow: public QQuickBasePositioner { Q_OBJECT Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged) @@ -387,6 +391,22 @@ 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 @@ -394,6 +414,8 @@ 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 6dd84e6098..1a7051615c 100644 --- a/src/quick/items/qquickpositioners_p_p.h +++ b/src/quick/items/qquickpositioners_p_p.h @@ -58,9 +58,6 @@ QT_REQUIRE_CONFIG(quick_positioners); #include "qquickpositioners_p.h" #include "qquickimplicitsizeitem_p_p.h" -#include <QtQuick/private/qquickstate_p.h> -#include <private/qquicktransitionmanager_p_p.h> -#include <private/qquickstatechangescript_p.h> #include <private/qlazilyallocated_p.h> #include <QtCore/qobject.h> @@ -92,10 +89,14 @@ public: QLazilyAllocated<ExtraData> extra; QQuickBasePositionerPrivate() - : spacing(0), type(QQuickBasePositioner::None) - , transitioner(0), positioningDirty(false) - , doingPositioning(false), anchorConflict(false), layoutDirection(Qt::LeftToRight) - + : spacing(0) + , type(QQuickBasePositioner::None) + , transitioner(0) + , positioningDirty(false) + , doingPositioning(false) + , anchorConflict(false) + , useImplicitSize(false) + , layoutDirection(Qt::LeftToRight) { } @@ -122,6 +123,7 @@ public: bool positioningDirty : 1; bool doingPositioning : 1; bool anchorConflict : 1; + bool useImplicitSize : 1; Qt::LayoutDirection layoutDirection; @@ -177,6 +179,34 @@ 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/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp index 9347b55c70..20c6973ee1 100644 --- a/src/quick/items/qquickscreen.cpp +++ b/src/quick/items/qquickscreen.cpp @@ -207,9 +207,9 @@ QT_BEGIN_NAMESPACE By default it is set to the value of the QScreen that the window uses. */ -QQuickScreenInfo::QQuickScreenInfo(QObject *parent) - : QObject(parent), - m_screen(nullptr) +QQuickScreenInfo::QQuickScreenInfo(QObject *parent, QScreen *wrappedScreen) + : QObject(parent) + , m_screen(wrappedScreen) { } diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h index 06efb3ab45..99e1466631 100644 --- a/src/quick/items/qquickscreen_p.h +++ b/src/quick/items/qquickscreen_p.h @@ -84,7 +84,7 @@ class Q_AUTOTEST_EXPORT QQuickScreenInfo : public QObject Q_PROPERTY(int virtualY READ virtualY NOTIFY virtualYChanged REVISION 1) public: - QQuickScreenInfo(QObject *parent = nullptr); + QQuickScreenInfo(QObject *parent = nullptr, QScreen *wrappedScreen = nullptr); QString name() const; int width() const; diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index 1b37a746d3..c782ddb5f7 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -189,6 +189,7 @@ QQuickShaderEffectSource::QQuickShaderEffectSource(QQuickItem *parent) , m_sourceItem(0) , m_textureSize(0, 0) , m_format(RGBA) + , m_samples(0) , m_live(true) , m_hideSource(false) , m_mipmap(false) @@ -582,6 +583,44 @@ void QQuickShaderEffectSource::setTextureMirroring(TextureMirroring mirroring) } /*! + \qmlproperty int QtQuick::ShaderEffectSource::samples + \since 5.10 + + This property allows requesting multisampled rendering. + + By default multisampling is enabled whenever multisampling is enabled for + the entire window, assuming the scenegraph renderer in use and the + underlying graphics API supports this. + + By setting the value to 2, 4, etc. multisampled rendering can be requested + for a part of the scene without enabling multisampling for the entire + scene. This way multisampling is applied only to a given subtree, which can + lead to significant performance gains since multisampling is not applied to + other parts of the scene. + + \note Enabling multisampling can be potentially expensive regardless of the + layer's size, as it incurs a hardware and driver dependent performance and + memory cost. + + \note This property is only functional when support for multisample + renderbuffers and framebuffer blits is available. Otherwise the value is + silently ignored. + */ +int QQuickShaderEffectSource::samples() const +{ + return m_samples; +} + +void QQuickShaderEffectSource::setSamples(int count) +{ + if (count == m_samples) + return; + m_samples = count; + update(); + emit samplesChanged(); +} + +/*! \qmlmethod QtQuick::ShaderEffectSource::scheduleUpdate() Schedules a re-rendering of the texture for the next frame. @@ -683,6 +722,7 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint m_texture->setHasMipmaps(m_mipmap); m_texture->setMirrorHorizontal(m_textureMirroring & MirrorHorizontally); m_texture->setMirrorVertical(m_textureMirroring & MirrorVertically); + m_texture->setSamples(m_samples); if (m_grab) m_texture->scheduleUpdate(); diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h index 5e7e354feb..d9f9079a3d 100644 --- a/src/quick/items/qquickshadereffectsource_p.h +++ b/src/quick/items/qquickshadereffectsource_p.h @@ -88,6 +88,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged) Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged) Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 1) + Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 2) public: enum WrapMode { @@ -150,6 +151,9 @@ public: Q_INVOKABLE void scheduleUpdate(); + int samples() const; + void setSamples(int count); + Q_SIGNALS: void wrapModeChanged(); void sourceItemChanged(); @@ -161,6 +165,7 @@ Q_SIGNALS: void mipmapChanged(); void recursiveChanged(); void textureMirroringChanged(); + void samplesChanged(); void scheduledUpdateCompleted(); @@ -185,6 +190,7 @@ private: QRectF m_sourceRect; QSize m_textureSize; Format m_format; + int m_samples; uint m_live : 1; uint m_hideSource : 1; uint m_mipmap : 1; diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 965fb0102f..1720377046 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -74,7 +74,7 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_HOVER_TRACE) const QChar QQuickTextPrivate::elideChar = QChar(0x2026); QQuickTextPrivate::QQuickTextPrivate() - : elideLayout(0), textLine(0), lineWidth(0) + : fontInfo(font), elideLayout(0), textLine(0), lineWidth(0) , color(0xFF000000), linkColor(0xFF0000FF), styleColor(0xFF000000) , lineCount(1), multilengthEos(-1) , elideMode(QQuickText::ElideNone), hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop) @@ -1018,6 +1018,17 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline) implicitWidthValid = true; implicitHeightValid = true; + QFontInfo scaledFontInfo(scaledFont); + if (fontInfo.weight() != scaledFontInfo.weight() + || fontInfo.pixelSize() != scaledFontInfo.pixelSize() + || fontInfo.italic() != scaledFontInfo.italic() + || !qFuzzyCompare(fontInfo.pointSizeF(), scaledFontInfo.pointSizeF()) + || fontInfo.family() != scaledFontInfo.family() + || fontInfo.styleName() != scaledFontInfo.styleName()) { + fontInfo = scaledFontInfo; + emit q->fontInfoChanged(); + } + if (eos != multilengthEos) truncated = true; @@ -2974,4 +2985,80 @@ void QQuickText::resetBottomPadding() d->setBottomPadding(0, true); } +/*! + \qmlproperty string QtQuick::Text::fontInfo.family + \since 5.9 + + The family name of the font that has been resolved for the current font + and fontSizeMode. +*/ + +/*! + \qmlproperty string QtQuick::Text::fontInfo.styleName + \since 5.9 + + The style name of the font info that has been resolved for the current font + and fontSizeMode. +*/ + +/*! + \qmlproperty bool QtQuick::Text::fontInfo.bold + \since 5.9 + + The bold state of the font info that has been resolved for the current font + and fontSizeMode. This is true if the weight of the resolved font is bold or higher. +*/ + +/*! + \qmlproperty int QtQuick::Text::fontInfo.weight + \since 5.9 + + The weight of the font info that has been resolved for the current font + and fontSizeMode. +*/ + +/*! + \qmlproperty bool QtQuick::Text::fontInfo.italic + \since 5.9 + + The italic state of the font info that has been resolved for the current font + and fontSizeMode. +*/ + +/*! + \qmlproperty real QtQuick::Text::fontInfo.pointSize + \since 5.9 + + The pointSize of the font info that has been resolved for the current font + and fontSizeMode. +*/ + +/*! + \qmlproperty string QtQuick::Text::fontInfo.pixelSize + \since 5.9 + + The pixel size of the font info that has been resolved for the current font + and fontSizeMode. +*/ +QJSValue QQuickText::fontInfo() const +{ + Q_D(const QQuickText); + + QJSEngine *engine = qjsEngine(this); + if (!engine) { + qmlWarning(this) << "fontInfo: item has no JS engine"; + return QJSValue(); + } + + QJSValue value = engine->newObject(); + value.setProperty(QStringLiteral("family"), d->fontInfo.family()); + value.setProperty(QStringLiteral("styleName"), d->fontInfo.styleName()); + value.setProperty(QStringLiteral("bold"), d->fontInfo.bold()); + value.setProperty(QStringLiteral("weight"), d->fontInfo.weight()); + value.setProperty(QStringLiteral("italic"), d->fontInfo.italic()); + value.setProperty(QStringLiteral("pointSize"), d->fontInfo.pointSizeF()); + value.setProperty(QStringLiteral("pixelSize"), d->fontInfo.pixelSize()); + return value; +} + QT_END_NAMESPACE diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h index c3d3906e7e..b190738cfb 100644 --- a/src/quick/items/qquicktext_p.h +++ b/src/quick/items/qquicktext_p.h @@ -98,6 +98,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6) Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6) + Q_PROPERTY(QJSValue fontInfo READ fontInfo NOTIFY fontInfoChanged REVISION 9) + public: QQuickText(QQuickItem *parent=0); ~QQuickText(); @@ -248,6 +250,8 @@ public: void setBottomPadding(qreal padding); void resetBottomPadding(); + QJSValue fontInfo() const; + Q_SIGNALS: void textChanged(const QString &text); void linkActivated(const QString &link); @@ -280,6 +284,7 @@ Q_SIGNALS: Q_REVISION(6) void leftPaddingChanged(); Q_REVISION(6) void rightPaddingChanged(); Q_REVISION(6) void bottomPaddingChanged(); + Q_REVISION(9) void fontInfoChanged(); protected: QQuickText(QQuickTextPrivate &dd, QQuickItem *parent = 0); diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h index 0669bcf115..6456750359 100644 --- a/src/quick/items/qquicktext_p_p.h +++ b/src/quick/items/qquicktext_p_p.h @@ -122,6 +122,7 @@ public: QString text; QFont font; QFont sourceFont; + QFontInfo fontInfo; QTextLayout layout; QTextLayout *elideLayout; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 660c5f8067..57810e4ec9 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -453,8 +453,13 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size) fboId = renderTargetId; renderer->setDeviceRect(rect); renderer->setViewportRect(rect); - renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), rect.size())); - renderer->setDevicePixelRatio(1); + if (QQuickRenderControl::renderWindowFor(q)) { + renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), size)); + renderer->setDevicePixelRatio(devicePixelRatio); + } else { + renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), rect.size())); + renderer->setDevicePixelRatio(1); + } } else { QRect rect(QPoint(0, 0), devicePixelRatio * size); renderer->setDeviceRect(rect); @@ -1798,7 +1803,7 @@ bool QQuickWindowPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event QPointF p = item->mapFromScene(event->posF()); if (item->contains(p)) { - QWheelEvent wheel(p, p, event->pixelDelta(), event->angleDelta(), event->delta(), + QWheelEvent wheel(p, event->globalPosF(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted()); wheel.setTimestamp(event->timestamp()); wheel.accept(); @@ -4167,25 +4172,25 @@ void QQuickWindow::resetOpenGLState() */ /*! - \qmlproperty variant Window::targetScreen - - Specifies the screen the window should be placed on. Equivalent to - QWindow::setScreen(). + \qmlproperty variant Window::screen - The value must be an element from the Qt.application.screens array. + The screen with which the window is associated. - By default the value is null which leads to using the primary screen. + If specified before showing a window, will result in the window being shown + on that screen, unless an explicit window position has been set. The value + must be an element from the Qt.application.screens array. - \note To ensure that the window is associated with the desired screen right - upon the underlying native window's initial creation, make sure this - property is set as early as possible and that the setting of its value is - not deferred. This can be particularly important on embedded platforms - without a windowing system, where only one window per screen is allowed at a - time. + \note To ensure that the window is associated with the desired screen when + the underlying native window is created, make sure this property is set as + early as possible and that the setting of its value is not deferred. This + can be particularly important on embedded platforms without a windowing system, + where only one window per screen is allowed at a time. Setting the screen after + a window has been created does not move the window if the new screen is part of + the same virtual desktop as the old screen. \since 5.9 - \sa QWindow::setScreen(), QScreen, Qt.application + \sa QWindow::setScreen(), QWindow::screen(), QScreen, Qt.application */ /*! diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index 42313e4584..6211b7802f 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -59,7 +59,6 @@ public: : complete(false) , visible(false) , visibility(QQuickWindow::AutomaticVisibility) - , targetScreen(nullptr) { } @@ -67,7 +66,6 @@ public: bool visible; QQuickWindow::Visibility visibility; QV4::PersistentValue rootItemMarker; - QObject *targetScreen; }; QQuickWindowQmlImpl::QQuickWindowQmlImpl(QWindow *parent) @@ -75,6 +73,7 @@ QQuickWindowQmlImpl::QQuickWindowQmlImpl(QWindow *parent) { connect(this, &QWindow::visibleChanged, this, &QQuickWindowQmlImpl::visibleChanged); connect(this, &QWindow::visibilityChanged, this, &QQuickWindowQmlImpl::visibilityChanged); + connect(this, &QWindow::screenChanged, this, &QQuickWindowQmlImpl::screenChanged); } void QQuickWindowQmlImpl::setVisible(bool visible) @@ -175,24 +174,15 @@ void QQuickWindowQmlImpl::setWindowVisibility() } } -QObject *QQuickWindowQmlImpl::targetScreen() const +QObject *QQuickWindowQmlImpl::screen() const { - Q_D(const QQuickWindowQmlImpl); - return d->targetScreen; + return new QQuickScreenInfo(const_cast<QQuickWindowQmlImpl *>(this), QWindow::screen()); } -void QQuickWindowQmlImpl::setTargetScreen(QObject *screen) +void QQuickWindowQmlImpl::setScreen(QObject *screen) { - Q_D(QQuickWindowQmlImpl); - if (d->targetScreen != screen) { - d->targetScreen = screen; - emit targetScreenChanged(); - QQuickScreenInfo *screenWrapper = qobject_cast<QQuickScreenInfo *>(screen); - if (screenWrapper) - setScreen(screenWrapper->wrappedScreen()); - else - setScreen(nullptr); - } + QQuickScreenInfo *screenWrapper = qobject_cast<QQuickScreenInfo *>(screen); + QWindow::setScreen(screenWrapper ? screenWrapper->wrappedScreen() : nullptr); } void QQuickWindowModule::defineModule() diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h index 7ca29880ea..16130bc8a0 100644 --- a/src/quick/items/qquickwindowmodule_p.h +++ b/src/quick/items/qquickwindowmodule_p.h @@ -67,7 +67,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public Q Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) Q_PROPERTY(Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged) - Q_PROPERTY(QObject *targetScreen READ targetScreen WRITE setTargetScreen NOTIFY targetScreenChanged REVISION 2) + Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION 2) public: QQuickWindowQmlImpl(QWindow *parent = Q_NULLPTR); @@ -75,15 +75,15 @@ public: void setVisible(bool visible); void setVisibility(Visibility visibility); - QObject *targetScreen() const; - void setTargetScreen(QObject *screen); + QObject *screen() const; + void setScreen(QObject *screen); static QQuickWindowAttached *qmlAttachedProperties(QObject *object); Q_SIGNALS: void visibleChanged(bool arg); void visibilityChanged(QWindow::Visibility visibility); - Q_REVISION(2) void targetScreenChanged(); + Q_REVISION(2) void screenChanged(); protected: void classBegin() Q_DECL_OVERRIDE; |