9 changes: 9 additions & 0 deletions src/gui/qgsmaptool.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
#include <QString>
#include <QObject>

#ifdef HAVE_TOUCH
#include <QGestureEvent>
#endif

class QgsMapLayer;
class QgsMapCanvas;
class QKeyEvent;
Expand Down Expand Up @@ -62,6 +66,11 @@ class GUI_EXPORT QgsMapTool : public QObject
//! Added in version 1.1
virtual void keyReleaseEvent( QKeyEvent* e );

#ifdef HAVE_TOUCH
//! gesture event for overriding. Default implementation does nothing.
virtual bool gestureEvent( QGestureEvent* e );
#endif

//! Called when rendering has finished. Default implementation does nothing.
virtual void renderComplete();

Expand Down
129 changes: 129 additions & 0 deletions src/gui/qgsmaptooltouch.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/***************************************************************************
qgsmaptooltouch.cpp - map tool for zooming and panning using qgestures
----------------------
begin : February 2012
copyright : (C) 2012 by Marco Bernasocchi
email : marco at bernawebdesign.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsmaptooltouch.h"
#include "qgsmapcanvas.h"
#include "qgscursors.h"
#include "qgsmaptopixel.h"
#include <QBitmap>
#include <QCursor>
#include <QMouseEvent>
#include <qgslogger.h>


QgsMapToolTouch::QgsMapToolTouch( QgsMapCanvas* canvas )
: QgsMapTool( canvas ), mDragging( false ), mPinching( false )
{
// set cursor
// QBitmap panBmp = QBitmap::fromData( QSize( 16, 16 ), pan_bits );
// QBitmap panBmpMask = QBitmap::fromData( QSize( 16, 16 ), pan_mask_bits );
// mCursor = QCursor( panBmp, panBmpMask, 5, 5 );
}

QgsMapToolTouch::~QgsMapToolTouch()
{
mCanvas->ungrabGesture(Qt::PinchGesture);
}

void QgsMapToolTouch::activate()
{
mCanvas->grabGesture(Qt::PinchGesture);
QgsMapTool::activate();
}

void QgsMapToolTouch::deactivate()
{
mCanvas->ungrabGesture(Qt::PinchGesture);
QgsMapTool::deactivate();
}

void QgsMapToolTouch::canvasMoveEvent( QMouseEvent * e )
{
if ( !mPinching )
{
if (( e->buttons() & Qt::LeftButton ) )
{
mDragging = true;
// move map and other canvas items
mCanvas->panAction( e );
}
}
}

void QgsMapToolTouch::canvasReleaseEvent( QMouseEvent * e )
{
if ( !mPinching )
{
if ( e->button() == Qt::LeftButton )
{
if ( mDragging )
{
mCanvas->panActionEnd( e->pos() );
mDragging = false;
}
else // add pan to mouse cursor
{
// transform the mouse pos to map coordinates
QgsPoint center = mCanvas->getCoordinateTransform()->toMapPoint( e->x(), e->y() );
mCanvas->setExtent( QgsRectangle( center, center ) );
mCanvas->refresh();
}
}
}
}

void QgsMapToolTouch::canvasDoubleClickEvent( QMouseEvent *e )
{
if ( !mPinching )
{
mCanvas->zoomWithCenter(e->x(), e->y(), true);
}
}

bool QgsMapToolTouch::gestureEvent(QGestureEvent *event)
{
qDebug() << "gesture " << event;
if (QGesture *gesture = event->gesture(Qt::PinchGesture))
{
mPinching = true;
pinchTriggered(static_cast<QPinchGesture *>(gesture));
}
return true;
}


void QgsMapToolTouch::pinchTriggered(QPinchGesture *gesture)
{
if (gesture->state() == Qt::GestureFinished) {
//a very small totalScaleFactor indicates a two finger tap (pinch gesture without pinching)
if (0.98 < gesture->totalScaleFactor() && gesture->totalScaleFactor() < 1.02 )
{
mCanvas->zoomOut();
}
else
{
//Transfor global coordinates to widget coordinates
QPoint pos = gesture->centerPoint().toPoint();
pos = mCanvas->mapFromGlobal( pos );
// transform the mouse pos to map coordinates
QgsPoint center = mCanvas->getCoordinateTransform()->toMapPoint( pos.x(),pos.y() );
QgsRectangle r = mCanvas->extent();
r.scale( 1/gesture->totalScaleFactor(), &center );
mCanvas->setExtent( r );
mCanvas->refresh();
}
mPinching = false;
}
}
62 changes: 62 additions & 0 deletions src/gui/qgsmaptooltouch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/***************************************************************************
qgsmaptooltouch.h - map tool for zooming and panning using qgestures
----------------------
begin : February 2012
copyright : (C) 2012 by Marco Bernasocchi
email : marco at bernawebdesign.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSMAPTOOLTOUCH_H
#define QGSMAPTOOLTOUCH_H

#include "qgsmaptool.h"
#include <QGestureEvent>
#include <QPinchGesture>

class QgsMapCanvas;


/** \ingroup gui
* A map tool for panning the map.
* @see QgsMapTool
*/
class GUI_EXPORT QgsMapToolTouch : public QgsMapTool
{
public:
//! constructor
QgsMapToolTouch( QgsMapCanvas* canvas );

~QgsMapToolTouch();

void activate();
void deactivate();

//! Overridden mouse move event
virtual void canvasMoveEvent( QMouseEvent * e );

//! Overridden mouse release event
virtual void canvasReleaseEvent( QMouseEvent * e );

//! Overridden Mouse double click event.
virtual void canvasDoubleClickEvent( QMouseEvent * e );

virtual bool isTransient() { return true; }

private:

//! Flag to indicate a map canvas drag operation is taking place
bool mDragging;
//! Flag to indicate a pinch gesture is taking place
bool mPinching;
bool gestureEvent(QGestureEvent *event);
void pinchTriggered(QPinchGesture *gesture);
};

#endif
16 changes: 16 additions & 0 deletions src/ui/qgisapp.ui
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="mActionTouch"/>
<addaction name="mActionPan"/>
<addaction name="mActionPanToSelected"/>
<addaction name="mActionZoomIn"/>
Expand Down Expand Up @@ -1587,6 +1588,21 @@
<string>Pan Map to Selection</string>
</property>
</action>
<action name="mActionTouch">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/gis/mActionTouch.png</normaloff>:/images/themes/gis/mActionTouch.png</iconset>
</property>
<property name="text">
<string>Touch zoom and pan</string>
</property>
<property name="toolTip">
<string>Touch zoom and pan</string>
</property>
</action>
<action name="mActionOffsetCurve">
<property name="checkable">
<bool>true</bool>
Expand Down