webengine/webkitutils/stmgesturefw/src/zoomgesturerecogniser.cpp
changeset 65 5bfc169077b2
parent 42 d39add9822e2
child 66 cacf6ee57968
equal deleted inserted replaced
42:d39add9822e2 65:5bfc169077b2
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Gesture helper implementation
       
    15 *
       
    16 */
       
    17 
       
    18 #include <e32math.h>
       
    19 #include <rt_uievent.h>
       
    20 #include "filelogger.h"
       
    21 #include "zoomgesturerecogniser.h"
       
    22 #include "GenericSimpleGesture.h"
       
    23 
       
    24 using namespace stmGesture ;
       
    25 
       
    26 _LIT8(KZoomInName, "ZoomIn") ;
       
    27 _LIT8(KZoomOutName, "ZoomOut") ;
       
    28 
       
    29 CZoomGestureRecogniser* CZoomGestureRecogniser::NewL(MGestureListener* aListener)
       
    30 {
       
    31     CZoomGestureRecogniser* self = new (ELeave) CZoomGestureRecogniser(aListener) ;
       
    32     return self;
       
    33 }
       
    34 
       
    35 CZoomGestureRecogniser::CZoomGestureRecogniser(MGestureListener* aListener) :
       
    36     CGestureRecogniser(aListener), m_area(TRect::EUninitialized)
       
    37 {
       
    38     m_rangesizeInPixels = 20 ;  // by default 20 pixels from the edges is the area
       
    39     m_zooming = false ;
       
    40 }
       
    41 
       
    42 CZoomGestureRecogniser::~CZoomGestureRecogniser()
       
    43 {
       
    44 }
       
    45 
       
    46 TGestureRecognitionState CZoomGestureRecogniser::recognise(int numOfActiveStreams,
       
    47         MGestureEngineIf* pge)
       
    48 {
       
    49     TGestureRecognitionState state = ENotMyGesture;
       
    50     // Check if we are enabled or not
       
    51     if (!m_gestureEnabled) return state ;
       
    52 
       
    53     // Look at the events to see if it looks like zoom with one pointer
       
    54     if (numOfActiveStreams == 1)
       
    55     {
       
    56         const stmUiEventEngine::MUiEvent* puie = pge->getUiEvents(0);
       
    57         int countOfEvents = puie->countOfEvents();
       
    58         stmUiEventEngine::TUiEventCode eventCode = puie->Code();
       
    59 
       
    60         if (m_loggingenabled)
       
    61         {
       
    62             LOGARG("CZoomGestureRecogniser: %d num %d code %d",
       
    63                     eventCode, countOfEvents, eventCode);
       
    64 
       
    65         }
       
    66         if (!m_zooming)
       
    67         {
       
    68             // We are not yet zoomin, check if we should start, i.e. whether we are
       
    69             // inside the zoom trigger areas near the corners when touch is done...
       
    70             if (eventCode == stmUiEventEngine::ETouch) // It must be ETouch inside the corner
       
    71             {
       
    72                 if (m_loggingenabled)
       
    73                 {
       
    74                     LOGARG("CZoomGestureRecogniser: 0x%x ETouch: num %d code %d, %d",
       
    75                             this, countOfEvents, puie->CurrentXY().iX, puie->CurrentXY().iY);
       
    76                     LOGARG("CZoomGestureRecogniser: area, %d,%d %d,%d, range: %d", m_area.iTl.iX, m_area.iTl.iY, m_area.iBr.iX, m_area.iBr.iY, m_rangesizeInPixels);
       
    77                 }
       
    78 
       
    79                 // the lower left rectangle is m_rangesizeIPixels from the corner
       
    80                 TRect lowerleft(m_area.iTl.iX, m_area.iBr.iY-m_rangesizeInPixels,
       
    81                         m_area.iTl.iX+m_rangesizeInPixels, m_area.iBr.iY) ;
       
    82                 TRect upperright(m_area.iBr.iX-m_rangesizeInPixels, m_area.iTl.iY,
       
    83                         m_area.iBr.iX, m_area.iTl.iY+m_rangesizeInPixels) ;
       
    84 
       
    85                 m_previoustouch = m_startingtouch = puie->CurrentXY() ;
       
    86                 m_delta = 0 ;
       
    87                 if (lowerleft.Contains(m_startingtouch) || upperright.Contains(m_startingtouch))
       
    88                 {
       
    89                     if (m_loggingenabled)
       
    90                     {
       
    91                         LOGARG("CZoomGestureRecogniser: ZOOM IN/OUT, (%d,%d) in %d,%d %d,%d, range: %d",
       
    92                             m_startingtouch.iX, m_startingtouch.iY,
       
    93                             m_area.iTl.iX, m_area.iTl.iY, m_area.iBr.iX, m_area.iBr.iY,
       
    94                             m_rangesizeInPixels);
       
    95                     }
       
    96                     m_zooming = true ;
       
    97                     if (lowerleft.Contains(m_startingtouch))
       
    98                     {
       
    99                         m_zoomtype = EZoomIn ;
       
   100                     }
       
   101                     else
       
   102                     {
       
   103                         m_zoomtype = EZoomOut ;
       
   104                     }
       
   105                     state = ELockToThisGesture ;    // keep zooming until release
       
   106                     TTwoPointGesture pgest(KUid, m_startingtouch, m_startingtouch);
       
   107                     pgest.setLogging(m_loggingenabled) ;
       
   108                     pgest.setDetails(m_delta) ;
       
   109                     pgest.setName(m_zoomtype == EZoomIn ? KZoomInName() : KZoomOutName()) ;
       
   110                     pgest.setType(m_zoomtype);
       
   111 
       
   112                     // Call the listener to inform that a gesture has happened
       
   113                     m_listener->gestureEnter(pgest) ;
       
   114                 }
       
   115                 else
       
   116                 {
       
   117                     // It is not our gesture so do nothing...
       
   118                 }
       
   119             }
       
   120             else
       
   121             {
       
   122                 // It is not touch, so not our initiating UI event.. do nothing
       
   123             }
       
   124         }
       
   125         else
       
   126         {
       
   127             // We are already zooming, calculate the changes in zooming factor if it looks we are still zooming
       
   128             if (eventCode == stmUiEventEngine::ERelease) // ERelease stops zooming
       
   129             {
       
   130                 // We were zooming, but if there are multiple touches we are not any more
       
   131                 m_listener->gestureExit(KUid) ; // should we call this or not?
       
   132             }
       
   133             else    // all other UI events will keep on zooming
       
   134             {
       
   135                 state = ELockToThisGesture ;    // Keep the gesture
       
   136                 const TPoint& p = puie->CurrentXY() ;
       
   137                 float newdist = calculateDistance(p) ;
       
   138                 float olddist = calculateDistance(m_previoustouch) ;
       
   139                 m_previoustouch = p ;
       
   140                 m_delta = adjustZoom(olddist, newdist) ;
       
   141                 state = EGestureActive ;
       
   142 
       
   143                 // Inform listener only if there is something to say
       
   144                 if (m_delta != 0)
       
   145                 {
       
   146                     TTwoPointGesture pgest = TTwoPointGesture(KUid, p, m_startingtouch);
       
   147                     pgest.setLogging(m_loggingenabled) ;
       
   148                     pgest.setDetails(m_delta) ;
       
   149                     pgest.setName(m_zoomtype == EZoomIn ? KZoomInName() : KZoomOutName()) ;
       
   150                     pgest.setType(m_zoomtype);
       
   151 
       
   152                     // Call the listener to inform that a gesture has happened
       
   153                     m_listener->gestureEnter(pgest) ;
       
   154                 }
       
   155             }
       
   156         }
       
   157     }
       
   158     else
       
   159     {
       
   160         if (m_zooming)
       
   161         {
       
   162             // We were zooming, but if there are multiple touches we are not any more
       
   163             m_listener->gestureExit(KUid) ; // should we call this or not?
       
   164         }
       
   165         m_zooming = false ;
       
   166     }
       
   167     return state;
       
   168 }
       
   169 
       
   170 void CZoomGestureRecogniser::release(MGestureEngineIf*)
       
   171 {
       
   172     if (m_zooming)
       
   173     {
       
   174         m_zooming = false ;
       
   175         m_listener->gestureExit(KUid) ; // should we call this or not?
       
   176     }
       
   177     if (m_loggingenabled)
       
   178     {
       
   179         LOGARG("CZoomGestureRecogniser: 0x%x release", this);
       
   180     }
       
   181 }
       
   182 
       
   183 void CZoomGestureRecogniser::setRange(int rangeInPixels)
       
   184 {
       
   185     m_rangesizeInPixels = rangeInPixels ;
       
   186 }
       
   187 
       
   188 void CZoomGestureRecogniser::setArea(const TRect& theArea)
       
   189 {
       
   190     m_area = theArea ;
       
   191     if (m_loggingenabled)
       
   192     {
       
   193         LOGARG("CZoomGestureRecogniser: set area, %d,%d %d,%d",
       
   194                 m_area.iTl.iX, m_area.iTl.iY, m_area.iBr.iX, m_area.iBr.iY);
       
   195     }
       
   196 }
       
   197 
       
   198 /*!
       
   199  * calculate the distance, return as as float
       
   200  */
       
   201 float CZoomGestureRecogniser::calculateDistance(const TPoint& tp)
       
   202 {
       
   203     double x = ((m_startingtouch.iX-tp.iX)*(m_startingtouch.iX-tp.iX)) +
       
   204                 ((m_startingtouch.iY-tp.iY)*(m_startingtouch.iY-tp.iY)) ;
       
   205     double ddist ;
       
   206     Math::Sqrt(ddist, x) ;
       
   207     return ddist ;
       
   208 }
       
   209 
       
   210 int CZoomGestureRecogniser::adjustZoom(float& aPreviousDistance, float aNewDistance)
       
   211 {
       
   212     float diff = aNewDistance - aPreviousDistance ;
       
   213     float logdiff = diff ;
       
   214     if (diff < 0) diff = -diff ;
       
   215     float changePercentage = (diff/aPreviousDistance)*100.f ;
       
   216     if (changePercentage > 10.f)
       
   217     {
       
   218         // change more than 10%, make at most 10%
       
   219         float newdiff = aPreviousDistance*0.1f;
       
   220         if (aPreviousDistance > aNewDistance) newdiff = -newdiff ;
       
   221         if (m_loggingenabled)
       
   222         {
       
   223             LOGARG("CZoomGestureRecogniser: adjust zoom from %f to %f : was, now %f %f",
       
   224                 double(logdiff), double(newdiff), double(aPreviousDistance), double(aNewDistance));
       
   225         }
       
   226 
       
   227         aPreviousDistance = aPreviousDistance + newdiff ;
       
   228         diff = newdiff ;
       
   229 
       
   230     }
       
   231     else
       
   232     {
       
   233         if (m_loggingenabled)
       
   234         {
       
   235             LOGARG("CZoomGestureRecogniser: adjust zoom from %f to %f : was, now %f %f",
       
   236                 double(logdiff), double(diff), double(aPreviousDistance), double(aNewDistance));
       
   237         }
       
   238         aPreviousDistance = aNewDistance ;  // accept the new value and update the new length
       
   239         diff = logdiff ;    // put the original back
       
   240     }
       
   241     return (int)diff ;
       
   242 }