Merge remote-tracking branch 'origin/5.13' into 5.14
Change-Id: I06578422b4558feabf7a77426b01e77953ab60e2
This commit is contained in:
commit
1619b7d207
|
@ -401,57 +401,20 @@ void QQmlVMEMetaObject::writeProperty(int id, double v)
|
|||
void QQmlVMEMetaObject::writeProperty(int id, const QString& v)
|
||||
{
|
||||
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
|
||||
if (md)
|
||||
md->set(engine, id, engine->newString(v));
|
||||
}
|
||||
|
||||
void QQmlVMEMetaObject::writeProperty(int id, const QUrl& v)
|
||||
{
|
||||
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
|
||||
if (md)
|
||||
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
|
||||
}
|
||||
|
||||
void QQmlVMEMetaObject::writeProperty(int id, const QDate& v)
|
||||
{
|
||||
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
|
||||
if (md)
|
||||
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
|
||||
}
|
||||
|
||||
void QQmlVMEMetaObject::writeProperty(int id, const QDateTime& v)
|
||||
{
|
||||
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
|
||||
if (md)
|
||||
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
|
||||
}
|
||||
|
||||
void QQmlVMEMetaObject::writeProperty(int id, const QPointF& v)
|
||||
{
|
||||
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
|
||||
if (md)
|
||||
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
|
||||
}
|
||||
|
||||
void QQmlVMEMetaObject::writeProperty(int id, const QSizeF& v)
|
||||
{
|
||||
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
|
||||
if (md)
|
||||
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
|
||||
}
|
||||
|
||||
void QQmlVMEMetaObject::writeProperty(int id, const QRectF& v)
|
||||
{
|
||||
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
|
||||
if (md)
|
||||
md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
|
||||
if (md) {
|
||||
QV4::Scope scope(engine);
|
||||
QV4::Scoped<QV4::MemberData>(scope, md)->set(engine, id, engine->newString(v));
|
||||
}
|
||||
}
|
||||
|
||||
void QQmlVMEMetaObject::writeProperty(int id, QObject* v)
|
||||
{
|
||||
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
|
||||
if (md)
|
||||
md->set(engine, id, QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, v)));
|
||||
if (md) {
|
||||
QV4::Scope scope(engine);
|
||||
QV4::Scoped<QV4::MemberData>(scope, md)->set(engine, id, QV4::Value::fromReturnedValue(
|
||||
QV4::QObjectWrapper::wrap(engine, v)));
|
||||
}
|
||||
|
||||
QQmlVMEVariantQObjectPtr *guard = getQObjectGuardForProperty(id);
|
||||
if (v && !guard) {
|
||||
|
|
|
@ -194,12 +194,18 @@ public:
|
|||
void writeProperty(int id, bool v);
|
||||
void writeProperty(int id, double v);
|
||||
void writeProperty(int id, const QString& v);
|
||||
void writeProperty(int id, const QPointF& v);
|
||||
void writeProperty(int id, const QSizeF& v);
|
||||
void writeProperty(int id, const QUrl& v);
|
||||
void writeProperty(int id, const QDate& v);
|
||||
void writeProperty(int id, const QDateTime& v);
|
||||
void writeProperty(int id, const QRectF& v);
|
||||
|
||||
template<typename VariantCompatible>
|
||||
void writeProperty(int id, const VariantCompatible &v)
|
||||
{
|
||||
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
|
||||
if (md) {
|
||||
QV4::Scope scope(engine);
|
||||
QV4::Scoped<QV4::MemberData>(scope, md)->set(engine, id, engine->newVariantObject(
|
||||
QVariant::fromValue(v)));
|
||||
}
|
||||
}
|
||||
|
||||
void writeProperty(int id, QObject *v);
|
||||
|
||||
void ensureQObjectWrapper();
|
||||
|
|
|
@ -402,6 +402,43 @@ property MyMenu optionsMenu
|
|||
For information on performance in QML and Qt Quick,
|
||||
see \l {Performance Considerations And Suggestions}.
|
||||
|
||||
\section1 Prefer Declarative Bindings Over Imperative Assignments
|
||||
|
||||
In QML, it's possible to use imperative JavaScript code to perform tasks
|
||||
such as responding to input events, send data over a network, and so on.
|
||||
Imperative code has an important place in QML, but it's also important
|
||||
to be aware of when not to use it.
|
||||
|
||||
For example, consider the following imperative assignment:
|
||||
|
||||
\code
|
||||
Rectangle {
|
||||
Component.onCompleted: color = "red"
|
||||
}
|
||||
\endcode
|
||||
|
||||
This has the following disadvantages:
|
||||
|
||||
\list
|
||||
\li It's slow. The color property will first be evaluated with a
|
||||
default-constructed value, and then again with "red" later on.
|
||||
\li It delays errors that could be found at build time to run time, slowing
|
||||
down the development process.
|
||||
\li It overwrites any declarative binding that was in place. In most cases this
|
||||
is intended, but sometimes it can be unintentional.
|
||||
See \l {Debugging overwriting of bindings} for more information.
|
||||
\li It interferes with tooling; Qt Quick Designer, for example, doesn't support
|
||||
JavaScript.
|
||||
\endlist
|
||||
|
||||
The code can be rewritten to be a declarative binding instead:
|
||||
|
||||
\code
|
||||
Rectangle {
|
||||
color: "red"
|
||||
}
|
||||
\endcode
|
||||
|
||||
\section1 Tools and Utilities
|
||||
|
||||
For information on useful tools and utilies that make working with QML and
|
||||
|
|
|
@ -433,6 +433,19 @@ void QQuickAccessibleAttached::setRole(QAccessible::Role role)
|
|||
}
|
||||
}
|
||||
|
||||
bool QQuickAccessibleAttached::wasNameExplicitlySet() const
|
||||
{
|
||||
return m_nameExplicitlySet;
|
||||
}
|
||||
|
||||
// Allows types to attach an accessible name to an item as a convenience,
|
||||
// so long as the user hasn't done so themselves.
|
||||
void QQuickAccessibleAttached::setNameImplicitly(const QString &name)
|
||||
{
|
||||
setName(name);
|
||||
m_nameExplicitlySet = false;
|
||||
}
|
||||
|
||||
QQuickAccessibleAttached *QQuickAccessibleAttached::qmlAttachedProperties(QObject *obj)
|
||||
{
|
||||
return new QQuickAccessibleAttached(obj);
|
||||
|
|
|
@ -118,7 +118,10 @@ public:
|
|||
return QString();
|
||||
return m_name;
|
||||
}
|
||||
|
||||
bool wasNameExplicitlySet() const;
|
||||
void setName(const QString &name) {
|
||||
m_nameExplicitlySet = true;
|
||||
if (name != m_name) {
|
||||
m_name = name;
|
||||
Q_EMIT nameChanged();
|
||||
|
@ -126,6 +129,7 @@ public:
|
|||
QAccessible::updateAccessibility(&ev);
|
||||
}
|
||||
}
|
||||
void setNameImplicitly(const QString &name);
|
||||
|
||||
QString description() const { return m_description; }
|
||||
void setDescription(const QString &description)
|
||||
|
@ -216,6 +220,7 @@ private:
|
|||
QAccessible::State m_state;
|
||||
QAccessible::State m_stateExplicitlySet;
|
||||
QString m_name;
|
||||
bool m_nameExplicitlySet = false;
|
||||
QString m_description;
|
||||
|
||||
static QMetaMethod sigPress;
|
||||
|
|
|
@ -1790,6 +1790,7 @@ void QQuickItemViewPrivate::refill(qreal from, qreal to)
|
|||
if (prevCount != itemCount)
|
||||
emit q->countChanged();
|
||||
} while (currentChanges.hasPendingChanges() || bufferedChanges.hasPendingChanges());
|
||||
storeFirstVisibleItemPosition();
|
||||
}
|
||||
|
||||
void QQuickItemViewPrivate::regenerate(bool orientationChanged)
|
||||
|
@ -1876,6 +1877,7 @@ void QQuickItemViewPrivate::layout()
|
|||
|
||||
updateSections();
|
||||
layoutVisibleItems();
|
||||
storeFirstVisibleItemPosition();
|
||||
|
||||
int lastIndexInView = findLastIndexInView();
|
||||
refill();
|
||||
|
@ -1960,7 +1962,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
|
|||
prevFirstItemInViewPos = prevFirstItemInView->position();
|
||||
prevFirstItemInViewIndex = prevFirstItemInView->index;
|
||||
}
|
||||
qreal prevVisibleItemsFirstPos = visibleItems.count() ? visibleItems.constFirst()->position() : 0.0;
|
||||
qreal prevVisibleItemsFirstPos = visibleItems.count() ? firstVisibleItemPosition : 0.0;
|
||||
|
||||
totalInsertionResult->visiblePos = prevFirstItemInViewPos;
|
||||
totalRemovalResult->visiblePos = prevFirstItemInViewPos;
|
||||
|
@ -2006,6 +2008,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
|
|||
if (!insertions.isEmpty()) {
|
||||
repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstItemInView, &insertionResult, &removalResult);
|
||||
layoutVisibleItems(removals.first().index);
|
||||
storeFirstVisibleItemPosition();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2026,6 +2029,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult
|
|||
if (i < insertions.count() - 1) {
|
||||
repositionFirstItem(prevVisibleItemsFirst, prevVisibleItemsFirstPos, prevFirstItemInView, &insertionResult, &removalResult);
|
||||
layoutVisibleItems(insertions[i].index);
|
||||
storeFirstVisibleItemPosition();
|
||||
}
|
||||
itemCount += insertions[i].count;
|
||||
}
|
||||
|
|
|
@ -260,6 +260,12 @@ public:
|
|||
MovementReason moveReason;
|
||||
|
||||
QList<FxViewItem *> visibleItems;
|
||||
qreal firstVisibleItemPosition = 0;
|
||||
void storeFirstVisibleItemPosition() {
|
||||
if (!visibleItems.isEmpty()) {
|
||||
firstVisibleItemPosition = visibleItems.constFirst()->position();
|
||||
}
|
||||
}
|
||||
int visibleIndex;
|
||||
int currentIndex;
|
||||
FxViewItem *currentItem;
|
||||
|
|
|
@ -805,6 +805,7 @@ void QQuickListViewPrivate::layoutVisibleItems(int fromModelIndex)
|
|||
|
||||
FxViewItem *firstItem = *visibleItems.constBegin();
|
||||
bool fixedCurrent = currentItem && firstItem->item == currentItem->item;
|
||||
firstVisibleItemPosition = firstItem->position();
|
||||
qreal sum = firstItem->size();
|
||||
qreal pos = firstItem->position() + firstItem->size() + spacing;
|
||||
firstItem->setVisible(firstItem->endPosition() >= from && firstItem->position() <= to);
|
||||
|
|
|
@ -185,7 +185,8 @@ void tst_QQuickAccessible::quickAttachedProperties()
|
|||
QObject *object = component.create();
|
||||
QVERIFY(object != nullptr);
|
||||
|
||||
QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
|
||||
const auto attachedObject = qobject_cast<QQuickAccessibleAttached*>(
|
||||
QQuickAccessibleAttached::attachedProperties(object));
|
||||
QVERIFY(attachedObject);
|
||||
if (attachedObject) {
|
||||
QVariant p = attachedObject->property("role");
|
||||
|
@ -195,6 +196,7 @@ void tst_QQuickAccessible::quickAttachedProperties()
|
|||
QCOMPARE(p.isNull(), true);
|
||||
p = attachedObject->property("description");
|
||||
QCOMPARE(p.isNull(), true);
|
||||
QCOMPARE(attachedObject->wasNameExplicitlySet(), false);
|
||||
}
|
||||
delete object;
|
||||
}
|
||||
|
@ -211,7 +213,8 @@ void tst_QQuickAccessible::quickAttachedProperties()
|
|||
QObject *object = component.create();
|
||||
QVERIFY(object != nullptr);
|
||||
|
||||
QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
|
||||
const auto attachedObject = qobject_cast<QQuickAccessibleAttached*>(
|
||||
QQuickAccessibleAttached::attachedProperties(object));
|
||||
QVERIFY(attachedObject);
|
||||
if (attachedObject) {
|
||||
QVariant p = attachedObject->property("role");
|
||||
|
@ -223,6 +226,7 @@ void tst_QQuickAccessible::quickAttachedProperties()
|
|||
p = attachedObject->property("description");
|
||||
QCOMPARE(p.isNull(), false);
|
||||
QCOMPARE(p.toString(), QLatin1String("Duck"));
|
||||
QCOMPARE(attachedObject->wasNameExplicitlySet(), true);
|
||||
}
|
||||
delete object;
|
||||
}
|
||||
|
@ -292,6 +296,32 @@ void tst_QQuickAccessible::quickAttachedProperties()
|
|||
}
|
||||
delete object;
|
||||
}
|
||||
// Check that a name can be implicitly set.
|
||||
{
|
||||
QQmlEngine engine;
|
||||
QQmlComponent component(&engine);
|
||||
component.setData(R"(
|
||||
import QtQuick 2.0
|
||||
Text {
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.description: "Text Button"
|
||||
})", QUrl());
|
||||
QScopedPointer<QObject> object(component.create());
|
||||
QVERIFY(object);
|
||||
|
||||
const auto attachedObject = qobject_cast<QQuickAccessibleAttached*>(
|
||||
QQuickAccessibleAttached::attachedProperties(object.data()));
|
||||
QVERIFY(attachedObject);
|
||||
QVERIFY(!attachedObject->wasNameExplicitlySet());
|
||||
|
||||
attachedObject->setNameImplicitly(QLatin1String("Implicit"));
|
||||
QCOMPARE(attachedObject->name(), QLatin1String("Implicit"));
|
||||
QVERIFY(!attachedObject->wasNameExplicitlySet());
|
||||
|
||||
attachedObject->setName(QLatin1String("Explicit"));
|
||||
QCOMPARE(attachedObject->name(), QLatin1String("Explicit"));
|
||||
QVERIFY(attachedObject->wasNameExplicitlySet());
|
||||
}
|
||||
QTestAccessibility::clearEvents();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue