libosmscout  1.1.1
InputHandler.h
Go to the documentation of this file.
1 #ifndef OSMSCOUT_CLIENT_QT_INPUTHANDLER_H
2 #define OSMSCOUT_CLIENT_QT_INPUTHANDLER_H
3 
4 /*
5  OSMScout - a Qt backend for libosmscout and libosmscout-map
6  Copyright (C) 2016 Lukas Karas
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21  */
22 
23 #include <QObject>
24 #include <QVector2D>
25 #include <QTouchEvent>
26 #include <QTimer>
27 #include <QElapsedTimer>
28 #include <QQueue>
29 
30 #include <osmscout/util/Bearing.h>
31 #include <osmscout/util/GeoBox.h>
33 
36 
37 namespace osmscout {
38 
58 class OSMSCOUT_CLIENT_QT_API TapRecognizer : public QObject{
59  Q_OBJECT
60 
61 private:
62  enum TapRecState{
63  INACTIVE = 0,
64  PRESSED = 1, // timer started with hold interval, if expired - long-tap is emitted
65  RELEASED = 2, // timer started with tap interval, if expired - tap is emitted
66  PRESSED2 = 3, // timer started with hold interval, if expired - tap-long-tap
67  };
68 
69  int startFingerId;
70  int startX;
71  int startY;
72 
73  QTimer timer;
74  TapRecState state;
75  int holdIntervalMs;
76  int hold2IntervalMs;
77  int tapIntervalMs;
78  int moveTolerance;
79 
80 private slots:
81  void onTimeout();
82 
83 public:
84  inline TapRecognizer():
85  state(INACTIVE),
86  holdIntervalMs(1000),
87  hold2IntervalMs(500),
88  tapIntervalMs(200),
89  moveTolerance(15)
90  {
91  timer.setSingleShot(true);
92  connect(&timer, &QTimer::timeout, this, &TapRecognizer::onTimeout);
93  }
94 
95  ~TapRecognizer() override = default;
96 
97  void touch(const QTouchEvent &event);
98 
99  inline void setPhysicalDpi(double physicalDpi)
100  {
101  moveTolerance = physicalDpi / 10.0; // ~ 2.5 mm
102  }
103 
104 signals:
105  void tap(const QPoint p);
106  void doubleTap(const QPoint p);
107  void longTap(const QPoint p);
108  void tapLongTap(const QPoint p);
109  void tapAndDrag(const QPoint p);
110 };
111 
116 {
117  QPointF pos;
118  QElapsedTimer time;
119 };
120 
128 class MoveAccumulator : public QObject{
129  Q_OBJECT
130 
131 private:
132  int memory; // ms
133  QQueue<AccumulatorEvent> events;
134  double factor;
135  double vectorLengthTreshold;
136 
137 public:
138 
145  inline MoveAccumulator(int memory = 100, double factor = 4, double vectorLengthTreshold = 5):
146  memory(memory), factor(factor), vectorLengthTreshold(vectorLengthTreshold)
147  {
148  }
149  ~MoveAccumulator() override = default;
150 
151  MoveAccumulator& operator+=(const QPointF p);
152  QVector2D collect();
153 };
154 
160 class OSMSCOUT_CLIENT_QT_API MapView: public QObject
161 {
162  Q_OBJECT
163 
164  Q_PROPERTY(double lat READ GetLat CONSTANT)
165  Q_PROPERTY(double lon READ GetLon CONSTANT)
166  Q_PROPERTY(double angle READ GetAngle CONSTANT)
167  Q_PROPERTY(double mag READ GetMag CONSTANT)
168  Q_PROPERTY(uint32_t magLevel READ GetMagLevel CONSTANT)
169  Q_PROPERTY(double mapDpi READ GetMapDpi CONSTANT)
170 
171 public:
172  explicit inline MapView(QObject *parent=nullptr): QObject(parent) {}
173 
174  inline MapView(QObject *parent,
175  const osmscout::GeoCoord &center,
176  const Bearing &angle,
177  const osmscout::Magnification &magnification,
178  double mapDpi):
179  QObject(parent), center(center), angle(angle), magnification(magnification), mapDpi(mapDpi) {}
180 
181  inline MapView(const osmscout::GeoCoord &center,
182  const Bearing &angle,
183  const osmscout::Magnification &magnification,
184  double mapDpi):
185  center(center), angle(angle), magnification(magnification), mapDpi(mapDpi) {}
186 
192  inline MapView(const MapView &mv):
193  QObject(), center(mv.center), angle(mv.angle), magnification(mv.magnification), mapDpi(mv.mapDpi) {}
194 
195  ~MapView() override = default;
196 
197  inline double GetLat() const{ return center.GetLat(); }
198  inline double GetLon() const{ return center.GetLon(); }
199  inline double GetAngle() const{ return angle.AsRadians(); }
200  inline double GetMag() const{ return magnification.GetMagnification(); }
201  inline double GetMagLevel() const{ return magnification.GetLevel(); }
202  inline double GetMapDpi() const{ return mapDpi; }
203 
204  inline bool IsValid() const{ return mapDpi > 0; }
205 
206  inline MapView& operator=(const MapView &mv)
207  {
208  center = mv.center;
209  angle = mv.angle;
210  magnification = mv.magnification;
211  mapDpi = mv.mapDpi;
212 
213  return *this;
214  }
215 
216  osmscout::GeoCoord center;
217  Bearing angle; // canvas clockwise
218  osmscout::Magnification magnification;
219  double mapDpi{0};
220 };
221 
222 inline bool operator==(const MapView& a, const MapView& b)
223 {
224  return a.center == b.center && a.angle == b.angle && a.magnification == b.magnification && a.mapDpi == b.mapDpi;
225 }
226 inline bool operator!=(const MapView& a, const MapView& b)
227 {
228  return ! (a == b);
229 }
230 
248 class OSMSCOUT_CLIENT_QT_API InputHandler : public QObject{
249  Q_OBJECT
250 public:
251  explicit InputHandler(const MapView &view);
252  ~InputHandler() override = default;
253 
254  virtual void painted();
255  virtual bool animationInProgress();
256 
257  virtual bool showCoordinates(const osmscout::GeoCoord &coord, const osmscout::Magnification &magnification, const osmscout::Bearing &bearing);
258  virtual bool zoom(double zoomFactor, const QPoint &widgetPosition, const QRect &widgetDimension);
259  virtual bool move(const QVector2D &vector); // move vector in pixels
260  virtual bool rotateTo(double angle);
261  virtual bool rotateBy(double angleChange);
262  virtual bool touch(const QTouchEvent &event);
263  virtual bool currentPosition(bool locationValid, osmscout::GeoCoord currentPosition);
264  virtual bool vehiclePosition(const VehiclePosition &vehiclePosition);
265  virtual bool isLockedToPosition();
266  virtual bool isFollowVehicle();
267  virtual bool focusOutEvent(QFocusEvent *event);
268  virtual void widgetResized(const QSizeF &widgetSize);
269 
270 signals:
271  void viewChanged(const MapView &view);
272 
273 protected:
275 };
276 
284  Q_OBJECT
285 
286 private:
287  QElapsedTimer animationStart;
288  QTimer timer;
289  MapView startMapView;
290  QVector2D _move;
291  osmscout::Magnification targetMagnification;
292  double targetAngle;
293  int animationDuration;
294 
295  const int MOVE_ANIMATION_DURATION = 1000; // ms
296  const int ZOOM_ANIMATION_DURATION = 500; // ms
297  const int ROTATE_ANIMATION_DURATION = 1000; //ms
298  const int ANIMATION_TICK = 16;
299 
300 private slots:
301  void onTimeout();
302 
303 public:
304  explicit MoveHandler(const MapView &view);
305  ~MoveHandler() override = default;
306 
307  bool animationInProgress() override;
308 
315  bool moveNow(const QVector2D &vector); // move vector in pixels, without animation
316 
317  bool zoom(double zoomFactor, const QPoint &widgetPosition, const QRect &widgetDimension) override;
318  bool move(const QVector2D &vector) override; // move vector in pixels
319  bool rotateTo(double angle) override;
320  bool rotateBy(double angleChange) override;
321  bool touch(const QTouchEvent &event) override;
322 };
323 
330 {
331  Q_OBJECT
332 private:
333  Magnification startMag;
334  QPoint gestureStart;
335  double zoomDistance;
336 
337 public:
343  ZoomGestureHandler(const MapView &view, const QPoint &p, double zoomDistance);
344  ~ZoomGestureHandler() override = default;
345 
346  bool touch(const QTouchEvent &event) override;
347 };
348 
355  Q_OBJECT
356 
357 private:
358  QElapsedTimer animationStart;
359  QTimer timer;
360  MapView startMapView;
361  MapView targetMapView;
362  double angleDiff; // radians
363 
364  double moveAnimationDuration;
365  double zoomAnimationDuration;
366 
367  static constexpr int ANIMATION_DURATION = 1000; // ms
368  static constexpr int ANIMATION_TICK = 16; // ms
369 
370 private slots:
371  void onTimeout();
372 
373 public:
374  explicit JumpHandler(const MapView &view,
375  double moveAnimationDuration = (double)ANIMATION_DURATION,
376  double zoomAnimationDuration = (double)ANIMATION_DURATION);
377 
378  ~JumpHandler() override = default;
379 
380  bool animationInProgress() override;
381  bool showCoordinates(const osmscout::GeoCoord &coord, const osmscout::Magnification &magnification, const osmscout::Bearing &bearing) override;
382 };
383 
390  Q_OBJECT
391 public:
392  explicit DragHandler(const MapView &view);
393  ~DragHandler() override = default;
394 
395  bool animationInProgress() override;
396 
397  bool zoom(double zoomFactor, const QPoint &widgetPosition, const QRect &widgetDimension) override;
398  bool move(const QVector2D &vector) override; // move vector in pixels
399  bool rotateBy(double angleChange) override;
400 
401  bool touch(const QTouchEvent &event) override;
402 
403 private:
404  bool moving;
405  MapView startView;
406  int fingerId;
407  int startX;
408  int startY;
409  bool ended;
410  MoveAccumulator moveAccumulator;
411 };
412 
420  Q_OBJECT
421 public:
422  explicit MultitouchHandler(const MapView &view);
423  ~MultitouchHandler() override = default;
424 
425  bool animationInProgress() override;
426 
427  bool zoom(double zoomFactor, const QPoint &widgetPosition, const QRect &widgetDimension) override;
428  bool move(const QVector2D &vector) override; // move vector in pixels
429  bool rotateBy(double angleChange) override;
430 
431  bool touch(const QTouchEvent &event) override;
432 
433 private:
434  bool moving;
435  MapView startView;
436  bool initialized;
437  bool ended;
438  MoveAccumulator moveAccumulator;
439 
440  // we take only first two touch points into account
441  QTouchEvent::TouchPoint startPointA;
442  QTouchEvent::TouchPoint startPointB;
443 };
444 
451  Q_OBJECT
452 public:
453  inline LockHandler(const MapView &view, const QSizeF &widgetSize):
454  JumpHandler(view), window(widgetSize)
455  {};
456 
457  ~LockHandler() override = default;
458 
459  bool currentPosition(bool locationValid, osmscout::GeoCoord currentPosition) override;
460  bool showCoordinates(const osmscout::GeoCoord &coord, const osmscout::Magnification &magnification, const osmscout::Bearing &bearing) override;
461  bool isLockedToPosition() override;
462  bool focusOutEvent(QFocusEvent *event) override;
463  void widgetResized(const QSizeF &widgetSize) override;
464 private:
465  QSizeF window;
466 };
467 
474 Q_OBJECT
475 public:
476  VehicleFollowHandler(const MapView &view, const QSizeF &widgetSize);
477  ~VehicleFollowHandler() override = default;
478 
479  bool vehiclePosition(const VehiclePosition &vehiclePosition) override;
480  bool isLockedToPosition() override;
481  bool isFollowVehicle() override;
482  void widgetResized(const QSizeF &widgetSize) override;
483 
484 private:
485  QSizeF window;
486 };
487 
488 }
489 
490 Q_DECLARE_METATYPE(osmscout::AccumulatorEvent)
491 Q_DECLARE_METATYPE(osmscout::MapView)
492 
493 #endif /* OSMSCOUT_CLIENT_QT_INPUTHANDLER_H */
Definition: InputHandler.h:473
double GetLat() const
Definition: InputHandler.h:197
double GetMagLevel() const
Definition: InputHandler.h:201
MapView(const osmscout::GeoCoord &center, const Bearing &angle, const osmscout::Magnification &magnification, double mapDpi)
Definition: InputHandler.h:181
#define OSMSCOUT_CLIENT_QT_API
Definition: ClientQtImportExport.h:45
MapView & operator=(const MapView &mv)
Definition: InputHandler.h:206
MapView view
Definition: InputHandler.h:274
Definition: InputHandler.h:450
QElapsedTimer time
Definition: InputHandler.h:118
MoveAccumulator & operator+=(const QPointF p)
osmscout::Magnification magnification
Definition: InputHandler.h:218
MapView(QObject *parent, const osmscout::GeoCoord &center, const Bearing &angle, const osmscout::Magnification &magnification, double mapDpi)
Definition: InputHandler.h:174
double angle
Definition: InputHandler.h:166
bool operator!=(const MapViewStruct &r1, const MapViewStruct &r2)
Definition: DBThread.h:61
Definition: InputHandler.h:283
Definition: InputHandler.h:329
Definition: InputHandler.h:389
LockHandler(const MapView &view, const QSizeF &widgetSize)
Definition: InputHandler.h:453
Definition: Area.h:38
Definition: InputHandler.h:354
Definition: InputHandler.h:248
double GetMapDpi() const
Definition: InputHandler.h:202
void setPhysicalDpi(double physicalDpi)
Definition: InputHandler.h:99
MapView(const MapView &mv)
Definition: InputHandler.h:192
MoveAccumulator(int memory=100, double factor=4, double vectorLengthTreshold=5)
Definition: InputHandler.h:145
double GetMag() const
Definition: InputHandler.h:200
double mapDpi
Definition: InputHandler.h:169
Bearing angle
Definition: InputHandler.h:217
double GetAngle() const
Definition: InputHandler.h:199
~MoveAccumulator() override=default
bool operator==(const MapView &a, const MapView &b)
Definition: InputHandler.h:222
Definition: VehiclePosition.h:40
TapRecognizer()
Definition: InputHandler.h:84
osmscout::GeoCoord center
Definition: InputHandler.h:216
double GetLon() const
Definition: InputHandler.h:198
QPointF pos
Definition: InputHandler.h:117
Definition: InputHandler.h:115
Definition: InputHandler.h:128
Definition: InputHandler.h:160
Definition: InputHandler.h:58
bool IsValid() const
Definition: InputHandler.h:204
Definition: InputHandler.h:419