File indexing completed on 2025-01-05 03:59:17
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2010 Bastian Holst <bastianholst@gmx.de> 0004 // 0005 0006 // Self 0007 #include "WidgetGraphicsItem.h" 0008 #include "WidgetGraphicsItem_p.h" 0009 0010 // Qt 0011 #include <QApplication> 0012 #include <QMouseEvent> 0013 #include <QPainter> 0014 #include <QWidget> 0015 0016 // Marble 0017 #include "MarbleWidget.h" 0018 0019 #include "digikam_debug.h" 0020 0021 using namespace Marble; 0022 0023 WidgetGraphicsItemPrivate::WidgetGraphicsItemPrivate(WidgetGraphicsItem *widgetGraphicsItem, 0024 MarbleGraphicsItem *parent) 0025 : ScreenGraphicsItemPrivate(widgetGraphicsItem, parent), 0026 m_widget(nullptr), m_marbleWidget(nullptr), m_activeWidget( nullptr ) 0027 { 0028 // nothing to do 0029 } 0030 0031 WidgetGraphicsItemPrivate::~WidgetGraphicsItemPrivate() 0032 { 0033 delete m_widget; 0034 } 0035 0036 WidgetGraphicsItem::WidgetGraphicsItem( MarbleGraphicsItem *parent ) 0037 : ScreenGraphicsItem(new WidgetGraphicsItemPrivate(this, parent)) 0038 { 0039 } 0040 0041 WidgetGraphicsItem::~WidgetGraphicsItem() 0042 { 0043 } 0044 0045 void WidgetGraphicsItem::setWidget(QWidget *widget) 0046 { 0047 Q_D(WidgetGraphicsItem); 0048 d->m_widget = widget; 0049 0050 QSize size = widget->sizeHint().expandedTo( widget->size() ); 0051 size = size.expandedTo( widget->minimumSize() ); 0052 size = size.boundedTo( widget->maximumSize() ); 0053 setSize( size ); 0054 widget->resize( size ); 0055 } 0056 0057 QWidget *WidgetGraphicsItem::widget() const 0058 { 0059 Q_D(const WidgetGraphicsItem); 0060 return d->m_widget; 0061 } 0062 0063 void WidgetGraphicsItem::paint( QPainter *painter ) 0064 { 0065 Q_D(WidgetGraphicsItem); 0066 if( d->m_widget == nullptr ) 0067 return; 0068 0069 // Paint widget without a background 0070 d->m_widget->render( painter, QPoint( 0, 0 ), QRegion(), QWidget::RenderFlags( QWidget::DrawChildren) ); 0071 } 0072 0073 bool WidgetGraphicsItem::eventFilter( QObject *object, QEvent *e ) 0074 { 0075 Q_D(WidgetGraphicsItem); 0076 if ( !visible() || d->m_widget == nullptr ) { 0077 return false; 0078 } 0079 0080 MarbleWidget *widget = dynamic_cast<MarbleWidget*> (object); 0081 if ( !widget ) { 0082 return ScreenGraphicsItem::eventFilter(object, e); 0083 } 0084 0085 if ( d->m_marbleWidget != widget ) { 0086 // Delayed initialization 0087 d->m_marbleWidget = widget; 0088 } 0089 0090 Q_ASSERT(d->m_marbleWidget); 0091 0092 if ( e->type() == QEvent::MouseButtonDblClick 0093 || e->type() == QEvent::MouseMove 0094 || e->type() == QEvent::MouseButtonPress 0095 || e->type() == QEvent::MouseButtonRelease ) 0096 { 0097 // Mouse events are forwarded to the underlying widget 0098 QMouseEvent *event = static_cast<QMouseEvent*> ( e ); 0099 0100 const QVector<QPointF> widgetPositions = absolutePositions(); 0101 QRectF widgetItemRect; 0102 QPoint shiftedPos; 0103 QVector<QPointF>::ConstIterator it = widgetPositions.begin(); 0104 bool foundRightPosition = false; 0105 for(; !foundRightPosition && it != widgetPositions.end(); ++it ) { 0106 widgetItemRect = QRectF( *it, size() ); 0107 0108 if ( widgetItemRect.contains( event->pos() ) ) { 0109 foundRightPosition = true; 0110 shiftedPos = event->pos() - widgetItemRect.topLeft().toPoint(); 0111 } 0112 } 0113 0114 if ( foundRightPosition ) { 0115 QWidget *child = d->m_widget->childAt( shiftedPos ); 0116 0117 if ( d->m_activeWidget && d->m_activeWidget != child ) { 0118 QEvent leaveEvent( QEvent::Leave ); 0119 QApplication::sendEvent( d->m_activeWidget, &leaveEvent ); 0120 } 0121 0122 if ( child && d->m_activeWidget != child ) { 0123 QEvent enterEvent( QEvent::Enter ); 0124 QApplication::sendEvent( child, &enterEvent ); 0125 } 0126 d->m_activeWidget = child; 0127 0128 if ( child ) { 0129 shiftedPos -= child->pos(); // transform to children's coordinates 0130 QMouseEvent shiftedEvent = QMouseEvent( e->type(), shiftedPos, 0131 0132 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0133 0134 event->globalPosition(), 0135 0136 #else 0137 0138 event->globalPos(), 0139 0140 #endif 0141 event->button(), event->buttons(), 0142 event->modifiers() ); 0143 if ( QApplication::sendEvent( child, &shiftedEvent ) ) { 0144 d->m_marbleWidget->setCursor( d->m_widget->cursor() ); 0145 return true; 0146 } 0147 } 0148 } else { 0149 if ( d->m_activeWidget ) { 0150 QEvent leaveEvent( QEvent::Leave ); 0151 QApplication::sendEvent( d->m_activeWidget, &leaveEvent ); 0152 d->m_activeWidget = nullptr; 0153 } 0154 } 0155 } 0156 0157 return ScreenGraphicsItem::eventFilter(object, e); 0158 }