meetingrequest/mrgui/src/cmrlistpane.cpp
branchRCL_3
changeset 25 3533d4323edc
equal deleted inserted replaced
24:d189ee25cf9d 25:3533d4323edc
       
     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:  List pane component for UI fields
       
    15 *
       
    16 */
       
    17 #include "cmrlistpane.h"
       
    18 #include "mesmrfieldstorage.h"
       
    19 #include "mmrscrollbarobserver.h"
       
    20 #include "esmrdef.h"
       
    21 #include "cesmrfield.h"
       
    22 #include "cmrfieldcontainer.h"
       
    23 #include "cmrlistpanephysics.h"
       
    24 #include "nmrlayoutmanager.h"
       
    25 
       
    26 #include <eikscrlb.h>
       
    27 #include <AknUtils.h>
       
    28 #include <touchfeedback.h>
       
    29 
       
    30 //DEBUG
       
    31 #include "emailtrace.h"
       
    32 
       
    33 namespace { // codescanner::namespace
       
    34 
       
    35 const TInt KLongTapDelay( 700000 ); // 0,7 sec
       
    36 const TInt KLongTapAnimationDelay( 300000 ); // 0,3 sec
       
    37 
       
    38 // ----------------
       
    39 // IndexByFieldId
       
    40 // ----------------
       
    41 //
       
    42 TInt IndexByFieldId( const MESMRFieldStorage& aFactory,
       
    43                      TESMREntryFieldId aFieldId )
       
    44     {
       
    45     TInt index( KErrNotFound );
       
    46     TInt count( aFactory.Count() );
       
    47 
       
    48     for ( TInt i = 0; i < count; ++i )
       
    49         {
       
    50         if ( aFactory.Field( i )->FieldId() == aFieldId )
       
    51             {
       
    52             index = i;
       
    53             break;
       
    54             }
       
    55         }
       
    56 
       
    57     return index;
       
    58     }
       
    59 }
       
    60 
       
    61 //----- MEMBER FUNCTIONS ----
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // CMRListPane::CMRListPane
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 CMRListPane::CMRListPane( MESMRFieldStorage& aFactory,
       
    68                           TAknDoubleSpanScrollBarModel& aScrollModel,
       
    69                           CAknDoubleSpanScrollBar& aScroll,
       
    70                           MMRScrollBarObserver& aScrollBarObserver )
       
    71     : iFactory( aFactory ),
       
    72       iScrollModel( aScrollModel ),
       
    73       iScroll( aScroll ),
       
    74       iScrollBarObserver( aScrollBarObserver )
       
    75     {
       
    76     FUNC_LOG;
       
    77     }
       
    78 
       
    79 // ---------------------------------------------------------------------------
       
    80 // CMRListPane::~CMRListPane
       
    81 // ---------------------------------------------------------------------------
       
    82 //
       
    83 CMRListPane::~CMRListPane()
       
    84     {
       
    85     FUNC_LOG;
       
    86     delete iLongtapDetector;
       
    87     delete iPhysics;
       
    88     delete iFieldContainer;
       
    89     }
       
    90 
       
    91 // ---------------------------------------------------------------------------
       
    92 // CMRListPane::NewL
       
    93 // ---------------------------------------------------------------------------
       
    94 //
       
    95 CMRListPane* CMRListPane::NewL( const CCoeControl& aParent,
       
    96                                 MESMRFieldStorage& aFactory,
       
    97                                 TAknDoubleSpanScrollBarModel& aScrollModel,
       
    98                                 CAknDoubleSpanScrollBar& aScroll,
       
    99                                 MMRScrollBarObserver& aScrollBarObserver )
       
   100     {
       
   101     FUNC_LOG;
       
   102     CMRListPane* self = new( ELeave )CMRListPane(
       
   103             aFactory,
       
   104             aScrollModel,
       
   105             aScroll,
       
   106             aScrollBarObserver );
       
   107     CleanupStack::PushL( self );
       
   108     self->ConstructL( aParent );
       
   109     CleanupStack::Pop( self );
       
   110     return self;
       
   111     }
       
   112 
       
   113 // ---------------------------------------------------------------------------
       
   114 // CMRListPane::ConstructL
       
   115 // ---------------------------------------------------------------------------
       
   116 //
       
   117 void CMRListPane::ConstructL( const CCoeControl& aParent )
       
   118     {
       
   119     FUNC_LOG;
       
   120     CCoeControl::SetComponentsToInheritVisibility( ETrue );
       
   121     SetContainerWindowL( aParent );
       
   122 
       
   123     iLongtapDetector = CAknLongTapDetector::NewL( this );
       
   124     iLongtapDetector->SetLongTapDelay( KLongTapDelay );
       
   125     iLongtapDetector->SetTimeDelayBeforeAnimation( KLongTapAnimationDelay );
       
   126 
       
   127     iFieldContainer = CMRFieldContainer::NewL( iFactory, *this );
       
   128     iFieldContainer->SetFieldContainerObserver( this );
       
   129 
       
   130     // Physics: Create physics
       
   131     // Give pointer to control that should be able to flick/drag
       
   132     iPhysics = CMRListPanePhysics::NewL( *this, *iFieldContainer, *this );
       
   133     }
       
   134 
       
   135 // ---------------------------------------------------------------------------
       
   136 // CMRListPane::InitializeL()
       
   137 // ---------------------------------------------------------------------------
       
   138 //
       
   139 void CMRListPane::InitializeL()
       
   140     {
       
   141     FUNC_LOG;
       
   142     const TInt count( iFactory.Count() );
       
   143     for ( TInt i = 0; i < count; i++ )
       
   144         {
       
   145         iFactory.Field(i)->InitializeL();
       
   146         }
       
   147     iClickedField = NULL;
       
   148     }
       
   149 
       
   150 
       
   151 // ---------------------------------------------------------------------------
       
   152 // CMRListPane::InternalizeL()
       
   153 // ---------------------------------------------------------------------------
       
   154 //
       
   155 void CMRListPane::InternalizeL( MESMRCalEntry& aEntry )
       
   156     {
       
   157     FUNC_LOG;
       
   158 
       
   159     iFactory.InternalizeL( aEntry );
       
   160 
       
   161     // Record visible fields
       
   162     RecordFields();
       
   163 
       
   164     // This is called to make sure everything is drawn correctly
       
   165     DrawDeferred();
       
   166     }
       
   167 
       
   168 // ---------------------------------------------------------------------------
       
   169 // CMRListPane::ExternalizeL()
       
   170 // ---------------------------------------------------------------------------
       
   171 //
       
   172 void CMRListPane::ExternalizeL(
       
   173         MESMRCalEntry& aEntry,
       
   174         TBool aForceValidation )
       
   175     {
       
   176     FUNC_LOG;
       
   177     CESMRField* currentFocus = FocusedField();
       
   178     ASSERT( currentFocus );
       
   179     TESMREntryFieldId id = currentFocus->FieldId();
       
   180 
       
   181     if ( aForceValidation )
       
   182         {
       
   183         // force validate the values:
       
   184         TInt err = iFactory.Validate( id, aForceValidation );
       
   185         // fill the calendar entry with data in fields.
       
   186         iFactory.ExternalizeL( aEntry );
       
   187         }
       
   188     else
       
   189         {
       
   190         TInt err = iFactory.Validate( id );
       
   191         if ( err )
       
   192             {
       
   193             //SetControlFocusedL( id ); Why would we set this focused here?
       
   194             User::Leave( err );
       
   195             }
       
   196         else
       
   197             {
       
   198             // fill the calendar entry with data in fields.
       
   199             iFactory.ExternalizeL( aEntry );
       
   200             }
       
   201         }
       
   202     }
       
   203 
       
   204 // ---------------------------------------------------------------------------
       
   205 // CMRListPane::DisableSizeChange()
       
   206 // ---------------------------------------------------------------------------
       
   207 //
       
   208 void CMRListPane::DisableSizeChange(TBool aDisable )
       
   209     {
       
   210     FUNC_LOG;
       
   211     iDisableSizeChanged = aDisable;
       
   212     }
       
   213 
       
   214 // ---------------------------------------------------------------------------
       
   215 // CMRListPane::InitialScroll
       
   216 // ---------------------------------------------------------------------------
       
   217 //
       
   218 void CMRListPane::InitialScrollL()
       
   219     {
       
   220     FUNC_LOG;
       
   221 
       
   222     // Check if the ResponseArea exist
       
   223     TESMREntryFieldId id = GetResponseFieldsFieldId();
       
   224 
       
   225     if( id == EESMRFieldResponseArea )
       
   226         {
       
   227         // Set the focus on the ResponseArea
       
   228         iFieldContainer->SetControlFocusedL( id );
       
   229         //iFactory.FieldById(id)->SetFocus( ETrue );
       
   230 
       
   231         // Scroll the list to put the ResponseArea on the top
       
   232         CESMRField* focusField = FocusedField();
       
   233         TPoint pos( focusField->Position() );
       
   234         ScrollFieldsUp(pos.iY);
       
   235         }
       
   236     }
       
   237 
       
   238 
       
   239 // ---------------------------------------------------------------------------
       
   240 // CMRListPane::FocusedItem
       
   241 // ---------------------------------------------------------------------------
       
   242 //
       
   243 CESMRField* CMRListPane::FocusedField() const
       
   244     {
       
   245     FUNC_LOG;
       
   246     return iFieldContainer->FocusedField();
       
   247     }
       
   248 
       
   249 // ---------------------------------------------------------------------------
       
   250 // CMRListPane::SetControlFocusedL
       
   251 // ---------------------------------------------------------------------------
       
   252 //
       
   253 void CMRListPane::SetControlFocusedL( TESMREntryFieldId aFieldId )
       
   254     {
       
   255     FUNC_LOG;
       
   256     iFieldContainer->SetControlFocusedL( aFieldId );
       
   257     }
       
   258 
       
   259 // ---------------------------------------------------------------------------
       
   260 // CMRListPane::ClickedItem
       
   261 // ---------------------------------------------------------------------------
       
   262 //
       
   263 CESMRField* CMRListPane::ClickedField() const
       
   264     {
       
   265     return iClickedField;
       
   266     }
       
   267 
       
   268 // ---------------------------------------------------------------------------
       
   269 // CMRListPane::CountComponentControls
       
   270 // ---------------------------------------------------------------------------
       
   271 //
       
   272 TInt CMRListPane::CountComponentControls() const
       
   273     {
       
   274     FUNC_LOG;
       
   275     return 1; // iFieldContainer
       
   276 
       
   277     }
       
   278 
       
   279 // ---------------------------------------------------------------------------
       
   280 // CMRListPane::ComponentControl
       
   281 // ---------------------------------------------------------------------------
       
   282 //
       
   283 CCoeControl* CMRListPane::ComponentControl( TInt /*aIndex*/ ) const
       
   284     {
       
   285     FUNC_LOG;
       
   286     return iFieldContainer;
       
   287     }
       
   288 
       
   289 // ---------------------------------------------------------------------------
       
   290 // CMRListPane::SizeChanged
       
   291 // ---------------------------------------------------------------------------
       
   292 //
       
   293 void CMRListPane::SizeChanged()
       
   294     {
       
   295     FUNC_LOG;
       
   296     if ( iDisableSizeChanged || Rect() == TRect( 0, 0, 0, 0 ) )
       
   297         {
       
   298         return;
       
   299         }
       
   300 
       
   301     TSize containerSize( iFieldContainer->MinimumSize() );
       
   302     iFieldContainer->SetSize( containerSize );
       
   303 
       
   304     // Physics:
       
   305     iPhysics->InitPhysics();
       
   306 
       
   307     DoUpdateScrollBar();
       
   308     }
       
   309 
       
   310 // ---------------------------------------------------------------------------
       
   311 // CMRListPane::OfferKeyEventL
       
   312 // ---------------------------------------------------------------------------
       
   313 //
       
   314 TKeyResponse CMRListPane::OfferKeyEventL( const TKeyEvent &aKeyEvent,
       
   315                                           TEventCode aType )
       
   316     {
       
   317     FUNC_LOG;
       
   318     TKeyResponse response( EKeyWasNotConsumed );
       
   319 
       
   320     // First check if the focused item needs the key event
       
   321     response = FocusedField()->OfferKeyEventL( aKeyEvent, aType );
       
   322 
       
   323     if ( aType == EEventKey
       
   324          && response == EKeyWasNotConsumed )
       
   325         {
       
   326         // Check if the focus should be changed
       
   327         switch ( aKeyEvent.iScanCode )
       
   328             {
       
   329             case EStdKeyUpArrow:
       
   330                 {
       
   331                 response = iFieldContainer->MoveFocusUpL( HiddenFocus() );
       
   332 
       
   333                 // Focus changed via keyboard, iClickedItem is no
       
   334                 // longer valid
       
   335                 iClickedField = NULL;
       
   336                 break;
       
   337                 }
       
   338             case EStdKeyDownArrow:
       
   339                 {
       
   340                 response = iFieldContainer->MoveFocusDownL( HiddenFocus() );
       
   341 
       
   342                 // Focus changed via keyboard, iClickedItem is no
       
   343                 // longer valid
       
   344                 iClickedField = NULL;
       
   345                 break;
       
   346                 }
       
   347             case EStdKeyEnter:
       
   348                 {
       
   349                 FocusedField()->ExecuteGenericCommandL( EAknCmdOpen );
       
   350                 break;
       
   351                 }
       
   352             default:
       
   353                 {
       
   354                 break;
       
   355                 }
       
   356             }
       
   357         }
       
   358 
       
   359     return response;
       
   360     }
       
   361 
       
   362 // ---------------------------------------------------------------------------
       
   363 // CMRListPane::HandleLongTapEventL
       
   364 // ---------------------------------------------------------------------------
       
   365 //
       
   366 void CMRListPane::HandleLongTapEventL(
       
   367         const TPoint& aPenEventLocation,
       
   368         const TPoint& /* aPenEventScreenLocation */ )
       
   369     {
       
   370     FUNC_LOG;
       
   371     iLongTapEventInProgess = EFalse;
       
   372     // Long tap functionality may vary between fields
       
   373     // ==> Command field to execute action related to long tap
       
   374     TInt count( iFactory.Count() );
       
   375     for ( TInt i = 0; i < count; ++i )
       
   376         {
       
   377         CESMRField* field = iFactory.Field( i );
       
   378 
       
   379         if ( field->IsVisible()
       
   380              && field->Rect().Contains( aPenEventLocation ) )
       
   381             {
       
   382             field->LongtapDetectedL( aPenEventLocation );
       
   383             iLongTapEventInProgess = ETrue;
       
   384             break;
       
   385             }
       
   386         }
       
   387     }
       
   388 
       
   389 // ---------------------------------------------------------------------------
       
   390 // CMRListPane::DoUpdateScrollBar
       
   391 // ---------------------------------------------------------------------------
       
   392 //
       
   393 void CMRListPane::DoUpdateScrollBar( TInt aFocusPosition )
       
   394     {
       
   395     FUNC_LOG;
       
   396     // Set this lispane's size as scroll bar's window size
       
   397     iScrollModel.SetWindowSize( iSize.iHeight );
       
   398     // Set fieldcontainer's height as scrolbar's scroll span
       
   399     iScrollModel.SetScrollSpan( iFieldContainer->MinimumSize().iHeight );
       
   400 
       
   401     // Update scrollbar focus position.
       
   402     if( aFocusPosition == KErrNotFound )
       
   403         {
       
   404         iScrollModel.SetFocusPosition( iPhysics->VerticalScrollIndex() );
       
   405         }
       
   406     else
       
   407         {
       
   408         iScrollModel.SetFocusPosition( aFocusPosition );
       
   409         }
       
   410 
       
   411     iScroll.SetModel( &iScrollModel );
       
   412 
       
   413     // finally update the new thumb position to view's
       
   414     // iScrollBarThumbPosition member.
       
   415     iScrollBarObserver.ScrollBarPositionChanged(
       
   416             iScroll.ThumbPosition() );
       
   417     }
       
   418 
       
   419 // ---------------------------------------------------------------------------
       
   420 // CMRListPane::UpdatedFocusPosition
       
   421 // ---------------------------------------------------------------------------
       
   422 //
       
   423 TInt CMRListPane::UpdatedFocusPosition()
       
   424     {
       
   425     FUNC_LOG;
       
   426     TInt focusPos = 0;
       
   427     TInt count = iFactory.Count();
       
   428     for ( TInt i = 0; i < count; ++i )
       
   429         {
       
   430         CESMRField* field = iFactory.Field( i );
       
   431         if ( field->IsVisible() )
       
   432             {
       
   433             TRect rect( field->Rect() );
       
   434             // Check if the field's top is above scroll area origo.
       
   435             if ( rect.iTl.iY  < 0 )
       
   436                 {
       
   437                 // Whole field is above origo
       
   438                 if ( rect.iBr.iY < 0 )
       
   439                     {
       
   440                     focusPos += rect.Height();
       
   441                     }
       
   442                 // Part of the field is above origo
       
   443                 else
       
   444                     {
       
   445                     focusPos += Abs( rect.iTl.iY );
       
   446                     }
       
   447                 }
       
   448             else
       
   449                 {
       
   450                 // Rest of the fields are below scroll area origo
       
   451                 break;
       
   452                 }
       
   453             }
       
   454         }
       
   455 
       
   456     return focusPos;
       
   457     }
       
   458 
       
   459 // ---------------------------------------------------------------------------
       
   460 // CMRListPane::ScrollFieldsUp
       
   461 // ---------------------------------------------------------------------------
       
   462 //
       
   463 void CMRListPane::ScrollFieldsUp( TInt aPx )
       
   464     {
       
   465     FUNC_LOG;
       
   466     iPositionChanged = ETrue;
       
   467 
       
   468     iUpdatedPanePoint = iFieldContainer->Position();
       
   469     iUpdatedPanePoint.iY -= aPx;
       
   470 
       
   471     if ( !iPointerEventInProgress )
       
   472         {
       
   473         // We can updace view only if pointer event processing
       
   474         // is not ongoing.
       
   475         // If pointer event processing is ongoing, view is updated
       
   476         // in CMRListPane::HandlePointerEventL method.
       
   477         UpdatePosition();
       
   478         }
       
   479     }
       
   480 
       
   481 // ---------------------------------------------------------------------------
       
   482 // CMRListPane::ScrollFieldsDown
       
   483 // ---------------------------------------------------------------------------
       
   484 //
       
   485 void CMRListPane::ScrollFieldsDown( TInt aPx )
       
   486     {
       
   487     FUNC_LOG;
       
   488 
       
   489     iPositionChanged = ETrue;
       
   490 
       
   491     iUpdatedPanePoint = iFieldContainer->Position();
       
   492     iUpdatedPanePoint.iY += aPx;
       
   493 
       
   494     if ( !iPointerEventInProgress )
       
   495         {
       
   496         // We can updace view only if pointer event processing
       
   497         // is not ongoing.
       
   498         // If pointer event processing is ongoing, view is updated
       
   499         // in CMRListPane::HandlePointerEventL method.
       
   500         UpdatePosition();
       
   501         }
       
   502     }
       
   503 
       
   504 
       
   505 // ---------------------------------------------------------------------------
       
   506 // CMRListPane::UpdateScrollBarAndPhysics
       
   507 // ---------------------------------------------------------------------------
       
   508 //
       
   509 void CMRListPane::UpdateScrollBarAndPhysics()
       
   510     {
       
   511     FUNC_LOG;
       
   512     // Update physics world size
       
   513     iPhysics->InitPhysics();
       
   514 
       
   515     // Update scrollbar
       
   516     DoUpdateScrollBar();
       
   517     }
       
   518 
       
   519 
       
   520 // ---------------------------------------------------------------------------
       
   521 // CMRListPane::ShowControl
       
   522 // ---------------------------------------------------------------------------
       
   523 //
       
   524 void CMRListPane::ShowControl( TESMREntryFieldId aFieldId )
       
   525     {
       
   526     FUNC_LOG;
       
   527     iFieldContainer->ShowControl( aFieldId );
       
   528     }
       
   529 
       
   530 // ---------------------------------------------------------------------------
       
   531 // CMRListPane::ShowControl
       
   532 // ---------------------------------------------------------------------------
       
   533 //
       
   534 TBool CMRListPane::IsControlVisible( TESMREntryFieldId aFieldId )
       
   535     {
       
   536     FUNC_LOG;
       
   537     return iFieldContainer->IsControlVisible( aFieldId );
       
   538     }
       
   539 // ---------------------------------------------------------------------------
       
   540 // CMRListPane::GetResponseFieldsFieldId
       
   541 // ---------------------------------------------------------------------------
       
   542 //
       
   543 TESMREntryFieldId CMRListPane::GetResponseFieldsFieldId()
       
   544     {
       
   545     FUNC_LOG;
       
   546     CESMRField* rfield = iFactory.FieldById( EESMRFieldResponseArea );
       
   547 
       
   548     if ( rfield && rfield->IsVisible() && !rfield->IsNonFocusing() )
       
   549         {
       
   550         return EESMRFieldResponseArea;
       
   551         }
       
   552     else
       
   553         {
       
   554         return iFactory.Field(0)->FieldId();
       
   555         }
       
   556     }
       
   557 
       
   558 // ---------------------------------------------------------------------------
       
   559 // CMRListPane::ReActivateL
       
   560 // ---------------------------------------------------------------------------
       
   561 //
       
   562 void CMRListPane::ReActivateL()
       
   563     {
       
   564     FUNC_LOG;
       
   565     TInt count = iFactory.Count();
       
   566 
       
   567     for ( TInt i = 0; i < count; ++i )
       
   568         {
       
   569         CESMRField* field = iFactory.Field( i );
       
   570 
       
   571         if ( !field->IsFieldActivated() )
       
   572             {
       
   573             field->SetContainerWindowL( *iFieldContainer );
       
   574             field->SetListObserver( iFieldContainer );
       
   575             }
       
   576         }
       
   577 
       
   578     // This "for" circle can not be mixed with the above one, since the
       
   579     // field->ActivateL() will call some functions which will traverse
       
   580     // all the fields, but that time, not all the fields have set the
       
   581     // container window.
       
   582     for ( TInt i = 0; i < count; ++i )
       
   583         {
       
   584         CESMRField* field = iFactory.Field( i );
       
   585         if ( !field->IsFieldActivated() )
       
   586             {
       
   587             field->ActivateL();
       
   588             }
       
   589         }
       
   590     }
       
   591 
       
   592 // ---------------------------------------------------------------------------
       
   593 // CMRListPane::RecordFields
       
   594 // ---------------------------------------------------------------------------
       
   595 //
       
   596 void CMRListPane::RecordFields()
       
   597     {
       
   598     FUNC_LOG;
       
   599 
       
   600     // Loop all visible fields and record them
       
   601     TInt count( iFactory.Count() );
       
   602     for ( TInt i = 0; i < count; ++i )
       
   603         {
       
   604         CESMRField* field = iFactory.Field( i );
       
   605         if ( field->IsVisible() )
       
   606             {
       
   607             field->RecordField();
       
   608             }
       
   609         }
       
   610     }
       
   611 
       
   612 // ---------------------------------------------------------------------------
       
   613 // CMRListPane::HandlePointerEventL
       
   614 // ---------------------------------------------------------------------------
       
   615 //
       
   616 void CMRListPane::HandlePointerEventL( const TPointerEvent &aPointerEvent )
       
   617     {
       
   618     // Check if touch is enabled or not
       
   619     if( !AknLayoutUtils::PenEnabled() )
       
   620         {
       
   621         return;
       
   622         }
       
   623 
       
   624     iPointerEventInProgress = ETrue;
       
   625 
       
   626     // If new down event is received, and
       
   627     // iLongTapEventInProgess flag is still ETrue, we need to
       
   628     // set it back to EFalse -> Long tap event cannot be in progress
       
   629     // in this case anymore.
       
   630     if( aPointerEvent.iType == TPointerEvent::EButton1Down &&
       
   631     		iLongTapEventInProgess )
       
   632     	{
       
   633 		iLongTapEventInProgess = EFalse;
       
   634     	}
       
   635 
       
   636     // Forward all listpane related events to physics api first.
       
   637     if ( iPhysics->HandlePointerEventL( aPointerEvent, iPhysicsActionOngoing ) )
       
   638         {
       
   639         DoUpdateScrollBar();
       
   640         // Physics in action. If long tap detection is active,
       
   641         // it should be cancelled.
       
   642         if( iLongtapDetector->IsActive() )
       
   643         	{
       
   644 			iLongtapDetector->Cancel();
       
   645         	}
       
   646         }
       
   647 
       
   648     if( !iPhysicsActionOngoing && TPointerEvent::EDrag != aPointerEvent.iType )
       
   649     	{
       
   650 		UpdateClickedField( aPointerEvent );
       
   651 
       
   652 		// Offer pointer event to long tap detector if field supports long tap
       
   653 		// functionality
       
   654 		if( ClickedField()->SupportsLongTapFunctionalityL( aPointerEvent ) )
       
   655 			{
       
   656 			iLongtapDetector->PointerEventL( aPointerEvent );
       
   657 			}
       
   658 
       
   659 		SetFocusAfterPointerEventL( aPointerEvent );
       
   660 
       
   661         // If longtap event is in progress, do not pass events to coecontrol
       
   662         if( !iLongTapEventInProgess )
       
   663             {
       
   664             CCoeControl::HandlePointerEventL( aPointerEvent );
       
   665             }
       
   666         // Longtap event executed after up event ->
       
   667         // Let's set iLongTapEventInProgess to EFalse
       
   668         else if( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
   669             {
       
   670 			iLongTapEventInProgess = EFalse;
       
   671             }
       
   672     	}
       
   673 
       
   674     if ( iPositionChanged )
       
   675         {
       
   676         // Position has changed during pointer event processing
       
   677         // ==> adjusting UI to correct position.
       
   678         UpdatePosition();
       
   679         }
       
   680 
       
   681     iPointerEventInProgress = EFalse;
       
   682     }
       
   683 
       
   684 // ---------------------------------------------------------------------------
       
   685 // CMRListPane::ActivateL
       
   686 // ---------------------------------------------------------------------------
       
   687 //
       
   688 void CMRListPane::ActivateL()
       
   689     {
       
   690     FUNC_LOG;
       
   691     // This ActiveteL is required only for setting the initial position
       
   692     // of the field container. After setting the position, physics is
       
   693     // initialized with new values also.
       
   694 
       
   695     CCoeControl::ActivateL();
       
   696     iFieldContainer->SetPosition( Position() );
       
   697 
       
   698     // Physics:
       
   699     iPhysics->InitPhysics();
       
   700     }
       
   701 
       
   702 // ---------------------------------------------------------------------------
       
   703 // CMRListPane::PhysicsEmulationEnded
       
   704 // ---------------------------------------------------------------------------
       
   705 //
       
   706 void CMRListPane::PhysicsEmulationEnded()
       
   707     {
       
   708     FUNC_LOG;
       
   709     DoUpdateScrollBar();
       
   710     iPhysicsActionOngoing = EFalse;
       
   711     Parent()->DrawDeferred();
       
   712     }
       
   713 
       
   714 // ---------------------------------------------------------------------------
       
   715 // CMRListPane::UpdateScrollBarDuringOngoingPhysics
       
   716 // ---------------------------------------------------------------------------
       
   717 //
       
   718 void CMRListPane::UpdateScrollBarDuringOngoingPhysics()
       
   719     {
       
   720     FUNC_LOG;
       
   721     TInt verticalScrollIndex( iPhysics->VerticalScrollIndex() );
       
   722     iScrollModel.SetFocusPosition( verticalScrollIndex );
       
   723 
       
   724 	iScroll.SetModel( &iScrollModel );
       
   725 
       
   726 	// Update the new thumb position to view's
       
   727 	// iScrollBarThumbPosition member.
       
   728 	iScrollBarObserver.ScrollBarPositionChanged(
       
   729 			iScroll.ThumbPosition() );
       
   730 
       
   731 	iScroll.DrawDeferred();
       
   732 
       
   733 	if( FeedbackScrollMarginExceeded(
       
   734 			Abs( verticalScrollIndex - iPreviousVerticalScrollIndex ) ) )
       
   735 		{
       
   736 		HandleTactileFeedback( ETouchFeedbackSensitiveList );
       
   737 
       
   738 		iPreviousVerticalScrollIndex = verticalScrollIndex;
       
   739 		}
       
   740     }
       
   741 
       
   742 // ---------------------------------------------------------------------------
       
   743 // CESMRField::HandleTactileFeedback
       
   744 // ---------------------------------------------------------------------------
       
   745 //
       
   746 void CMRListPane::HandleTactileFeedback(
       
   747 		const TTouchLogicalFeedback& aType )
       
   748 	{
       
   749 	FUNC_LOG;
       
   750 
       
   751 	if( !iTactileFeedback )
       
   752 		{
       
   753 		// Aquire tactile feedback pointer from TLS
       
   754 		iTactileFeedback = MTouchFeedback::Instance();
       
   755 		}
       
   756 
       
   757 	if ( iTactileFeedback && iTactileFeedback->FeedbackEnabledForThisApp() )
       
   758 		{
       
   759 		iTactileFeedback->InstantFeedback( aType );
       
   760 		}
       
   761     }
       
   762 
       
   763 // ---------------------------------------------------------------------------
       
   764 // CMRListPane::SetFocusAfterPointerEventL
       
   765 // ---------------------------------------------------------------------------
       
   766 //
       
   767 void CMRListPane::SetFocusAfterPointerEventL(
       
   768         const TPointerEvent &aPointerEvent )
       
   769     {
       
   770     FUNC_LOG;
       
   771 
       
   772     if( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   773     	{
       
   774 		TInt count( iFactory.Count() );
       
   775 		for( TInt i = 0; i < count; ++i )
       
   776 			{
       
   777 			CESMRField* field = iFactory.Field( i );
       
   778 
       
   779             // Calculate actual screen rect for field.
       
   780             // If field does not have focus, it is layouted off screen
       
   781             TPoint pos( field->Position() );
       
   782             if ( !field->HasOutlineFocus() )
       
   783                 {
       
   784                 pos.iX = field->Parent()->Position().iX;
       
   785                 }
       
   786             TRect rect( pos, field->Size() );
       
   787 
       
   788             if ( field->IsVisible()
       
   789                  && rect.Contains( aPointerEvent.iPosition ) )
       
   790 				{
       
   791 				CESMRField* focusedField = iFieldContainer->FocusedField();
       
   792 
       
   793 				if ( field != focusedField )
       
   794 					{
       
   795 					TBool canLoseFocus(
       
   796 							focusedField->OkToLoseFocusL( field->FieldId() ) );
       
   797 
       
   798 					if ( canLoseFocus )
       
   799 						{
       
   800 						iFieldContainer->SetControlFocusedL( field->FieldId() );
       
   801 						}
       
   802 					}
       
   803                 else
       
   804                     {
       
   805                     // If field is not focused from coecontrol's point of view
       
   806                     // due to focus strategy, we have to set the field
       
   807                     // focused again.
       
   808                     if( !field->IsFocused() )
       
   809                         {
       
   810                         field->SetOutlineFocusL( ETrue );
       
   811                         field->SetFocus( ETrue );
       
   812                         DrawDeferred();
       
   813                         }
       
   814                     }
       
   815 				break;
       
   816 				}
       
   817 			}
       
   818     	}
       
   819     }
       
   820 
       
   821 // ---------------------------------------------------------------------------
       
   822 // CMRListPane::UpdateClickedField
       
   823 // ---------------------------------------------------------------------------
       
   824 //
       
   825 void CMRListPane::UpdateClickedField( const TPointerEvent &aPointerEvent )
       
   826     {
       
   827     FUNC_LOG;
       
   828     TInt fieldCount( iFactory.Count() );
       
   829 
       
   830     for( TInt i = 0; i < fieldCount; ++i )
       
   831         {
       
   832         CESMRField* field = iFactory.Field( i );
       
   833 
       
   834         // Calculate actual screen rect for field.
       
   835         // If field does not have focus, it is layouted off screen
       
   836         TPoint pos( field->Position() );
       
   837         if ( !field->HasOutlineFocus() )
       
   838             {
       
   839             pos.iX = field->Parent()->Position().iX;
       
   840             }
       
   841         TRect rect( pos, field->Size() );
       
   842 
       
   843         if( rect.Contains( aPointerEvent.iPosition )
       
   844             && field->IsVisible() )
       
   845             {
       
   846             if( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   847                 {
       
   848                 iClickedField = field;
       
   849                 }
       
   850             }
       
   851         }
       
   852     }
       
   853 
       
   854 // ---------------------------------------------------------------------------
       
   855 // CMRListPane::HiddenFocus
       
   856 // ---------------------------------------------------------------------------
       
   857 //
       
   858 TBool CMRListPane::HiddenFocus()
       
   859     {
       
   860     FUNC_LOG;
       
   861     TBool hiddenFocus( EFalse );
       
   862 
       
   863     CESMRField* focusedField( iFieldContainer->FocusedField() );
       
   864     TInt focusedFieldIndex( IndexByFieldId(
       
   865             iFactory, focusedField->FieldId() ) );
       
   866 
       
   867     if ( focusedFieldIndex < iFactory.Count() )
       
   868         {
       
   869         TRect focusedFieldRect( focusedField->Rect() );
       
   870         TRect listPaneRect( Rect() );
       
   871 
       
   872         TInt fieldTopY( focusedFieldRect.iTl.iY );
       
   873         TInt fieldBottomY( focusedFieldRect.iBr.iY );
       
   874 
       
   875         TInt listTopY( listPaneRect.iTl.iY );
       
   876         TInt listBottomY( listPaneRect.iBr.iY );
       
   877 
       
   878         if ( ( fieldBottomY > listBottomY ||
       
   879                 fieldTopY < listTopY ) &&
       
   880                     focusedFieldRect.Height() < listPaneRect.Height() )
       
   881             {
       
   882             hiddenFocus = ETrue;
       
   883             }
       
   884         }
       
   885     return hiddenFocus;
       
   886     }
       
   887 
       
   888 // ---------------------------------------------------------------------------
       
   889 // CMRListPane::FeedbackScrollMarginExceeded
       
   890 // ---------------------------------------------------------------------------
       
   891 //
       
   892 TBool CMRListPane::FeedbackScrollMarginExceeded( TInt aMargin )
       
   893     {
       
   894     FUNC_LOG;
       
   895 	/*
       
   896 	 * This compares given margin to default one row
       
   897 	 * field height, and returns ETrue if margin is exceeded.
       
   898 	 * Otherwise EFalse.
       
   899 	 */
       
   900 	TBool ret( EFalse );
       
   901 
       
   902 	if( !iDefaultFieldHeight )
       
   903 		{
       
   904 		TAknLayoutRect fieldLayoutRect(
       
   905 			NMRLayoutManager::GetFieldLayoutRect(
       
   906 					iFieldContainer->Rect(), 1 ) );
       
   907 
       
   908 		iDefaultFieldHeight = fieldLayoutRect.Rect().Height();
       
   909 		}
       
   910 
       
   911 	if( aMargin > iDefaultFieldHeight )
       
   912 		{
       
   913 		ret = ETrue;
       
   914 		}
       
   915 
       
   916     return ret;
       
   917     }
       
   918 
       
   919 // ---------------------------------------------------------------------------
       
   920 // CMRListPane::UpdatePosition
       
   921 // ---------------------------------------------------------------------------
       
   922 //
       
   923 void CMRListPane::UpdatePosition()
       
   924     {
       
   925     // This initializes Draw also
       
   926     iFieldContainer->SetPosition( iUpdatedPanePoint );
       
   927 
       
   928     // Non-kinetic scrolling executed. Update
       
   929     // new position to physics.
       
   930     iPhysics->UpdateVerticalScrollIndex( UpdatedFocusPosition() );
       
   931     DoUpdateScrollBar( UpdatedFocusPosition() );
       
   932 
       
   933     iPositionChanged = EFalse;
       
   934     }
       
   935 
       
   936 // End of file