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