diff options
author | Michael Brasser <mbrasser@ford.com> | 2016-10-21 17:21:36 -0500 |
---|---|---|
committer | Michael Brasser <michael.brasser@live.com> | 2017-01-13 03:02:09 +0000 |
commit | 0820efecb48d241f46f13f72c688d809fab6b72d (patch) | |
tree | 30facfdace243aeeec7f89f774cd41ebb7703e2a | |
parent | 93df3e3a3118080dcd6d9416d1622b88d99c4b8d (diff) |
Improve visibility into Positioner positioning from QML
Add a forceLayout function, similar to the views, as well
as a signal that indicates when positioning has completed.
Change-Id: Ice01ea0840c707e403fdd4ea59d92a89e2ed8e4b
Task-number: QTBUG-44762
Task-number: QTBUG-32114
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
-rw-r--r-- | src/quick/items/qquickitemsmodule.cpp | 4 | ||||
-rw-r--r-- | src/quick/items/qquickpositioners.cpp | 93 | ||||
-rw-r--r-- | src/quick/items/qquickpositioners_p.h | 3 | ||||
-rw-r--r-- | tests/auto/qmltest/positioners/tst_positioners.qml | 75 |
4 files changed, 175 insertions, 0 deletions
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index 0b325d7fa8..5bba52ed73 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -380,6 +380,10 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickTouchPoint>(uri, 2, 9, "TouchPoint"); qRegisterMetaType<QPointingDeviceUniqueId>("QPointingDeviceUniqueId"); qmlRegisterUncreatableType<QPointingDeviceUniqueId>(uri, 2, 9, "PointingDeviceUniqueId", QQuickTouchPoint::tr("PointingDeviceUniqueId is only available via read-only properties")); +#if QT_CONFIG(quick_positioners) + qmlRegisterUncreatableType<QQuickBasePositioner, 9>(uri, 2, 9, "Positioner", + QStringLiteral("Positioner is an abstract type that is only available as an attached property.")); +#endif } static void initResources() diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp index 0287fdd45c..05d3ae0191 100644 --- a/src/quick/items/qquickpositioners.cpp +++ b/src/quick/items/qquickpositioners.cpp @@ -290,6 +290,11 @@ void QQuickBasePositioner::itemChange(ItemChange change, const ItemChangeData &v QQuickItem::itemChange(change, value); } +void QQuickBasePositioner::forceLayout() +{ + updatePolish(); +} + void QQuickBasePositioner::prePositioning() { Q_D(QQuickBasePositioner); @@ -401,6 +406,8 @@ void QQuickBasePositioner::prePositioning() //Set implicit size to the size of its children setImplicitSize(contentSize.width(), contentSize.height()); + + emit positioningComplete(); } void QQuickBasePositioner::positionItem(qreal x, qreal y, PositionedItem *target) @@ -910,6 +917,28 @@ void QQuickPositionerAttached::setIsLastItem(bool isLastItem) \sa Grid::spacing */ +/*! + \qmlmethod QtQuick::Column::forceLayout() + \since 5.9 + + Column typically positions its children once per frame. This means that + inside script blocks it is possible for the underlying children to have changed, + but the Column to have not yet been updated accordingly. + + This method forces the Column to immediately respond to any outstanding + changes in its children. + + \b Note: methods in general should only be called after the Component has completed. +*/ +/*! + \qmlsignal QtQuick::Column::positioningComplete() + \since 5.9 + + This signal is emitted when positioning has been completed. + + The corresponding handler is \c onPositioningComplete. +*/ + QQuickColumn::QQuickColumn(QQuickItem *parent) : QQuickBasePositioner(Vertical, parent) { @@ -1077,6 +1106,27 @@ void QQuickColumn::reportConflictingAnchors() \sa Grid::spacing */ +/*! + \qmlmethod QtQuick::Row::forceLayout() + \since 5.9 + + Row typically positions its children once per frame. This means that + inside script blocks it is possible for the underlying children to have changed, + but the Row to have not yet been updated accordingly. + + This method forces the Row to immediately respond to any outstanding + changes in its children. + + \b Note: methods in general should only be called after the Component has completed. +*/ +/*! + \qmlsignal QtQuick::Row::positioningComplete() + \since 5.9 + + This signal is emitted when positioning has been completed. + + The corresponding handler is \c onPositioningComplete. +*/ class QQuickRowPrivate : public QQuickBasePositionerPrivate { @@ -1355,6 +1405,27 @@ void QQuickRow::reportConflictingAnchors() \sa rows, columns */ +/*! + \qmlmethod QtQuick::Grid::forceLayout() + \since 5.9 + + Grid typically positions its children once per frame. This means that + inside script blocks it is possible for the underlying children to have changed, + but the Grid to have not yet been updated accordingly. + + This method forces the Grid to immediately respond to any outstanding + changes in its children. + + \b Note: methods in general should only be called after the Component has completed. +*/ +/*! + \qmlsignal QtQuick::Grid::positioningComplete() + \since 5.9 + + This signal is emitted when positioning has been completed. + + The corresponding handler is \c onPositioningComplete. +*/ class QQuickGridPrivate : public QQuickBasePositionerPrivate { @@ -1920,6 +1991,28 @@ void QQuickGrid::reportConflictingAnchors() \sa Grid::spacing */ +/*! + \qmlmethod QtQuick::Flow::forceLayout() + \since 5.9 + + Flow typically positions its children once per frame. This means that + inside script blocks it is possible for the underlying children to have changed, + but the Flow to have not yet been updated accordingly. + + This method forces the Flow to immediately respond to any outstanding + changes in its children. + + + \b Note: methods in general should only be called after the Component has completed. +*/ +/*! + \qmlsignal QtQuick::Flow::positioningComplete() + \since 5.9 + + This signal is emitted when positioning has been completed. + + The corresponding handler is \c onPositioningComplete. +*/ class QQuickFlowPrivate : public QQuickBasePositionerPrivate { diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h index c25ecd6dbc..ae6e795794 100644 --- a/src/quick/items/qquickpositioners_p.h +++ b/src/quick/items/qquickpositioners_p.h @@ -155,6 +155,8 @@ public: void setBottomPadding(qreal padding); void resetBottomPadding(); + Q_REVISION(9) Q_INVOKABLE void forceLayout(); + protected: QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent); void componentComplete() Q_DECL_OVERRIDE; @@ -172,6 +174,7 @@ Q_SIGNALS: Q_REVISION(6) void leftPaddingChanged(); Q_REVISION(6) void rightPaddingChanged(); Q_REVISION(6) void bottomPaddingChanged(); + Q_REVISION(9) void positioningComplete(); protected Q_SLOTS: void prePositioning(); diff --git a/tests/auto/qmltest/positioners/tst_positioners.qml b/tests/auto/qmltest/positioners/tst_positioners.qml new file mode 100644 index 0000000000..03a0e13225 --- /dev/null +++ b/tests/auto/qmltest/positioners/tst_positioners.qml @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite 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 The Qt Company Ltd 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.9 +import QtTest 1.1 + +Item { + Column { + id: column + Repeater { + id: repeater + model: 2 + Rectangle { + width: 100 + height: 30 + border.width: 1 + } + } + } + + SignalSpy { + id: spy + target: column + signalName: "positioningComplete" + } + + TestCase { + function test_forceLayout() { + compare(column.height, 60) + repeater.model = 4 + column.forceLayout() + compare(column.height, 120) + + // initial positioning and our forced layout + compare(spy.count, 2) + } + } +} |