akntouchgesturefw/src/akntouchgesturefwimpl.cpp
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2009 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 "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:  Touch gesture framework implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 #include <aknappui.h>
       
    19 #include <e32base.h>
       
    20 
       
    21 #include "akntouchgesturefwimpl.h"
       
    22 #include "akntouchgesturefwdefs.h"
       
    23 #include "akntouchgesturefwevent.h"
       
    24 #include "akntouchgesturefwrecognitionengine.h"
       
    25 
       
    26 using namespace AknTouchGestureFw;
       
    27 
       
    28 // ---------------------------------------------------------------------------
       
    29 // Two-phased constructor.
       
    30 // ---------------------------------------------------------------------------
       
    31 //
       
    32 CAknTouchGestureFwImpl* CAknTouchGestureFwImpl::NewL(
       
    33     MAknTouchGestureFwObserver& aObserver,
       
    34     CCoeControl* aControl )
       
    35     {
       
    36     CAknTouchGestureFwImpl* self =
       
    37         CAknTouchGestureFwImpl::NewLC( aObserver, aControl );
       
    38     CleanupStack::Pop( self );
       
    39     return self;
       
    40     }
       
    41 
       
    42 
       
    43 // ---------------------------------------------------------------------------
       
    44 // Two-phased constructor.
       
    45 // ---------------------------------------------------------------------------
       
    46 //
       
    47 CAknTouchGestureFwImpl* CAknTouchGestureFwImpl::NewLC(
       
    48     MAknTouchGestureFwObserver& aObserver,
       
    49     CCoeControl* aControl )
       
    50     {
       
    51     CAknTouchGestureFwImpl* self =
       
    52         new ( ELeave ) CAknTouchGestureFwImpl( aControl );
       
    53     CleanupStack::PushL( self );
       
    54     self->ConstructL( aObserver );
       
    55     return self;
       
    56     }
       
    57 
       
    58 
       
    59 // ---------------------------------------------------------------------------
       
    60 // Destructor
       
    61 // ---------------------------------------------------------------------------
       
    62 //
       
    63 CAknTouchGestureFwImpl::~CAknTouchGestureFwImpl()
       
    64     {
       
    65     if ( iCoeEnv )
       
    66         {
       
    67         iCoeEnv->RemoveForegroundObserver( *this );
       
    68         iCoeEnv->RemoveMessageMonitorObserver( *this );
       
    69         }
       
    70 
       
    71     delete iRecognitionEngine;
       
    72     }
       
    73 
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // Handles simulated pointer events.
       
    77 // Used only for testing purposes.
       
    78 // ---------------------------------------------------------------------------
       
    79 //
       
    80 void CAknTouchGestureFwImpl::HandleSimulatedPointerEventL(
       
    81     const TPointerEventData& pointerData )
       
    82     {
       
    83     HandlePointerEventL( pointerData );
       
    84 
       
    85     iSubscriberControl->HandlePointerEventL( pointerData.iPointerEvent );
       
    86     }
       
    87 
       
    88 
       
    89 // ---------------------------------------------------------------------------
       
    90 // Sets target control for window server events.
       
    91 // ---------------------------------------------------------------------------
       
    92 //
       
    93 void CAknTouchGestureFwImpl::SetSubscriberControlL( CCoeControl* aControl )
       
    94     {
       
    95     CCoeControl* subsControl = aControl;
       
    96 
       
    97     CCoeControl* windowControl( subsControl );
       
    98 
       
    99     while ( windowControl && !windowControl->OwnsWindow() )
       
   100         {
       
   101         windowControl = windowControl->Parent();
       
   102         }
       
   103 
       
   104     if ( windowControl )
       
   105         {
       
   106         iWindowControl = windowControl;
       
   107         }
       
   108     else
       
   109         {
       
   110         // The subscriber control or it's parents have no window,
       
   111         // so there's no point to continue.
       
   112         User::Leave( KErrNotFound );
       
   113         }
       
   114 
       
   115     iSubscriberControl = subsControl;
       
   116 
       
   117     EnableAdditionalEvents();
       
   118     }
       
   119 
       
   120 
       
   121 // ---------------------------------------------------------------------------
       
   122 // Sets the gesture interest.
       
   123 // ---------------------------------------------------------------------------
       
   124 //
       
   125 void CAknTouchGestureFwImpl::SetGestureInterestL( TUint aGestureGroups )
       
   126     {
       
   127     TUint gestureInterest( EAknTouchGestureFwNoGroup );
       
   128     if ( aGestureGroups )
       
   129         {
       
   130         gestureInterest = aGestureGroups;
       
   131         }
       
   132 
       
   133     if ( !iMonitoringWs &&
       
   134          gestureInterest != EAknTouchGestureFwNoGroup )
       
   135         {
       
   136         iCoeEnv->AddMessageMonitorObserverL( *this );
       
   137         iMonitoringWs = ETrue;
       
   138         }
       
   139     else if ( iMonitoringWs &&
       
   140               gestureInterest == EAknTouchGestureFwNoGroup )
       
   141         {
       
   142         iCoeEnv->RemoveMessageMonitorObserver( *this );
       
   143         iMonitoringWs = EFalse;
       
   144         }
       
   145 
       
   146     TRAPD( err,
       
   147            iRecognitionEngine->SetGestureInterestL( gestureInterest ) );
       
   148 
       
   149     // If setting the gesture interes fails then there's no need to
       
   150     // monitor the WS events.
       
   151     if ( err != KErrNone && iMonitoringWs )
       
   152         {
       
   153         iCoeEnv->RemoveMessageMonitorObserver( *this );
       
   154         iMonitoringWs = EFalse;
       
   155 
       
   156         User::Leave( err );
       
   157         }
       
   158 
       
   159     EnableAdditionalEvents();
       
   160     }
       
   161 
       
   162 
       
   163 // ---------------------------------------------------------------------------
       
   164 // Returns the gesture groups which should be recognized.
       
   165 // ---------------------------------------------------------------------------
       
   166 //
       
   167 TUint CAknTouchGestureFwImpl::GestureInterest() const
       
   168     {
       
   169     TUint gestureInterest( EAknTouchGestureFwNoGroup );
       
   170     if ( iRecognitionEngine )
       
   171         {
       
   172         gestureInterest = iRecognitionEngine->GestureInterest();
       
   173         }
       
   174     return gestureInterest;
       
   175     }
       
   176 
       
   177 
       
   178 // ---------------------------------------------------------------------------
       
   179 // Defines gesture groups, which trigger tactile feedback automatically.
       
   180 // ---------------------------------------------------------------------------
       
   181 //
       
   182 void CAknTouchGestureFwImpl::SetFeedbackForGroupsL( TUint aGestureGroups )
       
   183     {
       
   184     iRecognitionEngine->SetFeedbackForGroupsL( aGestureGroups );
       
   185     }
       
   186 
       
   187 
       
   188 // ---------------------------------------------------------------------------
       
   189 // Defines gesture types, which trigger tactile feedback automatically.
       
   190 // ---------------------------------------------------------------------------
       
   191 //
       
   192 void CAknTouchGestureFwImpl::SetFeedbackForTypesL(
       
   193     TAknTouchGestureFwGroup aGestureGroup,
       
   194     TUint aGestureTypesForTactile,
       
   195     TUint aGestureTypesForAudio )
       
   196     {
       
   197     iRecognitionEngine->SetFeedbackForTypesL( aGestureGroup,
       
   198         aGestureTypesForTactile, aGestureTypesForAudio );
       
   199     }
       
   200 
       
   201 
       
   202 // ---------------------------------------------------------------------------
       
   203 // EnableTestingFeatures
       
   204 // ---------------------------------------------------------------------------
       
   205 //    
       
   206 void CAknTouchGestureFwImpl::EnableTestingFeatures()
       
   207     {
       
   208     iRecognitionEngine->EnableTestingFeatures();
       
   209     }
       
   210 
       
   211 
       
   212 // ----------------------------------------------------------------------------
       
   213 // C++ Constructor
       
   214 // ---------------------------------------------------------------------------
       
   215 //
       
   216 CAknTouchGestureFwImpl::CAknTouchGestureFwImpl( CCoeControl* aControl )
       
   217     :
       
   218     iMonitoringWs( EFalse ),
       
   219     iCoeEnv( CCoeEnv::Static() ),
       
   220     iSubscriberControl( aControl ),
       
   221     iWindowControl( NULL ),
       
   222     iRecognitionEngine( NULL )
       
   223     {
       
   224     }
       
   225 
       
   226 
       
   227 // ---------------------------------------------------------------------------
       
   228 // Symbian second-phase constructor.
       
   229 // ---------------------------------------------------------------------------
       
   230 //
       
   231 void CAknTouchGestureFwImpl::ConstructL(
       
   232     MAknTouchGestureFwObserver& aObserver )
       
   233     {
       
   234     SetSubscriberControlL( iSubscriberControl );
       
   235 
       
   236     iRecognitionEngine =
       
   237         CAknTouchGestureFwRecognitionEngine::NewL( aObserver,
       
   238             iSubscriberControl );
       
   239 
       
   240     iCoeEnv->AddForegroundObserverL( *this );
       
   241     }
       
   242 
       
   243 
       
   244 // ---------------------------------------------------------------------------
       
   245 // Handles pointer events.
       
   246 // ---------------------------------------------------------------------------
       
   247 //
       
   248 void CAknTouchGestureFwImpl::HandlePointerEventL(
       
   249     const TPointerEventData& aPointerData )
       
   250     {
       
   251 #ifdef GFW_DEBUG_TRACE_INPUTOUTPUT
       
   252     AknTouchGestureFwUtils::DumpPointerEvent( aEvent, aPointerData.iSimulated );
       
   253 #endif // GFW_DEBUG_TRACE_INPUTOUTPUT
       
   254     
       
   255     const TPointerEvent event = aPointerData.iPointerEvent;
       
   256     TInt pointerNumber = 0;
       
   257     if ( event.IsAdvancedPointerEvent() )
       
   258         {
       
   259         pointerNumber = event.AdvancedPointerEvent()->PointerNumber();
       
   260         }
       
   261 
       
   262     __ASSERT_ALWAYS( pointerNumber >= 0, User::Invariant() );
       
   263     __ASSERT_ALWAYS( pointerNumber <= 1, User::Invariant() );
       
   264 
       
   265     iRecognitionEngine->HandlePointerEventL( aPointerData );
       
   266    }
       
   267 
       
   268 
       
   269 // ---------------------------------------------------------------------------
       
   270 // Cancels ongoing recognition.
       
   271 // ---------------------------------------------------------------------------
       
   272 //
       
   273 void CAknTouchGestureFwImpl::CancelRecognition()
       
   274     {
       
   275     iRecognitionEngine->CancelRecognizing();
       
   276     }
       
   277 
       
   278 
       
   279 // ---------------------------------------------------------------------------
       
   280 // Enables the necessary events for the subscriber control's window.
       
   281 // ---------------------------------------------------------------------------
       
   282 //
       
   283 void CAknTouchGestureFwImpl::EnableAdditionalEvents()
       
   284     {
       
   285     // Additional pointer events are needed for the following gesture groups
       
   286     TUint gestureInterest( GestureInterest() );
       
   287     TBool multiEventsNeeded = gestureInterest & EAknTouchGestureFwGroupPinch;
       
   288     TBool dragEventsNeeded =
       
   289         gestureInterest & ( EAknTouchGestureFwGroupFlick |
       
   290                             EAknTouchGestureFwGroupDrag |
       
   291                             EAknTouchGestureFwGroupPinch );
       
   292 
       
   293     // Enables drag events and advanced pointer events for window if needed
       
   294     if ( iWindowControl )
       
   295         {
       
   296         RDrawableWindow* window = iWindowControl->DrawableWindow();
       
   297         if ( window )
       
   298             {
       
   299             if ( dragEventsNeeded )
       
   300                 {
       
   301                 window->PointerFilter( EPointerFilterDrag, 0 );
       
   302                 }
       
   303             if ( multiEventsNeeded )
       
   304                 {
       
   305                 window->EnableAdvancedPointers();
       
   306                 }
       
   307             if ( dragEventsNeeded || multiEventsNeeded )
       
   308 			    {
       
   309                 // Set pointer grab when drag or multi pointer events are
       
   310                 // needed to enable gesture recognition outside gesture control.
       
   311                 window->SetPointerGrab( ETrue );
       
   312 				}
       
   313             }
       
   314         }
       
   315     }
       
   316 
       
   317 
       
   318 // ---------------------------------------------------------------------------
       
   319 // Checks if pointer event is targeted to the gesture control.
       
   320 // ---------------------------------------------------------------------------
       
   321 //
       
   322 TBool CAknTouchGestureFwImpl::PointerEventTargetedToControl(
       
   323     CCoeControl* aTargetControl,
       
   324     TPointerEvent& aEvent ) const
       
   325     {
       
   326     if ( !aTargetControl )
       
   327         {
       
   328         return EFalse;
       
   329         }
       
   330 
       
   331     TBool targetedToControl( EFalse );
       
   332     TBool eventInControl(
       
   333             iSubscriberControl->Rect().Contains( aEvent.iPosition ) );
       
   334 
       
   335     // Check if target control is gesture control's window control.
       
   336     targetedToControl = aTargetControl == iWindowControl;
       
   337 
       
   338     // Check that pointer is in gesture control area.
       
   339     if ( targetedToControl &&
       
   340          aEvent.iType == TPointerEvent::EButton1Down )
       
   341         {
       
   342         targetedToControl = eventInControl;
       
   343         }
       
   344 
       
   345     // Check if pointer is targeted to child window that is on gesture
       
   346     // control area.
       
   347     else if ( !targetedToControl && eventInControl )
       
   348         {
       
   349         CCoeControl* windowControl( aTargetControl );
       
   350         while ( windowControl )
       
   351             {
       
   352             windowControl = windowControl->Parent();
       
   353             if ( windowControl == iWindowControl )
       
   354                 {
       
   355                 targetedToControl = ETrue;
       
   356                 ConvertPositionToControlWindow(
       
   357                         aTargetControl->DrawableWindow(),
       
   358                         aEvent.iPosition );
       
   359                 break;
       
   360                 }
       
   361             }
       
   362         }
       
   363 
       
   364     return targetedToControl;
       
   365     }
       
   366 
       
   367 
       
   368 // ---------------------------------------------------------------------------
       
   369 // Converts position in window area according to control window coordinates.
       
   370 // ---------------------------------------------------------------------------
       
   371 //
       
   372 void CAknTouchGestureFwImpl::ConvertPositionToControlWindow(
       
   373     RDrawableWindow* aWindow,
       
   374     TPoint& aPosition ) const
       
   375     {
       
   376     if ( aWindow )
       
   377         {
       
   378         TPoint targetPosition( aWindow->AbsPosition() );
       
   379         TPoint windowPosition(
       
   380                 iWindowControl->DrawableWindow()->AbsPosition() );
       
   381         aPosition.iX = aPosition.iX + targetPosition.iX - windowPosition.iX;
       
   382         aPosition.iY = aPosition.iY + targetPosition.iY - windowPosition.iY;
       
   383         }
       
   384     }
       
   385 
       
   386 
       
   387 // ---------------------------------------------------------------------------
       
   388 // Called when the application gains foreground.
       
   389 // ---------------------------------------------------------------------------
       
   390 //
       
   391 void CAknTouchGestureFwImpl::HandleGainingForeground()
       
   392     {
       
   393 #ifdef GFW_DEBUG_TRACE_INPUTOUTPUT
       
   394     _LIT( KAknTouchGainForeground, "[GFW] IN GAIN FOREGROUND" );
       
   395     RDebug::Print( KAknTouchGainForeground );
       
   396 #endif
       
   397 
       
   398     if ( !iMonitoringWs && GestureInterest() != EAknTouchGestureFwNoGroup )
       
   399         {
       
   400         TRAP_IGNORE( iCoeEnv->AddMessageMonitorObserverL( *this ) );
       
   401         iMonitoringWs = ETrue;
       
   402         }
       
   403     }
       
   404 
       
   405 
       
   406 // ---------------------------------------------------------------------------
       
   407 // Called when the application loses foreground.
       
   408 // ---------------------------------------------------------------------------
       
   409 //
       
   410 void CAknTouchGestureFwImpl::HandleLosingForeground()
       
   411     {
       
   412 #ifdef GFW_DEBUG_TRACE_INPUTOUTPUT
       
   413     _LIT( KAknTouchLostForeground, "[GFW] IN LOST FOREGROUND" );
       
   414     RDebug::Print( KAknTouchLostForeground );
       
   415 #endif
       
   416 
       
   417     // Reset framework state because it might be possible that
       
   418     // pointer is down when framework loses background.
       
   419     // In this situation corresponding up-event is never received
       
   420     // and framework stays to wrong state (assuming pointer is still down)
       
   421     // without resetting it.
       
   422     CancelRecognition();
       
   423 
       
   424     if ( iMonitoringWs )
       
   425         {
       
   426         iCoeEnv->RemoveMessageMonitorObserver( *this );
       
   427         iMonitoringWs = EFalse;
       
   428         }
       
   429     }
       
   430 
       
   431 
       
   432 // ---------------------------------------------------------------------------
       
   433 // Handles window server messages.
       
   434 // ---------------------------------------------------------------------------
       
   435 //
       
   436 void CAknTouchGestureFwImpl::MonitorWsMessage( const TWsEvent& aEvent )
       
   437     {
       
   438     if ( aEvent.Type() == EEventPointer )
       
   439         {
       
   440         CCoeControl* targetControl =
       
   441             reinterpret_cast<CCoeControl*>( aEvent.Handle() );
       
   442         TAdvancedPointerEvent event( *aEvent.Pointer() );
       
   443         TBool targetedToControl( PointerEventTargetedToControl(
       
   444                 targetControl, event ) );
       
   445         
       
   446         TPointerEventData pointerData( event, 
       
   447                                        event.PointerNumber(), 
       
   448                                        aEvent.Time(), 
       
   449                                        EFalse, 
       
   450                                        targetedToControl );
       
   451         
       
   452         TRAP_IGNORE( HandlePointerEventL( pointerData ) );
       
   453         }
       
   454     else if ( aEvent.Type() == EEventScreenDeviceChanged )
       
   455         {
       
   456         // Cancel recognition if layout changes
       
   457         CancelRecognition();
       
   458         }
       
   459     }
       
   460 
       
   461 // End of File