2 SPDX-FileCopyrightText: 2025 Felix Ernst <felixernst@kde.org>
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7 #include "barsecondrowflowlayout.h"
13 using namespace Search
;
17 constexpr int searchLocationButtonsCount
= 2;
20 BarSecondRowFlowLayout::BarSecondRowFlowLayout(QWidget
*parent
)
23 setContentsMargins(0, 0, 0, 0);
26 BarSecondRowFlowLayout::~BarSecondRowFlowLayout()
29 while ((item
= takeAt(0)))
33 void BarSecondRowFlowLayout::addItem(QLayoutItem
*item
)
35 itemList
.append(item
);
38 Qt::Orientations
BarSecondRowFlowLayout::expandingDirections() const
43 bool BarSecondRowFlowLayout::hasHeightForWidth() const
48 int BarSecondRowFlowLayout::count() const
50 return itemList
.size();
53 QLayoutItem
*BarSecondRowFlowLayout::itemAt(int index
) const
55 return itemList
.value(index
);
58 QSize
BarSecondRowFlowLayout::sizeHint() const
60 const QRect rect
= geometry();
62 for (const QLayoutItem
*item
: std::as_const(itemList
)) {
63 size
= size
.expandedTo(QSize
{item
->geometry().right() - rect
.x(), item
->geometry().bottom() - rect
.y()});
68 void BarSecondRowFlowLayout::setGeometry(const QRect
&rect
)
70 const int oldHeightHint
= sizeHint().height();
71 QLayout::setGeometry(rect
);
72 const bool isLeftToRight
= itemAt(0)->widget()->layoutDirection() == Qt::LeftToRight
;
76 /// The search location buttons are treated differently. They are meant to be in the same row and aligned the other way.
77 int totalLocationButtonWidth
= 0;
78 for (int i
= 0; i
< searchLocationButtonsCount
; i
++) {
79 totalLocationButtonWidth
+= itemAt(i
)->widget()->sizeHint().width();
81 if (totalLocationButtonWidth
> rect
.width()) {
82 /// There is not enough space so we will smush all the location buttons into the first row.
83 for (int i
= 0; i
< searchLocationButtonsCount
; i
++) {
84 QWidget
*widget
= itemAt(i
)->widget();
85 const int targetWidth
= qMin(widget
->sizeHint().width(), rect
.width() / searchLocationButtonsCount
);
86 widget
->setGeometry(isLeftToRight
? x
: rect
.right() - x
- targetWidth
, y
, targetWidth
, widget
->sizeHint().height());
90 for (int i
= 0; i
< searchLocationButtonsCount
; i
++) {
91 QWidget
*widget
= itemAt(i
)->widget();
92 QSize preferredSize
= widget
->sizeHint();
93 widget
->setGeometry(isLeftToRight
? x
: rect
.right() - x
- preferredSize
.width(), y
, preferredSize
.width(), preferredSize
.height());
94 x
+= widget
->width() + spacing();
98 // We want to align all further widgets the other way. We do this by first filling up the row like usual and then moving all widgets of the current row by
99 // the remaining space.
100 std::vector
<QWidget
*> currentRowWidgets
;
101 for (int i
= searchLocationButtonsCount
; i
< count(); i
++) {
102 QWidget
*widget
= itemAt(i
)->widget();
103 const int remainingSpace
= rect
.right() - x
+ spacing();
104 if (widget
->sizeHint().width() < remainingSpace
) {
105 QSize preferredSize
= widget
->sizeHint();
106 widget
->setGeometry(isLeftToRight
? x
: rect
.right() - x
- preferredSize
.width(), y
, preferredSize
.width(), preferredSize
.height());
107 x
+= widget
->width() + spacing();
108 currentRowWidgets
.push_back(widget
);
112 // There is not enough space for the next widget. We need to open up a new row.
113 // Right align all the widgets of the previous row.
114 for (QWidget
*widget
: std::as_const(currentRowWidgets
)) {
115 widget
->setGeometry(widget
->geometry().translated(isLeftToRight
? remainingSpace
: -remainingSpace
, 0));
117 currentRowWidgets
.clear();
120 y
+= itemAt(i
- 1)->widget()->height() + spacing();
122 QSize preferredSize
= widget
->sizeHint();
123 const int targetWidth
= qMin(preferredSize
.width(), rect
.width());
124 widget
->setGeometry(isLeftToRight
? x
: rect
.right() - x
- targetWidth
, y
, targetWidth
, preferredSize
.height());
125 x
+= widget
->width() + spacing();
126 currentRowWidgets
.push_back(widget
);
129 // Right align all the widgets of the previous row.
130 int remainingSpace
= rect
.right() - x
+ spacing();
131 for (QWidget
*widget
: std::as_const(currentRowWidgets
)) {
132 widget
->setGeometry(widget
->geometry().translated(isLeftToRight
? remainingSpace
: -remainingSpace
, 0));
135 if (sizeHint().height() != oldHeightHint
) {
136 Q_EMIT
heightHintChanged();
140 QSize
BarSecondRowFlowLayout::minimumSize() const
142 return QSize
{0, sizeHint().height()};
145 QLayoutItem
*BarSecondRowFlowLayout::takeAt(int index
)
147 if (index
>= 0 && index
< itemList
.size())
148 return itemList
.takeAt(index
);