QGIS API Documentation 3.41.0-Master (3440c17df1d)
Loading...
Searching...
No Matches
qgsfloatingwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsfloatingwidget.cpp
3 ---------------------
4 begin : April 2016
5 copyright : (C) 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
16#include "qgsfloatingwidget.h"
17#include "moc_qgsfloatingwidget.cpp"
18#include <QEvent>
19#include <QStyleOption>
20#include <QPainter>
21
22//
23// QgsFloatingWidget
24//
25
27 : QWidget( parent )
28{
29 if ( parent )
30 {
31 mParentEventFilter = new QgsFloatingWidgetEventFilter( parent );
32 parent->installEventFilter( mParentEventFilter );
33 connect( mParentEventFilter, &QgsFloatingWidgetEventFilter::anchorPointChanged, this, &QgsFloatingWidget::onAnchorPointChanged );
34 }
35}
36
38{
39 if ( widget == mAnchorWidget )
40 return;
41
42 // remove existing event filter
43 if ( mAnchorWidget )
44 {
45 mAnchorWidget->removeEventFilter( mAnchorEventFilter );
46 delete mAnchorEventFilter;
47 mAnchorEventFilter = nullptr;
48 }
49
50 mAnchorWidget = widget;
51 if ( mAnchorWidget )
52 {
53 mAnchorEventFilter = new QgsFloatingWidgetEventFilter( mAnchorWidget );
54 mAnchorWidget->installEventFilter( mAnchorEventFilter );
55 connect( mAnchorEventFilter, &QgsFloatingWidgetEventFilter::anchorPointChanged, this, &QgsFloatingWidget::onAnchorPointChanged );
56 }
57
58 onAnchorPointChanged();
59 emit anchorWidgetChanged( mAnchorWidget );
60}
61
63{
64 return mAnchorWidget;
65}
66
68{
69 if ( point == mFloatAnchorPoint )
70 return;
71
72 mFloatAnchorPoint = point;
73 onAnchorPointChanged();
74 emit anchorPointChanged( mFloatAnchorPoint );
75}
76
78{
79 if ( point == mAnchorWidgetAnchorPoint )
80 return;
81
82 mAnchorWidgetAnchorPoint = point;
83 onAnchorPointChanged();
84 emit anchorWidgetPointChanged( mAnchorWidgetAnchorPoint );
85}
86
87void QgsFloatingWidget::showEvent( QShowEvent *e )
88{
89 QWidget::showEvent( e );
90 onAnchorPointChanged();
91}
92
93void QgsFloatingWidget::paintEvent( QPaintEvent *e )
94{
95 Q_UNUSED( e )
96 QStyleOption opt;
97#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
98 opt.init( this );
99#else
100 opt.initFrom( this );
101#endif
102 QPainter p( this );
103 style()->drawPrimitive( QStyle::PE_Widget, &opt, &p, this );
104}
105
106void QgsFloatingWidget::resizeEvent( QResizeEvent *e )
107{
108 QWidget::resizeEvent( e );
109 onAnchorPointChanged();
110}
111
112void QgsFloatingWidget::onAnchorPointChanged()
113{
114 if ( !parentWidget() )
115 return;
116
117 if ( mAnchorWidget )
118 {
119 QPoint anchorWidgetOrigin;
120
121 switch ( mAnchorWidgetAnchorPoint )
122 {
123 case TopLeft:
124 anchorWidgetOrigin = QPoint( 0, 0 );
125 break;
126 case TopMiddle:
127 anchorWidgetOrigin = QPoint( mAnchorWidget->width() / 2, 0 );
128 break;
129 case TopRight:
130 anchorWidgetOrigin = QPoint( mAnchorWidget->width(), 0 );
131 break;
132 case MiddleLeft:
133 anchorWidgetOrigin = QPoint( 0, mAnchorWidget->height() / 2 );
134 break;
135 case Middle:
136 anchorWidgetOrigin = QPoint( mAnchorWidget->width() / 2, mAnchorWidget->height() / 2 );
137 break;
138 case MiddleRight:
139 anchorWidgetOrigin = QPoint( mAnchorWidget->width(), mAnchorWidget->height() / 2 );
140 break;
141 case BottomLeft:
142 anchorWidgetOrigin = QPoint( 0, mAnchorWidget->height() );
143 break;
144 case BottomMiddle:
145 anchorWidgetOrigin = QPoint( mAnchorWidget->width() / 2, mAnchorWidget->height() );
146 break;
147 case BottomRight:
148 anchorWidgetOrigin = QPoint( mAnchorWidget->width(), mAnchorWidget->height() );
149 break;
150 }
151
152 anchorWidgetOrigin = mAnchorWidget->mapTo( parentWidget(), anchorWidgetOrigin );
153 int anchorX = anchorWidgetOrigin.x();
154 int anchorY = anchorWidgetOrigin.y();
155
156 switch ( mFloatAnchorPoint )
157 {
158 case TopLeft:
159 break;
160 case TopMiddle:
161 anchorX = anchorX - width() / 2;
162 break;
163 case TopRight:
164 anchorX = anchorX - width();
165 break;
166 case MiddleLeft:
167 anchorY = anchorY - height() / 2;
168 break;
169 case Middle:
170 anchorY = anchorY - height() / 2;
171 anchorX = anchorX - width() / 2;
172 break;
173 case MiddleRight:
174 anchorX = anchorX - width();
175 anchorY = anchorY - height() / 2;
176 break;
177 case BottomLeft:
178 anchorY = anchorY - height();
179 break;
180 case BottomMiddle:
181 anchorX = anchorX - width() / 2;
182 anchorY = anchorY - height();
183 break;
184 case BottomRight:
185 anchorX = anchorX - width();
186 anchorY = anchorY - height();
187 break;
188 }
189
190 // constrain x so that widget floats within parent widget
191 anchorX = std::clamp( anchorX, 0, parentWidget()->width() - width() );
192
193 move( anchorX, anchorY );
194 }
195}
196
197//
198// QgsFloatingWidgetEventFilter
199//
200
202QgsFloatingWidgetEventFilter::QgsFloatingWidgetEventFilter( QWidget *parent )
203 : QObject( parent )
204{
205
206}
207
208bool QgsFloatingWidgetEventFilter::eventFilter( QObject *object, QEvent *event )
209{
210 Q_UNUSED( object )
211 switch ( event->type() )
212 {
213 case QEvent::Move:
214 case QEvent::Resize:
215 emit anchorPointChanged();
216 return false;
217 default:
218 return false;
219 }
220}
221
void anchorWidgetPointChanged(QgsFloatingWidget::AnchorPoint point)
Emitted when the anchor widget point changes.
void setAnchorWidget(QWidget *widget)
Sets the widget to "anchor" the floating widget to.
QgsFloatingWidget(QWidget *parent=nullptr)
Constructor for QgsFloatingWidget.
void setAnchorWidgetPoint(AnchorPoint point)
Returns the anchor widget's anchor point, which corresponds to the point on the anchor widget which t...
void resizeEvent(QResizeEvent *e) override
void anchorPointChanged(QgsFloatingWidget::AnchorPoint point)
Emitted when the anchor point changes.
AnchorPoint
Reference points for anchoring widget position.
@ BottomMiddle
Bottom center of widget.
@ TopMiddle
Top center of widget.
@ MiddleRight
Middle right of widget.
@ MiddleLeft
Middle left of widget.
@ BottomRight
Bottom-right of widget.
@ BottomLeft
Bottom-left of widget.
@ Middle
Middle of widget.
@ TopLeft
Top-left of widget.
@ TopRight
Top-right of widget.
void paintEvent(QPaintEvent *e) override
void setAnchorPoint(AnchorPoint point)
Sets the floating widget's anchor point, which corresponds to the point on the widget which should re...
void anchorWidgetChanged(QWidget *widget)
Emitted when the anchor widget changes.
void showEvent(QShowEvent *e) override