diff options
Diffstat (limited to 'src/quick')
36 files changed, 527 insertions, 370 deletions
diff --git a/src/quick/designer/designer.pri b/src/quick/designer/designer.pri index c523525977..9f3f7e8be6 100644 --- a/src/quick/designer/designer.pri +++ b/src/quick/designer/designer.pri @@ -1,2 +1,4 @@ -HEADERS += designer/designersupport.h -SOURCES += designer/designersupport.cpp +HEADERS += designer/designersupport.h \ + designer/designerwindowmanager_p.h +SOURCES += designer/designersupport.cpp \ + designer/designerwindowmanager.cpp diff --git a/src/quick/designer/designersupport.cpp b/src/quick/designer/designersupport.cpp index c06e8f0579..1b0fea9190 100644 --- a/src/quick/designer/designersupport.cpp +++ b/src/quick/designer/designersupport.cpp @@ -46,9 +46,13 @@ #include <QtQuick/private/qquickrectangle_p.h> #include <private/qqmlengine_p.h> #include <private/qquickview_p.h> +#include <private/qquickwindowmanager_p.h> #include <QtQuick/private/qquickstategroup_p.h> #include <QtGui/QImage> +#include "designerwindowmanager_p.h" + + QT_BEGIN_NAMESPACE DesignerSupport::DesignerSupport() @@ -119,6 +123,7 @@ QImage DesignerSupport::renderImageForItem(QQuickItem *referencedItem, const QRe return QImage(); renderTexture->setRect(boundingRect); renderTexture->setSize(imageSize); + renderTexture->markDirtyTexture(); renderTexture->updateTexture(); QImage renderImage = renderTexture->toImage(); @@ -138,6 +143,14 @@ bool DesignerSupport::isDirty(QQuickItem *referencedItem, DirtyType dirtyType) return QQuickItemPrivate::get(referencedItem)->dirtyAttributes & dirtyType; } +void DesignerSupport::addDirty(QQuickItem *referencedItem, DesignerSupport::DirtyType dirtyType) +{ + if (referencedItem == 0) + return; + + QQuickItemPrivate::get(referencedItem)->dirtyAttributes |= dirtyType; +} + void DesignerSupport::resetDirty(QQuickItem *referencedItem) { if (referencedItem == 0) @@ -407,7 +420,23 @@ bool DesignerSupport::isValidHeight(QQuickItem *item) void DesignerSupport::updateDirtyNode(QQuickItem *item) { - QQuickWindowPrivate::get(item->window())->updateDirtyNode(item); + if (item->window()) + QQuickWindowPrivate::get(item->window())->updateDirtyNode(item); +} + +void DesignerSupport::activateDesignerWindowManager() +{ + QQuickWindowManager::setInstance(new DesignerWindowManager); +} + +void DesignerSupport::createOpenGLContext(QQuickWindow *window) +{ + DesignerWindowManager::createOpenGLContext(window); +} + +void DesignerSupport::polishItems(QQuickWindow *window) +{ + QQuickWindowPrivate::get(window)->polishItems(); } QT_END_NAMESPACE diff --git a/src/quick/designer/designersupport.h b/src/quick/designer/designersupport.h index 54331fd008..723e1067d8 100644 --- a/src/quick/designer/designersupport.h +++ b/src/quick/designer/designersupport.h @@ -70,6 +70,7 @@ class QTransform; class QQmlContext; class QQuickView; class QObject; +class QQuickWindow; class Q_QUICK_EXPORT DesignerSupport { @@ -99,7 +100,8 @@ public: TransformUpdateMask = TransformOrigin | Transform | BasicTransform | Position | Size | Window, ComplexTransformUpdateMask = Transform | Window, ContentUpdateMask = Size | Content | Smooth | Window, - ChildrenUpdateMask = ChildrenChanged | ChildrenStackingChanged | EffectReference | Window + ChildrenUpdateMask = ChildrenChanged | ChildrenStackingChanged | EffectReference | Window, + AllMask = TransformUpdateMask | ContentUpdateMask | ChildrenUpdateMask }; @@ -112,6 +114,7 @@ public: QImage renderImageForItem(QQuickItem *referencedItem, const QRectF &boundingRect, const QSize &imageSize); static bool isDirty(QQuickItem *referencedItem, DirtyType dirtyType); + static void addDirty(QQuickItem *referencedItem, DirtyType dirtyType); static void resetDirty(QQuickItem *referencedItem); static QTransform windowTransform(QQuickItem *referencedItem); @@ -141,6 +144,12 @@ public: static void updateDirtyNode(QQuickItem *item); + static void activateDesignerWindowManager(); + + static void createOpenGLContext(QQuickWindow *window); + + static void polishItems(QQuickWindow *window); + private: QHash<QQuickItem*, QQuickShaderEffectTexture*> m_itemTextureHash; }; diff --git a/src/quick/designer/designerwindowmanager.cpp b/src/quick/designer/designerwindowmanager.cpp new file mode 100644 index 0000000000..fca9f5339b --- /dev/null +++ b/src/quick/designer/designerwindowmanager.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "designerwindowmanager_p.h" + +#include <QtGui/QOpenGLContext> + +#include <QtQuick/QQuickWindow> + + +QT_BEGIN_NAMESPACE + +DesignerWindowManager::DesignerWindowManager() + : m_sgContext(QSGContext::createDefaultContext()) +{ +} + +void DesignerWindowManager::show(QQuickWindow *window) +{ + makeOpenGLContext(window); +} + +void DesignerWindowManager::hide(QQuickWindow *) +{ +} + +void DesignerWindowManager::windowDestroyed(QQuickWindow *) +{ +} + +void DesignerWindowManager::makeOpenGLContext(QQuickWindow *window) +{ + if (!m_openGlContext) { + m_openGlContext.reset(new QOpenGLContext()); + m_openGlContext->setFormat(window->requestedFormat()); + m_openGlContext->create(); + if (!m_openGlContext->makeCurrent(window)) + qWarning("QQuickWindow: makeCurrent() failed..."); + m_sgContext->initialize(m_openGlContext.data()); + } else { + m_openGlContext->makeCurrent(window); + } +} + +void DesignerWindowManager::exposureChanged(QQuickWindow *) +{ +} + +QImage DesignerWindowManager::grab(QQuickWindow *) +{ + return QImage(); +} + +void DesignerWindowManager::resize(QQuickWindow *, const QSize &) +{ +} + +void DesignerWindowManager::maybeUpdate(QQuickWindow *) +{ +} + +QSGContext *DesignerWindowManager::sceneGraphContext() const +{ + return m_sgContext.data(); +} + +void DesignerWindowManager::createOpenGLContext(QQuickWindow *window) +{ + window->create(); + window->update(); +} + +void DesignerWindowManager::update(QQuickWindow *window) +{ + makeOpenGLContext(window); +} + +QT_END_NAMESPACE + + diff --git a/src/quick/items/qquickcanvas.h b/src/quick/designer/designerwindowmanager_p.h index 907cf30752..222a93f90e 100644 --- a/src/quick/items/qquickcanvas.h +++ b/src/quick/designer/designerwindowmanager_p.h @@ -39,20 +39,69 @@ ** ****************************************************************************/ -#ifndef QQUICKCANVAS_H -#define QQUICKCANVAS_H +#ifndef DESIGNERWINDOWMANAGER_P_H +#define DESIGNERWINDOWMANAGER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QScopedPointer> + +#include <private/qquickwindowmanager_p.h> +#include <private/qtquickglobal_p.h> +#include <QtQuick/private/qsgcontext_p.h> -#include "qquickwindow.h" QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -typedef QQuickWindow QQuickCanvas; +class QQuickWindow; +class QSGContext; +class QAnimationDriver; +class QOpenGLContext; -QT_END_NAMESPACE +class DesignerWindowManager : public QObject, public QQuickWindowManager +{ + Q_OBJECT +public: + DesignerWindowManager(); -QT_END_HEADER + void show(QQuickWindow *window); + void hide(QQuickWindow *window); + + void windowDestroyed(QQuickWindow *window); + + void makeOpenGLContext(QQuickWindow *window); + void exposureChanged(QQuickWindow *window); + QImage grab(QQuickWindow *window); + void resize(QQuickWindow *window, const QSize &size); + + void maybeUpdate(QQuickWindow *window); + void update(QQuickWindow *window); // identical for this implementation. -#endif // QQUICKCANVAS_H + void releaseResources() { } + QAnimationDriver *animationDriver() const { return 0; } + + QSGContext *sceneGraphContext() const; + + static void createOpenGLContext(QQuickWindow *window); + +private: + QScopedPointer<QOpenGLContext> m_openGlContext; + QScopedPointer<QSGContext> m_sgContext; +}; + +QT_END_NAMESPACE + +QT_END_HEADER +#endif // DESIGNERWINDOWMANAGER_P_H diff --git a/src/quick/doc/images/rect-border-width.png b/src/quick/doc/images/rect-border-width.png Binary files differdeleted file mode 100644 index e232cf3ebd..0000000000 --- a/src/quick/doc/images/rect-border-width.png +++ /dev/null diff --git a/src/quick/doc/snippets/qml/rectangle/rect-border-width.qml b/src/quick/doc/snippets/qml/rectangle/rect-border-width.qml deleted file mode 100644 index 9616ca88d1..0000000000 --- a/src/quick/doc/snippets/qml/rectangle/rect-border-width.qml +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//![0] -Rectangle { - width: 100; height: 100 - color: "lightblue" - - Rectangle { - anchors.fill: parent - anchors.margins: 10 - clip: true - - Rectangle { - anchors.fill: parent - border.width: 1 - } - } -} -//![0] diff --git a/src/quick/doc/src/appdevguide/porting.qdoc b/src/quick/doc/src/appdevguide/porting.qdoc index 5843800363..3ac13cd255 100644 --- a/src/quick/doc/src/appdevguide/porting.qdoc +++ b/src/quick/doc/src/appdevguide/porting.qdoc @@ -27,7 +27,7 @@ /*! \page qtquick-porting-qt5.html -\title QML Application in Qt 5 +\title QML Applications in Qt 5 \brief Lists the Qt 5.0 changes that affect the existing QML applications When porting QML-related code from Qt 4.8 to Qt 5, application developers should be aware that diff --git a/src/quick/doc/src/appdevguide/qmlscene.qdoc b/src/quick/doc/src/appdevguide/qmlscene.qdoc index 33beba75f8..264adffee3 100644 --- a/src/quick/doc/src/appdevguide/qmlscene.qdoc +++ b/src/quick/doc/src/appdevguide/qmlscene.qdoc @@ -26,110 +26,121 @@ ****************************************************************************/ /*! -\page qtquick-qmlscene.html -\ingroup qtquick-tools -\title Prototyping with qmlscene -\ingroup qttools -\brief a tool for testing and loading QML files - -The Qt SDK includes \c qmlscene, a tool for loading QML documents that -makes it easy to quickly develop and debug QML applications. It provides a simple -way of loading QML documents and also includes additional features useful for -the development of QML applications. - -The \c qmlscene tool should only be used for testing and developing QML applications. It is -\e not intended for use in a production environment and should not be used for the -deployment of QML applications. In those cases, a custom C++ application should be -written instead, or the QML file should be bundled in a module. See -\l {Deploying QML applications} for more information. - -The \c qmlscene tool is located at \c QTDIR/bin/qmlscene. To load a \c .qml file, -run the tool and select the file to be opened, or provide the -file path on the command line: - -\code - qmlscene myqmlfile.qml -\endcode - -To see the configuration options, run \c qmlscene with the \c -help argument. - - -\section1 Adding module import paths - -Additional module import paths can be provided using the \c -I flag. -For example, the \l{declarative/cppextensions/plugins}{QML plugins example} creates -a C++ plugin identified as \c com.nokia.TimeExample. Since this has a namespaced -identifier, \c qmlscene has to be run with the \c -I flag from the example's -base directory: - -\code -qmlscene -I . plugins.qml -\endcode - -This adds the current directory to the import path so that \c qmlscene will -find the plugin in the \c com/nokia/TimeExample directory. - -Note by default, the current directory is included in the import search path, -but namespaced modules like \c com.nokia.TimeExample are not found unless -the path is explicitly added. - - -\section1 Loading placeholder data - -Often, QML applications are prototyped with fake data that is later replaced -by real data sources from C++ plugins. The \c qmlscene tool assists in this aspect by -loading fake data into the application context: it looks for a directory named -"dummydata" in the same directory as the target QML file, and any \c .qml -files in that directory are loaded as QML objects and bound to the root context -as properties named after the files. - -For example, this QML document refers to a \c lottoNumbers property which does -not actually exist within the document: - -\qml -import QtQuick 2.0 - -ListView { - width: 200; height: 300 - model: lottoNumbers - delegate: Text { text: number } -} -\endqml - -If within the document's directory, there is a "dummydata" directory which -contains a \c lottoNumbers.qml file like this: - -\qml -import QtQuick 2.0 - -ListModel { - ListElement { number: 23 } - ListElement { number: 44 } - ListElement { number: 78 } -} -\endqml - -Then this model would be automatically loaded into the ListView in the previous document. - -Child properties are included when loaded from dummy data. The following document -refers to a \c clock.time property: - -\qml -import QtQuick 2.0 -Text { text: clock.time } -\endqml - -The text value could be filled by a \c dummydata/clock.qml file with a \c time -property in the root context: - -\qml -import QtQuick 2.0 -QtObject { property int time: 54321 } -\endqml - -To replace this with real data, you can simply bind the real data object to -the root context in C++ using QQmlContext::setContextProperty(). This -is detailed in \l{qtqml-cppintegration-topic.html}{Integrating QML and C++}. + \page qtquick-qmlscene.html + \ingroup qtquick-tools + \title Prototyping with qmlscene + \ingroup qttools + \brief Utility to test and load QML files + + Qt 5 includes \c qmlscene, a utility to load QML documents. + The \c{qmlscene} utility enables viewing your QML document even before the + application is complete. This utility also provides the following + additional features that are useful while developing QML applications: + \list + \li View the QML document in a maximized window. + \li View the QML document in full-screen mode. + \li Make the window transparent. + \li Disable multi-sampling (anti-aliasing). + \li Do not detect the version of the .qml file. + \li Run all animations in slow motion. + \li Resize the window to the size of the root item. + \li Add the list of import paths. + \li Add a named bundle. + \li Use a translation file to set the language. + \endlist + + The \c qmlscene utility is meant to be used for testing your QML + applications, and not as a launcher in a production environment. + To launch a QML application in a production environment, develop a custom + C++ application or bundle the QML file in a module. See \l {Deploying QML + applications} for more information. + + To load a .qml file, run the tool and select the file to be opened, or + provide the file path on the command prompt: + + \code + qmlscene myqmlfile.qml + \endcode + + To see the configuration options, run \c qmlscene with the \c -help + argument. + + \section1 Adding Module Import Paths + + Additional module import paths can be provided using the \c -I flag. + For example, the \l{QML Plugin Example}{QML plugin example} + creates a C++ plugin identified with the namespace, \c TimeExample. + To load the plugin, you must run \c qmlscene with the \c{-I} flag from the + example's base directory: + + \code + qmlscene -I imports plugins.qml + \endcode + + This adds the current directory to the import path so that \c qmlscene will + find the plugin in the \c imports directory. + + \note By default, the current directory is included in the import search + path, but modules in a namespace such as \c TimeExample are not found + unless the path is explicitly added. + + \section1 Loading Test Data + + Often, QML applications are prototyped with test data that is later + replaced by real data sources from C++ plugins. The \c qmlscene utility + assists in this aspect by loading test data into the application context. + It looks for a directory named \c {dummydata} in the same directory as + the target QML file, and loads the .qml files in that directory as QML + objects and bind them to the root context as properties named after the files. + + For example, the following QML document refers to a \c lottoNumbers + property which does not exist within the document: + + \qml + import QtQuick 2.0 + + ListView { + width: 200; height: 300 + model: lottoNumbers + delegate: Text { text: number } + } + \endqml + + If within the document's directory, there is a \c{dummydata} directory + which contains a \c lottoNumbers.qml file like this: + + \qml + import QtQuick 2.0 + + ListModel { + ListElement { number: 23 } + ListElement { number: 44 } + ListElement { number: 78 } + } + \endqml + + Then this model would be automatically loaded into the ListView in the + previous document. + + Child properties are included when loaded from \c dummydata. The following + document refers to a \c clock.time property: + + \qml + import QtQuick 2.0 + Text { text: clock.time } + \endqml + + The text value could be filled by a \c dummydata/clock.qml file with a + \c time property in the root context: + + \qml + import QtQuick 2.0 + QtObject { property int time: 54321 } + \endqml + + To replace this with real data, bind the real data object to + the root context in C++ using QQmlContext::setContextProperty(). This is + detailed in \l{Integrating QML and C++}. */ diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc index e2bb247af8..c0b4968ce3 100644 --- a/src/quick/doc/src/qmltypereference.qdoc +++ b/src/quick/doc/src/qmltypereference.qdoc @@ -27,7 +27,8 @@ /*! \page qtquick-qmltypereference.html -\title QML Types Provided by Qt Quick +\title Qt Quick QML Types +\ingroup qmlmodules \brief Description of the QML types provided by the Qt Quick module The \c QtQuick QML module provides a variety of QML types for creating user diff --git a/src/quick/doc/src/qtquick-cpp.qdoc b/src/quick/doc/src/qtquick-cpp.qdoc index 6fc53c9f13..54a37f62b6 100644 --- a/src/quick/doc/src/qtquick-cpp.qdoc +++ b/src/quick/doc/src/qtquick-cpp.qdoc @@ -26,7 +26,8 @@ ****************************************************************************/ /*! \module QtQuick - \title Qt Quick Module - C++ Classes + \title Qt Quick Module C++ Classes + \ingroup modules \brief The Qt Quick module provides classes for embedding Qt Quick in Qt/C++ applications. diff --git a/src/quick/doc/src/qtquick.qdoc b/src/quick/doc/src/qtquick.qdoc index 5ce289c9e9..1d24e33cc4 100644 --- a/src/quick/doc/src/qtquick.qdoc +++ b/src/quick/doc/src/qtquick.qdoc @@ -39,7 +39,7 @@ visual components, receiving user input, creating data models and views and delayed object instantiation. The Qt Quick module provides both the \c QtQuick QML module, which supplies -\l{QML Types Provided by Qt Quick}{a set of QML types} for creating user +\l{Qt Quick QML Types}{a set of QML types} for creating user interfaces with the QML language, and the \c QtQuick C++ module, which supplies \l{Qt Quick Module - C++ Classes}{a set of C++ APIs} for integrating with user interfaces and applications built with QML and the \c QtQuick QML module. @@ -113,7 +113,7 @@ Additional Qt Quick information: \list \li \l{Qt Quick Module - C++ Classes} - the C++ API provided by the Qt Quick module -\li \l{QML Types Provided by Qt Quick} - a list of QML types provided by the +\li \l{Qt Quick QML Types} - a list of QML types provided by the \c{QtQuick} import \list \li \l{QML Module QtQuick.XmlListModel 2.0}{XML List Model} - contains types @@ -137,4 +137,3 @@ Further information for writing QML applications: Qt QML module, which provides the QML engine and language infrastructure \endlist */ - diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri index a73766895e..13abf7b958 100644 --- a/src/quick/items/items.pri +++ b/src/quick/items/items.pri @@ -10,7 +10,6 @@ HEADERS += \ $$PWD/qquickrectangle_p_p.h \ $$PWD/qquickwindow.h \ $$PWD/qquickwindow_p.h \ - $$PWD/qquickcanvas.h \ $$PWD/qquickfocusscope_p.h \ $$PWD/qquickitemsmodule_p.h \ $$PWD/qquickpainteditem.h \ diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 783994666c..f213111ccd 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2509,25 +2509,41 @@ void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o) automatically assigned to this property. */ -int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *prop) +int QQuickItemPrivate::data_count(QQmlListProperty<QObject> *property) { - Q_UNUSED(prop); - // XXX todo - return 0; + QQuickItem *item = static_cast<QQuickItem*>(property->object); + QQuickItemPrivate *privateItem = QQuickItemPrivate::get(item); + QQmlListProperty<QObject> resourcesProperty = privateItem->resources(); + QQmlListProperty<QQuickItem> childrenProperty = privateItem->children(); + + return resources_count(&resourcesProperty) + children_count(&childrenProperty); } -QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *prop, int i) +QObject *QQuickItemPrivate::data_at(QQmlListProperty<QObject> *property, int i) { - Q_UNUSED(prop); - Q_UNUSED(i); - // XXX todo + QQuickItem *item = static_cast<QQuickItem*>(property->object); + QQuickItemPrivate *privateItem = QQuickItemPrivate::get(item); + QQmlListProperty<QObject> resourcesProperty = privateItem->resources(); + QQmlListProperty<QQuickItem> childrenProperty = privateItem->children(); + + int resourcesCount = resources_count(&resourcesProperty); + if (i < resourcesCount) + return resources_at(&resourcesProperty, i); + const int j = i - resourcesCount; + if (j < children_count(&childrenProperty)) + return children_at(&childrenProperty, j); return 0; } -void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *prop) +void QQuickItemPrivate::data_clear(QQmlListProperty<QObject> *property) { - Q_UNUSED(prop); - // XXX todo + QQuickItem *item = static_cast<QQuickItem*>(property->object); + QQuickItemPrivate *privateItem = QQuickItemPrivate::get(item); + QQmlListProperty<QObject> resourcesProperty = privateItem->resources(); + QQmlListProperty<QQuickItem> childrenProperty = privateItem->children(); + + resources_clear(&resourcesProperty); + children_clear(&childrenProperty); } QObject *QQuickItemPrivate::resources_at(QQmlListProperty<QObject> *prop, int index) @@ -2593,12 +2609,6 @@ void QQuickItemPrivate::children_clear(QQmlListProperty<QQuickItem> *prop) p->childItems.at(0)->setParentItem(0); } -void QQuickItemPrivate::visibleChildren_append(QQmlListProperty<QQuickItem>*, QQuickItem *self) -{ - // do nothing - qmlInfo(self) << "QQuickItem: visibleChildren property is readonly and cannot be assigned to."; -} - int QQuickItemPrivate::visibleChildren_count(QQmlListProperty<QQuickItem> *prop) { QQuickItemPrivate *p = QQuickItemPrivate::get(static_cast<QQuickItem *>(prop->object)); @@ -3728,9 +3738,10 @@ QQmlListProperty<QQuickItem> QQuickItemPrivate::children() */ QQmlListProperty<QQuickItem> QQuickItemPrivate::visibleChildren() { - return QQmlListProperty<QQuickItem>(q_func(), 0, QQuickItemPrivate::visibleChildren_append, - QQuickItemPrivate::visibleChildren_count, - QQuickItemPrivate::visibleChildren_at); + return QQmlListProperty<QQuickItem>(q_func(), + 0, + QQuickItemPrivate::visibleChildren_count, + QQuickItemPrivate::visibleChildren_at); } @@ -6508,6 +6519,9 @@ bool QQuickItem::event(QEvent *ev) } else if (ev->type() == QEvent::InputMethod) { inputMethodEvent(static_cast<QInputMethodEvent *>(ev)); return true; + } else if (ev->type() == QEvent::StyleAnimationUpdate) { + update(); + return true; } return QObject::event(ev); } diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h index 75a8a8ecd5..fa6aa62907 100644 --- a/src/quick/items/qquickitem.h +++ b/src/quick/items/qquickitem.h @@ -196,8 +196,6 @@ public: QQuickItem(QQuickItem *parent = 0); virtual ~QQuickItem(); - //canvas() is being removed in favor of window() really soon now - QQuickWindow *canvas() const { return window(); } QQuickWindow *window() const; QQuickItem *parentItem() const; void setParentItem(QQuickItem *parent); diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h index eb7dd00509..3295467d4a 100644 --- a/src/quick/items/qquickitemview_p.h +++ b/src/quick/items/qquickitemview_p.h @@ -48,8 +48,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -QT_MODULE(Quick) - class QQuickChangeSet; class QQuickItemViewPrivate; diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index e50cd6cc61..3805568fb4 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -54,8 +54,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -QT_MODULE(Quick) - class FxViewItem { diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h index bc978dcdd6..36709294fb 100644 --- a/src/quick/items/qquickitemviewtransition_p.h +++ b/src/quick/items/qquickitemviewtransition_p.h @@ -48,8 +48,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -QT_MODULE(Quick) - class QQuickItem; class QQuickItemViewTransitionableItem; class QQuickItemViewTransitionJob; diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index e4c821f046..803840aeaf 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -264,7 +264,7 @@ void QQuickMouseAreaPrivate::propagate(QQuickMouseEvent* event, PropagateType t) if (!propagateComposedEvents) return; QPointF scenePos = q->mapToScene(QPointF(event->x(), event->y())); - propagateHelper(event, window->rootItem(), scenePos, t); + propagateHelper(event, window->contentItem(), scenePos, t); } bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *item,const QPointF &sp, PropagateType sig) diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp index 333946431b..46d486893e 100644 --- a/src/quick/items/qquickrectangle.cpp +++ b/src/quick/items/qquickrectangle.cpp @@ -317,23 +317,6 @@ QQuickRectangle::QQuickRectangle(QQuickItem *parent) void QQuickRectangle::doUpdate() { - Q_D(QQuickRectangle); - qreal penMargin = 0; - qreal penOffset = 0; - if (d->pen && d->pen->isValid()) { - if (d->pen->pixelAligned()) { - const int pw = qRound(d->pen->width()); - penMargin = qreal(0.5) * pw; - penOffset = (pw & 1) * qreal(0.5); - } else { - penMargin = qreal(0.5) * d->pen->width(); - } - } - if (penMargin != d->penMargin || penOffset != d->penOffset) { - d->penMargin = penMargin; - d->penOffset = penOffset; - d->dirty(QQuickItemPrivate::Size); // update clip - } update(); } @@ -348,21 +331,7 @@ void QQuickRectangle::doUpdate() \note The width of the rectangle's border does not affect the geometry of the rectangle itself or its position relative to other items if anchors are used. - If \c border.width is an odd number, the rectangle is painted at a half-pixel offset to retain - border smoothness. Also, the border is rendered evenly on either side of the - rectangle's boundaries, and the spare pixel is rendered to the right and below the - rectangle (as documented for QRect rendering). This can cause unintended effects if - \c border.width is 1 and the rectangle is \l{Item::clip}{clipped} by a parent item: - - \div {class="float-right"} - \inlineimage rect-border-width.png - \enddiv - - \snippet qml/rectangle/rect-border-width.qml 0 - - \clearfloat - Here, the innermost rectangle's border is clipped on the bottom and right edges by its - parent. To avoid this, the border width can be set to two instead of one. + The border is rendered within the rectangle's boundaries. */ QQuickPen *QQuickRectangle::border() { @@ -525,16 +494,4 @@ QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData return rectangle; } -QRectF QQuickRectangle::boundingRect() const -{ - Q_D(const QQuickRectangle); - return QRectF(d->penOffset - d->penMargin, d->penOffset - d->penMargin, - d->width + 2 * d->penMargin, d->height + 2 * d->penMargin); -} - -QRectF QQuickRectangle::clipRect() const -{ - return QQuickRectangle::boundingRect(); -} - QT_END_NAMESPACE diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h index 102506a163..481033a445 100644 --- a/src/quick/items/qquickrectangle_p.h +++ b/src/quick/items/qquickrectangle_p.h @@ -156,9 +156,6 @@ public: qreal radius() const; void setRadius(qreal radius); - virtual QRectF boundingRect() const; - virtual QRectF clipRect() const; - Q_SIGNALS: void colorChanged(); void radiusChanged(); diff --git a/src/quick/items/qquickrectangle_p_p.h b/src/quick/items/qquickrectangle_p_p.h index d8f3d66968..3d4d019327 100644 --- a/src/quick/items/qquickrectangle_p_p.h +++ b/src/quick/items/qquickrectangle_p_p.h @@ -66,7 +66,7 @@ class QQuickRectanglePrivate : public QQuickItemPrivate public: QQuickRectanglePrivate() : - color(Qt::white), gradient(0), pen(0), radius(0), penMargin(0), penOffset(0) + color(Qt::white), gradient(0), pen(0), radius(0) { } @@ -79,8 +79,6 @@ public: QQuickGradient *gradient; QQuickPen *pen; qreal radius; - qreal penMargin; - qreal penOffset; static int doUpdateSlotIdx; QQuickPen *getPen() { diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp index faada2d5b1..139cd72168 100644 --- a/src/quick/items/qquickscreen.cpp +++ b/src/quick/items/qquickscreen.cpp @@ -102,7 +102,8 @@ QT_BEGIN_NAMESPACE QQuickScreenAttached::QQuickScreenAttached(QObject* attachee) : QObject(attachee) - , m_screen(0) + , m_screen(NULL) + , m_window(NULL) { m_attachee = qobject_cast<QQuickItem*>(attachee); @@ -149,17 +150,27 @@ int QQuickScreenAttached::angleBetween(int a, int b) return m_screen->angleBetween((Qt::ScreenOrientation)a,(Qt::ScreenOrientation)b); } -void QQuickScreenAttached::windowChanged(QQuickWindow* c)//Called by QQuickItemPrivate::initWindow +void QQuickScreenAttached::windowChanged(QQuickWindow* c) { - QScreen* screen = c ? c->screen() : 0; + if (m_window) + disconnect(m_window, SIGNAL(screenChanged(QScreen*)), this, SLOT(screenChanged(QScreen*))); + m_window = c; + screenChanged(c ? c->screen() : NULL); + if (c) + connect(c, SIGNAL(screenChanged(QScreen*)), this, SLOT(screenChanged(QScreen*))); +} + +void QQuickScreenAttached::screenChanged(QScreen *screen) +{ + //qDebug() << "QQuickScreenAttached::screenChanged" << (screen ? screen->name() : QString::fromLatin1("null")); if (screen != m_screen) { QScreen* oldScreen = m_screen; m_screen = screen; if (oldScreen) { - disconnect(oldScreen, SIGNAL(sizeChanged(QSize)), + disconnect(oldScreen, SIGNAL(geometryChanged(QRect)), this, SIGNAL(widthChanged())); - disconnect(oldScreen, SIGNAL(sizeChanged(QSize)), + disconnect(oldScreen, SIGNAL(geometryChanged(QRect)), this, SIGNAL(heightChanged())); disconnect(oldScreen, SIGNAL(orientationChanged(Qt::ScreenOrientation)), this, SIGNAL(orientationChanged())); @@ -181,9 +192,9 @@ void QQuickScreenAttached::windowChanged(QQuickWindow* c)//Called by QQuickItemP emit primaryOrientationChanged(); - connect(screen, SIGNAL(sizeChanged(QSize)), + connect(screen, SIGNAL(geometryChanged(QRect)), this, SIGNAL(widthChanged())); - connect(screen, SIGNAL(sizeChanged(QSize)), + connect(screen, SIGNAL(geometryChanged(QRect)), this, SIGNAL(heightChanged())); connect(screen, SIGNAL(orientationChanged(Qt::ScreenOrientation)), this, SIGNAL(orientationChanged())); diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h index 55ac9796a6..46ea7ee137 100644 --- a/src/quick/items/qquickscreen_p.h +++ b/src/quick/items/qquickscreen_p.h @@ -84,8 +84,12 @@ Q_SIGNALS: void primaryOrientationChanged(); void orientationChanged(); +protected slots: + void screenChanged(QScreen*); + private: QScreen* m_screen; + QQuickWindow* m_window; QQuickItem* m_attachee; }; diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index e55ba73f4f..22551c9d4c 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -2378,8 +2378,8 @@ void QQuickTextInput::moveCursorSelection(int pos, SelectionMode mode) finder.setPosition(anchor); const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons(); - if (anchor < text.length() && (!(reasons & QTextBoundaryFinder::StartWord) - || ((reasons & QTextBoundaryFinder::EndWord) && anchor > cursor))) { + if (anchor < text.length() && (reasons == QTextBoundaryFinder::NotAtBoundary + || (reasons & QTextBoundaryFinder::EndOfItem))) { finder.toPreviousBoundary(); } anchor = finder.position() != -1 ? finder.position() : 0; @@ -2396,11 +2396,10 @@ void QQuickTextInput::moveCursorSelection(int pos, SelectionMode mode) finder.setPosition(anchor); const QTextBoundaryFinder::BoundaryReasons reasons = finder.boundaryReasons(); - if (anchor > 0 && (!(reasons & QTextBoundaryFinder::EndWord) - || ((reasons & QTextBoundaryFinder::StartWord) && anchor < cursor))) { + if (anchor > 0 && (reasons == QTextBoundaryFinder::NotAtBoundary + || (reasons & QTextBoundaryFinder::StartOfItem))) { finder.toNextBoundary(); } - anchor = finder.position() != -1 ? finder.position() : text.length(); finder.setPosition(pos); diff --git a/src/quick/items/qquickthreadedwindowmanager.cpp b/src/quick/items/qquickthreadedwindowmanager.cpp index 50bd569496..fac4fb034f 100644 --- a/src/quick/items/qquickthreadedwindowmanager.cpp +++ b/src/quick/items/qquickthreadedwindowmanager.cpp @@ -43,6 +43,7 @@ #include "qquickthreadedwindowmanager_p.h" #include <QtCore/QTime> +#include <QtCore/QDebug> #include <QtGui/QOpenGLContext> #include <QtGui/private/qguiapplication_p.h> @@ -396,20 +397,24 @@ void QQuickRenderThreadSingleContextWindowManager::run() WindowData *windowData = it.value(); QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(window); - Q_ASSERT(windowPrivate->isRenderable()); - - gl->makeCurrent(window); + if (windowPrivate->isRenderable()) { + gl->makeCurrent(window); - if (windowData->viewportSize != windowData->windowSize) { + if (windowData->viewportSize != windowData->windowSize) { #ifdef THREAD_DEBUG - printf(" RenderThread: --- window has changed size...\n"); + printf(" RenderThread: --- window has changed size...\n"); #endif - windowData->viewportSize = windowData->windowSize; - windowData->sizeWasChanged = true; - glViewport(0, 0, windowData->viewportSize.width(), windowData->viewportSize.height()); - } + windowData->viewportSize = windowData->windowSize; + windowData->sizeWasChanged = true; + glViewport(0, 0, windowData->viewportSize.width(), windowData->viewportSize.height()); + } - windowPrivate->syncSceneGraph(); + windowPrivate->syncSceneGraph(); + } else { + qWarning().nospace() + << "Non-renderable window " << window + << " (" << window->geometry() << ")."; + } } inSync = false; diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index f3610ea53a..7182e74c0c 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -461,7 +461,7 @@ void QQuickViewPrivate::setRootObject(QObject *obj) return; if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(obj)) { root = sgItem; - sgItem->setParentItem(q->QQuickWindow::rootItem()); + sgItem->setParentItem(q->QQuickWindow::contentItem()); } else { qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << endl << endl diff --git a/src/quick/items/qquickvisualdatamodel.cpp b/src/quick/items/qquickvisualdatamodel.cpp index 6f7afd5101..a297ec90df 100644 --- a/src/quick/items/qquickvisualdatamodel.cpp +++ b/src/quick/items/qquickvisualdatamodel.cpp @@ -597,7 +597,8 @@ QQmlListProperty<QQuickVisualDataGroup> QQuickVisualDataModel::groups() d, QQuickVisualDataModelPrivate::group_append, QQuickVisualDataModelPrivate::group_count, - QQuickVisualDataModelPrivate::group_at); + QQuickVisualDataModelPrivate::group_at, + 0); } /*! diff --git a/src/quick/items/qquickvisualitemmodel.cpp b/src/quick/items/qquickvisualitemmodel.cpp index 453b4a4b68..91f52695ad 100644 --- a/src/quick/items/qquickvisualitemmodel.cpp +++ b/src/quick/items/qquickvisualitemmodel.cpp @@ -62,6 +62,17 @@ class QQuickVisualItemModelPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QQuickVisualItemModel) public: + class Item { + public: + Item(QQuickItem *i) : item(i), ref(0) {} + + void addRef() { ++ref; } + bool deref() { return --ref == 0; } + + QQuickItem *item; + int ref; + }; + QQuickVisualItemModelPrivate() : QObjectPrivate() {} static void children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *item) { @@ -78,6 +89,12 @@ public: return static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.at(index).item; } + static void children_clear(QQmlListProperty<QQuickItem> *prop) { + static_cast<QQuickVisualItemModelPrivate *>(prop->data)->itemCleared(static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children); + static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.clear(); + static_cast<QQuickVisualItemModelPrivate *>(prop->data)->emitChildrenChanged(); + } + void itemAppended() { Q_Q(QQuickVisualItemModel); QQuickVisualItemModelAttached *attached = QQuickVisualItemModelAttached::properties(children.last().item); @@ -88,6 +105,13 @@ public: emit q->countChanged(); } + void itemCleared(const QList<Item> &children) { + Q_Q(QQuickVisualItemModel); + foreach (const Item &child, children) + emit q->destroyingItem(child.item); + emit q->countChanged(); + } + void emitChildrenChanged() { Q_Q(QQuickVisualItemModel); emit q->childrenChanged(); @@ -100,16 +124,6 @@ public: return -1; } - class Item { - public: - Item(QQuickItem *i) : item(i), ref(0) {} - - void addRef() { ++ref; } - bool deref() { return --ref == 0; } - - QQuickItem *item; - int ref; - }; QList<Item> children; }; @@ -168,8 +182,12 @@ QQuickVisualItemModel::QQuickVisualItemModel(QObject *parent) QQmlListProperty<QQuickItem> QQuickVisualItemModel::children() { Q_D(QQuickVisualItemModel); - return QQmlListProperty<QQuickItem>(this, d, d->children_append, - d->children_count, d->children_at); + return QQmlListProperty<QQuickItem>(this, + d, + d->children_append, + d->children_count, + d->children_at, + d->children_clear); } /*! diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 0a293d6608..f03a2c9a64 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -222,14 +222,14 @@ void QQuickWindow::hideEvent(QHideEvent *) void QQuickWindow::focusOutEvent(QFocusEvent *) { Q_D(QQuickWindow); - d->rootItem->setFocus(false); + d->contentItem->setFocus(false); } /*! \reimp */ void QQuickWindow::focusInEvent(QFocusEvent *) { Q_D(QQuickWindow); - d->rootItem->setFocus(true); + d->contentItem->setFocus(true); d->updateFocusItemTransform(); } @@ -309,10 +309,10 @@ void QQuickWindowPrivate::syncSceneGraph() emit q->beforeSynchronizing(); if (!renderer) { - forceUpdate(rootItem); + forceUpdate(contentItem); QSGRootNode *rootNode = new QSGRootNode; - rootNode->appendChildNode(QQuickItemPrivate::get(rootItem)->itemNode()); + rootNode->appendChildNode(QQuickItemPrivate::get(contentItem)->itemNode()); renderer = context->createRenderer(); renderer->setRootNode(rootNode); } @@ -348,7 +348,7 @@ void QQuickWindowPrivate::renderSceneGraph(const QSize &size) } QQuickWindowPrivate::QQuickWindowPrivate() - : rootItem(0) + : contentItem(0) , activeFocusItem(0) , mouseGrabberItem(0) #ifndef QT_NO_CURSOR @@ -382,18 +382,18 @@ void QQuickWindowPrivate::init(QQuickWindow *c) Q_Q(QQuickWindow); - rootItem = new QQuickRootItem; - QQmlEngine::setObjectOwnership(rootItem, QQmlEngine::CppOwnership); - QQuickItemPrivate *rootItemPrivate = QQuickItemPrivate::get(rootItem); - rootItemPrivate->window = q; - rootItemPrivate->windowRefCount = 1; - rootItemPrivate->flags |= QQuickItem::ItemIsFocusScope; + contentItem = new QQuickRootItem; + QQmlEngine::setObjectOwnership(contentItem, QQmlEngine::CppOwnership); + QQuickItemPrivate *contentItemPrivate = QQuickItemPrivate::get(contentItem); + contentItemPrivate->window = q; + contentItemPrivate->windowRefCount = 1; + contentItemPrivate->flags |= QQuickItem::ItemIsFocusScope; // In the absence of a focus in event on some platforms assume the window will - // be activated immediately and set focus on the rootItem + // be activated immediately and set focus on the contentItem // ### Remove when QTBUG-22415 is resolved. - //It is important that this call happens after the rootItem has a window.. - rootItem->setFocus(true); + //It is important that this call happens after the contentItem has a window.. + contentItem->setFocus(true); windowManager = QQuickWindowManager::instance(); context = windowManager->sceneGraphContext(); @@ -412,19 +412,19 @@ void QQuickWindowPrivate::init(QQuickWindow *c) QQmlListProperty<QObject> QQuickWindowPrivate::data() { - initRootItem(); - return QQuickItemPrivate::get(rootItem)->data(); + initContentItem(); + return QQuickItemPrivate::get(contentItem)->data(); } -void QQuickWindowPrivate::initRootItem() +void QQuickWindowPrivate::initContentItem() { Q_Q(QQuickWindow); q->connect(q, SIGNAL(widthChanged(int)), - rootItem, SLOT(setWidth(int))); + contentItem, SLOT(setWidth(int))); q->connect(q, SIGNAL(heightChanged(int)), - rootItem, SLOT(setHeight(int))); - rootItem->setWidth(q->width()); - rootItem->setHeight(q->height()); + contentItem, SLOT(setHeight(int))); + contentItem->setWidth(q->width()); + contentItem->setHeight(q->height()); } static QMouseEvent *touchToMouseEvent(QEvent::Type type, const QTouchEvent::TouchPoint &p, QTouchEvent *event, QQuickItem *item, bool transformNeeded = true) @@ -527,7 +527,7 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e lastMousePosition = me->windowPos(); bool accepted = me->isAccepted(); - bool delivered = deliverHoverEvent(rootItem, me->windowPos(), last, me->modifiers(), accepted); + bool delivered = deliverHoverEvent(contentItem, me->windowPos(), last, me->modifiers(), accepted); if (!delivered) { //take care of any exits accepted = clearHover(); @@ -594,7 +594,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F Q_Q(QQuickWindow); Q_ASSERT(item); - Q_ASSERT(scope || item == rootItem); + Q_ASSERT(scope || item == contentItem); #ifdef FOCUS_DEBUG qWarning() << "QQuickWindowPrivate::setFocusInScope():"; @@ -614,7 +614,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F QVarLengthArray<QQuickItem *, 20> changed; // Does this change the active focus? - if (item == rootItem || (scopePrivate->activeFocus && item->isEnabled())) { + if (item == contentItem || (scopePrivate->activeFocus && item->isEnabled())) { oldActiveFocusItem = activeFocusItem; newActiveFocusItem = item; while (newActiveFocusItem->isFocusScope() @@ -643,7 +643,7 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F } } - if (item != rootItem && !(options & DontChangeSubFocusItem)) { + if (item != contentItem && !(options & DontChangeSubFocusItem)) { QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem; if (oldSubFocusItem) { QQuickItemPrivate::get(oldSubFocusItem)->focus = false; @@ -654,13 +654,13 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, F } if (!(options & DontChangeFocusProperty)) { -// if (item != rootItem || QGuiApplication::focusWindow() == q) { // QTBUG-22415 +// if (item != contentItem || QGuiApplication::focusWindow() == q) { // QTBUG-22415 itemPrivate->focus = true; changed << item; // } } - if (newActiveFocusItem && rootItem->hasFocus()) { + if (newActiveFocusItem && contentItem->hasFocus()) { activeFocusItem = newActiveFocusItem; QQuickItemPrivate::get(newActiveFocusItem)->activeFocus = true; @@ -690,7 +690,7 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, Q_Q(QQuickWindow); Q_ASSERT(item); - Q_ASSERT(scope || item == rootItem); + Q_ASSERT(scope || item == contentItem); #ifdef FOCUS_DEBUG qWarning() << "QQuickWindowPrivate::clearFocusInScope():"; @@ -711,10 +711,10 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, QVarLengthArray<QQuickItem *, 20> changed; - Q_ASSERT(item == rootItem || item == scopePrivate->subFocusItem); + Q_ASSERT(item == contentItem || item == scopePrivate->subFocusItem); // Does this change the active focus? - if (item == rootItem || scopePrivate->activeFocus) { + if (item == contentItem || scopePrivate->activeFocus) { oldActiveFocusItem = activeFocusItem; newActiveFocusItem = scope; @@ -738,7 +738,7 @@ void QQuickWindowPrivate::clearFocusInScope(QQuickItem *scope, QQuickItem *item, } } - if (item != rootItem && !(options & DontChangeSubFocusItem)) { + if (item != contentItem && !(options & DontChangeSubFocusItem)) { QQuickItem *oldSubFocusItem = scopePrivate->subFocusItem; if (oldSubFocusItem && !(options & DontChangeFocusProperty)) { QQuickItemPrivate::get(oldSubFocusItem)->focus = false; @@ -953,7 +953,7 @@ QQuickWindow::~QQuickWindow() QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); delete d->incubationController; d->incubationController = 0; - delete d->rootItem; d->rootItem = 0; + delete d->contentItem; d->contentItem = 0; } @@ -1055,7 +1055,7 @@ QQuickItem *QQuickWindow::contentItem() const { Q_D(const QQuickWindow); - return d->rootItem; + return d->contentItem; } /*! @@ -1149,7 +1149,7 @@ bool QQuickWindow::event(QEvent *e) break; #endif case QEvent::WindowDeactivate: - rootItem()->windowDeactivateEvent(); + contentItem()->windowDeactivateEvent(); break; case QEvent::FocusAboutToChange: if (d->activeFocusItem) @@ -1241,7 +1241,7 @@ bool QQuickWindowPrivate::deliverMouseEvent(QMouseEvent *event) if (!mouseGrabberItem && event->type() == QEvent::MouseButtonPress && (event->buttons() & event->button()) == event->buttons()) { - if (deliverInitialMousePressEvent(rootItem, event)) + if (deliverInitialMousePressEvent(contentItem, event)) event->accept(); else event->ignore(); @@ -1299,7 +1299,7 @@ void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event) #endif if (!d->mouseGrabberItem && (event->buttons() & event->button()) == event->buttons()) { - if (d->deliverInitialMousePressEvent(d->rootItem, event)) + if (d->deliverInitialMousePressEvent(d->contentItem, event)) event->accept(); else event->ignore(); @@ -1344,7 +1344,7 @@ void QQuickWindow::mouseMoveEvent(QMouseEvent *event) d->lastMousePosition = event->windowPos(); bool accepted = event->isAccepted(); - bool delivered = d->deliverHoverEvent(d->rootItem, event->windowPos(), last, event->modifiers(), accepted); + bool delivered = d->deliverHoverEvent(d->contentItem, event->windowPos(), last, event->modifiers(), accepted); if (!delivered) { //take care of any exits accepted = d->clearHover(); @@ -1472,7 +1472,7 @@ void QQuickWindow::wheelEvent(QWheelEvent *event) return; event->ignore(); - d->deliverWheelEvent(d->rootItem, event); + d->deliverWheelEvent(d->contentItem, event); d->lastWheelEventAccepted = event->isAccepted(); } #endif // QT_NO_WHEELEVENT @@ -1543,7 +1543,7 @@ bool QQuickWindowPrivate::deliverTouchEvent(QTouchEvent *event) // or some item accepted a point and should receive an update if (newPoints.count() > 0 || updatedPoints.count() > 0) { QSet<int> acceptedNewPoints; - event->setAccepted(deliverTouchPoints(rootItem, event, newPoints, &acceptedNewPoints, &updatedPoints)); + event->setAccepted(deliverTouchPoints(contentItem, event, newPoints, &acceptedNewPoints, &updatedPoints)); } else event->ignore(); @@ -1814,7 +1814,7 @@ void QQuickWindowPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QEvent *e e->mouseButtons(), e->keyboardModifiers()); QQuickDropEventEx::copyActions(&enterEvent, *e); - event->setAccepted(deliverDragEvent(grabber, rootItem, &enterEvent)); + event->setAccepted(deliverDragEvent(grabber, contentItem, &enterEvent)); } } @@ -1874,7 +1874,7 @@ void QQuickWindowPrivate::updateCursor(const QPointF &scenePos) Q_Q(QQuickWindow); QQuickItem *oldCursorItem = cursorItem; - cursorItem = findCursorItem(rootItem, scenePos); + cursorItem = findCursorItem(contentItem, scenePos); if (cursorItem != oldCursorItem) { if (cursorItem) @@ -2118,7 +2118,7 @@ void QQuickWindowPrivate::cleanupNodesOnShutdown() { Q_Q(QQuickWindow); cleanupNodes(); - cleanupNodesOnShutdown(rootItem); + cleanupNodesOnShutdown(contentItem); QSet<QQuickItem *>::const_iterator it = parentlessItems.begin(); for (; it != parentlessItems.end(); ++it) cleanupNodesOnShutdown(*it); diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index 62b0aa3945..7f9af82d88 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -82,8 +82,6 @@ public: virtual ~QQuickWindow(); QQuickItem *contentItem() const; - //XXX rootItem renamed contentItem - this function must be removed before 5.0 - QQuickItem *rootItem() const { return contentItem(); } QQuickItem *activeFocusItem() const; QObject *focusObject() const; diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 530e547f3e..fdf5fe2abb 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -103,9 +103,9 @@ public: virtual ~QQuickWindowPrivate(); void init(QQuickWindow *); - void initRootItem();//Currently only used if items added in QML + void initContentItem();//Currently only used if items added in QML - QQuickRootItem *rootItem; + QQuickRootItem *contentItem; QSet<QQuickItem *> parentlessItems; QQmlListProperty<QObject> data(); diff --git a/src/quick/items/qquickwindowmanager.cpp b/src/quick/items/qquickwindowmanager.cpp index 6596343bc8..50887e8e99 100644 --- a/src/quick/items/qquickwindowmanager.cpp +++ b/src/quick/items/qquickwindowmanager.cpp @@ -74,6 +74,8 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_ DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP); DEFINE_BOOL_CONFIG_OPTION(qmlForceThreadedRenderer, QML_FORCE_THREADED_RENDERER); // Might trigger graphics driver threading bugs, use at own risk +QQuickWindowManager *QQuickWindowManager::s_instance = 0; + QQuickWindowManager::~QQuickWindowManager() { } @@ -124,11 +126,9 @@ public: QQuickWindowManager *QQuickWindowManager::instance() { - static QQuickWindowManager *theInstance; - - if (!theInstance) { + if (!s_instance) { - theInstance = QSGContext::createWindowManager(); + s_instance = QSGContext::createWindowManager(); bool bufferQueuing = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::BufferQueueingOpenGL); bool fancy = bufferQueuing @@ -148,13 +148,19 @@ QQuickWindowManager *QQuickWindowManager::instance() if (fixedAnimationSteps) QUnifiedTimer::instance(true)->setConsistentTiming(true); - if (!theInstance) { - theInstance = fancy + if (!s_instance) { + s_instance = fancy ? (QQuickWindowManager*) new QQuickRenderThreadSingleContextWindowManager : (QQuickWindowManager*) new QQuickTrivialWindowManager; } } - return theInstance; + return s_instance; +} + +void QQuickWindowManager::setInstance(QQuickWindowManager *instance) +{ + Q_ASSERT(!s_instance); + s_instance = instance; } QQuickTrivialWindowManager::QQuickTrivialWindowManager() @@ -219,7 +225,13 @@ void QQuickTrivialWindowManager::renderWindow(QQuickWindow *window) if (!masterWindow) return; - Q_ASSERT(QQuickWindowPrivate::get(masterWindow)->isRenderable()); + if (!QQuickWindowPrivate::get(masterWindow)->isRenderable()) { + qWarning().nospace() + << "Unable to find a renderable master window " + << masterWindow << "when trying to render" + << window << " (" << window->geometry() << ")."; + return; + } if (!gl) { gl = new QOpenGLContext(); diff --git a/src/quick/items/qquickwindowmanager_p.h b/src/quick/items/qquickwindowmanager_p.h index 7a6d26127a..ac46fd3d5f 100644 --- a/src/quick/items/qquickwindowmanager_p.h +++ b/src/quick/items/qquickwindowmanager_p.h @@ -76,6 +76,10 @@ public: // ### make this less of a singleton static QQuickWindowManager *instance(); + static void setInstance(QQuickWindowManager *instance); + +private: + static QQuickWindowManager *s_instance; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp index dab855064e..4d5094d526 100644 --- a/src/quick/scenegraph/qsgdefaultrectanglenode.cpp +++ b/src/quick/scenegraph/qsgdefaultrectanglenode.cpp @@ -342,9 +342,12 @@ void QSGDefaultRectangleNode::update() void QSGDefaultRectangleNode::updateGeometry() { - float penWidth = m_aligned ? float(qRound(m_pen_width)) : float(m_pen_width); float width = float(m_rect.width()); float height = float(m_rect.height()); + float penWidth = qMin(qMin(width, height) * 0.5f, float(m_pen_width)); + + if (m_aligned) + penWidth = qRound(penWidth); QSGGeometry *g = geometry(); g->setDrawingMode(GL_TRIANGLE_STRIP); @@ -377,14 +380,9 @@ void QSGDefaultRectangleNode::updateGeometry() float radius = qMin(qMin(width, height) * 0.5f, float(m_radius)); QRectF innerRect = m_rect; innerRect.adjust(radius, radius, -radius, -radius); - if (m_aligned && (int(penWidth) & 1)) { - // Pen width is odd, so add the offset as documented. - innerRect.moveLeft(innerRect.left() + qreal(0.5)); - innerRect.moveTop(innerRect.top() + qreal(0.5)); - } - float innerRadius = radius - penWidth * 0.5f; - float outerRadius = radius + penWidth * 0.5f; + float innerRadius = radius - penWidth * 1.0f; + float outerRadius = radius; float delta = qMin(width, height) * 0.5f; // Number of segments per corner, approximately one per 3 pixels. @@ -630,16 +628,8 @@ void QSGDefaultRectangleNode::updateGeometry() QRectF innerRect = m_rect; QRectF outerRect = m_rect; - if (penWidth) { - if (m_aligned && (int(penWidth) & 1)) { - // Pen width is odd, so add the offset as documented. - innerRect.moveLeft(innerRect.left() + qreal(0.5)); - innerRect.moveTop(innerRect.top() + qreal(0.5)); - outerRect = innerRect; - } - innerRect.adjust(0.5f * penWidth, 0.5f * penWidth, -0.5f * penWidth, -0.5f * penWidth); - outerRect.adjust(-0.5f * penWidth, -0.5f * penWidth, 0.5f * penWidth, 0.5f * penWidth); - } + if (penWidth) + innerRect.adjust(1.0f * penWidth, 1.0f * penWidth, -1.0f * penWidth, -1.0f * penWidth); float delta = qMin(width, height) * 0.5f; int innerVertexCount = 4 + gradientIntersections * 2; diff --git a/src/quick/util/qquickanimationcontroller_p.h b/src/quick/util/qquickanimationcontroller_p.h index 58b1ced1d8..4185803800 100644 --- a/src/quick/util/qquickanimationcontroller_p.h +++ b/src/quick/util/qquickanimationcontroller_p.h @@ -49,8 +49,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -QT_MODULE(Quick) - class QQuickAnimationControllerPrivate; class Q_AUTOTEST_EXPORT QQuickAnimationController : public QObject, public QQmlParserStatus { |