QTfrontend/ui/widget/flowlayout.cpp
changeset 8377 869f80966a77
child 8386 2aaa2995a32e
equal deleted inserted replaced
8376:c11cc7246df7 8377:869f80966a77
       
     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  }