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