• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.14
  • kdeedu
  • marble
  • src
  • lib
  • marble
MarbleInputHandler.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
9 // Copyright 2007 Inge Wallin <ingwa@kde.org>
10 // Copyright 2014 Adam Dabrowski <adamdbrw@gmail.com>
11 //
12 
13 #include "MarbleInputHandler.h"
14 
15 #include <QPoint>
16 #include <QPointer>
17 #include <QTimer>
18 #include <QCursor>
19 #include <QMouseEvent>
20 #include <QPixmap>
21 #include <QGestureEvent>
22 #include <QPinchGesture>
23 
24 #include "kineticmodel.h"
25 #include "MarbleGlobal.h"
26 #include "MarbleDebug.h"
27 #include "GeoDataCoordinates.h"
28 #include "MarbleAbstractPresenter.h"
29 #include "ViewportParams.h"
30 #include "AbstractFloatItem.h"
31 #include "AbstractDataPluginItem.h"
32 #include "RenderPlugin.h"
33 
34 namespace Marble {
35 
36 const int TOOLTIP_START_INTERVAL = 1000;
37 
38 class MarbleInputHandler::Protected
39 {
40 public:
41  Protected(MarbleAbstractPresenter *marblePresenter);
42 
43  MarbleAbstractPresenter *const m_marblePresenter;
44  bool m_positionSignalConnected;
45  QTimer *m_mouseWheelTimer;
46  Qt::MouseButtons m_disabledMouseButtons;
47  qreal m_wheelZoomTargetDistance;
48  bool m_panViaArrowsEnabled;
49  bool m_inertialEarthRotation;
50 };
51 
52 MarbleInputHandler::Protected::Protected(MarbleAbstractPresenter *marblePresenter)
53  : m_marblePresenter( marblePresenter ),
54  m_positionSignalConnected( false ),
55  m_mouseWheelTimer( 0 ),
56  m_disabledMouseButtons( Qt::NoButton ),
57  m_wheelZoomTargetDistance( 0.0 ),
58  m_panViaArrowsEnabled( true ),
59  m_inertialEarthRotation( true )
60 {
61 }
62 
63 MarbleInputHandler::MarbleInputHandler(MarbleAbstractPresenter *marblePresenter)
64  : d(new Protected(marblePresenter))
65 {
66  d->m_mouseWheelTimer = new QTimer( this );
67  connect(d->m_mouseWheelTimer, SIGNAL(timeout()), this, SLOT(restoreViewContext()));
68 
69  connect(d->m_marblePresenter->map(), SIGNAL(renderPluginInitialized(RenderPlugin*)),
70  this, SLOT(installPluginEventFilter(RenderPlugin*)));
71 }
72 
73 MarbleInputHandler::~MarbleInputHandler()
74 {
75  delete d->m_mouseWheelTimer;
76  delete d;
77 }
78 
79 void MarbleInputHandler::setPositionSignalConnected(bool connected)
80 {
81  d->m_positionSignalConnected = connected;
82 }
83 
84 bool MarbleInputHandler::isPositionSignalConnected() const
85 {
86  return d->m_positionSignalConnected;
87 }
88 
89 void MarbleInputHandler::setMouseButtonPopupEnabled(Qt::MouseButton mouseButton, bool enabled)
90 {
91  if (enabled)
92  {
93  d->m_disabledMouseButtons &= ~Qt::MouseButtons(mouseButton);
94  }
95  else
96  {
97  d->m_disabledMouseButtons |= mouseButton;
98  }
99 }
100 
101 bool MarbleInputHandler::isMouseButtonPopupEnabled(Qt::MouseButton mouseButton) const
102 {
103  return !(d->m_disabledMouseButtons & mouseButton);
104 }
105 
106 void MarbleInputHandler::setPanViaArrowsEnabled(bool enabled)
107 {
108  d->m_panViaArrowsEnabled = enabled;
109 }
110 
111 bool MarbleInputHandler::panViaArrowsEnabled() const
112 {
113  return d->m_panViaArrowsEnabled;
114 }
115 
116 void MarbleInputHandler::setInertialEarthRotationEnabled(bool enabled)
117 {
118  d->m_inertialEarthRotation = enabled;
119 }
120 
121 bool MarbleInputHandler::inertialEarthRotationEnabled() const
122 {
123  return d->m_inertialEarthRotation;
124 }
125 
126 class MarbleDefaultInputHandler::Private
127 {
128  public:
129  Private();
130  ~Private();
131 
132  QPixmap m_curpmtl;
133  QPixmap m_curpmtc;
134  QPixmap m_curpmtr;
135  QPixmap m_curpmcr;
136  QPixmap m_curpmcl;
137  QPixmap m_curpmbl;
138  QPixmap m_curpmbc;
139  QPixmap m_curpmbr;
140 
141  QCursor m_arrowCur[3][3];
142 
143  // Indicates if the left mouse button has been pressed already.
144  bool m_leftPressed;
145  // Indicates whether the drag was started by a click above or below the visible pole.
146  int m_leftPressedDirection;
147  // Indicates if the middle mouse button has been pressed already.
148  bool m_midPressed;
149  // The mouse pointer x position when the left mouse button has been pressed.
150  int m_leftPressedX;
151  // The mouse pointer y position when the left mouse button has been pressed.
152  int m_leftPressedY;
153  // The mouse pointer y position when the middle mouse button has been pressed.
154  int m_midPressedY;
155  int m_startingRadius;
156  // The center longitude in radian when the left mouse button has been pressed.
157  qreal m_leftPressedLon;
158  // The center latitude in radian when the left mouse button has been pressed.
159  qreal m_leftPressedLat;
160 
161  int m_dragThreshold;
162  QTimer m_lmbTimer;
163 
164  // Models to handle the kinetic spinning.
165  KineticModel m_kineticSpinning;
166 
167  QPoint m_selectionOrigin;
168 
169  QPointer<AbstractDataPluginItem> m_lastToolTipItem;
170  QTimer m_toolTipTimer;
171  QPoint m_toolTipPosition;
172 };
173 
174 MarbleDefaultInputHandler::Private::Private()
175  : m_leftPressed(false),
176  m_midPressed(false),
177  m_dragThreshold(MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ? 15 : 3)
178 {
179  m_curpmtl.load( ":/marble/cursor/tl.png");
180  m_curpmtc.load( ":/marble/cursor/tc.png");
181  m_curpmtr.load( ":/marble/cursor/tr.png");
182  m_curpmcr.load( ":/marble/cursor/cr.png");
183  m_curpmcl.load( ":/marble/cursor/cl.png");
184  m_curpmbl.load( ":/marble/cursor/bl.png");
185  m_curpmbc.load( ":/marble/cursor/bc.png");
186  m_curpmbr.load( ":/marble/cursor/br.png");
187 
188  m_arrowCur[0][0] = QCursor( m_curpmtl, 2, 2 );
189  m_arrowCur[1][0] = QCursor( m_curpmtc, 10, 3 );
190  m_arrowCur[2][0] = QCursor( m_curpmtr, 19, 2 );
191  m_arrowCur[0][1] = QCursor( m_curpmcl, 3, 10 );
192  m_arrowCur[1][1] = QCursor( Qt::OpenHandCursor );
193  m_arrowCur[2][1] = QCursor( m_curpmcr, 18, 10 );
194  m_arrowCur[0][2] = QCursor( m_curpmbl, 2, 19 );
195  m_arrowCur[1][2] = QCursor( m_curpmbc, 11, 18 );
196  m_arrowCur[2][2] = QCursor( m_curpmbr, 19, 19 );
197 }
198 
199 MarbleDefaultInputHandler::Private::~Private()
200 {
201 }
202 
203 MarbleDefaultInputHandler::MarbleDefaultInputHandler(MarbleAbstractPresenter *marblePresenter)
204  : MarbleInputHandler(marblePresenter),
205  d(new Private())
206 {
207  d->m_toolTipTimer.setSingleShot(true);
208  d->m_toolTipTimer.setInterval(TOOLTIP_START_INTERVAL);
209  connect(&d->m_toolTipTimer, SIGNAL(timeout()), this, SLOT(openItemToolTip()));
210  d->m_lmbTimer.setSingleShot(true);
211  connect(&d->m_lmbTimer, SIGNAL(timeout()), this, SLOT(lmbTimeout()));
212 
213  d->m_kineticSpinning.setUpdateInterval(35);
214  connect(&d->m_kineticSpinning, SIGNAL(positionChanged(qreal,qreal)),
215  MarbleInputHandler::d->m_marblePresenter, SLOT(centerOn(qreal,qreal)));
216  connect(&d->m_kineticSpinning, SIGNAL(finished()), SLOT(restoreViewContext()));
217 
218  // Left and right mouse button signals.
219  connect(this, SIGNAL(rmbRequest(int,int)), this, SLOT(showRmbMenu(int,int)));
220  connect(this, SIGNAL(lmbRequest(int,int)), this, SLOT(showLmbMenu(int,int)));
221 }
222 
223 MarbleDefaultInputHandler::~MarbleDefaultInputHandler()
224 {
225  delete d;
226 }
227 
228 void MarbleDefaultInputHandler::lmbTimeout()
229 {
230  if (!selectionRubber()->isVisible())
231  {
232  emit lmbRequest(d->m_leftPressedX, d->m_leftPressedY);
233  }
234 }
235 
236 void MarbleInputHandler::restoreViewContext()
237 {
238  // Needs to stop the timer since it repeats otherwise.
239  d->m_mouseWheelTimer->stop();
240 
241  // Redraw the map with the quality set for Still (if necessary).
242  d->m_marblePresenter->setViewContext(Still);
243  d->m_marblePresenter->map()->viewport()->resetFocusPoint();
244  d->m_wheelZoomTargetDistance = 0.0;
245 }
246 
247 void MarbleDefaultInputHandler::hideSelectionIfCtrlReleased(QEvent *e)
248 {
249  if (selectionRubber()->isVisible() && e->type() == QEvent::MouseMove)
250  {
251  QMouseEvent *event = static_cast<QMouseEvent*>(e);
252  if (!(event->modifiers() & Qt::ControlModifier))
253  {
254  selectionRubber()->hide();
255  }
256  }
257 }
258 
259 bool MarbleDefaultInputHandler::handleDoubleClick(QMouseEvent *event)
260 {
261  d->m_lmbTimer.stop();
262  MarbleInputHandler::d->m_marblePresenter->moveTo(event->pos(), 0.67);
263  MarbleInputHandler::d->m_mouseWheelTimer->start(400);
264  return acceptMouse();
265 }
266 
267 bool MarbleDefaultInputHandler::handleWheel(QWheelEvent *wheelevt)
268 {
269  MarbleAbstractPresenter *marblePresenter = MarbleInputHandler::d->m_marblePresenter;
270  marblePresenter->setViewContext(Animation);
271 
272  int steps = wheelevt->delta() / 3;
273  qreal zoom = marblePresenter->zoom();
274  qreal target = MarbleInputHandler::d->m_wheelZoomTargetDistance;
275  if (marblePresenter->animationsEnabled() && target > 0.0)
276  {
277  // Do not use intermediate (interpolated) distance values caused by animations
278  zoom = marblePresenter->zoomFromDistance(target);
279  }
280  qreal newDistance = marblePresenter->distanceFromZoom(zoom + steps);
281  MarbleInputHandler::d->m_wheelZoomTargetDistance = newDistance;
282  marblePresenter->zoomAt(wheelevt->pos(), newDistance);
283  if (MarbleInputHandler::d->m_inertialEarthRotation)
284  {
285  d->m_kineticSpinning.jumpToPosition(MarbleInputHandler::d->m_marblePresenter->centerLongitude(),
286  MarbleInputHandler::d->m_marblePresenter->centerLatitude());
287  }
288 
289  MarbleInputHandler::d->m_mouseWheelTimer->start(400);
290  return true;
291 }
292 
293 bool MarbleDefaultInputHandler::handlePinch(QPointF center, qreal scaleFactor, Qt::GestureState state)
294 {
295  qreal destLat;
296  qreal destLon;
297  MarbleAbstractPresenter *marblePresenter = MarbleInputHandler::d->m_marblePresenter;
298 
299  bool isValid = marblePresenter->map()->geoCoordinates(center.x(), center.y(),
300  destLon, destLat, GeoDataCoordinates::Radian );
301 
302  if (isValid)
303  {
304  marblePresenter->map()->viewport()->setFocusPoint(GeoDataCoordinates(destLon, destLat));
305  }
306 
307  switch (state)
308  {
309  case Qt::NoGesture:
310  break;
311  case Qt::GestureStarted:
312  marblePresenter->setViewContext(Animation);
313  d->m_midPressed = false;
314  d->m_leftPressed = false;
315  d->m_startingRadius = marblePresenter->radius();
316  break;
317  case Qt::GestureUpdated:
318  marblePresenter->setRadius(marblePresenter->radius() * scaleFactor);
319  break;
320  case Qt::GestureFinished:
321  marblePresenter->map()->viewport()->resetFocusPoint();
322  marblePresenter->setViewContext(Still);
323  break;
324  case Qt::GestureCanceled:
325  marblePresenter->setRadius(d->m_startingRadius);
326  marblePresenter->map()->viewport()->resetFocusPoint();
327  marblePresenter->setViewContext(Still);
328  break;
329  }
330  return true;
331 }
332 
333 bool MarbleDefaultInputHandler::handleGesture(QGestureEvent *ge)
334 {
335  QPinchGesture *pinch = static_cast<QPinchGesture*>(ge->gesture(Qt::PinchGesture));
336  if (!pinch)
337  {
338  return false;
339  }
340 
341  qreal scaleFactor = pinch->scaleFactor();
342  QPointF center = pinch->centerPoint();
343 
344  return handlePinch(center, scaleFactor, pinch->state());
345 }
346 
347 void MarbleDefaultInputHandler::checkReleasedMove(QMouseEvent *event)
348 {
349  // To prevent error from lost MouseButtonRelease events
350  if (event->type() == QEvent::MouseMove && !(event->buttons() & Qt::LeftButton))
351  {
352  if (d->m_leftPressed)
353  {
354  d->m_leftPressed = false;
355 
356  if (MarbleInputHandler::d->m_inertialEarthRotation)
357  {
358  d->m_kineticSpinning.start();
359  }
360  else
361  {
362  MarbleInputHandler::d->m_marblePresenter->setViewContext(Still);
363  }
364  }
365  }
366  if (event->type() == QEvent::MouseMove && !(event->buttons() & Qt::MidButton))
367  {
368  d->m_midPressed = false;
369  }
370 }
371 
372 void MarbleDefaultInputHandler::handleMouseButtonPress(QMouseEvent *event)
373 {
374  if (event->button() == Qt::LeftButton )
375  {
376  handleLeftMouseButtonPress(event);
377  }
378 
379  if ( event->button() == Qt::MidButton )
380  {
381  handleMiddleMouseButtonPress(event);
382  }
383 
384  if ( event->button() == Qt::RightButton )
385  {
386  handleRightMouseButtonPress(event);
387  }
388 }
389 
390 void MarbleDefaultInputHandler::handleLeftMouseButtonPress(QMouseEvent *event)
391 {
392  if (isMouseButtonPopupEnabled(Qt::LeftButton))
393  {
394  d->m_lmbTimer.start(400);
395  }
396 
397  d->m_leftPressed = true;
398  d->m_midPressed = false;
399  selectionRubber()->hide();
400 
401  // On the single event of a mouse button press these
402  // values get stored, to enable us to e.g. calculate the
403  // distance of a mouse drag while the mouse button is
404  // still down.
405  d->m_leftPressedX = event->x();
406  d->m_leftPressedY = event->y();
407 
408  // Calculate translation of center point
409  d->m_leftPressedLon = MarbleInputHandler::d->m_marblePresenter->centerLongitude();
410  d->m_leftPressedLat = MarbleInputHandler::d->m_marblePresenter->centerLatitude();
411 
412  d->m_leftPressedDirection = 1;
413 
414  if (MarbleInputHandler::d->m_inertialEarthRotation)
415  {
416  d->m_kineticSpinning.stop();
417  d->m_kineticSpinning.setPosition(d->m_leftPressedLon, d->m_leftPressedLat);
418  }
419 
420  // Choose spin direction by taking into account whether we
421  // drag above or below the visible pole.
422  if (MarbleInputHandler::d->m_marblePresenter->map()->projection() == Spherical)
423  {
424  if (d->m_leftPressedLat >= 0)
425  { // The visible pole is the north pole
426  qreal northPoleX, northPoleY;
427  MarbleInputHandler::d->m_marblePresenter->map()->screenCoordinates(0.0, 90.0, northPoleX, northPoleY);
428  if (event->y() < northPoleY)
429  {
430  d->m_leftPressedDirection = -1;
431  }
432  }
433  else
434  { // The visible pole is the south pole
435  qreal southPoleX, southPoleY;
436  MarbleInputHandler::d->m_marblePresenter->map()->screenCoordinates(0.0, -90.0, southPoleX, southPoleY);
437  if (event->y() > southPoleY)
438  {
439  d->m_leftPressedDirection = -1;
440  }
441  }
442  }
443 
444  MarbleInputHandler::d->m_marblePresenter->setViewContext(Animation);
445 
446  if (event->modifiers() & Qt::ControlModifier)
447  {
448  qDebug("Marble: Starting selection");
449  d->m_lmbTimer.stop();
450  d->m_selectionOrigin = event->pos();
451  selectionRubber()->setGeometry(QRect(d->m_selectionOrigin, QSize()));
452  selectionRubber()->show();
453  }
454 }
455 
456 void MarbleDefaultInputHandler::handleMiddleMouseButtonPress(QMouseEvent *event)
457 {
458  d->m_midPressed = true;
459  d->m_leftPressed = false;
460  d->m_startingRadius = MarbleInputHandler::d->m_marblePresenter->radius();
461  d->m_midPressedY = event->y();
462 
463  if (MarbleInputHandler::d->m_inertialEarthRotation)
464  {
465  d->m_kineticSpinning.start();
466  }
467 
468  selectionRubber()->hide();
469  MarbleInputHandler::d->m_marblePresenter->setViewContext(Animation);
470 }
471 
472 void MarbleDefaultInputHandler::handleRightMouseButtonPress(QMouseEvent *event)
473 {
474  emit rmbRequest(event->x(), event->y());
475 }
476 
477 void MarbleDefaultInputHandler::handleMouseButtonRelease(QMouseEvent *event)
478 {
479  if (event->button() == Qt::LeftButton)
480  {
481  //emit current coordinates to be be interpreted
482  //as requested
483  emit mouseClickScreenPosition(d->m_leftPressedX, d->m_leftPressedY);
484 
485  d->m_leftPressed = false;
486  if (MarbleInputHandler::d->m_inertialEarthRotation)
487  {
488  d->m_kineticSpinning.start();
489  }
490  else
491  {
492  MarbleInputHandler::d->m_marblePresenter->setViewContext(Still);
493  }
494  }
495 
496  if (event->button() == Qt::MidButton)
497  {
498  d->m_midPressed = false;
499 
500  MarbleInputHandler::d->m_marblePresenter->setViewContext(Still);
501  }
502 
503  if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::RightButton)
504  {
505  }
506 
507  if (event->type() == QEvent::MouseButtonRelease && event->button() == Qt::LeftButton
508  && selectionRubber()->isVisible())
509  {
510  qDebug("Marble: Leaving selection");
511  MarbleInputHandler::d->m_marblePresenter->setSelection(selectionRubber()->geometry());
512  selectionRubber()->hide();
513  }
514 }
515 
516 void MarbleDefaultInputHandler::notifyPosition(bool isMouseAboveMap, qreal mouseLon, qreal mouseLat)
517 {
518  // emit the position string only if the signal got attached
519  if (MarbleInputHandler::d->m_positionSignalConnected) {
520  if (!isMouseAboveMap)
521  {
522  emit mouseMoveGeoPosition(tr(NOT_AVAILABLE));
523  }
524  else
525  {
526  QString position = GeoDataCoordinates(mouseLon, mouseLat).toString();
527  emit mouseMoveGeoPosition(position);
528  }
529  }
530 }
531 
532 void MarbleDefaultInputHandler::adjustCursorShape(const QPoint &mousePosition, const QPoint &mouseDirection)
533 {
534  // Find out if there are data items and if one has defined an action
535  QList<AbstractDataPluginItem *> dataItems
536  = MarbleInputHandler::d->m_marblePresenter->map()->whichItemAt(mousePosition);
537  bool dataAction = false;
538  QPointer<AbstractDataPluginItem> toolTipItem;
539  QList<AbstractDataPluginItem *>::iterator it = dataItems.begin();
540  QList<AbstractDataPluginItem *>::iterator const end = dataItems.end();
541  for (; it != end && dataAction == false && toolTipItem.isNull(); ++it)
542  {
543  if ((*it)->action())
544  {
545  dataAction = true;
546  }
547 
548  if (!(*it)->toolTip().isNull() && toolTipItem.isNull())
549  {
550  toolTipItem = (*it);
551  }
552  }
553 
554  if (toolTipItem.isNull()) {
555  d->m_toolTipTimer.stop();
556  }
557  else if (!( d->m_lastToolTipItem.data() == toolTipItem.data()))
558  {
559  d->m_toolTipTimer.start();
560  d->m_lastToolTipItem = toolTipItem;
561  d->m_toolTipPosition = mousePosition;
562  }
563  else
564  {
565  if (!d->m_toolTipTimer.isActive())
566  {
567  d->m_toolTipTimer.start();
568  }
569  d->m_toolTipPosition = mousePosition;
570  }
571 
572  if ((MarbleInputHandler::d->m_marblePresenter->map()->whichFeatureAt(mousePosition).size() == 0)
573  && (!dataAction ))
574  {
575  if (!d->m_leftPressed)
576  {
577  d->m_arrowCur [1][1] = QCursor(Qt::OpenHandCursor);
578  }
579  else
580  {
581  d->m_arrowCur [1][1] = QCursor(Qt::ClosedHandCursor);
582  }
583  }
584  else
585  {
586  if (!d->m_leftPressed)
587  {
588  d->m_arrowCur [1][1] = QCursor(Qt::PointingHandCursor);
589  }
590  }
591 
592 #ifndef Q_WS_MAEMO_5
593  if (panViaArrowsEnabled())
594  {
595  setCursor(d->m_arrowCur[mouseDirection.x()+1][mouseDirection.y()+1]);
596  }
597  else
598  {
599  setCursor(d->m_arrowCur[1][1]);
600  }
601 #endif
602 }
603 
604 QPoint MarbleDefaultInputHandler::mouseMovedOutside(QMouseEvent *event)
605 { //Returns a 2d vector representing the direction in which the mouse left
606  int dirX = 0;
607  int dirY = 0;
608  int polarity = MarbleInputHandler::d->m_marblePresenter->viewport()->polarity();
609 
610  d->m_leftPressed = false;
611 
612  if (MarbleInputHandler::d->m_inertialEarthRotation)
613  {
614  d->m_kineticSpinning.start();
615  }
616 
617  QRect boundingRect = MarbleInputHandler::d->m_marblePresenter->viewport()->mapRegion().boundingRect();
618 
619  if (boundingRect.width() != 0)
620  {
621  dirX = (int)( 3 * (event->x() - boundingRect.left()) / boundingRect.width()) - 1;
622  }
623  if (dirX > 1)
624  {
625  dirX = 1;
626  }
627  if (dirX < -1)
628  {
629  dirX = -1;
630  }
631 
632  if (boundingRect.height() != 0)
633  {
634  dirY = (int)(3 * (event->y() - boundingRect.top()) / boundingRect.height()) - 1;
635  }
636  if (dirY > 1)
637  {
638  dirY = 1;
639  }
640  if (dirY < -1)
641  {
642  dirY = -1;
643  }
644 
645  if (event->button() == Qt::LeftButton && event->type() == QEvent::MouseButtonPress
646  && panViaArrowsEnabled())
647  {
648  d->m_lmbTimer.stop();
649  qreal moveStep = MarbleInputHandler::d->m_marblePresenter->moveStep();
650  if (polarity < 0)
651  {
652  MarbleInputHandler::d->m_marblePresenter->rotateBy(-moveStep * (qreal)(+dirX), moveStep * (qreal)(+dirY));
653  }
654  else
655  {
656  MarbleInputHandler::d->m_marblePresenter->rotateBy(-moveStep * (qreal)(-dirX), moveStep * (qreal)(+dirY));
657  }
658  }
659 
660  if (!MarbleInputHandler::d->m_inertialEarthRotation)
661  {
662  MarbleInputHandler::d->m_marblePresenter->setViewContext(Still);
663  }
664 
665  return QPoint(dirX, dirY);
666 }
667 
668 bool MarbleDefaultInputHandler::handleMouseEvent(QMouseEvent *event)
669 {
670  QPoint direction;
671 
672  checkReleasedMove(event);
673 
674  // Do not handle (and therefore eat) mouse press and release events
675  // that occur above visible float items. Mouse motion events are still
676  // handled, however.
677  if (event->type() != QEvent::MouseMove && !selectionRubber()->isVisible())
678  {
679  foreach (AbstractFloatItem *floatItem, MarbleInputHandler::d->m_marblePresenter->map()->floatItems())
680  {
681  if ( floatItem->enabled() && floatItem->visible()
682  && floatItem->contains( event->pos() ) )
683  {
684  d->m_lmbTimer.stop();
685  return false;
686  }
687  }
688  }
689 
690  qreal mouseLon;
691  qreal mouseLat;
692  const bool isMouseAboveMap = MarbleInputHandler::d->m_marblePresenter->map()->geoCoordinates(event->x(), event->y(),
693  mouseLon, mouseLat, GeoDataCoordinates::Radian);
694  notifyPosition(isMouseAboveMap, mouseLon, mouseLat);
695 
696  QPoint mousePosition(event->x(), event->y());
697 
698  if (isMouseAboveMap || selectionRubber()->isVisible()
699  || MarbleInputHandler::d->m_marblePresenter->map()->whichFeatureAt( mousePosition ).size() != 0)
700  {
701  if (event->type() == QEvent::MouseButtonPress)
702  {
703  handleMouseButtonPress(event);
704  }
705 
706  if (event->type() == QEvent::MouseButtonRelease)
707  {
708  handleMouseButtonRelease(event);
709  }
710 
711  // Regarding all kinds of mouse moves:
712  if (d->m_leftPressed && !selectionRubber()->isVisible())
713  {
714  qreal radius = (qreal)(MarbleInputHandler::d->m_marblePresenter->radius());
715  int deltax = event->x() - d->m_leftPressedX;
716  int deltay = event->y() - d->m_leftPressedY;
717 
718  if (abs(deltax) > d->m_dragThreshold
719  || abs(deltay) > d->m_dragThreshold
720  || !d->m_lmbTimer.isActive())
721  {
722  d->m_lmbTimer.stop();
723 
724  const qreal posLon = d->m_leftPressedLon - 90.0 * d->m_leftPressedDirection * deltax / radius;
725  const qreal posLat = d->m_leftPressedLat + 90.0 * deltay / radius;
726  MarbleInputHandler::d->m_marblePresenter->centerOn(posLon, posLat);
727  if (MarbleInputHandler::d->m_inertialEarthRotation)
728  {
729  d->m_kineticSpinning.setPosition(posLon, posLat);
730  }
731  }
732  }
733 
734  if (d->m_midPressed)
735  {
736  int eventy = event->y();
737  int dy = d->m_midPressedY - eventy;
738  MarbleInputHandler::d->m_marblePresenter->setRadius(d->m_startingRadius * pow(1.005, dy));
739  }
740 
741  if (selectionRubber()->isVisible())
742  {
743  // We change selection.
744  selectionRubber()->setGeometry(QRect(d->m_selectionOrigin, event->pos()).normalized());
745  }
746  }
747  else
748  {
749  direction = mouseMovedOutside(event);
750  }
751 
752  adjustCursorShape(mousePosition, direction);
753  return acceptMouse();
754 }
755 
756 bool MarbleDefaultInputHandler::acceptMouse()
757 {
758  // let others, especially float items, still process the event
759  // Note: This caused a bug in combination with oxygen, see https://bugs.kde.org/show_bug.cgi?id=242414
760  // and changing it a related regression, see https://bugs.kde.org/show_bug.cgi?id=324862
761  return false;
762 }
763 
764 bool MarbleDefaultInputHandler::eventFilter(QObject* o, QEvent* e)
765 {
766  Q_UNUSED(o);
767 
768  if (layersEventFilter(o, e))
769  {
770  return true;
771  }
772 
773  hideSelectionIfCtrlReleased(e);
774 
775  switch (e->type())
776  {
777  case QEvent::TouchBegin:
778  case QEvent::TouchUpdate:
779  case QEvent::TouchEnd:
780  return handleTouch(static_cast<QTouchEvent *>(e));
781  case QEvent::KeyPress:
782  return handleKeyPress(static_cast<QKeyEvent *>(e));
783  case QEvent::Gesture:
784  return handleGesture(static_cast<QGestureEvent *>(e));
785  case QEvent::Wheel:
786  return handleWheel(static_cast<QWheelEvent*>(e));
787  case QEvent::MouseButtonDblClick:
788  return handleDoubleClick(static_cast<QMouseEvent*>(e));
789  case QEvent::MouseButtonPress:
790  case QEvent::MouseButtonRelease:
791  case QEvent::MouseMove:
792  return handleMouseEvent(static_cast<QMouseEvent*>(e));
793  default:
794  return false;
795  }
796 }
797 
798 bool MarbleDefaultInputHandler::handleTouch(QTouchEvent*)
799 {
800  return false; //reimplement to handle in cases of QML and PinchArea element
801 }
802 
803 bool MarbleDefaultInputHandler::handleKeyPress(QKeyEvent* event)
804 {
805  if ( event->type() == QEvent::KeyPress ) {
806  MarbleAbstractPresenter *marblePresenter = MarbleInputHandler::d->m_marblePresenter;
807  bool handled = true;
808  switch ( event->key() ) {
809  case Qt::Key_Left:
810  marblePresenter->moveByStep(-1, 0);
811  break;
812  case Qt::Key_Right:
813  marblePresenter->moveByStep(1, 0);
814  break;
815  case Qt::Key_Up:
816  marblePresenter->moveByStep(0, -1);
817  break;
818  case Qt::Key_Down:
819  marblePresenter->moveByStep(0, 1);
820  break;
821  case Qt::Key_Plus:
822  marblePresenter->zoomIn();
823  break;
824  case Qt::Key_Minus:
825  marblePresenter->zoomOut();
826  break;
827  case Qt::Key_Home:
828  marblePresenter->goHome();
829  break;
830  default:
831  handled = false;
832  break;
833  }
834 
835  return handled;
836  }
837  return false;
838 }
839 
840 QPointer<AbstractDataPluginItem> MarbleDefaultInputHandler::lastToolTipItem()
841 {
842  return d->m_lastToolTipItem;
843 }
844 
845 QTimer* MarbleDefaultInputHandler::toolTipTimer()
846 {
847  return &d->m_toolTipTimer;
848 }
849 
850 QPoint MarbleDefaultInputHandler::toolTipPosition()
851 {
852  return d->m_toolTipPosition;
853 }
854 
855 }
856 
857 #include "MarbleInputHandler.moc"
858 
GeoDataCoordinates.h
Marble::RenderPlugin::enabled
bool enabled
Definition: RenderPlugin.h:51
QEvent
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
Marble::MarbleInputHandler::isMouseButtonPopupEnabled
bool isMouseButtonPopupEnabled(Qt::MouseButton mouseButton) const
Return whether the left mouse button popup menu is active.
Definition: MarbleInputHandler.cpp:101
Marble::AbstractFloatItem::visible
bool visible() const
Check visibility of the float item.
Definition: AbstractFloatItem.cpp:137
Marble::MarbleInputHandler::mouseClickScreenPosition
void mouseClickScreenPosition(int, int)
QGesture::state
state
QEvent::type
Type type() const
Marble::GeoDataCoordinates::Radian
Definition: GeoDataCoordinates.h:65
QPointer::data
T * data() const
Marble::MarbleAbstractPresenter::setRadius
void setRadius(int radius)
Definition: MarbleAbstractPresenter.cpp:316
Marble::MarbleDefaultInputHandler::handleMouseEvent
bool handleMouseEvent(QMouseEvent *e)
Definition: MarbleInputHandler.cpp:668
Marble::MarbleDefaultInputHandler::lastToolTipItem
QPointer< AbstractDataPluginItem > lastToolTipItem()
Definition: MarbleInputHandler.cpp:840
Marble::MarbleDefaultInputHandler::~MarbleDefaultInputHandler
virtual ~MarbleDefaultInputHandler()
Definition: MarbleInputHandler.cpp:223
Marble::MarbleInputHandler::isPositionSignalConnected
bool isPositionSignalConnected() const
Definition: MarbleInputHandler.cpp:84
QMouseEvent::x
int x() const
QMouseEvent::y
int y() const
AbstractFloatItem.h
QPointer
QWheelEvent
KineticModel
Definition: kineticmodel.h:39
QRect::height
int height() const
Marble::MarbleInputHandler::setInertialEarthRotationEnabled
void setInertialEarthRotationEnabled(bool enabled)
Definition: MarbleInputHandler.cpp:116
Marble::MarbleInputHandler::mouseMoveGeoPosition
void mouseMoveGeoPosition(QString)
QPoint
QMouseEvent
QWheelEvent::pos
const QPoint & pos() const
Marble::MarbleAbstractPresenter::radius
int radius() const
Definition: MarbleAbstractPresenter.cpp:311
Marble::MarbleInputHandler::lmbRequest
void lmbRequest(int, int)
QGestureEvent
MarbleDebug.h
Marble::MarbleInputHandler::panViaArrowsEnabled
bool panViaArrowsEnabled() const
Definition: MarbleInputHandler.cpp:111
QObject::tr
QString tr(const char *sourceText, const char *disambiguation, int n)
Marble::MarbleMap::viewport
ViewportParams * viewport()
Definition: MarbleMap.cpp:288
Marble::MarbleDefaultInputHandler::MarbleDefaultInputHandler
MarbleDefaultInputHandler(MarbleAbstractPresenter *marblePresenter)
Definition: MarbleInputHandler.cpp:203
QPoint::x
int x() const
QPoint::y
int y() const
QGestureEvent::gesture
QGesture * gesture(Qt::GestureType type) const
QPointF
QObject::event
virtual bool event(QEvent *e)
Marble::AbstractSelectionRubber::setGeometry
virtual void setGeometry(const QRect &geometry)=0
QRect
MarbleInputHandler.h
Marble::ViewportParams::setFocusPoint
void setFocusPoint(const GeoDataCoordinates &focusPoint)
Change the point of focus, overridding any previously set focus point.
Definition: ViewportParams.cpp:427
Marble::MarbleInputHandler::restoreViewContext
void restoreViewContext()
Definition: MarbleInputHandler.cpp:236
Marble::MarbleGraphicsItem::contains
bool contains(const QPointF &point) const
Returns true if the Item contains point in parent coordinates.
Definition: MarbleGraphicsItem.cpp:110
QPointF::x
qreal x() const
QPointF::y
qreal y() const
Marble::Animation
animated view (e.g. while rotating the globe)
Definition: MarbleGlobal.h:76
QTimer
QRect::top
int top() const
QObject
QPinchGesture::scaleFactor
scaleFactor
QPointer::isNull
bool isNull() const
Marble::AbstractFloatItem
The abstract class for float item plugins.
Definition: AbstractFloatItem.h:45
Marble::AbstractSelectionRubber::hide
virtual void hide()=0
QRect::left
int left() const
QMouseEvent::button
Qt::MouseButton button() const
Marble::radius
static qreal radius(qreal zoom)
Definition: thumbnailer.cpp:99
Marble::Still
still image
Definition: MarbleGlobal.h:75
Marble::MarbleInputHandler::inertialEarthRotationEnabled
bool inertialEarthRotationEnabled() const
Returns true iff dragging the map with the mouse keeps spinning in the chosen direction for a slightl...
Definition: MarbleInputHandler.cpp:121
Marble::NOT_AVAILABLE
static const char NOT_AVAILABLE[]
Definition: MarbleGlobal.h:251
QString
QList< AbstractDataPluginItem * >
MarbleGlobal.h
abs
double abs(const Vec3 &c)
Definition: attlib.cpp:100
MarbleAbstractPresenter.h
Marble::MarbleInputHandler::rmbRequest
void rmbRequest(int, int)
Marble::ViewportParams::resetFocusPoint
void resetFocusPoint()
Invalidate any focus point set with setFocusPoint.
Definition: ViewportParams.cpp:432
QPinchGesture::centerPoint
centerPoint
Marble::MarbleMap::geoCoordinates
bool geoCoordinates(int x, int y, qreal &lon, qreal &lat, GeoDataCoordinates::Unit=GeoDataCoordinates::Degree) const
Get the earth coordinates corresponding to a pixel in the map.
Definition: MarbleMap.cpp:686
QPixmap
QInputEvent::modifiers
Qt::KeyboardModifiers modifiers() const
Marble::MarbleDefaultInputHandler::toolTipTimer
QTimer * toolTipTimer()
Definition: MarbleInputHandler.cpp:845
QList::end
iterator end()
QKeyEvent::key
int key() const
QSize
ViewportParams.h
This file contains the headers for ViewportParams.
QWheelEvent::delta
int delta() const
QKeyEvent
Marble::MarbleDefaultInputHandler::eventFilter
bool eventFilter(QObject *, QEvent *)
Definition: MarbleInputHandler.cpp:764
kineticmodel.h
direction
qreal direction
Definition: tools/osm-addresses/OsmParser.cpp:40
QRect::width
int width() const
Qt::MouseButtons
typedef MouseButtons
Marble::MarbleInputHandler::~MarbleInputHandler
virtual ~MarbleInputHandler()
Definition: MarbleInputHandler.cpp:73
RenderPlugin.h
Marble::MarbleAbstractPresenter::map
MarbleMap * map()
Definition: MarbleAbstractPresenter.cpp:544
Marble::MarbleAbstractPresenter
Definition: MarbleAbstractPresenter.h:26
Marble::AbstractSelectionRubber::show
virtual void show()=0
QMouseEvent::pos
const QPoint & pos() const
Marble::AbstractSelectionRubber::isVisible
virtual bool isVisible() const =0
Marble::MarbleDefaultInputHandler::toolTipPosition
QPoint toolTipPosition()
Definition: MarbleInputHandler.cpp:850
Marble::MarbleInputHandler::setMouseButtonPopupEnabled
void setMouseButtonPopupEnabled(Qt::MouseButton mouseButton, bool enabled)
The MarbleInputHandler handles mouse and keyboard input.
Definition: MarbleInputHandler.cpp:89
Marble::Spherical
Spherical projection.
Definition: MarbleGlobal.h:45
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Marble::MarbleInputHandler::setPositionSignalConnected
void setPositionSignalConnected(bool connected)
Definition: MarbleInputHandler.cpp:79
QCursor
Marble::MarbleDefaultInputHandler::handlePinch
bool handlePinch(QPointF center, qreal scaleFactor, Qt::GestureState state)
Definition: MarbleInputHandler.cpp:293
QTouchEvent
Marble::RenderPlugin
The abstract class that creates a renderable item.
Definition: RenderPlugin.h:43
QList::begin
iterator begin()
AbstractDataPluginItem.h
Marble::MarbleInputHandler::d
Protected *const d
Definition: MarbleInputHandler.h:94
Marble::MarbleInputHandler::setPanViaArrowsEnabled
void setPanViaArrowsEnabled(bool enabled)
Definition: MarbleInputHandler.cpp:106
Marble::TOOLTIP_START_INTERVAL
const int TOOLTIP_START_INTERVAL
Definition: MarbleInputHandler.cpp:36
Marble::MarbleInputHandler
Definition: MarbleInputHandler.h:41
Marble::MarbleAbstractPresenter::setViewContext
void setViewContext(ViewContext viewContext)
Definition: MarbleAbstractPresenter.cpp:497
QPinchGesture
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:40 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal