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