Marble

WidgetGraphicsItem.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2010 Bastian Holst <[email protected]>
4 //
5 
6 // Self
7 #include "WidgetGraphicsItem.h"
8 #include "WidgetGraphicsItem_p.h"
9 
10 // Marble
11 #include "MarbleWidget.h"
12 #include "MarbleDebug.h"
13 
14 // Qt
15 #include <QApplication>
16 #include <QMouseEvent>
17 #include <QPainter>
18 #include <QWidget>
19 
20 using namespace Marble;
21 
22 WidgetGraphicsItemPrivate::WidgetGraphicsItemPrivate(WidgetGraphicsItem *widgetGraphicsItem,
23  MarbleGraphicsItem *parent)
24  : ScreenGraphicsItemPrivate(widgetGraphicsItem, parent),
25  m_widget(nullptr), m_marbleWidget(nullptr), m_activeWidget( nullptr )
26 {
27  // nothing to do
28 }
29 
30 WidgetGraphicsItemPrivate::~WidgetGraphicsItemPrivate()
31 {
32  delete m_widget;
33 }
34 
35 WidgetGraphicsItem::WidgetGraphicsItem( MarbleGraphicsItem *parent )
36  : ScreenGraphicsItem(new WidgetGraphicsItemPrivate(this, parent))
37 {
38 }
39 
40 WidgetGraphicsItem::~WidgetGraphicsItem()
41 {
42 }
43 
44 void WidgetGraphicsItem::setWidget(QWidget *widget)
45 {
46  Q_D(WidgetGraphicsItem);
47  d->m_widget = widget;
48 
49  QSize size = widget->sizeHint().expandedTo( widget->size() );
50  size = size.expandedTo( widget->minimumSize() );
51  size = size.boundedTo( widget->maximumSize() );
52  setSize( size );
53  widget->resize( size );
54 }
55 
56 QWidget *WidgetGraphicsItem::widget() const
57 {
58  Q_D(const WidgetGraphicsItem);
59  return d->m_widget;
60 }
61 
62 void WidgetGraphicsItem::paint( QPainter *painter )
63 {
64  Q_D(WidgetGraphicsItem);
65  if( d->m_widget == nullptr )
66  return;
67 
68  // Paint widget without a background
69  d->m_widget->render( painter, QPoint( 0, 0 ), QRegion(), QWidget::RenderFlags( QWidget::DrawChildren) );
70 }
71 
72 bool WidgetGraphicsItem::eventFilter( QObject *object, QEvent *e )
73 {
74  Q_D(WidgetGraphicsItem);
75  if ( !visible() || d->m_widget == nullptr ) {
76  return false;
77  }
78 
79  MarbleWidget *widget = dynamic_cast<MarbleWidget*> (object);
80  if ( !widget ) {
81  return ScreenGraphicsItem::eventFilter(object, e);
82  }
83 
84  if ( d->m_marbleWidget != widget ) {
85  // Delayed initialization
86  d->m_marbleWidget = widget;
87  }
88 
89  Q_ASSERT(d->m_marbleWidget);
90 
92  || e->type() == QEvent::MouseMove
94  || e->type() == QEvent::MouseButtonRelease )
95  {
96  // Mouse events are forwarded to the underlying widget
97  QMouseEvent *event = static_cast<QMouseEvent*> ( e );
98 
99  const QVector<QPointF> widgetPositions = absolutePositions();
100  QRectF widgetItemRect;
101  QPoint shiftedPos;
102  QVector<QPointF>::ConstIterator it = widgetPositions.begin();
103  bool foundRightPosition = false;
104  for(; !foundRightPosition && it != widgetPositions.end(); ++it ) {
105  widgetItemRect = QRectF( *it, size() );
106 
107  if ( widgetItemRect.contains( event->pos() ) ) {
108  foundRightPosition = true;
109  shiftedPos = event->pos() - widgetItemRect.topLeft().toPoint();
110  }
111  }
112 
113  if ( foundRightPosition ) {
114  QWidget *child = d->m_widget->childAt( shiftedPos );
115 
116  if ( d->m_activeWidget && d->m_activeWidget != child ) {
117  QEvent leaveEvent( QEvent::Leave );
118  QApplication::sendEvent( d->m_activeWidget, &leaveEvent );
119  }
120 
121  if ( child && d->m_activeWidget != child ) {
122  QEvent enterEvent( QEvent::Enter );
123  QApplication::sendEvent( child, &enterEvent );
124  }
125  d->m_activeWidget = child;
126 
127  if ( child ) {
128  shiftedPos -= child->pos(); // transform to children's coordinates
129  QMouseEvent shiftedEvent = QMouseEvent( e->type(), shiftedPos,
130  event->globalPos(), event->button(), event->buttons(),
131  event->modifiers() );
132  if ( QApplication::sendEvent( child, &shiftedEvent ) ) {
133  d->m_marbleWidget->setCursor( d->m_widget->cursor() );
134  return true;
135  }
136  }
137  } else {
138  if ( d->m_activeWidget ) {
139  QEvent leaveEvent( QEvent::Leave );
140  QApplication::sendEvent( d->m_activeWidget, &leaveEvent );
141  d->m_activeWidget = nullptr;
142  }
143  }
144  }
145 
146  return ScreenGraphicsItem::eventFilter(object, e);
147 }
MouseButtonDblClick
QVector::iterator begin()
A widget class that displays a view of the earth.
Definition: MarbleWidget.h:98
QPointF topLeft() const const
bool sendEvent(QObject *receiver, QEvent *event)
bool contains(const QRectF &rectangle) const const
QSize boundedTo(const QSize &otherSize) const const
Binds a QML item to a specific geodetic location in screen coordinates.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
QWidget * childAt(int x, int y) const const
QVector::iterator end()
void resize(int w, int h)
QSize expandedTo(const QSize &otherSize) const const
QEvent::Type type() const const
QPoint toPoint() const const
typedef RenderFlags
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu May 26 2022 04:07:51 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.