mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-03 00:05:24 -04:00
218 lines
5.8 KiB
C++
218 lines
5.8 KiB
C++
/***************************************************************************
|
|
qgsfloatingwidget.cpp
|
|
---------------------
|
|
begin : April 2016
|
|
copyright : (C) Nyall Dawson
|
|
email : nyall dot dawson at gmail dot com
|
|
***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "qgsfloatingwidget.h"
|
|
#include <QEvent>
|
|
#include <QStyleOption>
|
|
#include <QPainter>
|
|
|
|
//
|
|
// QgsFloatingWidget
|
|
//
|
|
|
|
QgsFloatingWidget::QgsFloatingWidget( QWidget *parent )
|
|
: QWidget( parent )
|
|
{
|
|
if ( parent )
|
|
{
|
|
mParentEventFilter = new QgsFloatingWidgetEventFilter( parent );
|
|
parent->installEventFilter( mParentEventFilter );
|
|
connect( mParentEventFilter, &QgsFloatingWidgetEventFilter::anchorPointChanged, this, &QgsFloatingWidget::onAnchorPointChanged );
|
|
}
|
|
}
|
|
|
|
void QgsFloatingWidget::setAnchorWidget( QWidget *widget )
|
|
{
|
|
if ( widget == mAnchorWidget )
|
|
return;
|
|
|
|
// remove existing event filter
|
|
if ( mAnchorWidget )
|
|
{
|
|
mAnchorWidget->removeEventFilter( mAnchorEventFilter );
|
|
delete mAnchorEventFilter;
|
|
mAnchorEventFilter = nullptr;
|
|
}
|
|
|
|
mAnchorWidget = widget;
|
|
if ( mAnchorWidget )
|
|
{
|
|
mAnchorEventFilter = new QgsFloatingWidgetEventFilter( mAnchorWidget );
|
|
mAnchorWidget->installEventFilter( mAnchorEventFilter );
|
|
connect( mAnchorEventFilter, &QgsFloatingWidgetEventFilter::anchorPointChanged, this, &QgsFloatingWidget::onAnchorPointChanged );
|
|
}
|
|
|
|
onAnchorPointChanged();
|
|
emit anchorWidgetChanged( mAnchorWidget );
|
|
}
|
|
|
|
QWidget *QgsFloatingWidget::anchorWidget()
|
|
{
|
|
return mAnchorWidget;
|
|
}
|
|
|
|
void QgsFloatingWidget::setAnchorPoint( QgsFloatingWidget::AnchorPoint point )
|
|
{
|
|
if ( point == mFloatAnchorPoint )
|
|
return;
|
|
|
|
mFloatAnchorPoint = point;
|
|
onAnchorPointChanged();
|
|
emit anchorPointChanged( mFloatAnchorPoint );
|
|
}
|
|
|
|
void QgsFloatingWidget::setAnchorWidgetPoint( QgsFloatingWidget::AnchorPoint point )
|
|
{
|
|
if ( point == mAnchorWidgetAnchorPoint )
|
|
return;
|
|
|
|
mAnchorWidgetAnchorPoint = point;
|
|
onAnchorPointChanged();
|
|
emit anchorWidgetPointChanged( mAnchorWidgetAnchorPoint );
|
|
}
|
|
|
|
void QgsFloatingWidget::showEvent( QShowEvent *e )
|
|
{
|
|
QWidget::showEvent( e );
|
|
onAnchorPointChanged();
|
|
}
|
|
|
|
void QgsFloatingWidget::paintEvent( QPaintEvent *e )
|
|
{
|
|
Q_UNUSED( e );
|
|
QStyleOption opt;
|
|
opt.init( this );
|
|
QPainter p( this );
|
|
style()->drawPrimitive( QStyle::PE_Widget, &opt, &p, this );
|
|
}
|
|
|
|
void QgsFloatingWidget::resizeEvent( QResizeEvent *e )
|
|
{
|
|
QWidget::resizeEvent( e );
|
|
onAnchorPointChanged();
|
|
}
|
|
|
|
void QgsFloatingWidget::onAnchorPointChanged()
|
|
{
|
|
if ( !parentWidget() )
|
|
return;
|
|
|
|
if ( mAnchorWidget )
|
|
{
|
|
QPoint anchorWidgetOrigin;
|
|
|
|
switch ( mAnchorWidgetAnchorPoint )
|
|
{
|
|
case TopLeft:
|
|
anchorWidgetOrigin = QPoint( 0, 0 );
|
|
break;
|
|
case TopMiddle:
|
|
anchorWidgetOrigin = QPoint( mAnchorWidget->width() / 2, 0 );
|
|
break;
|
|
case TopRight:
|
|
anchorWidgetOrigin = QPoint( mAnchorWidget->width(), 0 );
|
|
break;
|
|
case MiddleLeft:
|
|
anchorWidgetOrigin = QPoint( 0, mAnchorWidget->height() / 2 );
|
|
break;
|
|
case Middle:
|
|
anchorWidgetOrigin = QPoint( mAnchorWidget->width() / 2, mAnchorWidget->height() / 2 );
|
|
break;
|
|
case MiddleRight:
|
|
anchorWidgetOrigin = QPoint( mAnchorWidget->width(), mAnchorWidget->height() / 2 );
|
|
break;
|
|
case BottomLeft:
|
|
anchorWidgetOrigin = QPoint( 0, mAnchorWidget->height() );
|
|
break;
|
|
case BottomMiddle:
|
|
anchorWidgetOrigin = QPoint( mAnchorWidget->width() / 2, mAnchorWidget->height() );
|
|
break;
|
|
case BottomRight:
|
|
anchorWidgetOrigin = QPoint( mAnchorWidget->width(), mAnchorWidget->height() );
|
|
break;
|
|
}
|
|
|
|
anchorWidgetOrigin = mAnchorWidget->mapTo( parentWidget(), anchorWidgetOrigin );
|
|
int anchorX = anchorWidgetOrigin.x();
|
|
int anchorY = anchorWidgetOrigin.y();
|
|
|
|
switch ( mFloatAnchorPoint )
|
|
{
|
|
case TopLeft:
|
|
break;
|
|
case TopMiddle:
|
|
anchorX = anchorX - width() / 2;
|
|
break;
|
|
case TopRight:
|
|
anchorX = anchorX - width();
|
|
break;
|
|
case MiddleLeft:
|
|
anchorY = anchorY - height() / 2;
|
|
break;
|
|
case Middle:
|
|
anchorY = anchorY - height() / 2;
|
|
anchorX = anchorX - width() / 2;
|
|
break;
|
|
case MiddleRight:
|
|
anchorX = anchorX - width();
|
|
anchorY = anchorY - height() / 2;
|
|
break;
|
|
case BottomLeft:
|
|
anchorY = anchorY - height();
|
|
break;
|
|
case BottomMiddle:
|
|
anchorX = anchorX - width() / 2;
|
|
anchorY = anchorY - height();
|
|
break;
|
|
case BottomRight:
|
|
anchorX = anchorX - width();
|
|
anchorY = anchorY - height();
|
|
break;
|
|
}
|
|
|
|
// constrain x so that widget floats within parent widget
|
|
anchorX = qBound( 0, anchorX, parentWidget()->width() - width() );
|
|
|
|
move( anchorX, anchorY );
|
|
}
|
|
}
|
|
|
|
//
|
|
// QgsFloatingWidgetEventFilter
|
|
//
|
|
|
|
/// @cond PRIVATE
|
|
QgsFloatingWidgetEventFilter::QgsFloatingWidgetEventFilter( QWidget *parent )
|
|
: QObject( parent )
|
|
{
|
|
|
|
}
|
|
|
|
bool QgsFloatingWidgetEventFilter::eventFilter( QObject *object, QEvent *event )
|
|
{
|
|
Q_UNUSED( object );
|
|
switch ( event->type() )
|
|
{
|
|
case QEvent::Move:
|
|
case QEvent::Resize:
|
|
emit anchorPointChanged();
|
|
return false;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
///@endcond
|