Marble

ScreenGraphicsItem.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2009-2010 Bastian Holst <[email protected]>
4 //
5 
6 // Self
7 #include "ScreenGraphicsItem.h"
8 #include "ScreenGraphicsItem_p.h"
9 
10 // Marble
11 #include "MarbleDebug.h"
12 #include "MarbleWidget.h"
13 
14 // Qt
15 #include <QMouseEvent>
16 
17 
18 using namespace Marble;
19 
20 ScreenGraphicsItem::ScreenGraphicsItem( MarbleGraphicsItem *parent )
21  : MarbleGraphicsItem( new ScreenGraphicsItemPrivate( this, parent ) )
22 {
23 }
24 
25 ScreenGraphicsItem::ScreenGraphicsItem(ScreenGraphicsItemPrivate *dd)
26  : MarbleGraphicsItem(dd)
27 {
28 }
29 
30 ScreenGraphicsItem::~ScreenGraphicsItem()
31 {
32 }
33 
34 QPointF ScreenGraphicsItem::position() const
35 {
36  Q_D(const ScreenGraphicsItem);
37  return d->m_position;
38 }
39 
40 void ScreenGraphicsItem::setPosition( const QPointF& position )
41 {
42  Q_D(ScreenGraphicsItem);
43  d->m_position = position;
44 }
45 
46 QPointF ScreenGraphicsItem::positivePosition() const
47 {
48  Q_D(const ScreenGraphicsItem);
49  return d->positivePosition();
50 }
51 
52 QVector<QPointF> ScreenGraphicsItem::absolutePositions() const
53 {
54  Q_D(const ScreenGraphicsItem);
55  return d->absolutePositions();
56 }
57 
58 ScreenGraphicsItem::GraphicsItemFlags ScreenGraphicsItem::flags() const
59 {
60  Q_D(const ScreenGraphicsItem);
61  return d->m_flags;
62 }
63 
64 void ScreenGraphicsItem::setFlags( ScreenGraphicsItem::GraphicsItemFlags flags )
65 {
66  Q_D(ScreenGraphicsItem);
67  d->m_flags = flags;
68 }
69 
70 bool ScreenGraphicsItem::eventFilter( QObject *object, QEvent *e )
71 {
72  MarbleWidget *widget = dynamic_cast<MarbleWidget*>(object);
73  if ( !widget ) {
74  return MarbleGraphicsItem::eventFilter( object, e );
75  }
76 
77  Q_D(ScreenGraphicsItem);
78  if (!d->m_floatItemMoving) {
79  if ( MarbleGraphicsItem::eventFilter( object, e ) ) {
80  return true;
81  }
82 
83  if (!visible() || !d->isMovable()) {
84  return false;
85  }
86 
87  if ( e->type() == QEvent::MouseMove ) {
88  return false;
89  }
90 
91  // Move ScreenGraphicsItem
92  if ( e->type() == QEvent::MouseButtonPress )
93  {
94  QMouseEvent *event = static_cast<QMouseEvent*>(e);
95 
96  // Click and move above a float item triggers moving the float item
97  if ( contains( event->pos() ) ) {
98  if ( event->button() == Qt::LeftButton ) {
99  d->m_floatItemMoveStartPos = event->pos();
100  d->m_floatItemMoving = true;
101  return true;
102  }
103  }
104  }
105 
106  return false;
107  }
108  else {
109  // Move ScreenGraphicsItem
110  if ( e->type() == QEvent::MouseMove
111  || e->type() == QEvent::MouseButtonPress
112  || e->type() == QEvent::MouseButtonRelease )
113  {
114  QMouseEvent *event = static_cast<QMouseEvent*>( e );
115  // The rect the item was painted on before. We add one pixel as antialiasing could
116  // result into painting on these pixels to.
117  QRectF floatItemRect = QRectF( positivePosition() - QPoint( 1, 1 ),
118  size() + QSize( 2, 2 ) );
119 
120  if ( e->type() == QEvent::MouseMove && event->buttons() & Qt::LeftButton ) {
121  const QPoint &point = event->pos();
122  QPointF position = positivePosition();
123  qreal newX = qMax<qreal>(0, position.x() + point.x() - d->m_floatItemMoveStartPos.x());
124  qreal newY = qMax<qreal>(0, position.y() + point.y() - d->m_floatItemMoveStartPos.y());
125 
126  // docking behavior
127  const qreal dockArea = 60.0; // Alignment area width/height
128  const qreal dockJump = 30.0; // Alignment indicator jump size
129  if ( widget->width()-size().width()-newX < dockArea ) {
130  newX = qMin( qreal( -1.0 ), size().width() + newX-widget->width() );
131  if (d->m_floatItemMoveStartPos.x() < event->pos().x()) {
132  // Indicate change to right alignment with a short jump
133  newX = qMax( newX, -(dockArea-dockJump) );
134  }
135  }
136  if ( widget->height()-size().height()-newY < dockArea ) {
137  newY = qMin( qreal( -1.0 ), size().height() + newY-widget->height() );
138  if (d->m_floatItemMoveStartPos.y() < event->pos().y()) {
139  // Indicate change to bottom alignment with a short jump
140  newY = qMax( newY, -( dockArea - dockJump ) );
141  }
142  }
143 
144  setPosition( QPointF( newX,newY ) );
145  // The rect the item will be painted on now. We add one pixel as
146  // antialiasing could result into painting on these pixels to.
147  QRect newFloatItemRect = QRectF( positivePosition() - QPoint( 1, 1 ),
148  size() + QSize( 2, 2 ) ).toRect();
149  d->m_floatItemMoveStartPos = event->pos();
150  QRegion dirtyRegion( floatItemRect.toRect() );
151  dirtyRegion = dirtyRegion.united( newFloatItemRect );
152 
153  widget->setAttribute( Qt::WA_NoSystemBackground, false );
154  widget->update(dirtyRegion);
155  widget->setAttribute( Qt::WA_NoSystemBackground, widget->viewport()->mapCoversViewport() );
156  return true;
157  }
158 
159  if ( e->type() == QEvent::MouseButtonRelease ) {
160  d->m_floatItemMoving = false;
161  }
162 
163  // Use a special cursor as long as the item is moved
164  if (d->m_floatItemMoving) {
166  return true;
167  }
168  }
169 
170  return MarbleGraphicsItem::eventFilter( object, e );
171  }
172 }
QPoint pos() const const
QRect toRect() const const
void update()
A widget class that displays a view of the earth.
Definition: MarbleWidget.h:98
int x() const const
int y() const const
void setAttribute(Qt::WidgetAttribute attribute, bool on)
LeftButton
SizeAllCursor
Binds a QML item to a specific geodetic location in screen coordinates.
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
qreal x() const const
qreal y() const const
QEvent::Type type() const const
WA_NoSystemBackground
Q_D(Todo)
void setCursor(const QCursor &)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu May 26 2022 04:07:50 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.