Marble

WidgetGraphicsItem.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2010 Bastian Holst <bastianholst@gmx.de>
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
20using namespace Marble;
21
22WidgetGraphicsItemPrivate::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
30WidgetGraphicsItemPrivate::~WidgetGraphicsItemPrivate()
31{
32 delete m_widget;
33}
34
35WidgetGraphicsItem::WidgetGraphicsItem( MarbleGraphicsItem *parent )
36 : ScreenGraphicsItem(new WidgetGraphicsItemPrivate(this, parent))
37{
38}
39
40WidgetGraphicsItem::~WidgetGraphicsItem()
41{
42}
43
44void 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
56QWidget *WidgetGraphicsItem::widget() const
57{
58 Q_D(const WidgetGraphicsItem);
59 return d->m_widget;
60}
61
62void 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
72bool 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
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}
This file contains the headers for MarbleWidget.
A widget class that displays a view of the earth.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
Binds a QML item to a specific geodetic location in screen coordinates.
bool sendEvent(QObject *receiver, QEvent *event)
MouseButtonDblClick
Type type() const const
iterator begin()
iterator end()
QPoint toPoint() const const
bool contains(const QPointF &point) const const
QPointF topLeft() const const
QSize boundedTo(const QSize &otherSize) const const
QSize expandedTo(const QSize &otherSize) const const
typedef RenderFlags
QWidget * childAt(const QPoint &p) const const
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.