Geometrize  1.0
An application for geometrizing images into geometric primitives
Public Member Functions | Private Member Functions | Private Attributes | List of all members
geometrize::layout::FlowLayout Class Reference

The FlowLayout class implements a layout that arranges components in a directional flow, like lines of text in a paragraph. The layout adapts to changing window sizes, a little like the Swing FlowLayout. It is based on the Qt Flow Layout example. More...

#include <flowlayout.h>

Inheritance diagram for geometrize::layout::FlowLayout:
Inheritance graph
[legend]
Collaboration diagram for geometrize::layout::FlowLayout:
Collaboration graph
[legend]

Public Member Functions

 FlowLayout (const int margin=-1, const int hSpacing=-1, const int vSpacing=-1)
 
virtual ~FlowLayout ()
 
int horizontalSpacing () const
 
int verticalSpacing () const
 
void addItem (QLayoutItem *item) override
 
Qt::Orientations expandingDirections () const override
 
bool hasHeightForWidth () const override
 
int heightForWidth (int width) const override
 
int count () const override
 
QLayoutItem * itemAt (int index) const override
 
QSize minimumSize () const override
 
void setGeometry (const QRect &rect) override
 
QSize sizeHint () const override
 
QLayoutItem * takeAt (int index) override
 

Private Member Functions

int doLayout (const QRect &rect, bool testOnly) const
 
int smartSpacing (QStyle::PixelMetric pm) const
 

Private Attributes

QList< QLayoutItem * > m_itemList
 
int m_hSpace
 
int m_vSpace
 

Detailed Description

The FlowLayout class implements a layout that arranges components in a directional flow, like lines of text in a paragraph. The layout adapts to changing window sizes, a little like the Swing FlowLayout. It is based on the Qt Flow Layout example.

Constructor & Destructor Documentation

◆ FlowLayout()

geometrize::layout::FlowLayout::FlowLayout ( const int  margin = -1,
const int  hSpacing = -1,
const int  vSpacing = -1 
)
explicit
43  : m_hSpace(hSpacing), m_vSpace(vSpacing)
44 {
45  setContentsMargins(margin, margin, margin, margin);
46 }

◆ ~FlowLayout()

geometrize::layout::FlowLayout::~FlowLayout ( )
virtual
49 {
50  while (QLayoutItem* item = takeAt(0)) {
51  delete item;
52  item = nullptr;
53  }
54 }
Here is the call graph for this function:

Member Function Documentation

◆ addItem()

void geometrize::layout::FlowLayout::addItem ( QLayoutItem *  item)
override
75 {
76  m_itemList.append(item);
77 }

◆ count()

int geometrize::layout::FlowLayout::count ( ) const
override
95 {
96  return m_itemList.size();
97 }

◆ doLayout()

int geometrize::layout::FlowLayout::doLayout ( const QRect &  rect,
bool  testOnly 
) const
private
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, m_itemList) {
153  const QWidget* const wid{item->widget()};
154  if(wid->isHidden()) {
155  continue;
156  }
157 
158  int spaceX{horizontalSpacing()};
159  if (spaceX == -1) {
160  spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
161  }
162  int spaceY{verticalSpacing()};
163  if (spaceY == -1) {
164  spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
165  }
166  int nextX{x + item->sizeHint().width() + spaceX};
167  if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
168  x = effectiveRect.x();
169  y = y + lineHeight + spaceY;
170  nextX = x + item->sizeHint().width() + spaceX;
171  lineHeight = 0;
172  }
173 
174  if (!testOnly) {
175  item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
176  }
177 
178  x = nextX;
179  lineHeight = qMax(lineHeight, item->sizeHint().height());
180  }
181  return y + lineHeight - rect.y() + bottom;
182 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ expandingDirections()

Qt::Orientations geometrize::layout::FlowLayout::expandingDirections ( ) const
override
80 {
81  return Qt::Horizontal;
82 }

◆ hasHeightForWidth()

bool geometrize::layout::FlowLayout::hasHeightForWidth ( ) const
override
85 {
86  return true;
87 }

◆ heightForWidth()

int geometrize::layout::FlowLayout::heightForWidth ( int  width) const
override
90 {
91  return doLayout(QRect(0, 0, width, 0), true);
92 }
Here is the call graph for this function:

◆ horizontalSpacing()

int geometrize::layout::FlowLayout::horizontalSpacing ( ) const
57 {
58  if (m_hSpace >= 0) {
59  return m_hSpace;
60  } else {
61  return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
62  }
63 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ itemAt()

QLayoutItem * geometrize::layout::FlowLayout::itemAt ( int  index) const
override
100 {
101  return m_itemList.value(index);
102 }

◆ minimumSize()

QSize geometrize::layout::FlowLayout::minimumSize ( ) const
override
105 {
106  QSize size;
107  QLayoutItem* item;
108  foreach (item, m_itemList) {
109  size = size.expandedTo(item->minimumSize());
110  }
111 
112  int left = 0;
113  int right = 0;
114  int bottom = 0;
115  int top = 0;
116  getContentsMargins(&left, &top, &right, &bottom);
117 
118  size += QSize(left + right, bottom + top);
119  return size;
120 }
Here is the caller graph for this function:

◆ setGeometry()

void geometrize::layout::FlowLayout::setGeometry ( const QRect &  rect)
override
123 {
124  QLayout::setGeometry(rect);
125  doLayout(rect, false);
126 }
Here is the call graph for this function:

◆ sizeHint()

QSize geometrize::layout::FlowLayout::sizeHint ( ) const
override
129 {
130  return minimumSize();
131 }
Here is the call graph for this function:

◆ smartSpacing()

int geometrize::layout::FlowLayout::smartSpacing ( QStyle::PixelMetric  pm) const
private
185 {
186  QObject* parent{this->parent()};
187  if (!parent) {
188  return -1;
189  } else if (parent->isWidgetType()) {
190  QWidget* pw{static_cast<QWidget*>(parent)};
191  return pw->style()->pixelMetric(pm, 0, pw);
192  } else {
193  return static_cast<QLayout*>(parent)->spacing();
194  }
195 }
Here is the caller graph for this function:

◆ takeAt()

QLayoutItem * geometrize::layout::FlowLayout::takeAt ( int  index)
override
134 {
135  if (index >= 0 && index < m_itemList.size()) {
136  return m_itemList.takeAt(index);
137  } else {
138  return 0;
139  }
140 }
Here is the caller graph for this function:

◆ verticalSpacing()

int geometrize::layout::FlowLayout::verticalSpacing ( ) const
66 {
67  if (m_vSpace >= 0) {
68  return m_vSpace;
69  } else {
70  return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
71  }
72 }
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_hSpace

int geometrize::layout::FlowLayout::m_hSpace
private

◆ m_itemList

QList<QLayoutItem*> geometrize::layout::FlowLayout::m_itemList
private

◆ m_vSpace

int geometrize::layout::FlowLayout::m_vSpace
private

The documentation for this class was generated from the following files:
geometrize::layout::FlowLayout::smartSpacing
int smartSpacing(QStyle::PixelMetric pm) const
Definition: flowlayout.cpp:184
geometrize::layout::FlowLayout::m_itemList
QList< QLayoutItem * > m_itemList
Definition: flowlayout.h:76
geometrize::layout::FlowLayout::verticalSpacing
int verticalSpacing() const
Definition: flowlayout.cpp:65
geometrize::layout::FlowLayout::minimumSize
QSize minimumSize() const override
Definition: flowlayout.cpp:104
geometrize::layout::FlowLayout::m_vSpace
int m_vSpace
Definition: flowlayout.h:78
geometrize::layout::FlowLayout::horizontalSpacing
int horizontalSpacing() const
Definition: flowlayout.cpp:56
geometrize::layout::FlowLayout::takeAt
QLayoutItem * takeAt(int index) override
Definition: flowlayout.cpp:133
geometrize::layout::FlowLayout::doLayout
int doLayout(const QRect &rect, bool testOnly) const
Definition: flowlayout.cpp:142
geometrize::layout::FlowLayout::m_hSpace
int m_hSpace
Definition: flowlayout.h:77