QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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#include "qgis.h"
18#include <QWidget>
19
21 : QLayout( parent )
22{
23
24}
25
27{
28 QLayoutItem *item;
29 while ( ( item = takeAt( 0 ) ) )
30 delete item;
31}
32
34{
35 return mLeftItems.size() + mRightItems.size() + mTopItems.size() + mBottomItems.size();
36}
37
38void QgsOverlayWidgetLayout::addItem( QLayoutItem *item )
39{
40 if ( !mLeftItems.contains( item ) && !mRightItems.contains( item ) && !mTopItems.contains( item ) && !mBottomItems.contains( item ) )
41 mLeftItems.append( item );
42}
43
44QLayoutItem *QgsOverlayWidgetLayout::itemAt( int index ) const
45{
46 if ( index < 0 )
47 return nullptr;
48
49 if ( index < mLeftItems.size() )
50 return mLeftItems.at( index );
51 index -= mLeftItems.size();
52
53 if ( index < mRightItems.size() )
54 return mRightItems.at( index );
55 index -= mRightItems.size();
56
57 if ( index < mTopItems.size() )
58 return mTopItems.at( index );
59 index -= mTopItems.size();
60
61 if ( index < mBottomItems.size() )
62 return mBottomItems.at( index );
63
64 return nullptr;
65}
66
67QLayoutItem *QgsOverlayWidgetLayout::takeAt( int index )
68{
69 if ( index < 0 )
70 return nullptr;
71
72 if ( index < mLeftItems.size() )
73 return mLeftItems.takeAt( index );
74 index -= mLeftItems.size();
75
76 if ( index < mRightItems.size() )
77 return mRightItems.takeAt( index );
78 index -= mRightItems.size();
79
80 if ( index < mTopItems.size() )
81 return mTopItems.takeAt( index );
82 index -= mTopItems.size();
83
84 if ( index < mBottomItems.size() )
85 return mBottomItems.takeAt( index );
86
87 return nullptr;
88}
89
91{
92 if ( QWidget *parent = parentWidget() )
93 {
94 return parent->sizeHint();
95 }
96 return QSize();
97}
98
100{
101 if ( QWidget *parent = parentWidget() )
102 {
103 return parent->minimumSize();
104 }
105 return QSize();
106}
107
108void QgsOverlayWidgetLayout::setGeometry( const QRect &rect )
109{
110 QLayout::setGeometry( rect );
111
112 int leftMargin = 0;
113 int rightMargin = 0;
114 int topMargin = 0;
115 int bottomMargin = 0;
116 getContentsMargins( &leftMargin, &topMargin, &rightMargin, &bottomMargin );
117
118 // adjust available rect to account for margins
119 const int innerLeft = rect.left() + leftMargin;
120 const int innerRight = rect.right() - rightMargin;
121 const int innerTop = rect.top() + topMargin;
122 const int innerBottom = rect.bottom() - bottomMargin;
123 const int innerHeight = innerBottom - innerTop;
124
125 int left = innerLeft;
126 for ( QLayoutItem *item : std::as_const( mLeftItems ) )
127 {
128 const QSize sizeHint = item->sizeHint();
129 item->setGeometry( QRect( left, innerTop, sizeHint.width(), innerHeight ) );
130 left += sizeHint.width() + mHorizontalSpacing;
131 }
132
133 int right = innerRight;
134 for ( QLayoutItem *item : std::as_const( mRightItems ) )
135 {
136 const QSize sizeHint = item->sizeHint();
137 item->setGeometry( QRect( right - sizeHint.width(), innerTop, sizeHint.width(), innerHeight ) );
138 right -= sizeHint.width() + mHorizontalSpacing;
139 }
140
141 int top = innerTop;
142 for ( QLayoutItem *item : std::as_const( mTopItems ) )
143 {
144 const QSize sizeHint = item->sizeHint();
145 item->setGeometry( QRect( left, top, right - left, sizeHint.height() ) );
146 top += sizeHint.height() + mVerticalSpacing;
147 }
148
149 int bottom = innerBottom;
150 for ( QLayoutItem *item : std::as_const( mBottomItems ) )
151 {
152 const QSize sizeHint = item->sizeHint();
153 item->setGeometry( QRect( left, bottom - sizeHint.height(), right - left, sizeHint.height() ) );
154 bottom -= sizeHint.height() + mVerticalSpacing;
155 }
156}
157
158void QgsOverlayWidgetLayout::addWidget( QWidget *widget, Qt::Edge edge )
159{
160 QWidgetItem *widgetItem = new QWidgetItem( widget );
161 switch ( edge )
162 {
163 case Qt::LeftEdge:
164 mLeftItems.append( widgetItem );
165 break;
166 case Qt::RightEdge:
167 mRightItems.append( widgetItem );
168 break;
169 case Qt::TopEdge:
170 mTopItems.append( widgetItem );
171 break;
172 case Qt::BottomEdge:
173 mBottomItems.append( widgetItem );
174 break;
175 }
176
177 addChildWidget( widget );
178 invalidate();
179}
180
182{
183 mHorizontalSpacing = spacing;
184 invalidate();
185}
186
188{
189 mVerticalSpacing = spacing;
190 invalidate();
191}
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
QSize minimumSize() const 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.