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