/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the either Technology Preview License Agreement or the ** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://www.qtsoftware.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "flowlayout.h" #include #include FlowLayout::FlowLayout() { m_spacing[0] = 6; m_spacing[1] = 6; QSizePolicy sp = sizePolicy(); sp.setHeightForWidth(true); setSizePolicy(sp); } void FlowLayout::insertItem(int index, QGraphicsLayoutItem *item) { item->setParentLayoutItem(this); if (uint(index) > uint(m_items.count())) 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 { QPointF tl = geom.topLeft(); qreal maxw = geom.width(); qreal left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); maxw = maxw - left - right; qreal x = 0; qreal y = 0; qreal maxRowHeight = 0; QSizeF pref; for (int i = 0; i < m_items.count(); ++i) { QGraphicsLayoutItem *item = m_items.at(i); pref = item->effectiveSizeHint(Qt::PreferredSize); maxRowHeight = qMax(maxRowHeight, pref.height()); qreal next_x; next_x = x + pref.width(); if (next_x > maxw) { if (x == 0) { 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 qreal height = doLayout(QRectF(QPointF(0,0), constraint), false); size = QSizeF(constraint.width(), height); } else { QGraphicsLayoutItem *item; foreach (item, m_items) size = size.expandedTo(item->effectiveSizeHint(Qt::MinimumSize)); size += QSize(left + right, top + bottom); } return size; } QSizeF FlowLayout::prefSize() const { qreal left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); QGraphicsLayoutItem *item; qreal maxh = 0; qreal totalWidth = 0; foreach (item, 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 { QGraphicsLayoutItem *item; qreal totalWidth = 0; qreal totalHeight = 0; foreach (item, 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 { switch (which) { case Qt::PreferredSize: return prefSize(); case Qt::MinimumSize: return minSize(constraint); case Qt::MaximumSize: return maxSize(); default: break; } return constraint; }