QGIS API Documentation 3.99.0-Master (26c88405ac0)
Loading...
Searching...
No Matches
qgsoverlaywidgetlayout.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsoverlaywidgetlayout.cpp
3 ---------------------
4 begin : March 2024
5 copyright : (C) 2024 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgis.h"
19
20#include <QWidget>
21
22#include "moc_qgsoverlaywidgetlayout.cpp"
23
25 : QLayout( parent )
26{
27}
28
30{
31 QLayoutItem *item;
32 while ( ( item = takeAt( 0 ) ) )
33 delete item;
34}
35
37{
38 return mLeftItems.size() + mRightItems.size() + mTopItems.size() + mBottomItems.size();
39}
40
41void QgsOverlayWidgetLayout::addItem( QLayoutItem *item )
42{
43 if ( !mLeftItems.contains( item ) && !mRightItems.contains( item ) && !mTopItems.contains( item ) && !mBottomItems.contains( item ) )
44 mLeftItems.append( item );
45}
46
47QLayoutItem *QgsOverlayWidgetLayout::itemAt( int index ) const
48{
49 if ( index < 0 )
50 return nullptr;
51
52 if ( index < mLeftItems.size() )
53 return mLeftItems.at( index );
54 index -= mLeftItems.size();
55
56 if ( index < mRightItems.size() )
57 return mRightItems.at( index );
58 index -= mRightItems.size();
59
60 if ( index < mTopItems.size() )
61 return mTopItems.at( index );
62 index -= mTopItems.size();
63
64 if ( index < mBottomItems.size() )
65 return mBottomItems.at( index );
66
67 return nullptr;
68}
69
70QLayoutItem *QgsOverlayWidgetLayout::takeAt( int index )
71{
72 if ( index < 0 )
73 return nullptr;
74
75 if ( index < mLeftItems.size() )
76 return mLeftItems.takeAt( index );
77 index -= mLeftItems.size();
78
79 if ( index < mRightItems.size() )
80 return mRightItems.takeAt( index );
81 index -= mRightItems.size();
82
83 if ( index < mTopItems.size() )
84 return mTopItems.takeAt( index );
85 index -= mTopItems.size();
86
87 if ( index < mBottomItems.size() )
88 return mBottomItems.takeAt( index );
89
90 return nullptr;
91}
92
94{
95 if ( QWidget *parent = parentWidget() )
96 {
97 return parent->sizeHint();
98 }
99 return QSize();
100}
101
103{
104 if ( QWidget *parent = parentWidget() )
105 {
106 return parent->minimumSize();
107 }
108 return QSize();
109}
110
111void QgsOverlayWidgetLayout::setGeometry( const QRect &rect )
112{
113 QLayout::setGeometry( rect );
114
115 int leftMargin = 0;
116 int rightMargin = 0;
117 int topMargin = 0;
118 int bottomMargin = 0;
119 getContentsMargins( &leftMargin, &topMargin, &rightMargin, &bottomMargin );
120
121 // adjust available rect to account for margins
122 const int innerLeft = rect.left() + leftMargin;
123 const int innerRight = rect.right() - rightMargin;
124 const int innerTop = rect.top() + topMargin;
125 const int innerBottom = rect.bottom() - bottomMargin;
126 const int innerHeight = innerBottom - innerTop;
127
128 int left = innerLeft;
129 for ( QLayoutItem *item : std::as_const( mLeftItems ) )
130 {
131 const QSize sizeHint = item->sizeHint();
132 item->setGeometry( QRect( left, innerTop, sizeHint.width(), innerHeight ) );
133 left += sizeHint.width() + mHorizontalSpacing;
134 }
135
136 int right = innerRight;
137 for ( QLayoutItem *item : std::as_const( mRightItems ) )
138 {
139 const QSize sizeHint = item->sizeHint();
140 item->setGeometry( QRect( right - sizeHint.width(), innerTop, sizeHint.width(), innerHeight ) );
141 right -= sizeHint.width() + mHorizontalSpacing;
142 }
143
144 int top = innerTop;
145 for ( QLayoutItem *item : std::as_const( mTopItems ) )
146 {
147 const QSize sizeHint = item->sizeHint();
148 item->setGeometry( QRect( left, top, right - left, sizeHint.height() ) );
149 top += sizeHint.height() + mVerticalSpacing;
150 }
151
152 int bottom = innerBottom;
153 for ( QLayoutItem *item : std::as_const( mBottomItems ) )
154 {
155 const QSize sizeHint = item->sizeHint();
156 item->setGeometry( QRect( left, bottom - sizeHint.height(), right - left, sizeHint.height() ) );
157 bottom -= sizeHint.height() + mVerticalSpacing;
158 }
159}
160
161void QgsOverlayWidgetLayout::addWidget( QWidget *widget, Qt::Edge edge )
162{
163 QWidgetItem *widgetItem = new QWidgetItem( widget );
164 switch ( edge )
165 {
166 case Qt::LeftEdge:
167 mLeftItems.append( widgetItem );
168 break;
169 case Qt::RightEdge:
170 mRightItems.append( widgetItem );
171 break;
172 case Qt::TopEdge:
173 mTopItems.append( widgetItem );
174 break;
175 case Qt::BottomEdge:
176 mBottomItems.append( widgetItem );
177 break;
178 }
179
180 addChildWidget( widget );
181 invalidate();
182}
183
185{
186 mHorizontalSpacing = spacing;
187 invalidate();
188}
189
191{
192 mVerticalSpacing = spacing;
193 invalidate();
194}
QLayoutItem * itemAt(int index) const final
void setGeometry(const QRect &rect) final
void addItem(QLayoutItem *item) final
void addWidget(QWidget *widget, Qt::Edge edge)
Adds a widget to the layout, which will be bound to the specified edge.
QLayoutItem * takeAt(int index) final
void setVerticalSpacing(int spacing)
Sets the spacing between widgets that are laid out on top of each other.
QgsOverlayWidgetLayout(QWidget *parent=nullptr)
Constructor for QgsOverlayWidgetLayout, with the specified parent widget.
void setHorizontalSpacing(int spacing)
Sets the spacing between widgets that are laid out side by side.