mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2024-11-24 12:30:32 +08:00
171 lines
4.5 KiB
C++
171 lines
4.5 KiB
C++
|
// Copyright (C) 2016 The Qt Company Ltd.
|
||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||
|
|
||
|
#include "flowlayout.h"
|
||
|
|
||
|
#include <QtMath>
|
||
|
|
||
|
FlowLayout::FlowLayout(QGraphicsLayoutItem *parent) : QGraphicsLayout(parent)
|
||
|
{
|
||
|
QSizePolicy sp = sizePolicy();
|
||
|
sp.setHeightForWidth(true);
|
||
|
setSizePolicy(sp);
|
||
|
}
|
||
|
|
||
|
void FlowLayout::insertItem(int index, QGraphicsLayoutItem *item)
|
||
|
{
|
||
|
item->setParentLayoutItem(this);
|
||
|
if (index > m_items.count() || index < 0)
|
||
|
index = m_items.count();
|
||
|
m_items.insert(index, item);
|
||
|
invalidate();
|
||
|
}
|
||
|
|
||
|
int FlowLayout::count() const
|
||
|
{
|
||
|
return m_items.count();
|
||
|
}
|
||
|
|
||
|
QGraphicsLayoutItem *FlowLayout::itemAt(int index) const
|
||
|
{
|
||
|
return m_items.value(index);
|
||
|
}
|
||
|
|
||
|
void FlowLayout::removeAt(int index)
|
||
|
{
|
||
|
m_items.removeAt(index);
|
||
|
invalidate();
|
||
|
}
|
||
|
|
||
|
qreal FlowLayout::spacing(Qt::Orientation o) const
|
||
|
{
|
||
|
return m_spacing[int(o) - 1];
|
||
|
}
|
||
|
|
||
|
void FlowLayout::setSpacing(Qt::Orientations o, qreal spacing)
|
||
|
{
|
||
|
if (o & Qt::Horizontal)
|
||
|
m_spacing[0] = spacing;
|
||
|
if (o & Qt::Vertical)
|
||
|
m_spacing[1] = spacing;
|
||
|
}
|
||
|
|
||
|
void FlowLayout::setGeometry(const QRectF &geom)
|
||
|
{
|
||
|
QGraphicsLayout::setGeometry(geom);
|
||
|
doLayout(geom, true);
|
||
|
}
|
||
|
|
||
|
qreal FlowLayout::doLayout(const QRectF &geom, bool applyNewGeometry) const
|
||
|
{
|
||
|
qreal left, top, right, bottom;
|
||
|
getContentsMargins(&left, &top, &right, &bottom);
|
||
|
const qreal maxw = geom.width() - left - right;
|
||
|
|
||
|
qreal x = 0;
|
||
|
qreal y = 0;
|
||
|
qreal maxRowHeight = 0;
|
||
|
QSizeF pref;
|
||
|
for (QGraphicsLayoutItem *item : m_items) {
|
||
|
pref = item->effectiveSizeHint(Qt::PreferredSize);
|
||
|
maxRowHeight = qMax(maxRowHeight, pref.height());
|
||
|
|
||
|
qreal next_x;
|
||
|
next_x = x + pref.width();
|
||
|
if (next_x > maxw) {
|
||
|
if (qFuzzyIsNull(x)) {
|
||
|
pref.setWidth(maxw);
|
||
|
} else {
|
||
|
x = 0;
|
||
|
next_x = pref.width();
|
||
|
}
|
||
|
y += maxRowHeight + spacing(Qt::Vertical);
|
||
|
maxRowHeight = 0;
|
||
|
}
|
||
|
|
||
|
if (applyNewGeometry)
|
||
|
item->setGeometry(QRectF(QPointF(left + x, top + y), pref));
|
||
|
x = next_x + spacing(Qt::Horizontal);
|
||
|
}
|
||
|
maxRowHeight = qMax(maxRowHeight, pref.height());
|
||
|
return top + y + maxRowHeight + bottom;
|
||
|
}
|
||
|
|
||
|
QSizeF FlowLayout::minSize(const QSizeF &constraint) const
|
||
|
{
|
||
|
QSizeF size(0, 0);
|
||
|
qreal left, top, right, bottom;
|
||
|
getContentsMargins(&left, &top, &right, &bottom);
|
||
|
if (constraint.width() >= 0) { // height for width
|
||
|
const qreal height = doLayout(QRectF(QPointF(0,0), constraint), false);
|
||
|
size = QSizeF(constraint.width(), height);
|
||
|
} else if (constraint.height() >= 0) { // width for height?
|
||
|
// not supported
|
||
|
} else {
|
||
|
for (const QGraphicsLayoutItem *item : std::as_const(m_items))
|
||
|
size = size.expandedTo(item->effectiveSizeHint(Qt::MinimumSize));
|
||
|
size += QSizeF(left + right, top + bottom);
|
||
|
}
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
QSizeF FlowLayout::prefSize() const
|
||
|
{
|
||
|
qreal left, right;
|
||
|
getContentsMargins(&left, nullptr, &right, nullptr);
|
||
|
|
||
|
qreal maxh = 0;
|
||
|
qreal totalWidth = 0;
|
||
|
for (const QGraphicsLayoutItem *item : std::as_const(m_items)) {
|
||
|
if (totalWidth > 0)
|
||
|
totalWidth += spacing(Qt::Horizontal);
|
||
|
QSizeF pref = item->effectiveSizeHint(Qt::PreferredSize);
|
||
|
totalWidth += pref.width();
|
||
|
maxh = qMax(maxh, pref.height());
|
||
|
}
|
||
|
maxh += spacing(Qt::Vertical);
|
||
|
|
||
|
const qreal goldenAspectRatio = 1.61803399;
|
||
|
qreal w = qSqrt(totalWidth * maxh * goldenAspectRatio) + left + right;
|
||
|
|
||
|
return minSize(QSizeF(w, -1));
|
||
|
}
|
||
|
|
||
|
QSizeF FlowLayout::maxSize() const
|
||
|
{
|
||
|
qreal totalWidth = 0;
|
||
|
qreal totalHeight = 0;
|
||
|
for (const QGraphicsLayoutItem *item : std::as_const(m_items)) {
|
||
|
if (totalWidth > 0)
|
||
|
totalWidth += spacing(Qt::Horizontal);
|
||
|
if (totalHeight > 0)
|
||
|
totalHeight += spacing(Qt::Vertical);
|
||
|
QSizeF pref = item->effectiveSizeHint(Qt::PreferredSize);
|
||
|
totalWidth += pref.width();
|
||
|
totalHeight += pref.height();
|
||
|
}
|
||
|
|
||
|
qreal left, top, right, bottom;
|
||
|
getContentsMargins(&left, &top, &right, &bottom);
|
||
|
return QSizeF(left + totalWidth + right, top + totalHeight + bottom);
|
||
|
}
|
||
|
|
||
|
QSizeF FlowLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
|
||
|
{
|
||
|
QSizeF sh = constraint;
|
||
|
switch (which) {
|
||
|
case Qt::PreferredSize:
|
||
|
sh = prefSize();
|
||
|
break;
|
||
|
case Qt::MinimumSize:
|
||
|
sh = minSize(constraint);
|
||
|
break;
|
||
|
case Qt::MaximumSize:
|
||
|
sh = maxSize();
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return sh;
|
||
|
}
|