meetingrequest/mrgui/src/cmrlistpane.cpp
changeset 0 8466d47a6819
child 16 4ce476e64c59
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2009-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 
       
    19 #include <eikscrlb.h>
       
    20 #include <AknUtils.h>
       
    21 #include <touchfeedback.h>
       
    22 
       
    23 #include "mesmrfieldstorage.h"
       
    24 #include "cesmrfield.h"
       
    25 
       
    26 #include "emailtrace.h"
       
    27 
       
    28 namespace // codescanner::namespace
       
    29     {
       
    30     /**
       
    31      * Vertical scroll margin
       
    32      */
       
    33     const TInt KVerticalScrollMargin = 3;
       
    34 
       
    35     // ---------------------------------------------------------------------------
       
    36     // IndexByFieldId
       
    37     // ---------------------------------------------------------------------------
       
    38     //
       
    39     TInt IndexByFieldId( const MESMRFieldStorage& aFactory,
       
    40                          TESMREntryFieldId aFieldId )
       
    41         {
       
    42         TInt index( KErrNotFound );
       
    43         TInt count( aFactory.Count() );
       
    44         
       
    45         for ( TInt i = 0; i < count; ++i )
       
    46             {
       
    47             if ( aFactory.Field( i )->FieldId() == aFieldId )
       
    48                 {
       
    49                 index = i;
       
    50                 break;
       
    51                 }
       
    52             }
       
    53         
       
    54         return index;
       
    55         }
       
    56     }
       
    57 
       
    58 //----- MEMBER FUNCTIONS ----
       
    59 
       
    60 // ---------------------------------------------------------------------------
       
    61 // CMRListPane::NewL
       
    62 // ---------------------------------------------------------------------------
       
    63 //
       
    64 CMRListPane* CMRListPane::NewL( const CCoeControl& aParent,
       
    65                                 MESMRFieldStorage& aFactory,
       
    66                                 TAknDoubleSpanScrollBarModel& aScrollModel )
       
    67     {
       
    68     CMRListPane* self = new (ELeave) CMRListPane( aFactory, aScrollModel );
       
    69     CleanupStack::PushL( self );
       
    70     self->ConstructL( aParent );
       
    71     CleanupStack::Pop( self );
       
    72     return self;
       
    73     }
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // CMRListPane::~CMRListPane
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 CMRListPane::~CMRListPane()
       
    80     {
       
    81     }
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // CMRListPane::CMRListPane
       
    85 // ---------------------------------------------------------------------------
       
    86 //
       
    87 CMRListPane::CMRListPane( MESMRFieldStorage& aFactory,
       
    88                           TAknDoubleSpanScrollBarModel& aScrollModel )
       
    89     : iFactory( aFactory ),
       
    90       iScrollModel( aScrollModel )
       
    91     {
       
    92     }
       
    93 
       
    94 // ---------------------------------------------------------------------------
       
    95 // CMRListPane::ConstructL
       
    96 // ---------------------------------------------------------------------------
       
    97 //
       
    98 void CMRListPane::ConstructL( const CCoeControl& aParent )
       
    99     {
       
   100     SetContainerWindowL( aParent );
       
   101     TBool focusSet = EFalse;
       
   102     const TInt count( iFactory.Count() );
       
   103     for ( TInt i = 0; i < count; i++ )
       
   104         {
       
   105         iFactory.Field(i)->SetContainerWindowL( *this );
       
   106         }
       
   107 
       
   108     for ( TInt i = 0; i < count; i++ )
       
   109         {
       
   110         CESMRField* field = iFactory.Field( i );
       
   111         
       
   112         // Initialize field
       
   113         field->InitializeL();
       
   114         User::LeaveIfError( field->SetParent( this ) );
       
   115 
       
   116         if ( !focusSet
       
   117              && field->IsVisible()
       
   118              && !field->IsNonFocusing())
       
   119             {
       
   120             field->SetOutlineFocusL( ETrue );
       
   121             focusSet = ETrue;
       
   122             iFocus = i;
       
   123             }
       
   124         }    
       
   125     }
       
   126 
       
   127 // ---------------------------------------------------------------------------
       
   128 // CMRListPane::FocusedItem
       
   129 // ---------------------------------------------------------------------------
       
   130 //
       
   131 CESMRField* CMRListPane::FocusedItem() const
       
   132     {
       
   133     FUNC_LOG;
       
   134     CESMRField* field = NULL;
       
   135     if ( iFactory.Count() > 0 )
       
   136         {
       
   137         field = iFactory.Field( iFocus );
       
   138         }
       
   139     return field;
       
   140     }
       
   141         
       
   142 // ---------------------------------------------------------------------------
       
   143 // CMRListPane::CountComponentControls
       
   144 // ---------------------------------------------------------------------------
       
   145 //
       
   146 TInt CMRListPane::CountComponentControls() const
       
   147     {
       
   148     return iFactory.Count();
       
   149     }
       
   150 
       
   151 // ---------------------------------------------------------------------------
       
   152 // CMRListPane::ComponentControl
       
   153 // ---------------------------------------------------------------------------
       
   154 //
       
   155 CCoeControl* CMRListPane::ComponentControl( TInt aIndex ) const
       
   156     {
       
   157     return iFactory.Field( aIndex );
       
   158     }
       
   159 
       
   160 // ---------------------------------------------------------------------------
       
   161 // CMRListPane::SizeChanged
       
   162 // ---------------------------------------------------------------------------
       
   163 //
       
   164 void CMRListPane::SizeChanged()
       
   165     {
       
   166     TPoint tl( Position() );
       
   167     TInt scrollSpan = 0;
       
   168     // Loop all the visible fields and set size and position in the list
       
   169     TBool topVisibleFound( EFalse );
       
   170     
       
   171     const TInt count( iFactory.Count() );
       
   172     for ( TInt i = 0; i < count; i++ )
       
   173         {
       
   174         CESMRField* field = iFactory.Field( i );
       
   175 
       
   176         if ( field->IsVisible() )
       
   177             {
       
   178             LayoutField( *field, tl );
       
   179             
       
   180             if ( !topVisibleFound )
       
   181                 {
       
   182                 iTopVisibleIndex = i;
       
   183                 topVisibleFound = ETrue;
       
   184                 }
       
   185 
       
   186             TInt height = field->Size().iHeight;
       
   187             tl.iY += height;
       
   188             scrollSpan += height;
       
   189             }
       
   190         }
       
   191     
       
   192     iScrollModel.SetScrollSpan( scrollSpan );
       
   193     iScrollModel.SetWindowSize( iSize.iHeight );
       
   194     UpdateFocusPosition();
       
   195     }
       
   196 
       
   197 // ---------------------------------------------------------------------------
       
   198 // CMRListPane::OfferKeyEventL
       
   199 // ---------------------------------------------------------------------------
       
   200 //
       
   201 TKeyResponse CMRListPane::OfferKeyEventL( const TKeyEvent &aKeyEvent,
       
   202                                           TEventCode aType )
       
   203     {
       
   204     TKeyResponse response( EKeyWasNotConsumed );
       
   205     
       
   206     // If we have at least one item in the list
       
   207     if ( iFocus < iFactory.Count() )
       
   208         {
       
   209         CESMRField* field = iFactory.Field( iFocus );
       
   210         // First check if the focused item needs the key event
       
   211         response = field->OfferKeyEventL( aKeyEvent, aType );
       
   212 
       
   213         if ( aType == EEventKey
       
   214              && response == EKeyWasNotConsumed )
       
   215             {
       
   216             // Check if the focus should be changed
       
   217             switch ( aKeyEvent.iScanCode )
       
   218                 {
       
   219                 case EStdKeyUpArrow:
       
   220                     {
       
   221                     response = MoveFocusUpL();
       
   222                     break;
       
   223                     }
       
   224                 case EStdKeyDownArrow:
       
   225                     {
       
   226                     response = MoveFocusDownL();
       
   227                     break;
       
   228                     }
       
   229                 default:
       
   230                     {
       
   231                     break;
       
   232                     }
       
   233                 }
       
   234             }
       
   235         }
       
   236     return response;
       
   237     }
       
   238 
       
   239 // ---------------------------------------------------------------------------
       
   240 // CMRListPane::ControlSizeChanged
       
   241 // ---------------------------------------------------------------------------
       
   242 //
       
   243 void CMRListPane::ControlSizeChanged( CESMRField* aCtrl )
       
   244     {
       
   245     if ( !aCtrl )
       
   246         {
       
   247         SizeChanged();
       
   248         }
       
   249     else
       
   250         {
       
   251         TPoint tl( aCtrl->Position() );
       
   252         TInt index = IndexByFieldId( iFactory, aCtrl->FieldId() );
       
   253         
       
   254         // Relayout aCtrl
       
   255         TSize old( aCtrl->Size() );
       
   256         TSize size( aCtrl->MinimumSize() );
       
   257         if ( aCtrl->IsExpandable() )
       
   258             {
       
   259             size.iHeight = aCtrl->ExpandedHeight();
       
   260             }
       
   261         aCtrl->SetSize( size );
       
   262         iScrollModel.SetScrollSpan( iScrollModel.ScrollSpan()
       
   263                                     + size.iHeight - old.iHeight );
       
   264         
       
   265         // Move other fields
       
   266         ++index;
       
   267         tl.iY += size.iHeight;
       
   268         MoveFields( index, tl );
       
   269         UpdateFocusPosition();
       
   270         }
       
   271     }
       
   272 
       
   273 // ---------------------------------------------------------------------------
       
   274 // CMRListPane::InsertControl
       
   275 // ---------------------------------------------------------------------------
       
   276 //
       
   277 void CMRListPane::InsertControl( TESMREntryFieldId aField )
       
   278     {
       
   279     CESMRField* field = iFactory.FieldById( aField );
       
   280     
       
   281     if ( field && !field->IsVisible() )
       
   282         {
       
   283         // Make field visible 
       
   284         field->MakeVisible( ETrue );
       
   285         TInt index = IndexByFieldId( iFactory, aField );
       
   286         if ( index < iTopVisibleIndex )
       
   287             {
       
   288             iTopVisibleIndex = index;
       
   289             }
       
   290         
       
   291         TPoint tl( Rect().iTl );
       
   292         TInt prevIndex = index - 1;
       
   293         
       
   294         // Get previous visible field position
       
   295         if ( prevIndex >= 0 )
       
   296             {
       
   297             CESMRField* previous = NULL;
       
   298             do
       
   299                 {
       
   300                 previous = iFactory.Field( prevIndex-- );
       
   301                 }
       
   302             while ( prevIndex >= 0 && !previous->IsVisible() );
       
   303             
       
   304             tl.iY = previous->Rect().iBr.iY;
       
   305             }
       
   306         
       
   307         // Layout field
       
   308         LayoutField( *field, tl );
       
   309         iScrollModel.SetScrollSpan( iScrollModel.ScrollSpan()
       
   310                                     + field->Size().iHeight );
       
   311         
       
   312         // Move following fields
       
   313         tl.iY += field->Size().iHeight;
       
   314         MoveFields( ++index, tl );
       
   315         UpdateFocusPosition();
       
   316         }
       
   317     }
       
   318 
       
   319 // ---------------------------------------------------------------------------
       
   320 // CMRListPane::InsertControl
       
   321 // ---------------------------------------------------------------------------
       
   322 //
       
   323 void CMRListPane::RemoveControl( TESMREntryFieldId aField )
       
   324     {
       
   325     CESMRField* field = iFactory.FieldById( aField );
       
   326         
       
   327     if ( field && field->IsVisible() )
       
   328         {
       
   329         field->MakeVisible( EFalse );
       
   330         iScrollModel.SetScrollSpan( iScrollModel.ScrollSpan() - field->Size().iHeight );
       
   331         TInt index = IndexByFieldId( iFactory, aField );
       
   332         TBool focused = ( index == iFocus )? ETrue : EFalse;
       
   333         
       
   334         if ( index == iTopVisibleIndex )
       
   335             {
       
   336             // Find next
       
   337             TInt count( iFactory.Count() );
       
   338             while ( index < count )
       
   339                 {
       
   340                 if ( iFactory.Field( ++index )->IsVisible() )
       
   341                     {
       
   342                     iTopVisibleIndex = index;
       
   343                     break;
       
   344                     }
       
   345                 }
       
   346             }
       
   347         else
       
   348             {
       
   349             ++index;
       
   350             }
       
   351         TPoint pos( field->Position() );
       
   352         MoveFields( index, pos );
       
   353         if ( focused && !field->IsNonFocusing() )
       
   354             {
       
   355             TRAP_IGNORE( DoSetFocusL( index ) )
       
   356             }
       
   357         UpdateFocusPosition();
       
   358         }
       
   359     }
       
   360 
       
   361 // ---------------------------------------------------------------------------
       
   362 // CMRListPane::IsControlVisible
       
   363 // ---------------------------------------------------------------------------
       
   364 //
       
   365 TBool CMRListPane::IsControlVisible( TESMREntryFieldId aField )
       
   366     {
       
   367     TBool visible( EFalse );
       
   368     CESMRField* field = iFactory.FieldById( aField );
       
   369     
       
   370     if ( field )
       
   371         {
       
   372         visible = field->IsVisible();
       
   373         }
       
   374     
       
   375     return visible;
       
   376     }
       
   377 
       
   378 // ---------------------------------------------------------------------------
       
   379 // CMRListPane::SetControlFocusedL
       
   380 // ---------------------------------------------------------------------------
       
   381 //
       
   382 void CMRListPane::SetControlFocusedL( TESMREntryFieldId aField )
       
   383     {
       
   384     TInt count = iFactory.Count();
       
   385     for ( TInt i(0); i < count; i++ )
       
   386         {
       
   387         CESMRField* field = iFactory.Field(i);
       
   388         
       
   389         if ( field->FieldId() == aField )
       
   390             {
       
   391             if( field->IsVisible() && !field->IsNonFocusing() )
       
   392                 {
       
   393                 // Remove current focus before setting new one
       
   394                 CESMRField* focusedField = FocusedItem();
       
   395                 ASSERT( focusedField );
       
   396                 focusedField->SetOutlineFocusL( EFalse );
       
   397 
       
   398                 // Set new focus
       
   399                 field->SetOutlineFocusL( ETrue );
       
   400                 iFocus = i;
       
   401                 break;
       
   402                 }
       
   403             else
       
   404                 {
       
   405                 // Not possible to set focus to non-visible control
       
   406                 User::Leave( KErrGeneral );
       
   407                 }
       
   408             }
       
   409         }
       
   410     }
       
   411 
       
   412 // SCROLLING_MOD: These two methods are for CESMRRichTextViewer to 
       
   413 // be able to control view area
       
   414 // ---------------------------------------------------------------------------
       
   415 // CMRListPane::MoveListAreaDownL
       
   416 // ---------------------------------------------------------------------------
       
   417 //
       
   418 void CMRListPane::MoveListAreaDownL( TInt aAmount )
       
   419     {
       
   420     FUNC_LOG;
       
   421     // Method for CESMRRichTextViewer for moving view area down if the text in
       
   422     // text field does not fit on the screen.
       
   423 
       
   424     // Fetch the position info about the first visible field in field set:
       
   425     CESMRField* field;
       
   426     if( iTopVisibleIndex != KErrNotFound )
       
   427         {
       
   428         field = iFactory.Field( iTopVisibleIndex );
       
   429         }
       
   430     else
       
   431         {
       
   432         field = iFactory.Field( iFactory.Count() - 1 );
       
   433         }
       
   434     TRect rect( field->Rect() );
       
   435 
       
   436     // check whether the first field is visible, if not, let's
       
   437     // check should we scroll less than needed to get the first
       
   438     // field shown.
       
   439     if ( rect.iTl.iY + aAmount > Rect().iTl.iY )
       
   440         {
       
   441         aAmount = Rect().iTl.iY - rect.iTl.iY + KVerticalScrollMargin;
       
   442         }
       
   443     else if ( rect.iTl.iY == Rect().iTl.iY )
       
   444         {
       
   445         // field already visible, do not scroll.
       
   446         aAmount = 0;
       
   447         }
       
   448 
       
   449     // Do the view scrolling if needed:
       
   450     if ( aAmount )
       
   451         {
       
   452         ScrollItemsDown( aAmount );
       
   453         UpdateFocusPosition();
       
   454         //UpdateScrollBar();
       
   455         DrawDeferred();
       
   456         }
       
   457     }
       
   458 
       
   459 // ---------------------------------------------------------------------------
       
   460 // CMRListPane::MoveListAreaUpL
       
   461 // ---------------------------------------------------------------------------
       
   462 //
       
   463 void CMRListPane::MoveListAreaUpL( TInt aAmount )
       
   464     {
       
   465     FUNC_LOG;
       
   466     // Fetch the position information about currently focused field:
       
   467     CESMRField* field = iFactory.Field( iFocus );
       
   468     TRect rect( field->Rect() );
       
   469 
       
   470     // check whether the scroll pixels should be less than normal
       
   471     // scroll sequence to let the field bottom to be placed at
       
   472     // the bottom of view rect.
       
   473     if ( rect.iBr.iY - aAmount < Rect().iBr.iY )
       
   474         {
       
   475         aAmount = rect.iBr.iY - Rect().iBr.iY + KVerticalScrollMargin;
       
   476         }
       
   477     else if ( rect.iBr.iY + aAmount == Rect().iBr.iY )
       
   478         {
       
   479         // field already visible, do not scroll.
       
   480         aAmount = 0;
       
   481         }
       
   482 
       
   483     // do the scrolling if needed:
       
   484     if ( aAmount > 0 )
       
   485         {
       
   486         // if the focus is on last
       
   487         ScrollItemsUp( aAmount );
       
   488         UpdateFocusPosition();
       
   489         //UpdateScrollBar();
       
   490         DrawDeferred();
       
   491         }
       
   492     }
       
   493 
       
   494 // ---------------------------------------------------------------------------
       
   495 // CMRListPane::ListHeight
       
   496 // ---------------------------------------------------------------------------
       
   497 //
       
   498 TInt CMRListPane::ListHeight()
       
   499     {
       
   500     FUNC_LOG;
       
   501     return iSize.iHeight;
       
   502     }
       
   503 
       
   504 // ---------------------------------------------------------------------------
       
   505 // CMRListPane::IsFieldBottomVisible
       
   506 // ---------------------------------------------------------------------------
       
   507 //
       
   508 TBool CMRListPane::IsFieldBottomVisible()
       
   509     {
       
   510     // Fetch the position information about currently focused field:
       
   511     CESMRField* field = iFactory.Field( iFocus );
       
   512     TBool ret( EFalse );
       
   513     if ( field->Rect().iBr.iY <= Rect().iBr.iY )
       
   514        {
       
   515        ret = ETrue;
       
   516        }
       
   517 
       
   518     return ret;
       
   519     }
       
   520 
       
   521 // ---------------------------------------------------------------------------
       
   522 // CMRListPane::MoveFocusUpL
       
   523 // ---------------------------------------------------------------------------
       
   524 //
       
   525 TKeyResponse CMRListPane::MoveFocusUpL()
       
   526     {
       
   527     TInt ind( iFocus );
       
   528     
       
   529     // search next visible focus item
       
   530     while ( ind > 0 )
       
   531         {
       
   532         CESMRField* field = iFactory.Field( --ind );
       
   533 
       
   534         if ( !field->IsNonFocusing() )
       
   535             {
       
   536             field = iFactory.Field( ind );
       
   537 
       
   538             CESMRField* focusedField = iFactory.Field( iFocus );
       
   539             if ( field->IsVisible() )
       
   540                 {
       
   541                 TBool canLoseFocus( 
       
   542                         focusedField->OkToLoseFocusL( field->FieldId() ) );
       
   543 
       
   544                 if ( canLoseFocus )
       
   545                     {
       
   546                     iFocus = ind;
       
   547                                         
       
   548                     // update focus index and scroll the item visible
       
   549                     focusedField->SetOutlineFocusL( EFalse );
       
   550                     // This call changes the text color of previously 
       
   551                     // focused field
       
   552                     focusedField->SetFocus( EFalse );
       
   553                     field->SetOutlineFocusL( ETrue );
       
   554                     // This call changes the text color of focused field
       
   555                     field->SetFocus( ETrue );
       
   556 
       
   557                     ScrollItemVisible( iFocus );
       
   558                     }
       
   559                 return EKeyWasConsumed;
       
   560                 }
       
   561             }
       
   562         }
       
   563     return EKeyWasNotConsumed;
       
   564     }
       
   565 
       
   566 // ---------------------------------------------------------------------------
       
   567 // CMRListPane::MoveFocusDownL
       
   568 // ---------------------------------------------------------------------------
       
   569 //
       
   570 TKeyResponse CMRListPane::MoveFocusDownL()
       
   571     {
       
   572     TInt ind( iFocus );
       
   573 
       
   574     // start searching next possible focus item
       
   575     TInt maxItemIndex = iFactory.Count() - 1;
       
   576     
       
   577     while ( ind < maxItemIndex )
       
   578         {
       
   579         // only visible and focusable items can be focused
       
   580         CESMRField* field = iFactory.Field( ++ind );
       
   581 
       
   582         if ( field->IsVisible() && !field->IsNonFocusing() )
       
   583             {
       
   584             CESMRField* focusedField = iFactory.Field( iFocus );
       
   585                     
       
   586             TBool canLoseFocus( 
       
   587                     focusedField->OkToLoseFocusL( field->FieldId() ) );
       
   588 
       
   589             // check it its ok for the old focus item to lose focus
       
   590             if ( canLoseFocus )
       
   591                 {
       
   592                 iFocus = ind;
       
   593                                 
       
   594                 // update focus index and scroll the item visible
       
   595                 focusedField->SetOutlineFocusL( EFalse );
       
   596                 // This call changes the text color of previously 
       
   597                 // focused field
       
   598                 focusedField->SetFocus( EFalse );
       
   599                 field->SetOutlineFocusL( ETrue );
       
   600                 // This call changes the text color of focused field
       
   601                 field->SetFocus( ETrue );
       
   602 
       
   603                 ScrollItemVisible( iFocus );
       
   604                 }
       
   605             return EKeyWasConsumed;
       
   606             }
       
   607         }
       
   608     return EKeyWasNotConsumed;
       
   609     }
       
   610 
       
   611 // ---------------------------------------------------------------------------
       
   612 // CMRListPane::MoveFocusL
       
   613 // ---------------------------------------------------------------------------
       
   614 //
       
   615 TBool CMRListPane::MoveFocusL(TInt aNextFieldIndex)
       
   616     {
       
   617     // start searching next possible focus item
       
   618     TInt maxItemIndex = iFactory.Count() - 1;
       
   619 
       
   620     CESMRField* focusedField = iFactory.Field( iFocus );
       
   621     
       
   622     // only visible and focusable items can be focused
       
   623     CESMRField* field = iFactory.Field( aNextFieldIndex );
       
   624 
       
   625     if ( field->IsVisible() && !field->IsNonFocusing() )
       
   626         {
       
   627         TBool canLoseFocus( 
       
   628                 focusedField->OkToLoseFocusL( field->FieldId() ) );
       
   629 
       
   630         // check it its ok for the old focus item to lose focus
       
   631         if ( canLoseFocus )
       
   632             {
       
   633             // tactile feedback if touch 
       
   634             if ( AknLayoutUtils::PenEnabled() )
       
   635                 {
       
   636                 MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   637                 if ( feedback )
       
   638                     {
       
   639                     feedback->InstantFeedback( this, ETouchFeedbackBasic );
       
   640                     }
       
   641                 }
       
   642             
       
   643             iFocus = aNextFieldIndex;
       
   644                             
       
   645             // update focus index and scroll the item visible
       
   646             focusedField->SetOutlineFocusL( EFalse );
       
   647             // This call changes the text color of previously 
       
   648             // focused field
       
   649             focusedField->SetFocus( EFalse );
       
   650             field->SetOutlineFocusL( ETrue );
       
   651             // This call changes the text color of focused field
       
   652             field->SetFocus( ETrue );
       
   653             DrawDeferred();
       
   654             }
       
   655         return ETrue; // operation succeed
       
   656         }
       
   657     return EFalse;
       
   658     }
       
   659 
       
   660 // ---------------------------------------------------------------------------
       
   661 // CMRListPane::LayoutField
       
   662 // ---------------------------------------------------------------------------
       
   663 //
       
   664 void CMRListPane::LayoutField( CESMRField& aField,
       
   665                                const TPoint& aTl )
       
   666     {
       
   667     TSize size( aField.MinimumSize() );
       
   668     if ( aField.IsExpandable() )
       
   669         {
       
   670         size.iHeight = aField.ExpandedHeight();
       
   671         }
       
   672     aField.SetPosition( aTl );
       
   673     aField.SetSize( size );
       
   674     }
       
   675 
       
   676 // ---------------------------------------------------------------------------
       
   677 // CMRListPane::MoveFields
       
   678 // ---------------------------------------------------------------------------
       
   679 //
       
   680 void CMRListPane::MoveFields( TInt aIndex,
       
   681                               TPoint& aTl )
       
   682     {
       
   683     const TInt count( iFactory.Count() );
       
   684     
       
   685     for ( TInt i = aIndex; i < count; ++i )
       
   686         {
       
   687         CESMRField* field = iFactory.Field( i );
       
   688 
       
   689         if ( field->IsVisible() )
       
   690             {
       
   691             field->SetPosition( aTl );
       
   692             
       
   693             aTl.iY += field->Size().iHeight;
       
   694             }
       
   695         }
       
   696     }
       
   697 
       
   698 // ---------------------------------------------------------------------------
       
   699 // CMRListPane::DoSetFocusL
       
   700 // ---------------------------------------------------------------------------
       
   701 //
       
   702 void CMRListPane::DoSetFocusL( TInt aFocus )
       
   703     {
       
   704     TInt count( iFactory.Count() );
       
   705     aFocus = Max( 0, Min( aFocus, count - 1 ) );
       
   706     
       
   707     if ( aFocus != iFocus )
       
   708         {
       
   709         // Get current focused field
       
   710         CESMRField* old = iFactory.Field( iFocus );
       
   711         
       
   712         // Get next focused field
       
   713         CESMRField* field = iFactory.Field( aFocus );
       
   714         while ( aFocus < count && !field->IsVisible() )
       
   715             {
       
   716             field = iFactory.Field( aFocus++ );
       
   717             }
       
   718         
       
   719         if ( !field->IsVisible() )
       
   720             {
       
   721             aFocus = iFocus - 1;
       
   722             while ( aFocus > 0 && !field->IsVisible() )
       
   723                 {
       
   724                 field = iFactory.Field( aFocus-- );
       
   725                 }
       
   726             }
       
   727         
       
   728         ASSERT( field->IsVisible() );
       
   729         
       
   730         // Remove focus from old
       
   731         iFocus = aFocus;
       
   732         // update focus index and scroll the item visible
       
   733         old->SetOutlineFocusL( EFalse );
       
   734         // Change the text color of previously focused field
       
   735         old->SetFocus( EFalse );
       
   736         field->SetOutlineFocusL( ETrue );
       
   737         // This call changes the text color of focused field
       
   738         field->SetFocus( ETrue );
       
   739         }
       
   740     }
       
   741 
       
   742 // ---------------------------------------------------------------------------
       
   743 // CMRListPane::ScrollItemVisible
       
   744 // ---------------------------------------------------------------------------
       
   745 //
       
   746 void CMRListPane::ScrollItemVisible( TInt aInd )
       
   747     {
       
   748     FUNC_LOG;
       
   749     CESMRField* field = NULL;
       
   750     if ( aInd == KErrNotFound )
       
   751         {
       
   752         field = FocusedItem();
       
   753         }
       
   754     else
       
   755         {
       
   756         field = iFactory.Field( aInd );
       
   757         }
       
   758 
       
   759     ASSERT( field );
       
   760 
       
   761     TRect rect( field->Rect() );
       
   762 
       
   763     // move all items upwards
       
   764     TInt bottomRightY = Rect().iBr.iY;
       
   765 
       
   766 
       
   767     TInt fieldUpper(0);
       
   768     TInt fieldLower(0);
       
   769     field->GetMinimumVisibleVerticalArea( fieldUpper, fieldLower );
       
   770 
       
   771     // desired position below view rect:
       
   772     if ( rect.iTl.iY + fieldLower > Rect().iBr.iY )
       
   773         {
       
   774         // field rect Y position related to view rect:
       
   775         TInt fieldRelYPos = rect.iTl.iY - Size().iHeight;
       
   776         TInt px = fieldRelYPos + fieldLower;
       
   777 
       
   778         // if focus on first or last field: add margin height to
       
   779         // scroll amount.
       
   780         if ( iFocus == 0 || iFocus == iFactory.Count()-1 )
       
   781             {
       
   782             px += 2 * KVerticalScrollMargin;
       
   783             }
       
   784 
       
   785         ScrollItemsUp( px );
       
   786         }
       
   787 
       
   788     // move all items downwards.
       
   789     TInt topLeftY = Rect().iTl.iY;
       
   790 
       
   791     if ( rect.iBr.iY - (rect.Height() - fieldUpper ) < topLeftY )
       
   792         {
       
   793         TInt fieldRelYPos = topLeftY - rect.iBr.iY;
       
   794         TInt px = fieldRelYPos + ( rect.Height() - fieldUpper);
       
   795 
       
   796         // if focus on first or last field: add margin height to
       
   797         // scroll amount.
       
   798         if ( iFocus == 0 ||  iFocus == iFactory.Count()-1 )
       
   799             {
       
   800             px += KVerticalScrollMargin;
       
   801             }
       
   802 
       
   803         ScrollItemsDown( px );
       
   804         }
       
   805 
       
   806     UpdateFocusPosition();//UpdateScrollBar();
       
   807     DrawDeferred();
       
   808     }
       
   809 
       
   810 // ---------------------------------------------------------------------------
       
   811 // CMRListPane::UpdateScrollBar
       
   812 // ---------------------------------------------------------------------------
       
   813 //
       
   814 void CMRListPane::UpdateScrollBar()
       
   815     {
       
   816     FUNC_LOG;
       
   817     // Scroll span is the size of the scrolled list,
       
   818     // including the items that doesn't fit in the screen
       
   819     TInt spanSize( 0 );
       
   820     TInt hidden( 0 );
       
   821     const TInt count(iFactory.Count());
       
   822     for ( TInt i(0); i < count; i++ )
       
   823         {
       
   824         CESMRField* field = iFactory.Field( i );
       
   825         if ( field->IsVisible() )
       
   826             {
       
   827             TRect rect( field->Rect() );
       
   828             spanSize += rect.Height();
       
   829             // Check if the field's top Y-position is hidden.
       
   830             if ( rect.iTl.iY  < 0 )
       
   831                 {
       
   832                 // whole field is hidden
       
   833                 if ( rect.iBr.iY < 0 )
       
   834                     {
       
   835                     hidden += rect.Height();
       
   836                     }
       
   837                 // partly hidden:
       
   838                 else
       
   839                     {
       
   840                     hidden += Abs( rect.iTl.iY );
       
   841                     }
       
   842                 }
       
   843             }
       
   844         }
       
   845 
       
   846     iScrollModel.SetScrollSpan( spanSize );
       
   847     iScrollModel.SetWindowSize( iSize.iHeight );
       
   848     iScrollModel.SetFocusPosition( hidden );
       
   849 
       
   850     }
       
   851 
       
   852 // ---------------------------------------------------------------------------
       
   853 // CMRListPane::ScrollItemsUp
       
   854 // ---------------------------------------------------------------------------
       
   855 //
       
   856 void CMRListPane::ScrollItemsUp( TInt aPx )
       
   857     {
       
   858     FUNC_LOG;
       
   859     TInt count( iFactory.Count() );
       
   860     for ( TInt i = 0; i < count; ++i )
       
   861         {
       
   862         CESMRField* field = iFactory.Field(i);
       
   863         if ( field->IsVisible() )
       
   864             {
       
   865             TPoint pos( field->Position() );
       
   866             pos.iY -= aPx;
       
   867             if ( i == iTopVisibleIndex && pos.iY < 0 )
       
   868                 {
       
   869                 iTopVisibleIndex = KErrNotFound;
       
   870                 }
       
   871             else if ( iTopVisibleIndex == KErrNotFound && pos.iY >= 0 )
       
   872                 {
       
   873                 iTopVisibleIndex = i;
       
   874                 }
       
   875             field->SetPosition( pos );
       
   876             }
       
   877         }
       
   878     }
       
   879 
       
   880 // ---------------------------------------------------------------------------
       
   881 // CMRListPane::ScrollItemsDown
       
   882 // ---------------------------------------------------------------------------
       
   883 //
       
   884 void CMRListPane::ScrollItemsDown( TInt aPx )
       
   885     {
       
   886     FUNC_LOG;
       
   887     TInt count( iFactory.Count() );
       
   888     for ( TInt i = 0; i < count; ++i )
       
   889         {
       
   890         CESMRField* field = iFactory.Field( i );
       
   891         if ( field->IsVisible() )
       
   892             {
       
   893             TPoint pos( field->Position() );
       
   894             pos.iY += aPx;
       
   895             if ( pos.iY >= 0 && ( i < iTopVisibleIndex || iTopVisibleIndex == KErrNotFound ) )
       
   896                 {
       
   897                 iTopVisibleIndex = i;
       
   898                 }
       
   899             field->SetPosition( pos );
       
   900             }
       
   901         }
       
   902     }
       
   903 
       
   904 // ---------------------------------------------------------------------------
       
   905 // CMRListPane::ScrollView
       
   906 // ---------------------------------------------------------------------------
       
   907 //
       
   908 void CMRListPane::ScrollView( TInt aAmount )
       
   909     {
       
   910     FUNC_LOG;
       
   911     
       
   912     if ( aAmount > 0 )
       
   913         {
       
   914         // move list up
       
   915         ScrollItemsUp( aAmount );
       
   916         UpdateFocusPosition();
       
   917         DrawDeferred();
       
   918         }
       
   919     else if ( aAmount < 0 )
       
   920         {
       
   921         // move list down
       
   922         ScrollItemsDown( -aAmount );
       
   923         UpdateFocusPosition();
       
   924         DrawDeferred();
       
   925         }
       
   926     }
       
   927 
       
   928 
       
   929 // ---------------------------------------------------------------------------
       
   930 // CMRListPane::UpdateFocusPosition
       
   931 // ---------------------------------------------------------------------------
       
   932 //
       
   933 void CMRListPane::UpdateFocusPosition()
       
   934     {
       
   935     TInt focusPos = 0;
       
   936     TInt count = iFactory.Count();
       
   937     for ( TInt i = 0; i < count; ++i )
       
   938         {
       
   939         CESMRField* field = iFactory.Field( i );
       
   940         if ( field->IsVisible() )
       
   941             {
       
   942             TRect rect( field->Rect() );
       
   943             // Check if the field's top is above scroll area origo.
       
   944             if ( rect.iTl.iY  < 0 )
       
   945                 {
       
   946                 // Whole field is above origo
       
   947                 if ( rect.iBr.iY < 0 )
       
   948                     {
       
   949                     focusPos += rect.Height();
       
   950                     }
       
   951                 // Part of the field is above origo
       
   952                 else
       
   953                     {
       
   954                     focusPos += Abs( rect.iTl.iY );
       
   955                     }
       
   956                 }
       
   957             else
       
   958                 {
       
   959                 // Rest of the fields are below scroll area origo
       
   960                 break;
       
   961                 }
       
   962             }
       
   963         }
       
   964     
       
   965     iScrollModel.SetFocusPosition( focusPos );
       
   966     }
       
   967 
       
   968 
       
   969 // -----------------------------------------------------------------------------
       
   970 // CMRListPane::GetViewCenterPosition
       
   971 // -----------------------------------------------------------------------------
       
   972 //
       
   973 TPoint CMRListPane::GetViewCenterPosition() const
       
   974     {
       
   975     const TInt count( iFactory.Count() );
       
   976     TInt topFieldYPos( 0 );
       
   977     for ( TInt i = 0; i < count; i++ )
       
   978         {
       
   979         CESMRField* field = iFactory.Field( i );
       
   980 
       
   981         if ( field->IsVisible() )
       
   982             {
       
   983             topFieldYPos = field->Position().iY;    
       
   984             break;
       
   985             }
       
   986         }
       
   987     TInt centerX = iSize.iWidth / 2;
       
   988     TInt visibleHeight = iSize.iHeight;
       
   989 
       
   990     TInt centerY = visibleHeight / 2 - topFieldYPos;
       
   991     
       
   992     
       
   993     return TPoint( centerX, centerY );
       
   994     }
       
   995 
       
   996 
       
   997 // -----------------------------------------------------------------------------
       
   998 // CMRListPane::HandlePointerEventL
       
   999 // -----------------------------------------------------------------------------
       
  1000 //
       
  1001 void CMRListPane::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
  1002     {
       
  1003     if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  1004         {
       
  1005         TInt count = iFactory.Count();
       
  1006         for ( TInt i = 0; i < count; ++i )
       
  1007             {
       
  1008             CESMRField* field = static_cast<CESMRField*>(iFactory.Field( i ) );
       
  1009             TRect r = field->Rect();
       
  1010             TBool tapped = field->Rect().Contains( aPointerEvent.iPosition );
       
  1011             if (tapped && field->IsVisible() && !field->IsFocused() )
       
  1012                 {
       
  1013                 MoveFocusL( i );
       
  1014                 break;
       
  1015                 }
       
  1016             }
       
  1017         }
       
  1018     // here some fields can further adjust their state (for example, CESMRResponseField has sub-fields) 
       
  1019     CCoeControl::HandlePointerEventL(aPointerEvent);
       
  1020     }
       
  1021 // End of file
       
  1022