Use the canonical file name also for the "already open" check
[GPXSee.git] / src / GUI / flowlayout.cpp
blob8b6455927d6441df2dd525296410ad5ac7211b3e
1 #include <QtWidgets>
2 #include "flowlayout.h"
4 struct FlowLayoutItem
6 FlowLayoutItem() : item(0) {}
7 FlowLayoutItem(QLayoutItem *item, int x, int y) : item(item), pos(x, y) {}
9 QLayoutItem *item;
10 QPoint pos;
13 FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
14 : QLayout(parent), _hSpace(hSpacing), _vSpace(vSpacing)
16 setContentsMargins(margin, margin, margin, margin);
19 FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
20 : _hSpace(hSpacing), _vSpace(vSpacing)
22 setContentsMargins(margin, margin, margin, margin);
25 FlowLayout::~FlowLayout()
27 qDeleteAll(_items);
30 void FlowLayout::addItem(QLayoutItem *item)
32 _items.append(item);
35 int FlowLayout::horizontalSpacing() const
37 return (_hSpace >= 0)
38 ? _hSpace
39 : smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
42 int FlowLayout::verticalSpacing() const
44 return (_vSpace >= 0)
45 ? _vSpace
46 : smartSpacing(QStyle::PM_LayoutVerticalSpacing);
49 int FlowLayout::count() const
51 return _items.size();
54 QLayoutItem *FlowLayout::itemAt(int index) const
56 return _items.value(index);
59 QLayoutItem *FlowLayout::takeAt(int index)
61 if (index >= 0 && index < _items.size())
62 return _items.takeAt(index);
64 return 0;
67 Qt::Orientations FlowLayout::expandingDirections() const
69 return {};
72 bool FlowLayout::hasHeightForWidth() const
74 return true;
77 int FlowLayout::heightForWidth(int width) const
79 int height = doLayout(QRect(0, 0, width, 0), true);
80 return height;
83 void FlowLayout::setGeometry(const QRect &rect)
85 QLayout::setGeometry(rect);
86 doLayout(rect, false);
89 QSize FlowLayout::sizeHint() const
91 return minimumSize();
94 QSize FlowLayout::minimumSize() const
96 QSize size;
98 for (int i = 0; i < _items.size(); i++)
99 size = size.expandedTo(_items.at(i)->minimumSize());
101 const QMargins margins = contentsMargins();
102 size += QSize(margins.left() + margins.right(), margins.top()
103 + margins.bottom());
105 return size;
108 int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
110 int left, top, right, bottom;
111 getContentsMargins(&left, &top, &right, &bottom);
112 QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
113 int x = effectiveRect.x();
114 int y = effectiveRect.y();
115 int lineHeight = 0;
116 QVector<QVector<FlowLayoutItem>> rows;
118 for (int i = 0; i < _items.size(); i++) {
119 QLayoutItem *item = _items.at(i);
120 const QWidget *wid = item->widget();
121 int spaceX = horizontalSpacing();
122 if (spaceX == -1)
123 spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton,
124 QSizePolicy::PushButton, Qt::Horizontal);
125 int spaceY = verticalSpacing();
126 if (spaceY == -1)
127 spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton,
128 QSizePolicy::PushButton, Qt::Vertical);
130 int nextX = x + item->sizeHint().width() + spaceX;
131 if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
132 x = effectiveRect.x();
133 y = y + lineHeight + spaceY;
134 nextX = x + item->sizeHint().width() + spaceX;
135 lineHeight = 0;
136 rows.append(QVector<FlowLayoutItem>());
139 if (rows.isEmpty())
140 rows.append(QVector<FlowLayoutItem>());
141 rows.last().append(FlowLayoutItem(item, x, y));
143 x = nextX;
144 lineHeight = qMax(lineHeight, item->sizeHint().height());
147 if (!testOnly) {
148 for (int i = 0; i < rows.size(); i++) {
149 const FlowLayoutItem &li = rows.at(i).last();
150 int width = li.item->sizeHint().width() + li.pos.x()
151 - effectiveRect.x();
152 int offset = (effectiveRect.width() - width) / 2;
154 int height = 0;
155 for (int j = 0; j < rows.at(i).size(); j++)
156 height = qMax(rows.at(i).at(j).item->sizeHint().height(), height);
158 for (int j = 0; j < rows.at(i).size(); j++) {
159 QLayoutItem *item = rows.at(i).at(j).item;
160 const QPoint &p = rows.at(i).at(j).pos;
161 QSize sh(item->sizeHint());
162 item->setGeometry(QRect(QPoint(p.x() + offset, p.y() + height
163 - sh.height()), sh));
168 return y + lineHeight - rect.y() + bottom;
171 int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
173 QObject *parent = this->parent();
174 if (!parent)
175 return -1;
176 else if (parent->isWidgetType()) {
177 QWidget *pw = static_cast<QWidget *>(parent);
178 return pw->style()->pixelMetric(pm, 0, pw);
179 } else
180 return static_cast<QLayout *>(parent)->spacing();