LeechCraft  0.6.70-15082-g543737046d
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  * Distributed under the Boost Software License, Version 1.0.
6  * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7  **********************************************************************/
8 
9 #include "flowlayout.h"
10 #include <QWidget>
11 
12 namespace LC::Util
13 {
14  FlowLayout::FlowLayout (QWidget *parent,
15  int margin, int hspace, int vspace)
16  : QLayout { parent }
17  , HSpace_ { hspace }
18  , VSpace_ { vspace }
19  {
20  setContentsMargins (margin, margin, margin, margin);
21  }
22 
23  FlowLayout::FlowLayout (int margin, int hspace, int vspace)
24  : FlowLayout { nullptr, margin, hspace, vspace }
25  {
26  }
27 
29  {
30  qDeleteAll (ItemList_);
31  }
32 
33  void FlowLayout::addItem (QLayoutItem *item)
34  {
35  ItemList_ << item;
36  }
37 
39  {
40  return HSpace_ >= 0 ?
41  HSpace_ :
42  SmartSpacing (QStyle::PM_LayoutHorizontalSpacing);
43  }
44 
45  int FlowLayout::verticalSpacing () const
46  {
47  return VSpace_ >= 0 ?
48  VSpace_ :
49  SmartSpacing (QStyle::PM_LayoutVerticalSpacing);
50  }
51 
52  Qt::Orientations FlowLayout::expandingDirections () const
53  {
54  return {};
55  }
56 
57  bool FlowLayout::hasHeightForWidth () const
58  {
59  return true;
60  }
61 
62  int FlowLayout::heightForWidth (int width) const
63  {
64  return DoLayout ({ 0, 0, width, 0 }, true);
65  }
66 
67  int FlowLayout::count () const
68  {
69  return ItemList_.size ();
70  }
71 
72  QLayoutItem* FlowLayout::itemAt (int idx) const
73  {
74  return ItemList_.value (idx);
75  }
76 
77  QLayoutItem* FlowLayout::takeAt (int idx)
78  {
79  if (idx < 0 || idx >= ItemList_.size ())
80  return nullptr;
81 
82  return ItemList_.takeAt (idx);
83  }
84 
85  QSize FlowLayout::minimumSize () const
86  {
87  QSize size;
88  for (const auto item : ItemList_)
89  size = size.expandedTo (item->minimumSize ());
90 
91  int left = 0;
92  int top = 0;
93  int right = 0;
94  int bottom = 0;
95  getContentsMargins (&left, &top, &right, &bottom);
96  size += QSize { left + right, top + bottom };
97  return size;
98  }
99 
100  void FlowLayout::setGeometry (const QRect& rect)
101  {
102  QLayout::setGeometry (rect);
103  DoLayout (rect, false);
104  }
105 
106  QSize FlowLayout::sizeHint () const
107  {
108  return minimumSize ();
109  }
110 
111  int FlowLayout::DoLayout (const QRect& rect, bool testOnly) const
112  {
113  int left = 0, top = 0, right = 0, bottom = 0;
114  getContentsMargins (&left, &top, &right, &bottom);
115 
116  const auto& effectiveRect = rect.adjusted (left, top, -right, -bottom);
117  int x = effectiveRect.x ();
118  int y = effectiveRect.y ();
119  int lineHeight = 0;
120 
121  for (const auto item : ItemList_)
122  {
123  const auto widget = item->widget ();
124 
125  int spaceX = horizontalSpacing ();
126  if (spaceX == -1)
127  spaceX = widget->style ()->layoutSpacing (QSizePolicy::PushButton,
128  QSizePolicy::PushButton, Qt::Horizontal);
129  int spaceY = verticalSpacing ();
130  if (spaceY == -1)
131  spaceY = widget->style ()->layoutSpacing (QSizePolicy::PushButton,
132  QSizePolicy::PushButton, Qt::Vertical);
133 
134  const auto& sizeHint = item->sizeHint ();
135  const int hintWidth = sizeHint.width ();
136  int nextX = x + hintWidth + spaceX;
137  if (nextX - spaceX > effectiveRect.right () &&
138  lineHeight > 0)
139  {
140  x = effectiveRect.x ();
141  y += lineHeight + spaceY;
142  nextX = x + hintWidth + spaceX;
143  lineHeight = 0;
144  }
145 
146  if (!testOnly)
147  item->setGeometry ({ { x, y }, sizeHint });
148 
149  x = nextX;
150  lineHeight = std::max (lineHeight, sizeHint.height ());
151  }
152 
153  return y + lineHeight - rect.y () + bottom;
154  }
155 
156  int FlowLayout::SmartSpacing (QStyle::PixelMetric pm) const
157  {
158  const auto obj = parent ();
159  if (!obj)
160  return -1;
161 
162  if (const auto pw = dynamic_cast<QWidget*> (obj))
163  return pw->style ()->pixelMetric (pm, nullptr, pw);
164  if (const auto lay = dynamic_cast<QLayout*> (obj))
165  return lay->spacing ();
166 
167  return -1;
168  }
169 }
LC::Util
Definition: icoreproxy.h:33
LC::Util::FlowLayout::minimumSize
QSize minimumSize() const override
Definition: flowlayout.cpp:91
LC::Util::FlowLayout::itemAt
QLayoutItem * itemAt(int) const override
Definition: flowlayout.cpp:78
LC::Util::FlowLayout::verticalSpacing
int verticalSpacing() const
Definition: flowlayout.cpp:51
LC::Util::FlowLayout::count
int count() const override
Definition: flowlayout.cpp:73
flowlayout.h
LC::Util::FlowLayout::~FlowLayout
~FlowLayout() override
Definition: flowlayout.cpp:34
LC::Util::FlowLayout::heightForWidth
int heightForWidth(int) const override
Definition: flowlayout.cpp:68
LC::Util::oral::sph::max
constexpr detail::AggregateType< detail::AggregateFunction::Max, Ptr > max
Definition: oral.h:972
LC::Util::FlowLayout::horizontalSpacing
int horizontalSpacing() const
Definition: flowlayout.cpp:44
LC::Util::FlowLayout::sizeHint
QSize sizeHint() const override
Definition: flowlayout.cpp:112
LC::Util::FlowLayout::addItem
void addItem(QLayoutItem *) override
Definition: flowlayout.cpp:39
LC::Util::FlowLayout::setGeometry
void setGeometry(const QRect &) override
Definition: flowlayout.cpp:106
LC::Util::FlowLayout
A simple flow layout implementation.
Definition: flowlayout.h:30
LC::Util::FlowLayout::hasHeightForWidth
bool hasHeightForWidth() const override
Definition: flowlayout.cpp:63
LC::Util::FlowLayout::expandingDirections
Qt::Orientations expandingDirections() const override
Definition: flowlayout.cpp:58
LC::Util::FlowLayout::FlowLayout
FlowLayout(QWidget *, int=-1, int=-1, int=-1)
Definition: flowlayout.cpp:20
LC::Util::FlowLayout::takeAt
QLayoutItem * takeAt(int) override
Definition: flowlayout.cpp:83