diff options
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/doc/src/qtquick.qdoc | 6 | ||||
-rw-r--r-- | src/quick/doc/src/whatsnew.qdoc | 452 | ||||
-rw-r--r-- | src/quick/items/qquickanimatedimage.cpp | 33 | ||||
-rw-r--r-- | src/quick/items/qquickanimatedimage_p.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 8 | ||||
-rw-r--r-- | src/quick/items/qquickitem_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquickpathview.cpp | 20 | ||||
-rw-r--r-- | src/quick/items/qquicktextnodeengine.cpp | 97 | ||||
-rw-r--r-- | src/quick/items/qquicktextnodeengine_p.h | 29 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 3 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 4 | ||||
-rw-r--r-- | src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 4 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 19 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop_p.h | 1 | ||||
-rw-r--r-- | src/quick/util/qquickanimation_p_p.h | 2 | ||||
-rw-r--r-- | src/quick/util/qquickpath_p.h | 2 |
16 files changed, 177 insertions, 506 deletions
diff --git a/src/quick/doc/src/qtquick.qdoc b/src/quick/doc/src/qtquick.qdoc index 8d5680a1e3..98a77a48d8 100644 --- a/src/quick/doc/src/qtquick.qdoc +++ b/src/quick/doc/src/qtquick.qdoc @@ -42,9 +42,8 @@ The Qt Quick module provides both a \l{Qt Quick QML Types}{QML API} which suppli QML types for creating user interfaces with the QML language, and a \l{Qt Quick C++ Classes}{C++ API} for extending QML applications with C++ code. -\note From Qt 5.1, a set of Qt Quick based UI controls is available to -create user interfaces. Please see \l{Qt Quick Controls} -for more information. +\note A set of Qt Quick-based UI controls is also available to create user +interfaces. See \l{Qt Quick Controls} for more information. For those new to QML and Qt Quick, please see \l{QML Applications} @@ -108,7 +107,6 @@ Additional Qt Quick information: interacting with system dialogs \li \l{Qt Quick Test QML Types}{Tests} - contains types for writing unit test for a QML application \endlist -\li \l{Qt Quick Release Notes} - list of changes and additions in the Qt Quick \li \l{Qt Quick Examples and Tutorials} \endlist diff --git a/src/quick/doc/src/whatsnew.qdoc b/src/quick/doc/src/whatsnew.qdoc deleted file mode 100644 index b0a39e1dd3..0000000000 --- a/src/quick/doc/src/whatsnew.qdoc +++ /dev/null @@ -1,452 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! -\title Qt Quick Release Notes -\page qtquick-releasenotes.html - -\section1 Qt Quick in Qt 5.1 - -\l{Qt Quick} 2.1 is new in Qt 5.1. This is a summary of improvements and new -features introduced by the new import and new classes in Qt 5.1: -\list -\li New threaded render loop for Mac, Linux, and Embedded. -\li New render loop for windows for smoother animations. -\li New \l Window properties: activeFocusItem, minimumWidth, minimumHeight, - maximumWidth, maximumHeight, visibility, contentOrientation, and opacity. -\li New \l Screen attached properties: name, desktopAvailableWidth, - desktopAvailableHeight, logicalPixelDensity -\li New \l Grid properties: horizontalAlignment, verticalAlignment, and - effectiveHorizontalAlignment. -\li New \l TextEdit properties: selectByKeyboard and textDocument -\li A \l Window declared inside another Window or \l Item will automatically be - transient for (centered upon) the outer window. -\li These types are now part of \l{Qt QML}: - \list - \li \l {VisualItemModel} - \li \l {VisualDataModel} - Encapsulates a model and a delegate - \li \l {VisualDataGroup} - \endlist - These types are kept due to compatibility reasons and are replaced by the - \l{Qt QML Models QML Types}{Qt QML Models} types. -\endlist - -\section2 New Submodules - -In Qt 5.1, there are several new modules which extend Qt Quick functionalities. -\list -\li \l{Qt Quick Dialogs} - contains types for creating and interacting with system dialogs -\li \l{Qt Quick Controls} - provides a set of reusable UI components -\li \l{Qt Quick Layouts} - contains types that are used to arrange items in the user interface -\endlist - -The \l{What's New in Qt 5.1} has more information about the Qt 5.1 release. - -\section1 Qt Quick in Qt 5.0 - -The \l {Qt Quick} module is new in Qt 5. It provides the visual canvas and scenegraph back-end -as well as the \c QtQuick QML module for QML application development. - -As of Qt 5, the \l {Qt Quick} module is based on an OpenGL scenegraph. Many of the classes in -the \l {Qt Quick} module have been ported from the \l {Qt Quick 1}{QtDeclarative} module from Qt 4.8 to use -the scenegraph architecture; these classes have been renamed to use a \c QQuick* prefix. -(See the \l {Porting QML Applications to Qt 5} for porting information.) - -The following classes provide the basic functionality for interacting with the QML visual -canvas from C++: - -\list -\li QQuickItem - the base visual QML type (replaces \c QDeclarativeItem) -\li QQuickView - a convenience window for rendering a QML scene from a QML file (replaces \c QDeclarativeView) -\li QQuickWindow - a base window for displaying a QML scene -\li QQuickPaintedItem - convenience for using the QPainter API with the scenegraph -\li QQuickImageProvider - fetches custom images for use in QML applications (replaces \c - QDeclarativeImageProvider) -\li QQuickTextureFactory - use with QQuickImageProvider::requestTexture() -\endlist - -Custom rendering can be performed on the scenegraph using the following new classes: - -\list -\li QSGNode -\li QSGMaterial -\li QSGBasicGeometryNode -\li QSGGeometryNode -\li QSGClipNode -\li QSGTransformNode -\li QSGOpacityNode -\li QSGFlatColorMaterial -\li QSGSimpleRectNode -\li QSGSimpleTextureNode -\li QSGTexture -\li QSGDynamicTexture -\li QSGOpaqueTextureMaterial -\li QSGTextureMaterial -\li QSGTextureProvider -\li QSGVertexColorMaterial -\endlist - - -\section1 Qt 5.0 - QtQuick QML Module - -The \c {QtQuick 2.0} QML module is a major update. - -Below are the additions in \c {QtQuick 2.0}. For a list of behavioral changes which may affect -applications ported from \c {QtQuick 1.x}, see the \l {Porting QML Applications to Qt 5}. - -\section2 Visual types, Graphical Effects and Sprites - -\list -\li New \l Canvas type for drawing. This provides an API similar to that of the HTML5 Canvas API, - along with some additional features. - \list - \li Supports two render targets: \c Canvas.Image and \c Canvas.FramebufferObject. - \li Supports background thread rendering. - \li Supports tiled canvas rendering. - \li Supports most of the HTML5 context2d APIs. - \endlist -\li \l Item: - \list - \li New \l{Item::}{layer.enabled} property enables an item to be rendered into an offscreen - cache for optimization. - \li New \l{Item::}{contains()} method returns whether an item contains a specified point. - \li New \l{Item::}{anchors.alignWhenCentered} property can force centered anchors to align on a - whole pixel. - \li New \l{Item::}{enabled} property is available, which stops input event delivery and removes active focus. - \endlist -\li \l Image: - \list - \li New \l{Image::}{horizontalAlignment} and \l{Image::}{verticalAlignment} properties to set - the image alignment. - \li New \c Image.Pad enumeration value for \l{Image::}{fillMode} that does not transform the image, - unlike other \l{Image::}{fillMode} enumeration values. - \endlist -\li New ShaderEffect and ShaderEffectSource types enable GLSL shader programs to be integrated - directly into QML code and applied to QML items and images. (This obsoletes the experimental - Qt.labs.shaders module.) -\li New SpriteSequence type renders animated sprites and can transition between animations. Each - animation in a sequence is represented by the new \l Sprite type. -\li New AnimatedSprite type for drawing single sprite animations. -\endlist - - -\section2 Animations and Transitions -\list -\li New AnimationController type enables an animation to be manually driven by a - \l{AnimationController::}{progress} value. -\li New PathAnimation type animates an item along a \l Path. -\li New PathInterpolator type provides updated attribute values for an item animating along a path. - It can be used as an low-level alternative to PathAnimation. -\li \l Transition: - \list - \li New \l{Transition::}{running} property holds whether a transition is currently running. - \li New \l{Transition::}{enabled} property controls whether a transition is enabled. - \endlist -\endlist - - -\section2 Paths -\list -\li New PathArc type creates an arc-type path. -\li New PathCurve type creates a catmull-rom curve path. -\li New PathSvg type creates a path from a SVG string. -\li Changes common to PathLine, PathQuad and PathCubic: - \list - \li New \c relativeX and \c relativeY properties define the start and end points of a path -relative to its start. - \endlist -\li PathCubic only: - \list - \li New \l{PathCubic::}{relativeControl1X}, \l{PathCubic::}{relativeControl1Y}, - \l{PathCubic::}{relativeControl2X} and \l{PathCubic::}{relativeControl2Y} properties define the - positions of the control points relative to the start of the curve. - \endlist -\li PathQuad only: - \list - \li New \l{PathQuad::}{relativeControlX} and \l{PathQuad::}{relativeControlY} - define the positions of the control points relative to the start of the curve. - \endlist -\endlist - - -\section2 Text Rendering and Input - -\list -\li Changes common to \l Text, TextEdit and TextInput: - \list - \li New \c contentWidth and \c contentHeight properties provide the dimensions of the textual - content. - \li New \c effectiveHorizontalAlignment property provides the read-only actual horizontal - alignment. - \endlist -\li Changes common to both TextEdit and TextInput: - \list - \li New \c canUndo and \c canRedo properties specify whether undo and redo operations are - available. - \li New \c getText() method returns the text located between specified start and end indexes. - Additionally TextEdit has a \l{TextEdit::}{getFormattedText()} method that returns the formatted - text. - \endlist -\li \l Text only: - \list - \li \c Text.RightElide is now supported where text spans multiple lines. - \li New \l{Text::}{linkColor} property controls the color of linked text. - \li New \l{Text::}{lineLaidOut} signal is emitted for every line during the layout process to - give the option of positioning and/or resizing lines as they are laid out. - \li New \l{Text::}{doLayout()} method will trigger the text layout from Javascript. - \li New \l{Text::}{fontSizeMode} property allows text to be fitted to the item size. - \li New \l{Text::}{minimumPixelSize} and \l {Text::}{minimumPointSize} properties can be used to - specify a lower bound when auto-fitting. - \endlist -\li TextEdit only: - \list - \li New \l{TextEdit::}{baseUrl} property specified the base URL used to resolve relative URLs - within the text. - \endlist -\li TextInput only: - \list - \li New \l{TextInput::}{wrapMode} property sets the text wrapping mode. - \li New \l{TextInput::}{horizontalAlignment} and \l{TextInput::}{verticalAlignment} properties. - \li New \l{TextInput::}{length} property provides the total number of text characters. - \li New \l{TextInput::}{persistentSelection} property enables the text selection to persist when -the window loses focus. - \li \l{TextInput::}{positionAt()} method now takes a y parameter. - \endlist -\endlist - -\section2 User Input - -\list -\li New MultiPointTouchArea type processes multi-point touches and provides information on touch - points including position, pressure and velocity. Touch point data is provided by the new \l - TouchPoint type. -\li New DropArea type provides more advanced drag and drop functionality. -\li MouseArea: - \list - \li Wheel events are now supported; events are provided through the new WheelEvent type. - \li New \l{MouseArea::}{propagateComposedEvents} property sets whether composed events are - propagated to other mouse areas. If this property is true and the handlers of the - \l{MouseArea::}{clicked}, \l{MouseArea::}{doubleClicked} or \l{MouseArea::}{pressAndHold} - signals reject a mouse event, the event will be propagated to overlapping MouseArea items - in the same area that are lower in the stacking order. - \li New \l{MouseArea::}{cursorShape} property controls the cursor shape. - \endlist -\endlist - -\section2 Specialized Containers - -\list -\li Flickable: - \list - \li New \l{Flickable::}{rebound} property specifies the transition to be applied when a - flickable snaps back to its bounds. - \li New \l{Flickable::}{topMargin}, \l{Flickable::}{bottomMargin}, \l{Flickable::}{leftMargin}, - \l{Flickable::}{rightMargin} allow extra margin space to be specified for a flickable. This can be - used, for example, to implement pull-to-refresh functionality for a list. - \li New \l{Flickable::}{originX} and \l{Flickable::}{originY} properties provide the top left - position of the content item. - \li New \l{Flickable::}{dragging}, \l{Flickable::}{draggingHorizontally} and - \l{Flickable::}{draggingVertically} properties provide information on whether a flickable is - currently being dragged. - \li New \l{Flickable::}{flick()} method flicks the view with a specific velocity. - \li New \l{Flickable::}{cancelFlick()} method stops any current flicking movement. - \endlist -\endlist - -\section2 Positioners (Row, Column, Grid, Flow types): - -\list -\li Changes common to \l Row, \l Column, \l Grid and \l Flow: - \list - \li The \c add and \c move transitions can access a new ViewTransition attached property (see - the ViewTransition documentation for examples) and can now animate arbitrary item properties - (instead of being restricted to animating an item's position). - \li New \c effectiveLayoutDirection property provides the read-only actual layout direction of a - positioner. - \li New \l Positioner type provides \c index, \c isFirstItem and \c isLastItem attached - properties for items within positioners. - \li All \c spacing properties on positioners now use real numbers instead of integers. - \endlist -\li Grid only: - \list - \li New \l{Grid::}{rowSpacing} and \l{Grid::}{columnSpacing} properties. - \endlist -\endlist - -\section2 Models and Views - -\list -\li Any delegate of a view that uses a QAbstractItemModel-derived model type can use the syntax - \c {model.<role> = <newDataValue>} to modify the data for a particular role. (Previously, - the \c {model.<role>} syntax was only available for reading, not writing to, a role value.) -\li ListModel: - \list - \li By default, roles can no longer change type during a model's lifetime. The new - \l{ListModel::}{dynamicRoles} property can be set to restore the original (less performant) - behavior. - \endlist -\li VisualDataModel: - \list - \li Now has features to filter the items to be displayed in a view. This is supported by the new - \l {DelegateModel::}{groups}, \l {DelegateModel::}{filterOnGroup}, \l {DelegateModel::}{items} - and \l {DelegateModel::}{persistedItems} properties. - \endlist -\li Changes common to both ListView and GridView: - \list - \li New transition support for animating the adding, removing and moving of items in a ListView - or GridView. See the ViewTransition documentation for details. - \li New \c verticalLayoutDirection property enables items to be laid out from bottom-to-top - using the new \c BottomToTop enumeration value. - \li New \c headerItem and \c footerItem properties provide access to the instantiated header and - footer items. - \li The \c cacheBuffer property now has a non-zero default. - \li Delegates in the cache buffer are now created asynchronously. - \li Setting a \c RightToLeft layout now also reverses the \c preferredHighlightBegin and \c - preferredHighlightEnd. - \li If the model is changed after the component is completed, currentIndex is reset to 0. - \endlist -\li ListView only: - \list - \li New \l{ListView::}{section.labelPositioning} property can fix the current section label to - the start of the view, and the next section label to the end of the view, to prevent labels from - scrolling while section items are still in view. - \li \c highlightMoveSpeed and \c highlightResizeSpeed have been renamed to - \l{ListView::}{highlightMoveVelocity} and \l{ListView::}{highlightResizeVelocity}. - \endlist -\li GridView only: - \list - \li \l{GridView::}{cellWidth} and \l{GridView::}{cellHeight} now use real numbers instead of - integers. - \endlist -\li PathView: - \list - \li New \l{PathView::}{currentItem} property holds the current item in the view. - \li New \l{PathView::}{maximumFlickVelocity} property controls the maximum flick velocity of the - view. - \li New \l{PathView::}{snapMode} property controls the snap model when flicking between items - \li If the model is changed after the component is completed, the offset and currentIndex are - reset to 0. - \li New \l{PathView::}{positionViewAtIndex()} function allows the view to be moved to display - the specified index. - \li New \l{PathView::}{indexAt()} and \l{PathView::}{itemAt()} functions return the index or - item at a specified point in the view. - \endlist -\endlist - -\section2 Utility types - -\list -\li New \l Accessible attached property for implementing accessibility features in QML applications. -\li \l Loader: - \list - \li New \l{Loader::}{asynchronous} property allows components to be instantiated with lower - chance of blocking. If source is used with \e {asynchronous: true} the component will be compiled in - a background thread. - \li New \l{Loader::}{active} property can delay instantiation of a \l Loader object's - \l{Loader::}{item}. - \li New \l{Loader::}{setSource()} method loads an object with specific initial property values, - similar to \l Component::createObject(). - \endlist -\li \l Binding: - \list - \li This type can now be used as a value source, and will also restore any previously set - binding when its \l{Binding::}{when} clause becomes false. - \endlist -\endlist - -\section2 Property types - -Support for various math and geometry-related value types, including QVector2D, QVector3D, QVector4D, -QMatrix4x4 and QQuaternion, as well as QColor and QFont, are now provided by \l {Qt Quick}. Properties of -these types can be declared in QML documents via the property syntax where the type name is \c vector2d, -\c vector3d, \c vector4d, \c matrix4x4, \c quaternion, \c color and \c font respectively. - -\l {Qt Quick} also provides implementation for the various value type factory or utility functions of the -\c Qt object which return or operate on values of the above types. The functions are: -\table - \header - \li Value type - \li Functions - - \row - \li color - \li Qt.rgba(), Qt.hsla(), Qt.tint(), Qt.lighter(), Qt.darker(), Qt.colorEqual() - - \row - \li font - \li Qt.font(), Qt.fontFamilies() - - \row - \li vector2d - \li Qt.vector2d() - - \row - \li vector3d - \li Qt.vector3d() - - \row - \li vector4d - \li Qt.vector4d() - - \row - \li matrix4x4 - \li Qt.matrix4x4() - - \row - \li quaternion - \li Qt.quaternion() -\endtable - -The \c Qt.rgba(), \c Qt.hsla(), \c Qt.tint(), \c Qt.lighter(), \c Qt.darker() -and \c Qt.fontFamilies() functions already existed in \l {Qt Quick 1}{QtDeclarative} prior -to \l {Qt Quick}{Qt Quick 2}; the other functions are all new in \l {Qt Quick}{Qt Quick 2}. - -\section1 Qt 5.0 - Additional QML Modules - -\section2 QtQuick.Particles - -This new module provides particle system support for creating a variety of 2D particle systems. See -the \l QtQuick.Particles documentation for comprehensive details. - -This obsoletes the experimental \c Qt.labs.particles module. - -\section2 QtQuick.Window - -This new module contains the \l Window type for creating a basic window and the \l Screen type for -accessing a screen's resolution and other details. See the \l QtQuick.Window -documentation for comprehensive details. - -\section2 QtQuick.XmlListModel - -This new module contains XmlListModel and associated types, which were previously in the \c QtQuick -module. See the \l QtQuick.XmlListModel documentation for details. - -\section2 QtQuick.LocalStorage - -This new module provides access to the SQL Local Storage API that was previously accessible from the -\l {QML Global Object}. See the \l QtQuick.LocalStorage documentation for details. -*/ diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index a989e81176..49fef12467 100644 --- a/src/quick/items/qquickanimatedimage.cpp +++ b/src/quick/items/qquickanimatedimage.cpp @@ -104,7 +104,13 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine about its state, such as the current frame and total number of frames. The result is an animated image with a simple progress indicator underneath it. - \b Note: Unlike images, animated images are not cached or shared internally. + \b Note: When animated images are cached, every frame of the animation will be cached. + + Set cache to false if you are playing a long or large animation and you + want to conserve memory. + + If the image data comes from a sequential device (e.g. a socket), + AnimatedImage can only loop if cache is set to true. \clearfloat \snippet qml/animatedimage.qml document @@ -126,6 +132,7 @@ QQuickPixmap* QQuickAnimatedImagePrivate::infoForCurrentFrame(QQmlEngine *engine QQuickAnimatedImage::QQuickAnimatedImage(QQuickItem *parent) : QQuickImage(*(new QQuickAnimatedImagePrivate), parent) { + QObject::connect(this, &QQuickImageBase::cacheChanged, this, &QQuickAnimatedImage::onCacheChanged); } QQuickAnimatedImage::~QQuickAnimatedImage() @@ -372,7 +379,8 @@ void QQuickAnimatedImage::movieRequestFinished() this, SLOT(playingStatusChanged())); connect(d->_movie, SIGNAL(frameChanged(int)), this, SLOT(movieUpdate())); - d->_movie->setCacheMode(QMovie::CacheAll); + if (d->cache) + d->_movie->setCacheMode(QMovie::CacheAll); d->status = Ready; emit statusChanged(d->status); @@ -406,6 +414,11 @@ void QQuickAnimatedImage::movieUpdate() { Q_D(QQuickAnimatedImage); + if (!d->cache) { + qDeleteAll(d->frameMap); + d->frameMap.clear(); + } + if (d->_movie) { d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this))); emit frameChanged(); @@ -426,6 +439,22 @@ void QQuickAnimatedImage::playingStatusChanged() } } +void QQuickAnimatedImage::onCacheChanged() +{ + Q_D(QQuickAnimatedImage); + if (!cache()) { + qDeleteAll(d->frameMap); + d->frameMap.clear(); + if (d->_movie) { + d->_movie->setCacheMode(QMovie::CacheNone); + } + } else { + if (d->_movie) { + d->_movie->setCacheMode(QMovie::CacheAll); + } + } +} + QSize QQuickAnimatedImage::sourceSize() { Q_D(QQuickAnimatedImage); diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h index de37cd8209..409933817f 100644 --- a/src/quick/items/qquickanimatedimage_p.h +++ b/src/quick/items/qquickanimatedimage_p.h @@ -84,6 +84,7 @@ private Q_SLOTS: void movieUpdate(); void movieRequestFinished(); void playingStatusChanged(); + void onCacheChanged(); protected: void load() Q_DECL_OVERRIDE; diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 9c03a6db28..a9396051ab 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1041,7 +1041,7 @@ void QQuickFlickablePrivate::drag(qint64 currentTimestamp, QEvent::Type eventTyp } if (fuzzyLessThanOrEqualTo(minY, newY)) { newY = minY; - rejectY = vData.pressPos == minY && vData.move.value() == minY && dy > 0; + rejectY |= vData.pressPos == minY && vData.move.value() == minY && dy > 0; } } else { qreal vel = velocity.y() / QML_FLICK_OVERSHOOTFRICTION; @@ -1101,7 +1101,7 @@ void QQuickFlickablePrivate::drag(qint64 currentTimestamp, QEvent::Type eventTyp } if (fuzzyLessThanOrEqualTo(minX, newX)) { newX = minX; - rejectX = hData.pressPos == minX && hData.move.value() == minX && dx > 0; + rejectX |= hData.pressPos == minX && hData.move.value() == minX && dx > 0; } } else { qreal vel = velocity.x() / QML_FLICK_OVERSHOOTFRICTION; @@ -1527,13 +1527,13 @@ qreal QQuickFlickable::minXExtent() const qreal QQuickFlickable::maxXExtent() const { Q_D(const QQuickFlickable); - return width() - vWidth() - d->hData.endMargin; + return qMin<qreal>(0, width() - vWidth() - d->hData.endMargin); } /* returns -ve */ qreal QQuickFlickable::maxYExtent() const { Q_D(const QQuickFlickable); - return height() - vHeight() - d->vData.endMargin; + return qMin<qreal>(0, height() - vHeight() - d->vData.endMargin); } void QQuickFlickable::componentComplete() diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index f2ad487a0b..64d8bd0ede 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -58,7 +58,7 @@ #include <private/qpodvector_p.h> #include <QtQuick/private/qquickstate_p.h> -#include <private/qqmlnullablevalue_p_p.h> +#include <private/qqmlnullablevalue_p.h> #include <private/qqmlnotifier_p.h> #include <private/qqmlglobal_p.h> #include <private/qlazilyallocated_p.h> diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 352a939e1b..58605f79dd 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -35,6 +35,7 @@ #include "qquickpathview_p_p.h" #include "qquickwindow.h" #include "qquickflickablebehavior_p.h" //Contains flicking behavior defines +#include "qquicktext_p.h" #include <QtQuick/private/qquickstate_p.h> #include <private/qqmlglobal_p.h> @@ -52,6 +53,8 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcItemViewDelegateLifecycle) + const qreal MinimumFlickVelocity = 75.0; inline qreal qmlMod(qreal x, qreal y) @@ -194,6 +197,7 @@ void QQuickPathViewPrivate::releaseItem(QQuickItem *item) { if (!item || !model) return; + qCDebug(lcItemViewDelegateLifecycle) << "release" << item; QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry); QQmlInstanceModel::ReleaseFlags flags = model->release(item); @@ -824,9 +828,11 @@ void QQuickPathViewPrivate::setOffset(qreal o) Q_Q(QQuickPathView); if (offset != o) { if (isValid() && q->isComponentComplete()) { + qreal oldOffset = offset; offset = qmlMod(o, qreal(modelCount)); if (offset < 0) offset += qreal(modelCount); + qCDebug(lcItemViewDelegateLifecycle) << o << "was" << oldOffset << "now" << offset; q->refill(); } else { offset = o; @@ -1891,10 +1897,18 @@ void QQuickPathView::refill() // first move existing items and remove items off path int idx = d->firstIndex; + qCDebug(lcItemViewDelegateLifecycle) << "firstIndex" << idx << "currentIndex" << d->currentIndex << "offset" << d->offset; QList<QQuickItem*>::iterator it = d->items.begin(); while (it != d->items.end()) { qreal pos = d->positionOfIndex(idx); QQuickItem *item = *it; + if (lcItemViewDelegateLifecycle().isDebugEnabled()) { + QQuickText *text = qmlobject_cast<QQuickText*>(item); + if (text) + qCDebug(lcItemViewDelegateLifecycle) << "idx" << idx << "@" << pos << ": QQuickText" << text->objectName() << text->text().left(40); + else + qCDebug(lcItemViewDelegateLifecycle) << "idx" << idx << "@" << pos << ":" << item; + } if (pos < 1.0) { d->updateItem(item, pos); if (idx == d->currentIndex) { @@ -1907,7 +1921,7 @@ void QQuickPathView::refill() if (QQuickPathViewAttached *att = d->attached(item)) att->setOnPath(pos < 1.0); if (!d->isInBound(pos, d->mappedRange - d->mappedCache, 1.0 + d->mappedCache)) { -// qDebug() << "release"; + qCDebug(lcItemViewDelegateLifecycle) << "release" << idx << "@" << pos << ", !isInBound: lower" << (d->mappedRange - d->mappedCache) << "upper" << (1.0 + d->mappedCache); d->releaseItem(item); if (it == d->items.begin()) { if (++d->firstIndex >= d->modelCount) { @@ -1942,7 +1956,7 @@ void QQuickPathView::refill() } qreal pos = d->positionOfIndex(idx); while ((d->isInBound(pos, startPos, 1.0 + d->mappedCache) || !d->items.count()) && d->items.count() < count+d->cacheSize) { -// qDebug() << "append" << idx; + qCDebug(lcItemViewDelegateLifecycle) << "append" << idx << "@" << pos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count(); QQuickItem *item = d->getItem(idx, idx+1, pos >= 1.0); if (!item) { waiting = true; @@ -1967,7 +1981,7 @@ void QQuickPathView::refill() idx = d->modelCount - 1; pos = d->positionOfIndex(idx); while (!waiting && d->isInBound(pos, d->mappedRange - d->mappedCache, startPos) && d->items.count() < count+d->cacheSize) { -// qDebug() << "prepend" << idx; + qCDebug(lcItemViewDelegateLifecycle) << "prepend" << idx << "@" << pos << (d->currentIndex == idx ? "current" : "") << "items count was" << d->items.count(); QQuickItem *item = d->getItem(idx, idx+1, pos >= 1.0); if (!item) { waiting = true; diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp index 369570f657..14d305ad50 100644 --- a/src/quick/items/qquicktextnodeengine.cpp +++ b/src/quick/items/qquicktextnodeengine.cpp @@ -670,61 +670,86 @@ void QQuickTextNodeEngine::addFrameDecorations(QTextDocument *document, QTextFra } } -void QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode, - QQuickText::TextStyle style, - const QColor &styleColor) +uint qHash(const QQuickTextNodeEngine::BinaryTreeNodeKey &key) { - if (m_currentLine.isValid()) - processCurrentLine(); + // Just use the default hash for pairs + return qHash(qMakePair(key.fontEngine, qMakePair(key.clipNode, + qMakePair(key.color, key.selectionState)))); +} + +void QQuickTextNodeEngine::mergeProcessedNodes(QList<BinaryTreeNode *> *regularNodes, + QList<BinaryTreeNode *> *imageNodes) +{ + QMultiHash<BinaryTreeNodeKey, BinaryTreeNode *> map; - // Then, go through all the nodes for all lines and combine all QGlyphRuns with a common - // font, selection state and clip node. - typedef QPair<QFontEngine *, QPair<QQuickDefaultClipNode *, QPair<QRgb, int> > > KeyType; - QHash<KeyType, BinaryTreeNode *> map; - QList<BinaryTreeNode *> nodes; - QList<BinaryTreeNode *> imageNodes; for (int i = 0; i < m_processedNodes.size(); ++i) { BinaryTreeNode *node = m_processedNodes.data() + i; if (node->image.isNull()) { - QGlyphRun glyphRun = node->glyphRun; - QRawFont rawFont = glyphRun.rawFont(); + QRawFont rawFont = node->glyphRun.rawFont(); QRawFontPrivate *rawFontD = QRawFontPrivate::get(rawFont); - QFontEngine *fontEngine = rawFontD->fontEngine; - KeyType key(qMakePair(fontEngine, - qMakePair(node->clipNode, - qMakePair(node->color.rgba(), int(node->selectionState))))); - - BinaryTreeNode *otherNode = map.value(key, 0); - if (otherNode != 0) { - QGlyphRun &otherGlyphRun = otherNode->glyphRun; + BinaryTreeNodeKey key(fontEngine, + node->clipNode, + node->color.rgba(), + int(node->selectionState)); + map.insertMulti(key, node); + } else { + imageNodes->append(node); + } + } - QVector<quint32> otherGlyphIndexes = otherGlyphRun.glyphIndexes(); - QVector<QPointF> otherGlyphPositions = otherGlyphRun.positions(); + QMultiHash<BinaryTreeNodeKey, BinaryTreeNode *>::const_iterator it = map.constBegin(); + while (it != map.constEnd()) { + BinaryTreeNode *primaryNode = it.value(); + regularNodes->append(primaryNode); - otherGlyphIndexes += glyphRun.glyphIndexes(); + int count = 0; + QMultiHash<BinaryTreeNodeKey, BinaryTreeNode *>::const_iterator jt; + for (jt = it; jt != map.constEnd() && jt.key() == it.key(); ++jt) + count += jt.value()->glyphRun.glyphIndexes().size(); - QVector<QPointF> glyphPositions = glyphRun.positions(); - otherGlyphPositions.reserve(otherGlyphPositions.size() + glyphPositions.size()); - for (int j = 0; j < glyphPositions.size(); ++j) { - otherGlyphPositions += glyphPositions.at(j) + (node->position - otherNode->position); - } + if (count != primaryNode->glyphRun.glyphIndexes().size()) { + QGlyphRun &glyphRun = primaryNode->glyphRun; + QVector<quint32> glyphIndexes = glyphRun.glyphIndexes(); + glyphIndexes.reserve(count); - otherGlyphRun.setGlyphIndexes(otherGlyphIndexes); - otherGlyphRun.setPositions(otherGlyphPositions); + QVector<QPointF> glyphPositions = glyphRun.positions(); + glyphPositions.reserve(count); - otherNode->ranges += node->ranges; + for (jt = it + 1; jt != map.constEnd() && jt.key() == it.key(); ++jt) { + BinaryTreeNode *otherNode = jt.value(); + glyphIndexes += otherNode->glyphRun.glyphIndexes(); + primaryNode->ranges += otherNode->ranges; - } else { - map.insert(key, node); - nodes.append(node); + QVector<QPointF> otherPositions = otherNode->glyphRun.positions(); + for (int j = 0; j < otherPositions.size(); ++j) + glyphPositions += otherPositions.at(j) + (otherNode->position - primaryNode->position); } + it = jt; + + Q_ASSERT(glyphPositions.size() == count); + Q_ASSERT(glyphIndexes.size() == count); + + glyphRun.setGlyphIndexes(glyphIndexes); + glyphRun.setPositions(glyphPositions); } else { - imageNodes.append(node); + ++it; } } +} + +void QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode, + QQuickText::TextStyle style, + const QColor &styleColor) +{ + if (m_currentLine.isValid()) + processCurrentLine(); + + QList<BinaryTreeNode *> nodes; + QList<BinaryTreeNode *> imageNodes; + mergeProcessedNodes(&nodes, &imageNodes); for (int i = 0; i < m_backgrounds.size(); ++i) { const QRectF &rect = m_backgrounds.at(i).first; diff --git a/src/quick/items/qquicktextnodeengine_p.h b/src/quick/items/qquicktextnodeengine_p.h index 3441a5a973..178454b19e 100644 --- a/src/quick/items/qquicktextnodeengine_p.h +++ b/src/quick/items/qquicktextnodeengine_p.h @@ -102,6 +102,33 @@ public: static void inOrder(const QVarLengthArray<BinaryTreeNode, 16> &binaryTree, QVarLengthArray<int> *sortedIndexes, int currentIndex = 0); }; + struct BinaryTreeNodeKey + { + BinaryTreeNodeKey(QFontEngine *fe, + QQuickDefaultClipNode *cn, + QRgb col, + int selState) + : fontEngine(fe) + , clipNode(cn) + , color(col) + , selectionState(selState) + { + } + + bool operator==(const BinaryTreeNodeKey &otherKey) const + { + return fontEngine == otherKey.fontEngine + && clipNode == otherKey.clipNode + && color == otherKey.color + && selectionState == otherKey.selectionState; + } + + QFontEngine *fontEngine; + QQuickDefaultClipNode *clipNode; + QRgb color; + int selectionState; + }; + QQuickTextNodeEngine() : m_hasSelection(false), m_hasContents(false) {} bool hasContents() const { return m_hasContents; } @@ -141,6 +168,8 @@ public: int start, int end, int selectionStart, int selectionEnd); + void mergeProcessedNodes(QList<BinaryTreeNode *> *regularNodes, + QList<BinaryTreeNode *> *imageNodes); void addToSceneGraph(QQuickTextNode *parent, QQuickText::TextStyle style = QQuickText::Normal, const QColor &styleColor = QColor()); diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index aabeefb317..35f4a84980 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1403,6 +1403,9 @@ bool QQuickWindow::event(QEvent *e) break; } + if (e->type() == QEvent::Type(QQuickWindowPrivate::FullUpdateRequest)) + update(); + return QWindow::event(e); } diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index c3ae6c054c..a61c0b0346 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -101,6 +101,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate : public QWindowPrivate public: Q_DECLARE_PUBLIC(QQuickWindow) + enum CustomEvents { + FullUpdateRequest = QEvent::User + 1 + }; + static inline QQuickWindowPrivate *get(QQuickWindow *c) { return c->d_func(); } QQuickWindowPrivate(); diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 8f94a86026..886e614620 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -2899,7 +2899,7 @@ void Renderer::visualizeChangesPrepare(Node *n, uint parentChanges) void Renderer::visualizeChanges(Node *n) { - if (n->type() == QSGNode::GeometryNodeType && m_visualizeChanceSet.contains(n)) { + if (n->type() == QSGNode::GeometryNodeType && n->element()->batch && m_visualizeChanceSet.contains(n)) { uint dirty = m_visualizeChanceSet.value(n); bool tinted = (dirty & QSGNODE_DIRTY_PARENT) != 0; @@ -2934,7 +2934,7 @@ void Renderer::visualizeChanges(Node *n) void Renderer::visualizeOverdraw_helper(Node *node) { - if (node->type() == QSGNode::GeometryNodeType) { + if (node->type() == QSGNode::GeometryNodeType && node->element()->batch) { VisualizeShader *shader = static_cast<VisualizeShader *>(m_shaderManager->visualizeProgram); QSGGeometryNode *gn = static_cast<QSGGeometryNode *>(node->sgNode); diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 460f92edd7..e1a54810b7 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -490,6 +490,14 @@ void QSGRenderThread::sync(bool inExpose) bool current = false; if (windowSize.width() > 0 && windowSize.height() > 0) current = gl->makeCurrent(window); + // Check for context loss. + if (!current && !gl->isValid()) { + QQuickWindowPrivate::get(window)->cleanupNodesOnShutdown(); + sgrc->invalidate(); + current = gl->create() && gl->makeCurrent(window); + if (current) + sgrc->initialize(gl); + } if (current) { QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); bool hadRenderer = d->renderer != 0; @@ -571,6 +579,12 @@ void QSGRenderThread::syncAndRender() bool current = false; if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0) current = gl->makeCurrent(window); + // Check for context loss. + if (!current && !gl->isValid()) { + // Cannot do anything here because gui is not locked. Request a new + // sync+render round on the gui thread and let the sync handle it. + QCoreApplication::postEvent(window, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))); + } if (current) { d->renderSceneGraph(windowSize); if (profileFrames) @@ -694,6 +708,11 @@ QSGThreadedRenderLoop::QSGThreadedRenderLoop() m_animation_driver->install(); } +QSGThreadedRenderLoop::~QSGThreadedRenderLoop() +{ + delete sg; +} + QSGRenderContext *QSGThreadedRenderLoop::createRenderContext(QSGContext *sg) const { return sg->createRenderContext(); diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h index f371efc1a1..d5ffbf10a3 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h +++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h @@ -49,6 +49,7 @@ class QSGThreadedRenderLoop : public QSGRenderLoop Q_OBJECT public: QSGThreadedRenderLoop(); + ~QSGThreadedRenderLoop(); void show(QQuickWindow *) {} void hide(QQuickWindow *); diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h index 5e6679d901..4224c6d9ed 100644 --- a/src/quick/util/qquickanimation_p_p.h +++ b/src/quick/util/qquickanimation_p_p.h @@ -47,7 +47,7 @@ #include "qquickanimation_p.h" -#include <private/qqmlnullablevalue_p_p.h> +#include <private/qqmlnullablevalue_p.h> #include <qqml.h> #include <qqmlcontext.h> diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h index f5bb01260e..eea313eeb1 100644 --- a/src/quick/util/qquickpath_p.h +++ b/src/quick/util/qquickpath_p.h @@ -36,7 +36,7 @@ #include <qqml.h> -#include <private/qqmlnullablevalue_p_p.h> +#include <private/qqmlnullablevalue_p.h> #include <private/qbezier_p.h> #include <QtCore/QObject> |