aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2016-02-19 12:49:16 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2016-02-19 12:59:04 +0100
commit4e7f570f921671c627040537b4dd8cdb77bda3d1 (patch)
tree7d82e1b6536d5274ab29a3e6307fedcbefd3ce78 /src/quick/items
parent72447b6dbf98ace65ec46559337243970a668d26 (diff)
parent39df6760e4db6af700c46a420286b51113b5dadb (diff)
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts: src/quick/items/qquickitem.cpp tests/auto/quick/qquickgridview/tst_qquickgridview.cpp tests/auto/quick/qquicklistview/tst_qquicklistview.cpp Change-Id: I3cf47faa2fe567d62fffd985aeecbefe5811cc42
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickgridview.cpp80
-rw-r--r--src/quick/items/qquickitem.cpp30
-rw-r--r--src/quick/items/qquickitem.h3
-rw-r--r--src/quick/items/qquicktext.cpp19
-rw-r--r--src/quick/items/qquicktextnodeengine.cpp7
-rw-r--r--src/quick/items/qquickwindow.cpp39
-rw-r--r--src/quick/items/qquickwindow.h1
-rw-r--r--src/quick/items/qquickwindow_p.h3
8 files changed, 143 insertions, 39 deletions
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 421c9762ff..da48fd869d 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -182,6 +182,8 @@ public:
bool addVisibleItems(qreal fillFrom, qreal fillTo, qreal bufferFrom, qreal bufferTo, bool doBuffer) Q_DECL_OVERRIDE;
bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) Q_DECL_OVERRIDE;
+ void removeItem(FxViewItem *item);
+
FxViewItem *newViewItem(int index, QQuickItem *item) Q_DECL_OVERRIDE;
void initializeViewItem(FxViewItem *item) Q_DECL_OVERRIDE;
void repositionItemAt(FxViewItem *item, int index, qreal sizeBuffer) Q_DECL_OVERRIDE;
@@ -567,6 +569,17 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
return changed;
}
+void QQuickGridViewPrivate::removeItem(FxViewItem *item)
+{
+ if (item->transitionScheduledOrRunning()) {
+ qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item:" << item->index << item->item->objectName();
+ item->releaseAfterTransition = true;
+ releasePendingTransition.append(item);
+ } else {
+ releaseItem(item);
+ }
+}
+
bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo)
{
FxGridItemSG *item = 0;
@@ -581,13 +594,7 @@ bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
if (item->index != -1)
visibleIndex++;
visibleItems.removeFirst();
- if (item->transitionScheduledOrRunning()) {
- qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item:" << item->index << item->item->objectName();
- item->releaseAfterTransition = true;
- releasePendingTransition.append(item);
- } else {
- releaseItem(item);
- }
+ removeItem(item);
changed = true;
}
while (visibleItems.count() > 1
@@ -597,13 +604,7 @@ bool QQuickGridViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer
break;
qCDebug(lcItemViewDelegateLifecycle) << "refill: remove last" << visibleIndex+visibleItems.count()-1;
visibleItems.removeLast();
- if (item->transitionScheduledOrRunning()) {
- qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item:" << item->index << item->item->objectName();
- item->releaseAfterTransition = true;
- releasePendingTransition.append(item);
- } else {
- releaseItem(item);
- }
+ removeItem(item);
changed = true;
}
@@ -2406,11 +2407,12 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
int i = count - 1;
int from = tempPos - buffer - displayMarginBeginning;
- while (i >= 0) {
- if (rowPos > from && insertionIdx < visibleIndex) {
- // item won't be visible, just note the size for repositioning
- insertResult->countChangeBeforeVisible++;
- } else {
+ if (rowPos > from && insertionIdx < visibleIndex) {
+ // items won't be visible, just note the size for repositioning
+ insertResult->countChangeBeforeVisible += count;
+ insertResult->sizeChangesBeforeVisiblePos += ((count + columns - 1) / columns) * rowSize();
+ } else {
+ while (i >= 0) {
// item is before first visible e.g. in cache buffer
FxViewItem *item = 0;
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
@@ -2426,19 +2428,40 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
insertResult->changedFirstItem = true;
if (!change.isMove()) {
addedItems->append(item);
- item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true);
+ if (transitioner)
+ item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true);
+ else
+ item->moveTo(QPointF(colPos, rowPos), true);
}
insertResult->sizeChangesBeforeVisiblePos += rowSize();
+
+ if (--colNum < 0 ) {
+ colNum = columns - 1;
+ rowPos -= rowSize();
+ }
+ colPos = colNum * colSize();
+ index++;
+ i--;
}
+ }
- if (--colNum < 0 ) {
- colNum = columns - 1;
- rowPos -= rowSize();
+ // There may be gaps in the index sequence of visibleItems because
+ // of the index shift/update done before the insertion just above.
+ // Find if there is any...
+ int firstOkIdx = -1;
+ for (int i = 0; i <= insertionIdx && i < visibleItems.count() - 1; i++) {
+ if (visibleItems.at(i)->index + 1 != visibleItems.at(i + 1)->index) {
+ firstOkIdx = i + 1;
+ break;
}
- colPos = colNum * colSize();
- index++;
- i--;
}
+ // ... and remove all the items before that one
+ for (int i = 0; i < firstOkIdx; i++) {
+ FxViewItem *nvItem = visibleItems.takeFirst();
+ addedItems->removeOne(nvItem);
+ removeItem(nvItem);
+ }
+
} else {
int i = 0;
int to = buffer+displayMarginEnd+tempPos+size()-1;
@@ -2463,7 +2486,10 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
movingIntoView->append(MovedItem(item, change.moveKey(item->index)));
} else {
addedItems->append(item);
- item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true);
+ if (transitioner)
+ item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true);
+ else
+ item->moveTo(QPointF(colPos, rowPos), true);
}
insertResult->sizeChangesAfterVisiblePos += rowSize();
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 8715fa2772..4bd95d5520 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2074,6 +2074,10 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
\value ItemRotationHasChanged The item's rotation has changed.
ItemChangeData::realValue contains the new rotation.
+
+ \value ItemDevicePixelRatioHasChanged The device pixel ratio of the screen
+ the item is on has changed. ItemChangedData::realValue contains the new
+ device pixel ratio.
*/
/*!
@@ -2477,6 +2481,7 @@ QQuickItem *QQuickItemPrivate::prevTabChildItem(const QQuickItem *item, int star
QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, bool forward)
{
Q_ASSERT(item);
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: item:" << item << ", forward:" << forward;
if (!item->window())
return item;
@@ -2487,19 +2492,25 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
bool all = QGuiApplication::styleHints()->tabFocusBehavior() == Qt::TabFocusAllControls;
QQuickItem *from = 0;
+ bool isTabFence = item->d_func()->isTabFence;
if (forward) {
- from = item->parentItem();
+ if (!isTabFence)
+ from = item->parentItem();
} else {
if (!item->childItems().isEmpty())
from = item->d_func()->childItems.constFirst();
- else
+ else if (!isTabFence)
from = item->parentItem();
}
bool skip = false;
QQuickItem * startItem = item;
QQuickItem * firstFromItem = from;
QQuickItem *current = item;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
do {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
skip = false;
QQuickItem *last = current;
@@ -2513,7 +2524,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
else
lastChild = prevTabChildItem(current, -1);
}
- bool isTabFence = current->d_func()->isTabFence;
+ isTabFence = current->d_func()->isTabFence;
if (isTabFence && !hasChildren)
return current;
@@ -2568,9 +2579,14 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
return startItem;
}
}
- if (!firstFromItem) { //start from root
- startItem = current;
- firstFromItem = from;
+ if (!firstFromItem) {
+ if (startItem->d_func()->isTabFence) {
+ if (current == startItem)
+ firstFromItem = from;
+ } else { //start from root
+ startItem = current;
+ firstFromItem = from;
+ }
}
} while (skip || !current->activeFocusOnTab() || !current->isEnabled() || !current->isVisible()
|| !(all || QQuickItemPrivate::canAcceptTabFocus(current)));
@@ -5968,6 +5984,8 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
}
break;
case QQuickItem::ItemAntialiasingHasChanged:
+ // fall through
+ case QQuickItem::ItemDevicePixelRatioHasChanged:
q->itemChange(change, data);
break;
}
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 8795c71b38..b33f3d8b6a 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -172,7 +172,8 @@ public:
ItemOpacityHasChanged, // value.realValue
ItemActiveFocusHasChanged, // value.boolValue
ItemRotationHasChanged, // value.realValue
- ItemAntialiasingHasChanged // value.boolValue
+ ItemAntialiasingHasChanged, // value.boolValue
+ ItemDevicePixelRatioHasChanged // value.realValue
};
union ItemChangeData {
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 0f7f1961a1..f3254cf8d7 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -1465,7 +1465,8 @@ void QQuickText::itemChange(ItemChange change, const ItemChangeData &value)
{
Q_D(QQuickText);
Q_UNUSED(value);
- if (change == ItemAntialiasingHasChanged) {
+ switch (change) {
+ case ItemAntialiasingHasChanged:
if (!antialiasing())
d->font.setStyleStrategy(QFont::NoAntialias);
else
@@ -1473,6 +1474,22 @@ void QQuickText::itemChange(ItemChange change, const ItemChangeData &value)
d->implicitWidthValid = false;
d->implicitHeightValid = false;
d->updateLayout();
+ break;
+
+ case ItemDevicePixelRatioHasChanged:
+ if (d->renderType == NativeRendering) {
+ // Native rendering optimizes for a given pixel grid, so its results must not be scaled.
+ // Text layout code respects the current device pixel ratio automatically, we only need
+ // to rerun layout after the ratio changed.
+ // Changes of implicit size should be minimal; they are hard to avoid.
+ d->implicitWidthValid = false;
+ d->implicitHeightValid = false;
+ d->updateLayout();
+ }
+ break;
+
+ default:
+ break;
}
QQuickItem::itemChange(change, value);
}
diff --git a/src/quick/items/qquicktextnodeengine.cpp b/src/quick/items/qquicktextnodeengine.cpp
index 34b9d6efa2..2872c3e230 100644
--- a/src/quick/items/qquicktextnodeengine.cpp
+++ b/src/quick/items/qquicktextnodeengine.cpp
@@ -828,14 +828,15 @@ void QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode,
for (int i = 0; i < node->ranges.size(); ++i) {
const QPair<int, int> &range = node->ranges.at(i);
- int rangeLength = range.second - range.first;
+ int rangeLength = range.second - range.first + 1;
if (previousNode != 0) {
for (int j = 0; j < previousNode->ranges.size(); ++j) {
const QPair<int, int> &otherRange = previousNode->ranges.at(j);
+
if (range.first < otherRange.second && range.second > otherRange.first) {
int start = qMax(range.first, otherRange.first);
int end = qMin(range.second, otherRange.second);
- rangeLength -= end - start;
+ rangeLength -= end - start + 1;
if (rangeLength == 0)
break;
}
@@ -849,7 +850,7 @@ void QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode,
if (range.first < otherRange.second && range.second > otherRange.first) {
int start = qMax(range.first, otherRange.first);
int end = qMin(range.second, otherRange.second);
- rangeLength -= end - start;
+ rangeLength -= end - start + 1;
if (rangeLength == 0)
break;
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 10f4fb20fc..44ff9aef81 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -294,10 +294,43 @@ void QQuickWindow::update()
QQuickRenderControlPrivate::get(d->renderControl)->update();
}
+static void updatePixelRatioHelper(QQuickItem *item, float pixelRatio)
+{
+ if (item->flags() & QQuickItem::ItemHasContents) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->itemChange(QQuickItem::ItemDevicePixelRatioHasChanged, pixelRatio);
+ }
+
+ QList <QQuickItem *> items = item->childItems();
+ for (int i = 0; i < items.size(); ++i)
+ updatePixelRatioHelper(items.at(i), pixelRatio);
+}
+
+void QQuickWindow::physicalDpiChanged()
+{
+ Q_D(QQuickWindow);
+ const qreal newPixelRatio = screen()->devicePixelRatio();
+ if (qFuzzyCompare(newPixelRatio, d->devicePixelRatio))
+ return;
+ d->devicePixelRatio = newPixelRatio;
+ if (d->contentItem)
+ updatePixelRatioHelper(d->contentItem, newPixelRatio);
+}
+
void QQuickWindow::handleScreenChanged(QScreen *screen)
{
Q_D(QQuickWindow);
- Q_UNUSED(screen)
+ if (screen) {
+ physicalDpiChanged();
+ // When physical DPI changes on the same screen, either the resolution or the device pixel
+ // ratio changed. We must check what it is. Device pixel ratio does not have its own
+ // ...Changed() signal.
+ d->physicalDpiChangedConnection = connect(screen, SIGNAL(physicalDotsPerInchChanged(qreal)),
+ this, SLOT(physicalDpiChanged()));
+ } else {
+ disconnect(d->physicalDpiChangedConnection);
+ }
+
d->forcePolish();
}
@@ -416,6 +449,7 @@ QQuickWindowPrivate::QQuickWindowPrivate()
, touchMouseId(-1)
, touchMousePressTimestamp(0)
, dirtyItemList(0)
+ , devicePixelRatio(0)
, context(0)
, renderer(0)
, windowManager(0)
@@ -470,6 +504,9 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
Q_ASSERT(windowManager || renderControl);
+ if (QScreen *screen = q->screen())
+ devicePixelRatio = screen->devicePixelRatio();
+
QSGContext *sg;
if (renderControl) {
QQuickRenderControlPrivate *renderControlPriv = QQuickRenderControlPrivate::get(renderControl);
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index 262828ad1d..e04a4a1ce2 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -202,6 +202,7 @@ protected:
private Q_SLOTS:
void maybeUpdate();
void cleanupSceneGraph();
+ void physicalDpiChanged();
void handleScreenChanged(QScreen *screen);
void setTransientParent_helper(QQuickWindow *window);
void runJobsAfterSwap();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 652320c1c9..1064be7178 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -211,6 +211,9 @@ public:
QVector<QQuickItem *> itemsToPolish;
+ qreal devicePixelRatio;
+ QMetaObject::Connection physicalDpiChangedConnection;
+
void updateDirtyNodes();
void cleanupNodes();
void cleanupNodesOnShutdown();