summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Arve Saether <jan-arve.saether@digia.com>2014-03-14 12:19:27 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-19 14:39:01 +0100
commitf9bff211ba4efbae35b8dc4d764e2992a8132826 (patch)
treec2bee50ab2a4dacad593d006a3bc6ee5e44d72a1
parent241ffae4518159caa812d594c2702ac16e0c8f29 (diff)
downloadqtquickcontrols-f9bff211ba4efbae35b8dc4d764e2992a8132826.tar.gz
Do not reduce items size when snapping to pixel grid.
Due to the required snapping to pixel grid, there was a high risk of reducing the size of an item to become smaller than its minimum size. With the original way of snapping (simply doing qRound) it didn't happen very often, but with the last change the problem became more evident: If an item that covered the full extent of a cell was snapped it would *always* shrink. Sometimes it could then shrink to become smaller than its minimum size. This was easy to see if the item snapped was a Text element with eliding enabled, since that meant that the text was elided as soon as the Text element got resized to smaller than its minimum. The current solution now is to always snap the x,y coordinates (with qCeil), but keep the width and height that was calculated by the layout. This means that snapped items will be shifted slightly to the right. Due to this they might extend almost a pixel outside their calculated cell (on the right or bottom sides). Due to this we also have to adjust the size hint result calculation so that it will also ceil up to the nearest integer. The only downside now is that row/column spacings might be less than specified, but they should not reduce by more than 1 pixel. Task-number: QTBUG-36235 Change-Id: Idca909f2102a1f7c5cb50d2490c7af39d722ff4f Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
-rw-r--r--src/layouts/qquickgridlayoutengine.cpp10
-rw-r--r--src/layouts/qquickgridlayoutengine_p.h12
-rw-r--r--tests/auto/controls/data/tst_gridlayout.qml10
3 files changed, 18 insertions, 14 deletions
diff --git a/src/layouts/qquickgridlayoutengine.cpp b/src/layouts/qquickgridlayoutengine.cpp
index 419a81df..09684b5d 100644
--- a/src/layouts/qquickgridlayoutengine.cpp
+++ b/src/layouts/qquickgridlayoutengine.cpp
@@ -142,6 +142,8 @@ static inline void combineImplicitHints(QQuickLayoutAttached *info, Qt::SizeHint
explicitly or implicitly set with QQuickLayoutAttached::isExtentExplicitlySet(). This
determines if it should be used as a USER or as a HINT value.
+ Fractional size hints will be ceiled to the closest integer. This is in order to give some
+ slack when the items are snapped to the pixel grid.
| *Minimum* | *Preferred* | *Maximum* |
+----------------+----------------------+-----------------------+--------------------------+
@@ -173,12 +175,12 @@ void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *c
Q_ASSERT(getter);
if (info->isExtentExplicitlySet(Qt::Horizontal, (Qt::SizeHint)i))
- cachedSizeHints[i].setWidth((info->*getter)());
+ cachedSizeHints[i].setWidth(qCeil((info->*getter)()));
getter = verGetters.call[i];
Q_ASSERT(getter);
if (info->isExtentExplicitlySet(Qt::Vertical, (Qt::SizeHint)i))
- cachedSizeHints[i].setHeight((info->*getter)());
+ cachedSizeHints[i].setHeight(qCeil((info->*getter)()));
}
}
@@ -213,9 +215,9 @@ void QQuickGridLayoutItem::effectiveSizeHints_helper(QQuickItem *item, QSizeF *c
qreal &prefWidth = prefS.rwidth();
qreal &prefHeight = prefS.rheight();
if (prefWidth < 0 && item->implicitWidth() > 0)
- prefWidth = item->implicitWidth();
+ prefWidth = qCeil(item->implicitWidth());
if (prefHeight < 0 && item->implicitHeight() > 0)
- prefHeight = item->implicitHeight();
+ prefHeight = qCeil(item->implicitHeight());
// If that fails, make an ultimate fallback to width/height
diff --git a/src/layouts/qquickgridlayoutengine_p.h b/src/layouts/qquickgridlayoutengine_p.h
index 94b8677a..f1dba1e9 100644
--- a/src/layouts/qquickgridlayoutengine_p.h
+++ b/src/layouts/qquickgridlayoutengine_p.h
@@ -113,15 +113,15 @@ public:
void setGeometry(const QRectF &rect)
{
- const QPoint innerTopLeft(qCeil(rect.left()), qCeil(rect.top()));
- const QPoint innerBottomRight(qFloor(rect.right()), qFloor(rect.bottom()));
- const QSize newSize(innerBottomRight.x() - innerTopLeft.x(), innerBottomRight.y() - innerTopLeft.y());
- m_item->setPosition(innerTopLeft);
- QSizeF oldSize(m_item->width(), m_item->height());
+ const QSizeF oldSize(m_item->width(), m_item->height());
+ const QSizeF newSize = rect.size();
+ const QPointF topLeft(qCeil(rect.x()), qCeil(rect.y()));
+ m_item->setPosition(topLeft);
if (newSize == oldSize) {
- if (QQuickLayout *lay = qobject_cast<QQuickLayout *>(m_item))
+ if (QQuickLayout *lay = qobject_cast<QQuickLayout *>(m_item)) {
if (lay->arrangementIsDirty())
lay->rearrange(newSize);
+ }
} else {
m_item->setSize(newSize);
}
diff --git a/tests/auto/controls/data/tst_gridlayout.qml b/tests/auto/controls/data/tst_gridlayout.qml
index 509eb098..7ca13b6b 100644
--- a/tests/auto/controls/data/tst_gridlayout.qml
+++ b/tests/auto/controls/data/tst_gridlayout.qml
@@ -901,14 +901,16 @@ Item {
var visualGeom = [child.x, child.y, child.x + child.width, child.y + child.height]
// verify that visualGeom is an integer number
- for (var i = 0; i < 4; ++i)
+ for (var i = 0; i < 2; ++i)
compare(visualGeom[i] % 1, 0)
- // verify that visualGeom is never outside the idealGeom
+ // verify that x,y is is inside idealGeom
verify(visualGeom[0] >= idealGeom[0])
verify(visualGeom[1] >= idealGeom[1])
- verify(visualGeom[2] <= idealGeom[2])
- verify(visualGeom[3] <= idealGeom[3])
+
+ // verify that the visual size is no more than 1 pixel taller/wider than the ideal size.
+ verify(visualGeom[2] <= idealGeom[2] + 1)
+ verify(visualGeom[3] <= idealGeom[3] + 1)
idealGeom[0] = idealGeom[2] + sp
idealGeom[2] = idealGeom[0] + rectWidth
}