LeechCraft  0.6.70-13729-g7046a9d2a7
Modular cross-platform feature rich live environment.
flowlayout.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2014 Georg Rudoy
4  *
5  * Boost Software License - Version 1.0 - August 17th, 2003
6  *
7  * Permission is hereby granted, free of charge, to any person or organization
8  * obtaining a copy of the software and accompanying documentation covered by
9  * this license (the "Software") to use, reproduce, display, distribute,
10  * execute, and transmit the Software, and to prepare derivative works of the
11  * Software, and to permit third-parties to whom the Software is furnished to
12  * do so, all subject to the following:
13  *
14  * The copyright notices in the Software and this entire statement, including
15  * the above license grant, this restriction and the following disclaimer,
16  * must be included in all copies of the Software, in whole or in part, and
17  * all derivative works of the Software, unless such copies or derivative
18  * works are solely in the form of machine-executable object code generated by
19  * a source language processor.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
24  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
25  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  **********************************************************************/
29 
30 #include "flowlayout.h"
31 #include <QWidget>
32 
33 namespace LC
34 {
35 namespace Util
36 {
37  FlowLayout::FlowLayout (QWidget *parent,
38  int margin, int hspace, int vspace)
39  : QLayout { parent }
40  , HSpace_ { hspace }
41  , VSpace_ { vspace }
42  {
43  setContentsMargins (margin, margin, margin, margin);
44  }
45 
46  FlowLayout::FlowLayout (int margin, int hspace, int vspace)
47  : FlowLayout { nullptr, margin, hspace, vspace }
48  {
49  }
50 
52  {
53  while (const auto item = takeAt (0))
54  delete item;
55  }
56 
57  void FlowLayout::addItem (QLayoutItem *item)
58  {
59  ItemList_ << item;
60  }
61 
63  {
64  return HSpace_ >= 0 ?
65  HSpace_ :
66  SmartSpacing (QStyle::PM_LayoutHorizontalSpacing);
67  }
68 
70  {
71  return VSpace_ >= 0 ?
72  VSpace_ :
73  SmartSpacing (QStyle::PM_LayoutVerticalSpacing);
74  }
75 
76  Qt::Orientations FlowLayout::expandingDirections () const
77  {
78  return 0;
79  }
80 
82  {
83  return true;
84  }
85 
86  int FlowLayout::heightForWidth (int width) const
87  {
88  return DoLayout ({ 0, 0, width, 0 }, true);
89  }
90 
91  int FlowLayout::count () const
92  {
93  return ItemList_.size ();
94  }
95 
96  QLayoutItem* FlowLayout::itemAt (int idx) const
97  {
98  return ItemList_.value (idx);
99  }
100 
101  QLayoutItem* FlowLayout::takeAt (int idx)
102  {
103  if (idx >= 0 && idx < ItemList_.size ())
104  return ItemList_.takeAt (idx);
105  else
106  return nullptr;
107  }
108 
109  QSize FlowLayout::minimumSize () const
110  {
111  QSize size;
112  for (const auto item : ItemList_)
113  size = size.expandedTo (item->minimumSize ());
114 
115  size += QSize { margin () * 2, margin () * 2 };
116  return size;
117  }
118 
119  void FlowLayout::setGeometry (const QRect& rect)
120  {
121  QLayout::setGeometry (rect);
122  DoLayout (rect, false);
123  }
124 
125  QSize FlowLayout::sizeHint () const
126  {
127  return minimumSize ();
128  }
129 
130  int FlowLayout::DoLayout (const QRect& rect, bool testOnly) const
131  {
132  int left = 0, top = 0, right = 0, bottom = 0;
133  getContentsMargins (&left, &top, &right, &bottom);
134 
135  const auto& effectiveRect = rect.adjusted (left, top, -right, -bottom);
136  int x = effectiveRect.x ();
137  int y = effectiveRect.y ();
138  int lineHeight = 0;
139 
140  for (const auto item : ItemList_)
141  {
142  const auto widget = item->widget ();
143 
144  int spaceX = horizontalSpacing ();
145  if (spaceX == -1)
146  spaceX = widget->style ()->layoutSpacing (QSizePolicy::PushButton,
147  QSizePolicy::PushButton, Qt::Horizontal);
148  int spaceY = verticalSpacing ();
149  if (spaceY == -1)
150  spaceY = widget->style ()->layoutSpacing (QSizePolicy::PushButton,
151  QSizePolicy::PushButton, Qt::Vertical);
152 
153  const auto& sizeHint = item->sizeHint ();
154  const int hintWidth = sizeHint.width ();
155  int nextX = x + hintWidth + spaceX;
156  if (nextX - spaceX > effectiveRect.right () &&
157  lineHeight > 0)
158  {
159  x = effectiveRect.x ();
160  y += lineHeight + spaceY;
161  nextX = x + hintWidth + spaceX;
162  lineHeight = 0;
163  }
164 
165  if (!testOnly)
166  item->setGeometry ({ { x, y }, sizeHint });
167 
168  x = nextX;
169  lineHeight = std::max (lineHeight, sizeHint.height ());
170  }
171 
172  return y + lineHeight - rect.y () + bottom;
173  }
174 
175  int FlowLayout::SmartSpacing (QStyle::PixelMetric pm) const
176  {
177  const auto obj = parent ();
178  if (!obj)
179  return -1;
180  else if (obj->isWidgetType ())
181  {
182  const auto pw = static_cast<QWidget*> (obj);
183  return pw->style ()->pixelMetric (pm, 0, pw);
184  }
185  else
186  return static_cast<QLayout*> (obj)->spacing ();
187  }
188 }
189 }
QSize sizeHint() const override
Definition: flowlayout.cpp:125
FlowLayout(QWidget *, int=-1, int=-1, int=-1)
Definition: flowlayout.cpp:37
constexpr detail::AggregateType< detail::AggregateFunction::Max, Ptr > max
Definition: oral.h:975
bool hasHeightForWidth() const override
Definition: flowlayout.cpp:81
int verticalSpacing() const
Definition: flowlayout.cpp:69
QLayoutItem * itemAt(int) const override
Definition: flowlayout.cpp:96
QSize minimumSize() const override
Definition: flowlayout.cpp:109
void addItem(QLayoutItem *) override
Definition: flowlayout.cpp:57
void setGeometry(const QRect &) override
Definition: flowlayout.cpp:119
Qt::Orientations expandingDirections() const override
Definition: flowlayout.cpp:76
A simple flow layout implementation.
Definition: flowlayout.h:47
QLayoutItem * takeAt(int) override
Definition: flowlayout.cpp:101
int count() const override
Definition: flowlayout.cpp:91
int heightForWidth(int) const override
Definition: flowlayout.cpp:86
Definition: constants.h:35
int horizontalSpacing() const
Definition: flowlayout.cpp:62