diff options
Diffstat (limited to 'src/gui/util/qgridlayoutengine.cpp')
-rw-r--r-- | src/gui/util/qgridlayoutengine.cpp | 150 |
1 files changed, 87 insertions, 63 deletions
diff --git a/src/gui/util/qgridlayoutengine.cpp b/src/gui/util/qgridlayoutengine.cpp index d875db0da6..07981e8388 100644 --- a/src/gui/util/qgridlayoutengine.cpp +++ b/src/gui/util/qgridlayoutengine.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/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 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qglobal.h" @@ -47,10 +11,14 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + +#define LAYOUTITEMSIZE_MAX (1 << 24) + template<typename T> static void insertOrRemoveItems(QList<T> &items, int index, int delta) { - int count = items.count(); + int count = items.size(); if (index < count) { if (delta > 0) { items.insert(index, delta, T()); @@ -228,7 +196,8 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz sumAvailable = targetSize - totalBox.q_minimumSize; if (sumAvailable > 0.0) { - qreal sumDesired = totalBox.q_preferredSize - totalBox.q_minimumSize; + const qreal totalBox_preferredSize = qMin(totalBox.q_preferredSize, qreal(LAYOUTITEMSIZE_MAX)); + qreal sumDesired = totalBox_preferredSize - totalBox.q_minimumSize; for (int i = 0; i < n; ++i) { if (ignore.testBit(start + i)) { @@ -237,7 +206,8 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz } const QGridLayoutBox &box = boxes.at(start + i); - qreal desired = box.q_preferredSize - box.q_minimumSize; + const qreal box_preferredSize = qMin(box.q_preferredSize, qreal(LAYOUTITEMSIZE_MAX)); + qreal desired = box_preferredSize - box.q_minimumSize; factors[i] = growthFactorBelowPreferredSize(desired, sumAvailable, sumDesired); sumFactors += factors[i]; } @@ -750,7 +720,7 @@ void QGridLayoutItem::dump(int indent) const if (q_alignment != 0) qDebug("%*s Alignment: %x", indent, "", uint(q_alignment)); qDebug("%*s Horizontal size policy: %x Vertical size policy: %x", - indent, "", sizePolicy(Qt::Horizontal), sizePolicy(Qt::Vertical)); + indent, "", (unsigned int)sizePolicy(Qt::Horizontal), (unsigned int)sizePolicy(Qt::Vertical)); } #endif @@ -792,6 +762,8 @@ QGridLayoutEngine::QGridLayoutEngine(Qt::Alignment defaultAlignment, bool snapTo m_visualDirection = Qt::LeftToRight; m_defaultAlignment = defaultAlignment; m_snapToPixelGrid = snapToPixelGrid; + m_uniformCellWidths = false; + m_uniformCellHeights = false; invalidate(); } @@ -807,7 +779,7 @@ int QGridLayoutEngine::columnCount(Qt::Orientation orientation) const int QGridLayoutEngine::itemCount() const { - return q_items.count(); + return q_items.size(); } QGridLayoutItem *QGridLayoutEngine::itemAt(int index) const @@ -852,7 +824,7 @@ void QGridLayoutEngine::setRowSpacing(int row, qreal spacing, Qt::Orientation or Q_ASSERT(row >= 0); QGridLayoutRowInfo &rowInfo = q_infos[orientation]; - if (row >= rowInfo.spacings.count()) + if (row >= rowInfo.spacings.size()) rowInfo.spacings.resize(row + 1); if (spacing >= 0) rowInfo.spacings[row].setUserValue(spacing); @@ -877,7 +849,7 @@ void QGridLayoutEngine::setRowStretchFactor(int row, int stretch, Qt::Orientatio maybeExpandGrid(row, -1, orientation); QGridLayoutRowInfo &rowInfo = q_infos[orientation]; - if (row >= rowInfo.stretches.count()) + if (row >= rowInfo.stretches.size()) rowInfo.stretches.resize(row + 1); rowInfo.stretches[row].setUserValue(stretch); } @@ -899,7 +871,7 @@ void QGridLayoutEngine::setRowSizeHint(Qt::SizeHint which, int row, qreal size, maybeExpandGrid(row, -1, orientation); QGridLayoutRowInfo &rowInfo = q_infos[orientation]; - if (row >= rowInfo.boxes.count()) + if (row >= rowInfo.boxes.size()) rowInfo.boxes.resize(row + 1); rowInfo.boxes[row].q_sizes(which) = size; } @@ -909,6 +881,34 @@ qreal QGridLayoutEngine::rowSizeHint(Qt::SizeHint which, int row, Qt::Orientatio return q_infos[orientation].boxes.value(row).q_sizes(which); } +bool QGridLayoutEngine::uniformCellWidths() const +{ + return m_uniformCellWidths; +} + +void QGridLayoutEngine::setUniformCellWidths(bool uniformCellWidths) +{ + if (m_uniformCellWidths == uniformCellWidths) + return; + + m_uniformCellWidths = uniformCellWidths; + invalidate(); +} + +bool QGridLayoutEngine::uniformCellHeights() const +{ + return m_uniformCellHeights; +} + +void QGridLayoutEngine::setUniformCellHeights(bool uniformCellHeights) +{ + if (m_uniformCellHeights == uniformCellHeights) + return; + + m_uniformCellHeights = uniformCellHeights; + invalidate(); +} + void QGridLayoutEngine::setRowAlignment(int row, Qt::Alignment alignment, Qt::Orientation orientation) { @@ -917,7 +917,7 @@ void QGridLayoutEngine::setRowAlignment(int row, Qt::Alignment alignment, maybeExpandGrid(row, -1, orientation); QGridLayoutRowInfo &rowInfo = q_infos[orientation]; - if (row >= rowInfo.alignments.count()) + if (row >= rowInfo.alignments.size()) rowInfo.alignments.resize(row + 1); rowInfo.alignments[row] = alignment; } @@ -964,8 +964,11 @@ void QGridLayoutEngine::insertItem(QGridLayoutItem *item, int index) for (int i = item->firstRow(); i <= item->lastRow(); ++i) { for (int j = item->firstColumn(); j <= item->lastColumn(); ++j) { - if (itemAt(i, j)) - qWarning("QGridLayoutEngine::addItem: Cell (%d, %d) already taken", i, j); + const auto existingItem = itemAt(i, j); + if (existingItem) { + qWarning("QGridLayoutEngine::addItem: Can't add %s at cell (%d, %d) because it's already taken by %s", + qPrintable(item->toString()), i, j, qPrintable(existingItem->toString())); + } setItemAt(i, j, item); } } @@ -1026,7 +1029,7 @@ void QGridLayoutEngine::setGeometries(const QRectF &contentsGeometry, const QAbs ensureGeometries(contentsGeometry.size(), styleInfo); - for (int i = q_items.count() - 1; i >= 0; --i) { + for (int i = q_items.size() - 1; i >= 0; --i) { QGridLayoutItem *item = q_items.at(i); qreal x = q_xx.at(item->firstColumn()); @@ -1155,7 +1158,7 @@ void QGridLayoutEngine::transpose() { invalidate(); - for (int i = q_items.count() - 1; i >= 0; --i) + for (int i = q_items.size() - 1; i >= 0; --i) q_items.at(i)->transpose(); q_defaultSpacings.transpose(); @@ -1179,7 +1182,7 @@ void QGridLayoutEngine::dump(int indent) const { qDebug("%*sEngine", indent, ""); - qDebug("%*s Items (%d)", indent, "", q_items.count()); + qDebug("%*s Items (%lld)", indent, "", q_items.count()); int i; for (i = 0; i < q_items.count(); ++i) q_items.at(i)->dump(indent + 2); @@ -1187,12 +1190,12 @@ void QGridLayoutEngine::dump(int indent) const qDebug("%*s Grid (%d x %d)", indent, "", internalGridRowCount(), internalGridColumnCount()); for (int row = 0; row < internalGridRowCount(); ++row) { - QString message = QLatin1String("[ "); + QString message = "[ "_L1; for (int column = 0; column < internalGridColumnCount(); ++column) { message += QString::number(q_items.indexOf(itemAt(row, column))).rightJustified(3); - message += QLatin1Char(' '); + message += u' '; } - message += QLatin1Char(']'); + message += u']'; qDebug("%*s %s", indent, "", qPrintable(message)); } @@ -1214,10 +1217,10 @@ void QGridLayoutEngine::dump(int indent) const for (int pass = 0; pass < 2; ++pass) { QString message; for (i = 0; i < cellPos->count(); ++i) { - message += QLatin1String((message.isEmpty() ? "[" : ", ")); + message += (message.isEmpty() ? "["_L1 : ", "_L1); message += QString::number(cellPos->at(i)); } - message += QLatin1Char(']'); + message += u']'; qDebug("%*s %s %s", indent, "", (pass == 0 ? "rows:" : "columns:"), qPrintable(message)); cellPos = &q_xx; } @@ -1244,7 +1247,7 @@ void QGridLayoutEngine::maybeExpandGrid(int row, int column, Qt::Orientation ori int newGridColumnCount = internalGridColumnCount(); int newGridSize = newGridRowCount * newGridColumnCount; - if (newGridSize != q_grid.count()) { + if (newGridSize != q_grid.size()) { q_grid.resize(newGridSize); if (newGridColumnCount != oldGridColumnCount) { @@ -1266,7 +1269,7 @@ void QGridLayoutEngine::regenerateGrid() { q_grid.fill(nullptr); - for (int i = q_items.count() - 1; i >= 0; --i) { + for (int i = q_items.size() - 1; i >= 0; --i) { QGridLayoutItem *item = q_items.at(i); for (int j = item->firstRow(); j <= item->lastRow(); ++j) { @@ -1299,7 +1302,7 @@ void QGridLayoutEngine::insertOrRemoveRows(int row, int delta, Qt::Orientation o q_infos[orientation].insertOrRemoveRows(row, delta); - for (int i = q_items.count() - 1; i >= 0; --i) + for (int i = q_items.size() - 1; i >= 0; --i) q_items.at(i)->insertOrRemoveRows(row, delta, orientation); q_grid.resize(internalGridRowCount() * internalGridColumnCount()); @@ -1440,7 +1443,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, } } } - if (row < rowInfo.boxes.count()) { + if (row < rowInfo.boxes.size()) { QGridLayoutBox rowBoxInfo = rowInfo.boxes.at(row); rowBoxInfo.normalize(); rowBox.q_minimumSize = qMax(rowBox.q_minimumSize, rowBoxInfo.q_minimumSize); @@ -1533,6 +1536,27 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, rowSpacing = qMax(windowMargin, rowSpacing); } } + + if (rowData->boxes.size() > 1 && + ((orientation == Qt::Horizontal && m_uniformCellWidths) || + (orientation == Qt::Vertical && m_uniformCellHeights))) { + qreal averagePreferredSize = 0.; + qreal minimumMaximumSize = std::numeric_limits<qreal>::max(); + qreal maximumMinimumSize = 0.; + for (const auto &box : rowData->boxes) { + averagePreferredSize += box.q_preferredSize; + minimumMaximumSize = qMin(minimumMaximumSize, box.q_maximumSize); + maximumMinimumSize = qMax(maximumMinimumSize, box.q_minimumSize); + } + averagePreferredSize /= rowData->boxes.size(); + minimumMaximumSize = qMax(minimumMaximumSize, maximumMinimumSize); + averagePreferredSize = qBound(maximumMinimumSize, averagePreferredSize, minimumMaximumSize); + for (auto &box : rowData->boxes) { + box.q_preferredSize = averagePreferredSize; + box.q_minimumSize = maximumMinimumSize; + box.q_maximumSize = minimumMaximumSize; + } + } } void QGridLayoutEngine::ensureEffectiveFirstAndLastRows() const @@ -1544,7 +1568,7 @@ void QGridLayoutEngine::ensureEffectiveFirstAndLastRows() const q_cachedEffectiveFirstRows = {columnCount, rowCount}; q_cachedEffectiveLastRows = {-1, -1}; - for (int i = q_items.count() - 1; i >= 0; --i) { + for (int i = q_items.size() - 1; i >= 0; --i) { const QGridLayoutItem *item = q_items.at(i); for (Qt::Orientation o : {Qt::Horizontal, Qt::Vertical}) { @@ -1590,7 +1614,7 @@ void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGri bool QGridLayoutEngine::ensureDynamicConstraint() const { if (q_cachedConstraintOrientation == UnknownConstraint) { - for (int i = q_items.count() - 1; i >= 0; --i) { + for (int i = q_items.size() - 1; i >= 0; --i) { QGridLayoutItem *item = q_items.at(i); if (item->hasDynamicConstraint()) { Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation(); |