Copyright (C) 2010 Ixonos Plc. Authors:
Sami Rämö - sami.ramo@ixonos.com
+ Pekka Nissinen - pekka.nissinen@ixonos.com
Situare is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
#define MAPVIEW_H
#include <QGraphicsView>
+#include <QTime>
+
+#include "coordinates/scenecoordinate.h"
+
+class QParallelAnimationGroup;
+class QPropertyAnimation;
+
+class MapScroller;
+
+#define VALUES 4
/**
* @brief Map view widget
*
* @author Sami Rämö - sami.ramo (at) ixonos.com
+* @author Pekka Nissinen - pekka.nissinen (at) ixonos.com
*/
class MapView : public QGraphicsView
{
Q_OBJECT
+
+ /**
+ * @brief View scaling
+ *
+ * @property viewScale
+ */
+ Q_PROPERTY(qreal viewScale READ viewScale WRITE setViewScale)
+
+ /**
+ * @brief View shifting
+ *
+ * @property viewShift
+ */
+ Q_PROPERTY(qreal viewShift READ viewShift WRITE setViewShift)
+
public:
/**
* @brief Constructor
MapView(QWidget *parent = 0);
/**
+ * @brief Destructor.
+ *
+ * Takes MapScroller animation from double click zoom animation group and
+ * deletes animation group.
+ */
+ ~MapView();
+
+/*******************************************************************************
+ * BASE CLASS INHERITED AND REIMPLEMENTED MEMBER FUNCTIONS
+ ******************************************************************************/
+protected:
+ /**
+ * @brief Called when view is resized.
+ *
+ * @param event resize event
+ */
+ void resizeEvent(QResizeEvent *event);
+
+private:
+ /**
+ * @brief Event handler for mouse double click event
+ *
+ * Emits zoomIn signal.
+ * @param event QMouseEvent
+ */
+ void mouseDoubleClickEvent(QMouseEvent *event);
+
+ /**
+ * @brief Event handler for mouse move events
+ *
+ * Does calculate mouse movement delta from last event position and new view center
+ * based on that delta. Saves current event position for next round. Emits viewScrolled
+ * signal and doesn't actually scroll the view.
+ *
+ * Saves mouse movement deltas and durations for last few move events to be used for
+ * calculating the kinetic scrolling speed.
+ *
+ * @param event Mouse event
+ */
+ void mouseMoveEvent(QMouseEvent *event);
+
+ /**
+ * @brief Event handler for mouse press events
+ *
+ * Saves inial values for mouse and scene location for dragging the view. Does stop currently
+ * running kinetic scroll effect.
+ *
+ * @param event Mouse event
+ */
+ void mousePressEvent(QMouseEvent *event);
+
+ /**
+ * @brief Event handler for mouse release events
+ *
+ * Set up and start kinetic scrolling effect if time elapsed from last mouseMoveEvent is below
+ * the limit and drag length is over the limit.
+ *
+ * Kinetic scroll distance is calculated based on mouse movement event values saved in
+ * mouseMoveEvent(). The distance is also limited so that map doesn't run too far.
+ *
+ * @param event Mouse event
+ */
+ void mouseReleaseEvent(QMouseEvent *event);
+
+/*******************************************************************************
+ * MEMBER FUNCTIONS AND SLOTS
+ ******************************************************************************/
+public slots:
+ /**
+ * @brief Slot for centering view to new location
+ *
+ * Does also shift the center point horizontally, if required.
+ *
+ * @param coordinate Scene coordinates of the new center point
+ * @param isUserDragAction True if caused by user dragging action. Does not shift the center
+ * point if true.
+ */
+ void centerToSceneCoordinates(const SceneCoordinate &coordinate, bool isUserDragAction = false);
+
+ /**
* @brief Set zoom level of the view
*
* @param zoomLevel Zoom level
*/
void setZoomLevel(int zoomLevel);
-public slots:
+private slots:
+ /**
+ * @brief Disables shifting of the center point
+ */
+ void disableCenterShift();
+
/**
- * @brief Slot for mouse events
+ * @brief Double tap zoom finished.
*
- * @param event Mouse event
+ * Disables double tap zoom flag and emits zoomIn signal.
*/
- void mousePressEvent(QMouseEvent *event);
+ void doubleTapZoomFinished();
+
+ /**
+ * @brief Enables shifting of the center point
+ */
+ void enableCenterShift();
+
+private:
+ /**
+ * @brief Set new view scale
+ *
+ * @param viewScale New scaling factor
+ */
+ void setViewScale(qreal viewScale);
+
+ /**
+ * @brief Set new view shifting
+ *
+ * @param viewShift New shifting amount
+ */
+ void setViewShift(qreal viewShift);
+
+ /**
+ * @brief Toggles the shifting of the center point
+ *
+ * @param enabled True if shifting is enabled
+ */
+ void toggleCenterShift(bool enabled);
+
+ /**
+ * @brief Update center shifting value
+ */
+ void updateCenterShift();
+
+ /**
+ * @brief Get current view scale
+ *
+ * @return Current view scaling factor
+ */
+ qreal viewScale() const;
+
+ /**
+ * @brief Get current view shifting
+ *
+ * @return Current view shifting amount
+ */
+ qreal viewShift() const;
+
+/*******************************************************************************
+ * SIGNALS
+ ******************************************************************************/
+signals:
+ /**
+ * @brief Emitted when map center point shiftin is changed
+ *
+ * @param shifting New shifting value
+ */
+ void horizontalShiftingChanged(int shifting);
+
+ /**
+ * @brief Signal for view resize events.
+ *
+ * Signal is emitted when view has been resized.
+ * @param size view size
+ */
+ void viewResized(const QSize &size);
+
+ /**
+ * @brief Signal for view scroll events
+ *
+ * Signal is emitted when view is scrolled.
+ * @param coordinate Scene coordinates of the new center point of the view
+ * @param isUserDragAction True if caused by user dragging action
+ */
+ void viewScrolled(const SceneCoordinate &coordinate, bool isUserDragAction);
+
+ /**
+ * @brief Signal for informing that zooming animation is finished
+ */
+ void viewZoomFinished();
+
+ /**
+ * @brief Signal for informing that double click zoom is finished
+ */
+ void zoomIn();
+
+/*******************************************************************************
+ * DATA MEMBERS
+ ******************************************************************************/
+private:
+ bool m_doubleTapZoomRunning; ///< Double tap zoom running flag
+
+ int m_dragTime[VALUES]; ///< Table of mouse event durations
+ int m_index; ///< Current index of mouse event values table
+ int m_zoomLevel; ///< Current zoom level
+
+ qreal m_centerHorizontalShiftViewPixels; ///< Center point horizontal shift in the view
+ qreal m_kineticMaxViewDistance; ///< Maximum kinetic scroll distance in view pixels
+
+ QParallelAnimationGroup *m_scrollAndZoomAnimation; ///< Double click zoom animation
+
+ QPoint m_dragMovement[VALUES]; ///< Table of mouse event distances
+ QPoint m_internalScenePosition; ///< New center position (used for dragging)
+ QPoint m_lastMouseEventScenePosition; ///< Previous mouse event position in the scene
+ QPoint m_lastMouseEventViewPosition; ///< Previous mouse event position in the view
+
+ QPointF m_centerHorizontalShiftPoint; ///< Current amount of center point shifting
+
+ QPropertyAnimation *m_zoomAnimation; ///< Zoom animation
+
+ QTime m_time; ///< Elapsed time between mouse events
+
+ QPropertyAnimation *m_centerShiftAnimation; ///< Animation for shifting the center point
+
+ MapScroller *m_scroller; ///< Kinetic scroller
+ SceneCoordinate m_lastSetScenePosition; ///< Last center point coordinate set by MapEngine
};
#endif // MAPVIEW_H