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