idlehomescreen/xmluirendering/uiengine/src/xnviewswitcher.cpp
branchRCL_3
changeset 102 ba63c83f4716
parent 93 b01126ce0bec
child 103 966d119a7e67
equal deleted inserted replaced
93:b01126ce0bec 102:ba63c83f4716
     1 /*
       
     2  * Copyright (c) 2002-2004 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:  Implementation for wrapper for a box
       
    15  *
       
    16  */
       
    17 
       
    18 // System includes
       
    19 #include <akntouchgesturefwevents.h>
       
    20 #include <centralrepository.h>
       
    21 
       
    22 #include <activeidle2domaincrkeys.h>
       
    23 #include <gfxtranseffect/gfxtranseffect.h>  
       
    24 
       
    25 #ifdef RD_TACTILE_FEEDBACK
       
    26 #include <touchfeedback.h>
       
    27 #endif // RD_TACTILE_FEEDBACK
       
    28 
       
    29 // User includes
       
    30 #include "xnappuiadapter.h"
       
    31 #include "xnuiengine.h"
       
    32 #include "xnproperty.h"
       
    33 #include "xnviewmanager.h"
       
    34 #include "xnviewdata.h"
       
    35 #include "xndomnode.h"
       
    36 #include "xnnode.h"
       
    37 #include "xnviewcontroladapter.h"
       
    38 #include "xneffectmanager.h"
       
    39 #include "xnrootdata.h"
       
    40 #include "xnviewadapter.h"
       
    41 #include "xnbackgroundmanager.h"
       
    42 
       
    43 #include "xnviewswitcher.h"
       
    44 
       
    45 // Constants
       
    46 const TInt KDrawDelay( 25000 ); // 16100 = 62 fps
       
    47 const TInt KDragTreshold( 30 );
       
    48 const TInt KMaxScrollSpeed( 150 );
       
    49 const TInt KMinScrollSpeed( 20 );
       
    50 const TInt KAnimationDuration( 500000 );
       
    51 const TInt KDragOffsetForBackground( 100 );
       
    52 const TInt KDragOffsetForPageSwitch( 50 );
       
    53 
       
    54 enum TViewPosition
       
    55     {
       
    56     KCurrentView, KNextView, KPreviousView
       
    57     };
       
    58 
       
    59 // ============================= LOCAL FUNCTIONS ===============================
       
    60 
       
    61 // -----------------------------------------------------------------------------
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 void HideAdapter( CXnControlAdapter* aAdapter )
       
    65     {
       
    66     if( aAdapter )
       
    67         {
       
    68         aAdapter->Window().SetOrdinalPosition( -1 );
       
    69         }    
       
    70     }
       
    71 
       
    72 // -----------------------------------------------------------------------------
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 void ShowAdapter( CXnControlAdapter* aAdapter )
       
    76     {
       
    77     if( aAdapter )
       
    78         {
       
    79         aAdapter->Window().SetOrdinalPosition( 1 );
       
    80         }    
       
    81     }
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // Changes window position
       
    85 // -----------------------------------------------------------------------------
       
    86 //
       
    87 void SetWindowPosition( CXnControlAdapter* aAdapter, const TPoint& aPos )
       
    88     {
       
    89     if( aAdapter )
       
    90         {
       
    91         aAdapter->Window().SetPosition( aPos );
       
    92         }
       
    93     }
       
    94 
       
    95 // -----------------------------------------------------------------------------
       
    96 // Hide/Show control
       
    97 // -----------------------------------------------------------------------------
       
    98 //
       
    99 void SetVisible( CCoeControl* aControl, TBool aVisible )
       
   100     {
       
   101     if( aControl )
       
   102         {
       
   103         aControl->MakeVisible( aVisible );
       
   104         }
       
   105     }
       
   106 
       
   107 // -----------------------------------------------------------------------------
       
   108 // ShowNodes
       
   109 // -----------------------------------------------------------------------------
       
   110 //
       
   111 void ShowNodesL( CXnNode& aNode, TBool aShow )
       
   112     {    
       
   113     CXnDomStringPool* sp( aNode.DomNode()->StringPool() );
       
   114     
       
   115     CXnProperty* prop( NULL );
       
   116     if( aShow )
       
   117         {
       
   118         prop = CXnProperty::NewL(
       
   119             XnPropertyNames::style::common::KDisplay, 
       
   120             XnPropertyNames::style::common::display::KBlock,
       
   121             CXnDomPropertyValue::EString, *sp );    
       
   122         } 
       
   123     else
       
   124         {
       
   125         prop = CXnProperty::NewL(
       
   126             XnPropertyNames::style::common::KDisplay, 
       
   127             XnPropertyNames::style::common::display::KNone,
       
   128             CXnDomPropertyValue::EString, *sp );
       
   129         }
       
   130     CleanupStack::PushL( prop );    
       
   131     
       
   132     aNode.SetPropertyWithoutNotificationL( prop );
       
   133     CleanupStack::Pop( prop );
       
   134     }
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // IsNodeVisible
       
   138 // -----------------------------------------------------------------------------
       
   139 //
       
   140 TBool IsNodeVisibleL( CXnNode& aNode )
       
   141     {
       
   142     CXnProperty* displayProp( aNode.DisplayL() );
       
   143 
       
   144     if ( displayProp )
       
   145         {
       
   146         const TDesC8& display( displayProp->StringValue() );
       
   147 
       
   148         if ( display == XnPropertyNames::style::common::display::KBlock )
       
   149             {
       
   150             return ETrue;
       
   151             }
       
   152         }
       
   153     return EFalse;
       
   154     }
       
   155     
       
   156 // ============================ MEMBER FUNCTIONS ===============================
       
   157 
       
   158 // -----------------------------------------------------------------------------
       
   159 // CXnViewSwitcher::NewL
       
   160 // Symbian static 1st phase constructor
       
   161 // -----------------------------------------------------------------------------
       
   162 //
       
   163 CXnViewSwitcher* CXnViewSwitcher::NewL()
       
   164     {
       
   165     CXnViewSwitcher* self = new (ELeave) CXnViewSwitcher();
       
   166 
       
   167     CleanupStack::PushL(self);
       
   168     self->ConstructL();
       
   169     CleanupStack::Pop(self);
       
   170 
       
   171     return self;
       
   172     }
       
   173 
       
   174 // -----------------------------------------------------------------------------
       
   175 // CXnViewSwitcher::ConstructL
       
   176 // Symbian 2nd phase constructor can leave.
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 void CXnViewSwitcher::ConstructL()
       
   180     {
       
   181     iFingerFollowSupported = IsFingerFollowSupportedL();
       
   182     iTimer = CPeriodic::NewL( CActive::EPriorityUserInput );
       
   183     iViewSwitchState = KViewSwitchIdle;
       
   184     }
       
   185 
       
   186 // -----------------------------------------------------------------------------
       
   187 // CXnViewSwitcher::CXnViewSwitcher
       
   188 // C++ default constructor
       
   189 // -----------------------------------------------------------------------------
       
   190 //
       
   191 CXnViewSwitcher::CXnViewSwitcher() :
       
   192     iAppUi(static_cast<CXnAppUiAdapter&> (*iAvkonAppUi))
       
   193     {
       
   194     }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CXnViewSwitcher::~CXnViewSwitcher
       
   198 // C++ destructor
       
   199 // -----------------------------------------------------------------------------
       
   200 //
       
   201 CXnViewSwitcher::~CXnViewSwitcher()
       
   202     {    
       
   203     if (iTimer->IsActive())
       
   204         {
       
   205         iTimer->Cancel();
       
   206         }
       
   207     delete iTimer;
       
   208     }
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // -----------------------------------------------------------------------------
       
   212 //
       
   213 TBool CXnViewSwitcher::FingerFollowSupported() const
       
   214     {
       
   215     return iFingerFollowSupported;
       
   216     }
       
   217 
       
   218 // -----------------------------------------------------------------------------
       
   219 // -----------------------------------------------------------------------------
       
   220 //
       
   221 TBool CXnViewSwitcher::ProcessPointerEventL(const TPointerEvent& aPointerEvent )
       
   222     {
       
   223     TBool consumed(EFalse);
       
   224     
       
   225     if ( FingerFollowSupported() )
       
   226         {
       
   227         TPoint parentPos = aPointerEvent.iParentPosition;
       
   228 
       
   229         switch (aPointerEvent.iType)
       
   230             {
       
   231             case TPointerEvent::EButton1Down:
       
   232                 {
       
   233                 if ( iViewSwitchState == KViewSwitchBegin || iViewSwitchState
       
   234                         == KViewSwitchIdle )
       
   235                     {
       
   236                     if (iTimer->IsActive())
       
   237                         {
       
   238                         iTimer->Cancel();
       
   239                         }
       
   240                     if( SetupViewsL() )
       
   241                         {
       
   242                         iViewSwitchState = KViewSwitchBegin;
       
   243                         iStartPosition = parentPos;
       
   244                         iScrollSpeed = KMaxScrollSpeed;
       
   245                         iTickAmount = 0;
       
   246                         iDirection = KCurrentView;
       
   247                         iScrollDistance = 0;
       
   248                         iScrollDirectionDistance = 0;
       
   249                         }
       
   250                     }
       
   251                 else if( iViewSwitchState == KViewSwitchDragOngoing )
       
   252                     {
       
   253                     consumed = ETrue;
       
   254                     }
       
   255                 else if( iViewSwitchState == KViewSwitchScroll )
       
   256                     {
       
   257                     consumed = ETrue;
       
   258 
       
   259                     if( iActivateView == KCurrentView )
       
   260                         {
       
   261                         if (iTimer->IsActive())
       
   262                             {
       
   263                             iTimer->Cancel();
       
   264                             }                    
       
   265 
       
   266                         iViewSwitchState = KViewSwitchDragOngoing;
       
   267                         consumed = ETrue;    
       
   268                         iViewStartPosition = iViewPosition;
       
   269                         iScrollDistance = 0;
       
   270                         iScrollDirectionDistance = 0;
       
   271                         iStartPosition = parentPos;
       
   272 
       
   273                         iTimer->Start( 0, KDrawDelay, TCallBack(
       
   274                                 TimerCallback, this ) );
       
   275                         }
       
   276                     else if( iActivateView == KNextView )
       
   277                         {
       
   278                         if( iCurrentView.iAdapter && iNextView.iAdapter && 
       
   279                             iPreviousView.iAdapter )
       
   280                             {
       
   281                             if (iTimer->IsActive())
       
   282                                 {
       
   283                                 iTimer->Cancel();
       
   284                                 }
       
   285                             
       
   286                             iViewSwitchState = KViewSwitchDragOngoing;
       
   287                             iActivateView = KCurrentView;
       
   288                             
       
   289                             if( iPreviousView.iAdapter == iNextView.iAdapter )
       
   290                                 {
       
   291                                 iPreviousView = iCurrentView;
       
   292                                 iCurrentView = iNextView;
       
   293                                 iNextView = iPreviousView;
       
   294                                 }
       
   295                             else
       
   296                                 {
       
   297                                 iPreviousView = iCurrentView;
       
   298     
       
   299                                 iCurrentView = iNextView;
       
   300                                 
       
   301                                 iNextView.iReadyToDraw = EFalse;
       
   302                                 CXnViewData* nextViewData( 
       
   303                                     ViewData( *iCurrentView.iViewData, KNextView ) );
       
   304                                 CXnNode* nextViewNode( nextViewData->ViewNode() );
       
   305                                 if( nextViewNode )
       
   306                                     {
       
   307                                     iNextView.iAdapter = nextViewNode->Control();
       
   308                                     iNextView.iViewData = nextViewData;
       
   309                                     iNextView.iBgDrawn = EFalse;
       
   310                                     }                            
       
   311                                 }
       
   312                             
       
   313                             iViewStartPosition = iCurrentView.iAdapter->Window().Position();
       
   314                             iScrollDistance = 0;
       
   315                             iScrollDirectionDistance = 0;
       
   316                             iStartPosition = parentPos;
       
   317                         
       
   318                             iScrollSpeed = KMaxScrollSpeed;
       
   319                             iTickAmount = 0;
       
   320                             iTimer->Start( 0, KDrawDelay, TCallBack(
       
   321                                     TimerCallback, this ) );
       
   322                             }
       
   323                         consumed = ETrue;
       
   324                         }
       
   325                     else if( iActivateView == KPreviousView )
       
   326                         {
       
   327                         if( iCurrentView.iAdapter && iNextView.iAdapter && 
       
   328                             iPreviousView.iAdapter )
       
   329                             {
       
   330                             if (iTimer->IsActive())
       
   331                                 {
       
   332                                 iTimer->Cancel();
       
   333                                 }
       
   334                             
       
   335                             iViewSwitchState = KViewSwitchDragOngoing;
       
   336                             iActivateView = KCurrentView;
       
   337 
       
   338                             if( iPreviousView.iAdapter == iNextView.iAdapter )
       
   339                                 {
       
   340                                 iNextView = iCurrentView;
       
   341                                 iCurrentView = iPreviousView;
       
   342                                 iPreviousView = iNextView;
       
   343                                 }
       
   344                             else
       
   345                                 {
       
   346                                 iNextView = iCurrentView;
       
   347     
       
   348                                 iCurrentView = iPreviousView;
       
   349                                 
       
   350                                 iPreviousView.iReadyToDraw = EFalse;
       
   351                                 CXnViewData* prevViewData( 
       
   352                                     ViewData( *iCurrentView.iViewData, KPreviousView ) );
       
   353                                 CXnNode* prevViewNode( prevViewData->ViewNode() );
       
   354                                 if( prevViewNode )
       
   355                                     {
       
   356                                     iPreviousView.iAdapter = prevViewNode->Control();
       
   357                                     iPreviousView.iViewData = prevViewData;
       
   358                                     iPreviousView.iBgDrawn = EFalse;
       
   359                                     }                            
       
   360                                 }
       
   361 
       
   362                             iViewStartPosition = iCurrentView.iAdapter->Window().Position();
       
   363                             iScrollDistance = 0;
       
   364                             iScrollDirectionDistance = 0;
       
   365                             iStartPosition = parentPos;
       
   366                         
       
   367                             iScrollSpeed = KMaxScrollSpeed;
       
   368                             iTickAmount = 0;
       
   369                             iTimer->Start( 0, KDrawDelay, TCallBack(
       
   370                                 TimerCallback, this ) );
       
   371                             }
       
   372                         consumed = ETrue;
       
   373                         }
       
   374                     }
       
   375                 }
       
   376                 break;
       
   377             case TPointerEvent::EDrag:
       
   378                 {
       
   379                 if( iViewSwitchState == KViewSwitchIdle )
       
   380                     {
       
   381                     consumed = EFalse;
       
   382                     }
       
   383                 else if( iViewSwitchState == KViewSwitchBegin )
       
   384                     {
       
   385                     TPoint delta = parentPos - iStartPosition;
       
   386 
       
   387                     if( Abs(delta.iX) > KDragTreshold || Abs(delta.iY) > KDragTreshold )
       
   388                         {
       
   389 #ifdef RD_TACTILE_FEEDBACK            
       
   390                         MTouchFeedback* feedback( MTouchFeedback::Instance() );
       
   391                         
       
   392                         if ( feedback )
       
   393                             {
       
   394                             feedback->InstantFeedback( ETouchFeedbackBasic );
       
   395                             }
       
   396 #endif                           
       
   397 
       
   398                         iViewSwitchState = KViewSwitchDragOngoing;
       
   399                         iActivateView = KCurrentView;
       
   400                         iViewPosition.iY = iCurrentView.iAdapter->Position().iY;
       
   401                         iViewPosition.iX = 0;
       
   402                         iStartPosition = parentPos;
       
   403 
       
   404                         StartViewDraggingL();
       
   405 
       
   406                         iTimer->Start( 0, KDrawDelay, TCallBack(
       
   407                                 TimerCallback, this ) );
       
   408                         }
       
   409                     consumed = ETrue;
       
   410                     }
       
   411                 else if( iViewSwitchState == KViewSwitchDragOngoing )
       
   412                     {
       
   413                     iScrollDistance = parentPos.iX - iStartPosition.iX;
       
   414                     consumed = ETrue;
       
   415                     }
       
   416                 else
       
   417                     {
       
   418                     consumed = EFalse;                
       
   419                     }
       
   420                 }
       
   421                 break;
       
   422             case TPointerEvent::EButton1Up:
       
   423                 {
       
   424                 if( iViewSwitchState == KViewSwitchBegin )
       
   425                     {
       
   426                     iViewSwitchState = KViewSwitchIdle;
       
   427                     }
       
   428                 else if( iViewSwitchState == KViewSwitchDragOngoing )
       
   429                     {
       
   430                     if (iTimer->IsActive())
       
   431                         {
       
   432                         iTimer->Cancel();
       
   433                         }                    
       
   434 
       
   435 #ifdef RD_TACTILE_FEEDBACK            
       
   436 /*
       
   437                     MTouchFeedback* feedback( MTouchFeedback::Instance() );
       
   438                     
       
   439                     if ( feedback )
       
   440                         {
       
   441                         feedback->InstantFeedback( ETouchFeedbackBasic );
       
   442                         }
       
   443 */
       
   444 #endif                           
       
   445 
       
   446                     consumed = ETrue;
       
   447                     
       
   448                     StartViewScrolling();
       
   449                     iViewSwitchState = KViewSwitchScroll;
       
   450                     }
       
   451                 else if( iViewSwitchState == KViewSwitchScroll )
       
   452                     {
       
   453                     consumed = ETrue;
       
   454                     }
       
   455                 }
       
   456                 break;
       
   457             default:
       
   458                 break;
       
   459             }
       
   460         }
       
   461 
       
   462     return consumed;
       
   463     }
       
   464     
       
   465 // -----------------------------------------------------------------------------
       
   466 // -----------------------------------------------------------------------------
       
   467 //
       
   468 void CXnViewSwitcher::TouchGesture( TAknTouchGestureFwType& /*aTouchGesture*/ )
       
   469     {
       
   470     }
       
   471 
       
   472 // -----------------------------------------------------------------------------
       
   473 // CXnViewSwitcher::SizeChanged
       
   474 // -----------------------------------------------------------------------------
       
   475 // 
       
   476 void CXnViewSwitcher::SizeChanged( TRect aRect )
       
   477     {
       
   478     iRect = aRect;
       
   479     }
       
   480 
       
   481 // -----------------------------------------------------------------------------
       
   482 // -----------------------------------------------------------------------------
       
   483 //
       
   484 TBool CXnViewSwitcher::SetupViewsL()
       
   485     {
       
   486     TBool ret = EFalse;
       
   487     
       
   488     CXnViewManager& wManager = iAppUi.ViewManager();
       
   489     iCurrentView.iViewData = &wManager.ActiveViewData();
       
   490     iCurrentView.iAdapter = iCurrentView.iViewData->ViewNode()->Control();
       
   491     iCurrentView.iReadyToDraw = ETrue;
       
   492     iCurrentView.iBgDrawn = ETrue;
       
   493 
       
   494     iViewStartPosition = TPoint( 0, iCurrentView.iAdapter->Window().Position().iY );
       
   495 
       
   496     if ( wManager.ViewAmount() > 1 )
       
   497         {
       
   498         ret = ETrue;
       
   499         
       
   500         CXnNode* nextViewNode( wManager.NextViewData().ViewNode() );
       
   501         if( nextViewNode )
       
   502             {
       
   503             iNextView.iAdapter = nextViewNode->Control();
       
   504             iNextView.iViewData = &wManager.NextViewData();
       
   505             }
       
   506 
       
   507         CXnNode* prevViewNode( wManager.PreviousViewData().ViewNode() );
       
   508         if( prevViewNode && prevViewNode == nextViewNode )
       
   509             {
       
   510             // Only 2 views in Homesceern -> previous = next
       
   511             iPreviousView = iNextView;
       
   512             }
       
   513         else if( prevViewNode )
       
   514             {
       
   515             iPreviousView.iAdapter = prevViewNode->Control();
       
   516             iPreviousView.iViewData = &wManager.PreviousViewData();
       
   517             }
       
   518         }
       
   519     return ret;
       
   520     }
       
   521 
       
   522 // -----------------------------------------------------------------------------
       
   523 // -----------------------------------------------------------------------------
       
   524 //
       
   525 void CXnViewSwitcher::PrepareViewL( CXnViewSwitcher::TViewInformation& aView )
       
   526     {
       
   527     if( !aView.iAdapter || !aView.iViewData )
       
   528         {
       
   529         return;
       
   530         }
       
   531     
       
   532     CXnControlAdapter& adapter = *aView.iAdapter;
       
   533     RWindow& win( adapter.Window() );
       
   534     win.SetOrdinalPosition( -1 );
       
   535     adapter.MakeVisible( ETrue );
       
   536 
       
   537     CXnNode* viewNode( aView.iViewData->ViewNode() );
       
   538     TBool nodesVisible( IsNodeVisibleL( *viewNode ) );
       
   539     if( !nodesVisible )
       
   540         {
       
   541         // Set visible temporarily
       
   542         ShowNodesL( *viewNode, ETrue );
       
   543         }
       
   544     
       
   545     iAppUi.ViewAdapter().EnterEditStateL( *aView.iViewData, EFalse );
       
   546         
       
   547     viewNode->UiEngine()->RenderUIL( viewNode );
       
   548     aView.iReadyToDraw = ETrue;
       
   549     }
       
   550 
       
   551 // -----------------------------------------------------------------------------
       
   552 // -----------------------------------------------------------------------------
       
   553 //
       
   554 void CXnViewSwitcher::StartViewDraggingL()
       
   555     {
       
   556     // Remove focused node, in order to prevent activate triggers
       
   557     CXnNode* currentViewNode =
       
   558             iAppUi.ViewManager().ActiveViewData(). Node()->LayoutNode();
       
   559     CXnUiEngine* engine(currentViewNode->UiEngine());
       
   560 
       
   561     CXnNode* focusedNode = engine->FocusedNode();
       
   562     if (focusedNode)
       
   563         {
       
   564         focusedNode->UnsetStateL(XnPropertyNames::style::common::KPressedDown);
       
   565         focusedNode->UnsetStateL(XnPropertyNames::style::common::KFocus);
       
   566         }
       
   567 
       
   568     // Send button up to prevent long tapping 
       
   569     TPointerEvent pointerEvent;
       
   570     pointerEvent.iType = TPointerEvent::EButton1Up;
       
   571     if ( iCurrentView.iAdapter )
       
   572         {
       
   573         iCurrentView.iAdapter->CXnControlAdapter::HandlePointerEventL(
       
   574                 pointerEvent);
       
   575         }
       
   576     }
       
   577 
       
   578 // -----------------------------------------------------------------------------
       
   579 // -----------------------------------------------------------------------------
       
   580 //
       
   581 void CXnViewSwitcher::StartViewScrolling()
       
   582     {
       
   583     TInt screenWidth = iCurrentView.iAdapter->Window().Size().iWidth;
       
   584 
       
   585     UpdateViewToBeActivated( KDragOffsetForPageSwitch );
       
   586 
       
   587     switch (iActivateView)
       
   588         {
       
   589         case KPreviousView:
       
   590             {
       
   591             iScrollDistance = screenWidth - iViewPosition.iX;
       
   592             }
       
   593             break;
       
   594         case KNextView:
       
   595             {
       
   596             iScrollDistance = -screenWidth - iViewPosition.iX;
       
   597             }
       
   598             break;
       
   599         default: // KCurrentView
       
   600             {
       
   601             iScrollDistance = -iViewPosition.iX;
       
   602             }
       
   603             break;
       
   604         }
       
   605 
       
   606     TInt minSpeed = Abs( iScrollDistance / ( KAnimationDuration / KDrawDelay ) );
       
   607     iScrollSpeed = Abs( iScrollSpeed );
       
   608     if( iScrollSpeed < minSpeed )
       
   609         {
       
   610         iScrollSpeed = minSpeed;
       
   611         }
       
   612     if( iScrollSpeed < KMinScrollSpeed )
       
   613         {
       
   614         iScrollSpeed = KMinScrollSpeed;
       
   615         }
       
   616     if (iTimer->IsActive())
       
   617         {
       
   618         iTimer->Cancel();
       
   619         }
       
   620     
       
   621     iTimer->Start(KDrawDelay, KDrawDelay, TCallBack(
       
   622             TimerCallback, this));
       
   623     }
       
   624 
       
   625 
       
   626 // -----------------------------------------------------------------------------
       
   627 // -----------------------------------------------------------------------------
       
   628 //
       
   629 void CXnViewSwitcher::ViewSwitchEndedL()
       
   630     {
       
   631     iViewSwitchState = KViewSwitchIdle;
       
   632 
       
   633     if (iTimer->IsActive())
       
   634         {
       
   635         iTimer->Cancel();
       
   636         }
       
   637 
       
   638     iViewPosition.iX = 0;
       
   639 
       
   640     if ( iCurrentView.iAdapter )
       
   641         {
       
   642         CXnViewManager& wManager( iAppUi.ViewManager() );
       
   643         CXnViewData* activeViewData( &wManager.ActiveViewData() ); 
       
   644         
       
   645         switch( iActivateView )
       
   646             {
       
   647             case KCurrentView:
       
   648                 SetVisible( iNextView.iAdapter, EFalse );
       
   649                 SetVisible( iPreviousView.iAdapter, EFalse );    
       
   650                 
       
   651                 if( iCurrentView.iViewData && activeViewData != iCurrentView.iViewData )
       
   652                     {
       
   653                     wManager.ActivateViewL( *iCurrentView.iViewData, TUid::Null(), EFalse );            
       
   654                     }
       
   655                 break;
       
   656             case KPreviousView:
       
   657                 if ( iPreviousView.iAdapter )
       
   658                     {
       
   659                     SetVisible( iCurrentView.iAdapter, EFalse );
       
   660                     if( iPreviousView.iAdapter != iNextView.iAdapter )
       
   661                         {
       
   662                         SetVisible( iNextView.iAdapter, EFalse );
       
   663                         }
       
   664 
       
   665                     CXnViewData* prevViewData( ViewData( *iCurrentView.iViewData, KPreviousView ) );
       
   666                     if( prevViewData && activeViewData != prevViewData )
       
   667                         {
       
   668                         wManager.ActivateViewL( *prevViewData, TUid::Null(), EFalse );            
       
   669                         }
       
   670                     }
       
   671                 break;
       
   672             case KNextView:
       
   673                 if ( iNextView.iAdapter )
       
   674                     {
       
   675                     SetVisible( iCurrentView.iAdapter, EFalse );
       
   676                     if( iPreviousView.iAdapter != iNextView.iAdapter )
       
   677                         {
       
   678                         SetVisible( iPreviousView.iAdapter, EFalse );                
       
   679                         }
       
   680 
       
   681                     CXnViewData* nextViewData( ViewData( *iCurrentView.iViewData, KNextView ) );
       
   682                     if( nextViewData && activeViewData != nextViewData )
       
   683                         {
       
   684                         wManager.ActivateViewL( *nextViewData, TUid::Null(), EFalse );            
       
   685                         }                    
       
   686                     }
       
   687                 break;
       
   688             }
       
   689 
       
   690         ClearViews();
       
   691         }
       
   692     }
       
   693 
       
   694 // -----------------------------------------------------------------------------
       
   695 // -----------------------------------------------------------------------------
       
   696 //
       
   697 void CXnViewSwitcher::Scroll()
       
   698     {
       
   699     TInt scrollStep = iScrollDistance / 1.5;
       
   700 
       
   701     if( Abs( scrollStep ) > Abs( iScrollSpeed ) )
       
   702         {
       
   703         scrollStep = ( scrollStep > 0 ) ? iScrollSpeed : -iScrollSpeed;
       
   704         }
       
   705 
       
   706     iViewPosition.iX += scrollStep;
       
   707     iScrollDistance -= scrollStep;
       
   708     }
       
   709         
       
   710 // -----------------------------------------------------------------------------
       
   711 // -----------------------------------------------------------------------------
       
   712 //
       
   713 void CXnViewSwitcher::DoScroll()
       
   714     {
       
   715     SetWindowPosition( iCurrentView.iAdapter, iViewPosition );
       
   716 
       
   717     if( iViewPosition.iX < 0 && iNextView.iAdapter )
       
   718         {
       
   719         // next view shown
       
   720         if( !iNextView.iReadyToDraw )
       
   721             {
       
   722             TRAP_IGNORE( PrepareViewL( iNextView ) );
       
   723             if( iPreviousView.iAdapter == iNextView.iAdapter )
       
   724                 {
       
   725                 iPreviousView.iReadyToDraw = ETrue;          
       
   726                 }
       
   727             }
       
   728         
       
   729         ShowAdapter( iNextView.iAdapter );
       
   730         if( iPreviousView.iAdapter != iNextView.iAdapter )
       
   731             {
       
   732             HideAdapter( iPreviousView.iAdapter );
       
   733             }
       
   734         
       
   735         TPoint pos( TPoint( iViewPosition.iX + iRect.Width(), iViewPosition.iY ) );
       
   736         SetWindowPosition( iNextView.iAdapter, pos );
       
   737         }
       
   738 
       
   739     else if( iViewPosition.iX > 0 && iPreviousView.iAdapter )
       
   740         {
       
   741         // previous view shown
       
   742         if( !iPreviousView.iReadyToDraw )
       
   743             {
       
   744             TRAP_IGNORE( PrepareViewL( iPreviousView ) );
       
   745             }
       
   746 
       
   747         ShowAdapter( iPreviousView.iAdapter );
       
   748         if( iPreviousView.iAdapter != iNextView.iAdapter )
       
   749             {
       
   750             HideAdapter( iNextView.iAdapter );
       
   751             }
       
   752         TPoint pos( TPoint( iViewPosition.iX - iRect.Width(), iViewPosition.iY ) );
       
   753         SetWindowPosition( iPreviousView.iAdapter, pos );
       
   754         }
       
   755     
       
   756     else
       
   757         {
       
   758         HideAdapter( iPreviousView.iAdapter );
       
   759         HideAdapter( iNextView.iAdapter );
       
   760         }
       
   761     }
       
   762 
       
   763 // -----------------------------------------------------------------------------
       
   764 // -----------------------------------------------------------------------------
       
   765 //
       
   766 TInt CXnViewSwitcher::TimerCallback(TAny *aPtr)
       
   767     {
       
   768     CXnViewSwitcher* self = reinterpret_cast<CXnViewSwitcher*> (aPtr);
       
   769 
       
   770     if( self->iViewSwitchState == KViewSwitchDragOngoing )
       
   771         {
       
   772         TInt prevViewPos( self->iViewPosition.iX );
       
   773         self->iViewPosition.iX = self->iViewStartPosition.iX + self->iScrollDistance;
       
   774         self->DoScroll();
       
   775         
       
   776         self->UpdateViewToBeActivated( KDragOffsetForBackground );
       
   777         
       
   778         // Hack for informing NGA to draw. 
       
   779         self->iAppUi.ViewAdapter().BgManager().DrawNow(TRect(0,0,1,1));
       
   780         
       
   781         // Scroll speed is average drag delta between timer callbacks.
       
   782         self->iTickAmount++;
       
   783 
       
   784         TInt scrollDistance = self->iViewPosition.iX - prevViewPos;
       
   785         
       
   786         if( ( scrollDistance < 0 && self->iScrollDirectionDistance > 0 ) || 
       
   787             ( scrollDistance > 0 && self->iScrollDirectionDistance < 0 ) )
       
   788             {
       
   789             // Scroll direction has been changed
       
   790             self->iScrollDirectionDistance = scrollDistance;
       
   791             self->iScrollSpeed = scrollDistance;
       
   792             self->iTickAmount = 1;            
       
   793             }
       
   794         else
       
   795             {
       
   796             self->iScrollDirectionDistance += scrollDistance;
       
   797             self->iScrollSpeed = self->iScrollDistance / self->iTickAmount;    
       
   798             }
       
   799         
       
   800         if( scrollDistance < 0 )
       
   801             {
       
   802             self->iDirection = KNextView;
       
   803             }
       
   804         else if( scrollDistance > 0 )
       
   805             {
       
   806             self->iDirection = KPreviousView;
       
   807             }
       
   808 
       
   809         return 0;
       
   810         }
       
   811 
       
   812     if ( Abs( self->iScrollDistance ) <= 2 )
       
   813         {
       
   814         TRAP_IGNORE( self->ViewSwitchEndedL() );
       
   815         }
       
   816     else
       
   817         {
       
   818         self->Scroll();
       
   819         self->DoScroll();
       
   820         
       
   821         // Hack for inforing NGA to draw. 
       
   822         self->iAppUi.ViewAdapter().BgManager().DrawNow(TRect(0,0,1,1));
       
   823         }
       
   824     return 0;
       
   825     }
       
   826 
       
   827 // -----------------------------------------------------------------------------
       
   828 // -----------------------------------------------------------------------------
       
   829 //
       
   830 TBool CXnViewSwitcher::IsFingerFollowSupportedL() const
       
   831     {    
       
   832     CRepository* repository =
       
   833             CRepository::NewL(TUid::Uid(KCRUidActiveIdleLV));
       
   834     TBool value(EFalse);
       
   835     TInt err(repository->Get(KAIFingerFollowSupport, value));
       
   836     delete repository;
       
   837 
       
   838     return value && (KErrNone == err);
       
   839     }
       
   840 
       
   841 // -----------------------------------------------------------------------------
       
   842 // -----------------------------------------------------------------------------
       
   843 //
       
   844 CXnViewData* CXnViewSwitcher::ViewData( CXnViewData& aCurrentViewData, 
       
   845     TInt aView )
       
   846     {
       
   847     CXnRootData& rootData = iAppUi.ViewManager().ActiveAppData();
       
   848     RPointerArray<CXnPluginData>& rootDataArr = rootData.PluginData();
       
   849 
       
   850     CXnViewData* ret( NULL );
       
   851     
       
   852     TInt viewAmount( rootDataArr.Count() );
       
   853     for( TInt i = 0; i < viewAmount; i++ )
       
   854         {
       
   855         CXnViewData* viewData = static_cast<CXnViewData*>( rootDataArr[i] );
       
   856         if( &aCurrentViewData == viewData )
       
   857             {
       
   858             if( aView == KNextView )
       
   859                 {
       
   860                 if( i < viewAmount - 1 )
       
   861                     {
       
   862                     ret = static_cast<CXnViewData*>( rootDataArr[i + 1] );
       
   863                     }
       
   864                 else
       
   865                     {
       
   866                     ret = static_cast<CXnViewData*>( rootDataArr[0] );            
       
   867                     }
       
   868                 break;
       
   869                 }
       
   870             else if( aView == KPreviousView )
       
   871                 {
       
   872                 if( i == 0 )
       
   873                     {
       
   874                     ret = static_cast<CXnViewData*>( rootDataArr[viewAmount - 1] );
       
   875                     }
       
   876                 else
       
   877                     {
       
   878                     ret = static_cast<CXnViewData*>( rootDataArr[i - 1] );            
       
   879                     }            
       
   880                 break;
       
   881                 }
       
   882             }
       
   883         }
       
   884     
       
   885     return ret;
       
   886     }
       
   887 
       
   888 // -----------------------------------------------------------------------------
       
   889 // -----------------------------------------------------------------------------
       
   890 //
       
   891 void CXnViewSwitcher::ClearViews()
       
   892     {
       
   893     TPoint p( 0, iCurrentView.iAdapter->Window().Position().iY );
       
   894     SetWindowPosition( iCurrentView.iAdapter, p );
       
   895     SetWindowPosition( iPreviousView.iAdapter, p );
       
   896     SetWindowPosition( iNextView.iAdapter, p );
       
   897     ShowAdapter( iPreviousView.iAdapter );
       
   898     ShowAdapter( iNextView.iAdapter );
       
   899     ShowAdapter( iCurrentView.iAdapter );
       
   900     iCurrentView.iAdapter = NULL;
       
   901     iCurrentView.iViewData = NULL;
       
   902     iCurrentView.iReadyToDraw = EFalse;
       
   903     iCurrentView.iBgDrawn = EFalse;
       
   904     iNextView.iAdapter = NULL;
       
   905     iNextView.iViewData = NULL;
       
   906     iNextView.iReadyToDraw = EFalse;
       
   907     iNextView.iBgDrawn = EFalse;
       
   908     iPreviousView.iAdapter = NULL;
       
   909     iPreviousView.iViewData = NULL;
       
   910     iPreviousView.iReadyToDraw = EFalse;
       
   911     iPreviousView.iBgDrawn = EFalse;
       
   912     }
       
   913 
       
   914 // -----------------------------------------------------------------------------
       
   915 // -----------------------------------------------------------------------------
       
   916 //
       
   917 void CXnViewSwitcher::UpdateViewToBeActivated( TInt aOffset )
       
   918     {
       
   919     if ( iViewPosition.iX > aOffset && iDirection == KPreviousView && 
       
   920         iScrollDirectionDistance > aOffset / 2)
       
   921         {
       
   922         if( iActivateView != KPreviousView &&
       
   923             iPreviousView.iViewData && iCurrentView.iViewData )
       
   924             {
       
   925             iActivateView = KPreviousView;
       
   926             if( !iPreviousView.iBgDrawn )
       
   927                 {
       
   928                 ChangeBackground( *iCurrentView.iViewData, 
       
   929                     *iPreviousView.iViewData );
       
   930                 iPreviousView.iBgDrawn = ETrue; 
       
   931                 iNextView.iBgDrawn = EFalse;
       
   932                 iCurrentView.iBgDrawn = EFalse;
       
   933                 }
       
   934             }
       
   935         }
       
   936     else if ( iViewPosition.iX < -aOffset && iDirection == KNextView && 
       
   937         iScrollDirectionDistance < -aOffset / 2 )
       
   938         {
       
   939         if( iActivateView != KNextView && 
       
   940             iNextView.iViewData && iCurrentView.iViewData )
       
   941             {
       
   942             iActivateView = KNextView;
       
   943             if( !iNextView.iBgDrawn )
       
   944                 {
       
   945                 ChangeBackground( *iCurrentView.iViewData, 
       
   946                     *iNextView.iViewData );
       
   947                 iPreviousView.iBgDrawn = EFalse; 
       
   948                 iNextView.iBgDrawn = ETrue;
       
   949                 iCurrentView.iBgDrawn = EFalse;                            
       
   950                 }
       
   951             }
       
   952         }
       
   953     else if( iActivateView != KCurrentView && 
       
   954         iPreviousView.iViewData && iNextView.iViewData && iCurrentView.iViewData )
       
   955         {
       
   956         if( Abs( iScrollDirectionDistance ) > aOffset / 2 )
       
   957             {
       
   958             iActivateView = KCurrentView;
       
   959             if( !iCurrentView.iBgDrawn )
       
   960                 {    
       
   961                 ChangeBackground( ( iPreviousView.iBgDrawn ) ? *iPreviousView.iViewData :
       
   962                     *iNextView.iViewData, *iCurrentView.iViewData );                                
       
   963                 iPreviousView.iBgDrawn = EFalse; 
       
   964                 iNextView.iBgDrawn = EFalse;
       
   965                 iCurrentView.iBgDrawn = ETrue;                            
       
   966                 }        
       
   967             }
       
   968         }
       
   969     }
       
   970 
       
   971 // -----------------------------------------------------------------------------
       
   972 // -----------------------------------------------------------------------------
       
   973 //
       
   974 void CXnViewSwitcher::ChangeBackground( CXnViewData& aCurrent, CXnViewData& aNext )
       
   975     {
       
   976     CXnBackgroundManager& bg( iAppUi.ViewAdapter().BgManager() );
       
   977 
       
   978     GfxTransEffect::Begin( &bg, KGfxControlActionBgImgToImgAppear );
       
   979     
       
   980     bg.ChangeWallpaper( aCurrent, aNext, EFalse );
       
   981 
       
   982     GfxTransEffect::SetDemarcation( &bg, bg.Position() );
       
   983     GfxTransEffect::End( &bg ); 
       
   984     }
       
   985 
       
   986 // -----------------------------------------------------------------------------
       
   987 // -----------------------------------------------------------------------------
       
   988 //
       
   989 void CXnViewSwitcher::StopViewSwitchL()
       
   990     {
       
   991     ViewSwitchEndedL();
       
   992     }
       
   993 
       
   994 // End of file