File indexing completed on 2024-11-24 04:53:01

0001 /* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
0002    All rights reserved.
0003    Contact: Nokia Corporation (qt-info@nokia.com)
0004 
0005    This file is part of the Trojita Qt IMAP e-mail client,
0006    http://trojita.flaska.net/
0007 
0008    It was taken from the examples of the Qt Toolkit.
0009 
0010    $QT_BEGIN_LICENSE:LGPL$
0011    Commercial Usage
0012    Licensees holding valid Qt Commercial licenses may use this file in
0013    accordance with the Qt Commercial License Agreement provided with the
0014    Software or, alternatively, in accordance with the terms contained in
0015    a written agreement between you and Nokia.
0016 
0017    GNU Lesser General Public License Usage
0018    Alternatively, this file may be used under the terms of the GNU Lesser
0019    General Public License version 2.1 as published by the Free Software
0020    Foundation and appearing in the file LICENSE.LGPL included in the
0021    packaging of this file.  Please review the following information to
0022    ensure the GNU Lesser General Public License version 2.1 requirements
0023    will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
0024 
0025    In addition, as a special exception, Nokia gives you certain additional
0026    rights.  These rights are described in the Nokia Qt LGPL Exception
0027    version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
0028 
0029    GNU General Public License Usage
0030    Alternatively, this file may be used under the terms of the GNU
0031    General Public License version 3.0 as published by the Free Software
0032    Foundation and appearing in the file LICENSE.GPL included in the
0033    packaging of this file.  Please review the following information to
0034    ensure the GNU General Public License version 3.0 requirements will be
0035    met: http://www.gnu.org/copyleft/gpl.html.
0036 
0037    If you have questions regarding the use of this file, please contact
0038    Nokia at qt-info@nokia.com.
0039    $QT_END_LICENSE$
0040 */
0041 
0042 #include <QWidget>
0043 
0044 #include "FlowLayout.h"
0045 
0046 namespace Gui
0047 {
0048 
0049 FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
0050     : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
0051 {
0052     setContentsMargins(margin, margin, margin, margin);
0053 }
0054 
0055 FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
0056     : m_hSpace(hSpacing), m_vSpace(vSpacing)
0057 {
0058     setContentsMargins(margin, margin, margin, margin);
0059 }
0060 
0061 FlowLayout::~FlowLayout()
0062 {
0063     QLayoutItem *item;
0064     while ((item = takeAt(0)))
0065         delete item;
0066 }
0067 
0068 void FlowLayout::addItem(QLayoutItem *item)
0069 {
0070     itemList.append(item);
0071 }
0072 
0073 int FlowLayout::horizontalSpacing() const
0074 {
0075     if (m_hSpace >= 0) {
0076         return m_hSpace;
0077     } else {
0078         return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
0079     }
0080 }
0081 
0082 int FlowLayout::verticalSpacing() const
0083 {
0084     if (m_vSpace >= 0) {
0085         return m_vSpace;
0086     } else {
0087         return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
0088     }
0089 }
0090 
0091 int FlowLayout::count() const
0092 {
0093     return itemList.size();
0094 }
0095 
0096 QLayoutItem *FlowLayout::itemAt(int index) const
0097 {
0098     return itemList.value(index);
0099 }
0100 
0101 QLayoutItem *FlowLayout::takeAt(int index)
0102 {
0103     if (index >= 0 && index < itemList.size())
0104         return itemList.takeAt(index);
0105     else
0106         return 0;
0107 }
0108 
0109 Qt::Orientations FlowLayout::expandingDirections() const
0110 {
0111     return Qt::Orientations();
0112 }
0113 
0114 bool FlowLayout::hasHeightForWidth() const
0115 {
0116     return true;
0117 }
0118 
0119 int FlowLayout::heightForWidth(int width) const
0120 {
0121     int height = doLayout(QRect(0, 0, width, 0), true);
0122     return height;
0123 }
0124 
0125 void FlowLayout::setGeometry(const QRect &rect)
0126 {
0127     QLayout::setGeometry(rect);
0128     doLayout(rect, false);
0129 }
0130 
0131 QSize FlowLayout::sizeHint() const
0132 {
0133     return minimumSize();
0134 }
0135 
0136 QSize FlowLayout::minimumSize() const
0137 {
0138     QSize size;
0139     QLayoutItem *item;
0140     foreach(item, itemList)
0141     size = size.expandedTo(item->minimumSize());
0142 
0143     int left, top;
0144     getContentsMargins(&left, &top, 0, 0);
0145     size += QSize(2*left, 2*top);
0146     return size;
0147 }
0148 
0149 int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
0150 {
0151     int left, top, right, bottom;
0152     getContentsMargins(&left, &top, &right, &bottom);
0153     QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
0154     int x = effectiveRect.x();
0155     int y = effectiveRect.y();
0156     int lineHeight = 0;
0157 
0158     QLayoutItem *item;
0159     foreach(item, itemList) {
0160         QWidget *wid = item->widget();
0161         int spaceX = horizontalSpacing();
0162         if (spaceX == -1)
0163             spaceX = wid->style()->layoutSpacing(
0164                          QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
0165         int spaceY = verticalSpacing();
0166         if (spaceY == -1)
0167             spaceY = wid->style()->layoutSpacing(
0168                          QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
0169         int nextX = x + item->sizeHint().width() + spaceX;
0170         if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
0171             x = effectiveRect.x();
0172             y = y + lineHeight + spaceY;
0173             nextX = x + item->sizeHint().width() + spaceX;
0174             lineHeight = 0;
0175         }
0176 
0177         if (!testOnly)
0178             item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
0179 
0180         x = nextX;
0181         lineHeight = qMax(lineHeight, item->sizeHint().height());
0182     }
0183     return y + lineHeight - rect.y() + bottom;
0184 }
0185 int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
0186 {
0187     QObject *parent = this->parent();
0188     if (!parent) {
0189         return -1;
0190     } else if (parent->isWidgetType()) {
0191         QWidget *pw = static_cast<QWidget *>(parent);
0192         return pw->style()->pixelMetric(pm, 0, pw);
0193     } else {
0194         return static_cast<QLayout *>(parent)->spacing();
0195     }
0196 }
0197 
0198 } // namespace Gui