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

marble

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