QTfrontend/ui/widget/flowlayout.cpp
changeset 8475 f605bc59c603
parent 8473 555235e90010
child 8487 ec8391680132
equal deleted inserted replaced
8473:555235e90010 8475:f605bc59c603
     1  /****************************************************************************
       
     2  **
       
     3  ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
       
     4  ** All rights reserved.
       
     5  ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6  **
       
     7  ** This file is part of the examples of the Qt Toolkit.
       
     8  **
       
     9  ** $QT_BEGIN_LICENSE:BSD$
       
    10  ** You may use this file under the terms of the BSD license as follows:
       
    11  **
       
    12  ** "Redistribution and use in source and binary forms, with or without
       
    13  ** modification, are permitted provided that the following conditions are
       
    14  ** met:
       
    15  **   * Redistributions of source code must retain the above copyright
       
    16  **     notice, this list of conditions and the following disclaimer.
       
    17  **   * Redistributions in binary form must reproduce the above copyright
       
    18  **     notice, this list of conditions and the following disclaimer in
       
    19  **     the documentation and/or other materials provided with the
       
    20  **     distribution.
       
    21  **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
       
    22  **     the names of its contributors may be used to endorse or promote
       
    23  **     products derived from this software without specific prior written
       
    24  **     permission.
       
    25  **
       
    26  ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    27  ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    28  ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    29  ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    30  ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    31  ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    32  ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    33  ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    34  ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    35  ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    36  ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
       
    37  ** $QT_END_LICENSE$
       
    38  **
       
    39  ****************************************************************************/
       
    40 
       
    41  #include <QtGui>
       
    42 
       
    43  #include "flowlayout.h"
       
    44 
       
    45 FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
       
    46     : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
       
    47 {
       
    48     setContentsMargins(margin, margin, margin, margin);
       
    49 }
       
    50 
       
    51 FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
       
    52     : m_hSpace(hSpacing), m_vSpace(vSpacing)
       
    53 {
       
    54     setContentsMargins(margin, margin, margin, margin);
       
    55 }
       
    56 
       
    57 FlowLayout::~FlowLayout()
       
    58 {
       
    59     QLayoutItem *item;
       
    60     while ((item = takeAt(0)))
       
    61         delete item;
       
    62 }
       
    63 
       
    64 void FlowLayout::addItem(QLayoutItem *item)
       
    65 {
       
    66     itemList.append(item);
       
    67 }
       
    68 
       
    69 int FlowLayout::horizontalSpacing() const
       
    70 {
       
    71     if (m_hSpace >= 0) {
       
    72         return m_hSpace;
       
    73     } else {
       
    74         return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
       
    75     }
       
    76 }
       
    77 
       
    78 int FlowLayout::verticalSpacing() const
       
    79 {
       
    80     if (m_vSpace >= 0) {
       
    81         return m_vSpace;
       
    82     } else {
       
    83         return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
       
    84     }
       
    85 }
       
    86 
       
    87 int FlowLayout::count() const
       
    88 {
       
    89     return itemList.size();
       
    90 }
       
    91 
       
    92 QLayoutItem *FlowLayout::itemAt(int index) const
       
    93 {
       
    94     return itemList.value(index);
       
    95 }
       
    96 
       
    97 QLayoutItem *FlowLayout::takeAt(int index)
       
    98 {
       
    99     if (index >= 0 && index < itemList.size())
       
   100         return itemList.takeAt(index);
       
   101     else
       
   102         return 0;
       
   103 }
       
   104 
       
   105 Qt::Orientations FlowLayout::expandingDirections() const
       
   106 {
       
   107     return 0;
       
   108 }
       
   109 
       
   110 bool FlowLayout::hasHeightForWidth() const
       
   111 {
       
   112     return true;
       
   113 }
       
   114 
       
   115 int FlowLayout::heightForWidth(int width) const
       
   116 {
       
   117     int height = doLayout(QRect(0, 0, width, 0), true);
       
   118     return height;
       
   119 }
       
   120 
       
   121 void FlowLayout::setGeometry(const QRect &rect)
       
   122 {
       
   123     QLayout::setGeometry(rect);
       
   124     doLayout(rect, false);
       
   125 }
       
   126 
       
   127 QSize FlowLayout::sizeHint() const
       
   128 {
       
   129     return minimumSize();
       
   130 }
       
   131 
       
   132 QSize FlowLayout::minimumSize() const
       
   133 {
       
   134     QSize size;
       
   135     QLayoutItem *item;
       
   136     foreach (item, itemList)
       
   137         size = size.expandedTo(item->minimumSize());
       
   138 
       
   139     size += QSize(2*margin(), 2*margin());
       
   140     return size;
       
   141 }
       
   142 
       
   143 int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
       
   144 {
       
   145     int left, top, right, bottom;
       
   146     getContentsMargins(&left, &top, &right, &bottom);
       
   147     QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
       
   148     int x = effectiveRect.x();
       
   149     int y = effectiveRect.y();
       
   150     int lineHeight = 0;
       
   151 
       
   152     QLayoutItem *item;
       
   153     foreach (item, itemList) {
       
   154         QWidget *wid = item->widget();
       
   155         int spaceX = horizontalSpacing();
       
   156         if (spaceX == -1)
       
   157             spaceX = wid->style()->layoutSpacing(
       
   158                 QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
       
   159         int spaceY = verticalSpacing();
       
   160         if (spaceY == -1)
       
   161             spaceY = wid->style()->layoutSpacing(
       
   162                 QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
       
   163         int nextX = x + item->sizeHint().width() + spaceX;
       
   164         if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
       
   165             x = effectiveRect.x();
       
   166             y = y + lineHeight + spaceY;
       
   167             nextX = x + item->sizeHint().width() + spaceX;
       
   168             lineHeight = 0;
       
   169         }
       
   170 
       
   171         if (!testOnly)
       
   172             item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
       
   173 
       
   174         x = nextX;
       
   175         lineHeight = qMax(lineHeight, item->sizeHint().height());
       
   176     }
       
   177     return y + lineHeight - rect.y() + bottom;
       
   178 }
       
   179 int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
       
   180 {
       
   181     QObject *parent = this->parent();
       
   182     if (!parent) {
       
   183         return -1;
       
   184     } else if (parent->isWidgetType()) {
       
   185         QWidget *pw = static_cast<QWidget *>(parent);
       
   186         return pw->style()->pixelMetric(pm, 0, pw);
       
   187     } else {
       
   188         return static_cast<QLayout *>(parent)->spacing();
       
   189     }
       
   190 }