ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
flowlayout.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "flowlayout.h"
9 
10 #include <QtWidgets>
11 FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
12  : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) {
13  setContentsMargins(margin, margin, margin, margin);
14 }
15 
16 FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
17  : m_hSpace(hSpacing), m_vSpace(vSpacing) {
18  setContentsMargins(margin, margin, margin, margin);
19 }
20 
22 
24  QLayoutItem *item;
25  while ((item = takeAt(0))) delete item;
26 }
27 
28 void FlowLayout::addItem(QLayoutItem *item) { itemList.append(item); }
29 
31  if (m_hSpace >= 0) {
32  return m_hSpace;
33  } else {
34  return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
35  }
36 }
37 
39  if (m_vSpace >= 0) {
40  return m_vSpace;
41  } else {
42  return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
43  }
44 }
45 
46 int FlowLayout::count() const { return itemList.size(); }
47 
48 QLayoutItem *FlowLayout::itemAt(int index) const {
49  return itemList.value(index);
50 }
51 
52 QLayoutItem *FlowLayout::takeAt(int index) {
53  if (index >= 0 && index < itemList.size())
54  return itemList.takeAt(index);
55  else
56  return 0;
57 }
58 
59 Qt::Orientations FlowLayout::expandingDirections() const {
60 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
61  return Qt::Orientations();
62 #else
63  return 0;
64 #endif
65 }
66 
67 bool FlowLayout::hasHeightForWidth() const { return true; }
68 
70  int height = doLayout(QRect(0, 0, width, 0), true);
71  return height;
72 }
73 
74 void FlowLayout::setGeometry(const QRect &rect) {
75  QLayout::setGeometry(rect);
76  doLayout(rect, false);
77 }
78 
79 QSize FlowLayout::sizeHint() const { return minimumSize(); }
80 
81 QSize FlowLayout::minimumSize() const {
82  QSize size;
83  QLayoutItem *item;
84  foreach (item, itemList) size = size.expandedTo(item->minimumSize());
85 
86 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
87  QMargins margins = contentsMargins();
88  size += QSize(margins.left() + margins.right(),
89  margins.top() + margins.bottom());
90 #else
91  size += QSize(2 * margin(), 2 * margin());
92 #endif
93  return size;
94 }
95 
96 int FlowLayout::doLayout(const QRect &rect, bool testOnly) const {
97  int left, top, right, bottom;
98  getContentsMargins(&left, &top, &right, &bottom);
99  QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
100  int x = effectiveRect.x();
101  int y = effectiveRect.y();
102  int lineHeight = 0;
103 
104  QLayoutItem *item;
105  foreach (item, itemList) {
106  QWidget *wid = item->widget();
107  int spaceX = horizontalSpacing();
108  if (spaceX == -1)
109  spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton,
110  QSizePolicy::PushButton,
111  Qt::Horizontal);
112  int spaceY = verticalSpacing();
113  if (spaceY == -1)
114  spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton,
115  QSizePolicy::PushButton,
116  Qt::Vertical);
117  int nextX = x + item->sizeHint().width() + spaceX;
118  if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
119  x = effectiveRect.x();
120  y = y + lineHeight + spaceY;
121  nextX = x + item->sizeHint().width() + spaceX;
122  lineHeight = 0;
123  }
124 
125  if (!testOnly) item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
126 
127  x = nextX;
128  lineHeight = qMax(lineHeight, item->sizeHint().height());
129  }
130  return y + lineHeight - rect.y() + bottom;
131 }
132 int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const {
133  QObject *parent = this->parent();
134  if (!parent) {
135  return -1;
136  } else if (parent->isWidgetType()) {
137  QWidget *pw = static_cast<QWidget *>(parent);
138  return pw->style()->pixelMetric(pm, 0, pw);
139  } else {
140  return static_cast<QLayout *>(parent)->spacing();
141  }
142 }
int width
int size
int height
Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE
Definition: flowlayout.cpp:59
int horizontalSpacing() const
Definition: flowlayout.cpp:30
int verticalSpacing() const
Definition: flowlayout.cpp:38
void addItem(QLayoutItem *item) Q_DECL_OVERRIDE
Definition: flowlayout.cpp:28
void clear()
Definition: flowlayout.cpp:23
QSize minimumSize() const Q_DECL_OVERRIDE
Definition: flowlayout.cpp:81
QLayoutItem * takeAt(int index) Q_DECL_OVERRIDE
Definition: flowlayout.cpp:52
void setGeometry(const QRect &rect) Q_DECL_OVERRIDE
Definition: flowlayout.cpp:74
QSize sizeHint() const Q_DECL_OVERRIDE
Definition: flowlayout.cpp:79
QLayoutItem * itemAt(int index) const Q_DECL_OVERRIDE
Definition: flowlayout.cpp:48
bool hasHeightForWidth() const Q_DECL_OVERRIDE
Definition: flowlayout.cpp:67
int heightForWidth(int) const Q_DECL_OVERRIDE
Definition: flowlayout.cpp:69
int count() const Q_DECL_OVERRIDE
Definition: flowlayout.cpp:46
FlowLayout(QWidget *parent, int margin=-1, int hSpacing=-1, int vSpacing=-1)
Definition: flowlayout.cpp:11
normal_z y
normal_z x