meetingrequest/mrgui/src/cmrfieldcontainer.cpp
branchRCL_3
changeset 12 4ce476e64c59
child 16 b5fbb9b25d57
equal deleted inserted replaced
11:0396474f30f5 12:4ce476e64c59
       
     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:  Field container for UI fields
       
    15 *
       
    16 */
       
    17 #include "cmrfieldcontainer.h"
       
    18 #include "mesmrfieldstorage.h"
       
    19 #include "mmrfieldcontainerobserver.h"
       
    20 #include "cesmrfield.h"
       
    21 
       
    22 //DEBUG
       
    23 #include "emailtrace.h"
       
    24 
       
    25 namespace { // codescanner::namespace
       
    26 
       
    27 /**
       
    28  * Vertical scroll margin
       
    29  */
       
    30 const TInt KVerticalScrollMargin = 3;
       
    31 
       
    32 
       
    33 // ----------------
       
    34 // IndexByFieldId
       
    35 // ----------------
       
    36 //
       
    37 TInt IndexByFieldId( const MESMRFieldStorage& aFactory,
       
    38                      TESMREntryFieldId aFieldId )
       
    39     {
       
    40     TInt index( KErrNotFound );
       
    41     TInt count( aFactory.Count() );
       
    42 
       
    43     for ( TInt i = 0; i < count; ++i )
       
    44         {
       
    45         if ( aFactory.Field( i )->FieldId() == aFieldId )
       
    46             {
       
    47             index = i;
       
    48             break;
       
    49             }
       
    50         }
       
    51 
       
    52     return index;
       
    53     }
       
    54 }
       
    55 
       
    56 //----- MEMBER FUNCTIONS ----
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // CMRFieldContainer::CMRFieldContainer
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 CMRFieldContainer::CMRFieldContainer( MESMRFieldStorage& aFactory )
       
    63     : iFactory( aFactory )
       
    64     {
       
    65     FUNC_LOG;
       
    66     }
       
    67 
       
    68 // ---------------------------------------------------------------------------
       
    69 // CMRFieldContainer::~CMRFieldContainer
       
    70 // ---------------------------------------------------------------------------
       
    71 //
       
    72 CMRFieldContainer::~CMRFieldContainer()
       
    73     {
       
    74     FUNC_LOG;
       
    75     // No implementation
       
    76     }
       
    77 
       
    78 // ---------------------------------------------------------------------------
       
    79 // CMRFieldContainer::NewL
       
    80 // ---------------------------------------------------------------------------
       
    81 //
       
    82 CMRFieldContainer* CMRFieldContainer::NewL( 
       
    83         MESMRFieldStorage& aFactory, 
       
    84         const CCoeControl& aParent )
       
    85     {
       
    86     FUNC_LOG;
       
    87     CMRFieldContainer* self = new( ELeave )CMRFieldContainer( aFactory );
       
    88     CleanupStack::PushL( self );
       
    89     self->ConstructL( aParent );
       
    90     CleanupStack::Pop( self );
       
    91     return self;
       
    92     }
       
    93 
       
    94 // ---------------------------------------------------------------------------
       
    95 // CMRFieldContainer::ConstructL
       
    96 // ---------------------------------------------------------------------------
       
    97 //
       
    98 void CMRFieldContainer::ConstructL( const CCoeControl& aParent )
       
    99     {
       
   100     FUNC_LOG;
       
   101     CCoeControl::SetComponentsToInheritVisibility( ETrue );
       
   102     SetContainerWindowL( aParent );
       
   103     
       
   104     TBool focusSet( EFalse );
       
   105     const TInt count( iFactory.Count() );
       
   106     for ( TInt i = 0; i < count; i++ )
       
   107         {
       
   108         iFactory.Field(i)->SetContainerWindowL( *this );
       
   109         }
       
   110 
       
   111     for ( TInt i = 0; i < count; i++ )
       
   112         {
       
   113         CESMRField* field = iFactory.Field( i );
       
   114 
       
   115         // Initialize field
       
   116         field->InitializeL();
       
   117         User::LeaveIfError( field->SetParent( this ) );
       
   118 
       
   119         if ( !focusSet
       
   120              && field->IsVisible()
       
   121              && !field->IsNonFocusing())
       
   122             {
       
   123             field->SetOutlineFocusL( ETrue );
       
   124             focusSet = ETrue;
       
   125             iFocusedFieldIndex = i;
       
   126             }
       
   127         }
       
   128 
       
   129     for ( TInt i = 0; i < count; i++ )
       
   130         {
       
   131         CESMRField* field = iFactory.Field( i );
       
   132 
       
   133         field->SetListObserver( this );
       
   134         }
       
   135     }
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // CMRFieldContainer::FocusedItem
       
   139 // ---------------------------------------------------------------------------
       
   140 //
       
   141 CESMRField* CMRFieldContainer::FocusedField() const
       
   142     {
       
   143     FUNC_LOG;
       
   144     /*
       
   145      * Returns currently focused field
       
   146      */
       
   147     CESMRField* field = NULL;
       
   148     if ( iFactory.Count() > 0 )
       
   149         {
       
   150         field = iFactory.Field( iFocusedFieldIndex );
       
   151         }
       
   152     return field;
       
   153     }
       
   154 
       
   155 
       
   156 // ---------------------------------------------------------------------------
       
   157 // CMRFieldContainer::MoveFocusUpL
       
   158 // ---------------------------------------------------------------------------
       
   159 //
       
   160 TKeyResponse CMRFieldContainer::MoveFocusUpL( TBool aHiddenFocus )
       
   161     {
       
   162     FUNC_LOG;
       
   163     /*
       
   164      * Moves focus up after key event. If aHiddenFocus, moves focus 
       
   165      * to the first visible field in the bottom of the viewable area.
       
   166      */
       
   167      
       
   168     if( aHiddenFocus )
       
   169         {
       
   170         return MoveFocusVisibleL();
       
   171         }
       
   172     else
       
   173         {
       
   174         TInt ind( iFocusedFieldIndex );
       
   175 
       
   176         // search next visible focus item
       
   177         while ( ind > 0 )
       
   178             {
       
   179             CESMRField* field = iFactory.Field( --ind );
       
   180 
       
   181             if ( !field->IsNonFocusing() )
       
   182                 {
       
   183                 field = iFactory.Field( ind );
       
   184 
       
   185                 CESMRField* focusedField = iFactory.Field( iFocusedFieldIndex );
       
   186                 if ( field->IsVisible() )
       
   187                     {
       
   188                     TBool canLoseFocus(
       
   189                             focusedField->OkToLoseFocusL( field->FieldId() ) );
       
   190 
       
   191                     if ( canLoseFocus )
       
   192                         {
       
   193                         field->SetPreItemIndex( iFocusedFieldIndex );
       
   194                         iFocusedFieldIndex = ind;
       
   195                         field->SetCurrentItemIndex( iFocusedFieldIndex );
       
   196 
       
   197                         // Remove focus from previous position 
       
   198                         focusedField->SetOutlineFocusL( EFalse );
       
   199                         focusedField->SetFocus( EFalse );
       
   200                         
       
   201                         // Set focus to new position
       
   202                         field->SetOutlineFocusL( ETrue );
       
   203                         field->SetFocus( ETrue );
       
   204 
       
   205                         // Scrollbar and physics update is done here
       
   206                         ScrollControlVisible( iFocusedFieldIndex );
       
   207                         
       
   208                         DrawDeferred();
       
   209                         }
       
   210 
       
   211                     return EKeyWasConsumed;
       
   212                     }
       
   213                 }
       
   214             }
       
   215         return EKeyWasNotConsumed;
       
   216         }
       
   217     }
       
   218 
       
   219 // ---------------------------------------------------------------------------
       
   220 // CMRFieldContainer::MoveFocusDownL
       
   221 // ---------------------------------------------------------------------------
       
   222 //
       
   223 TKeyResponse CMRFieldContainer::MoveFocusDownL( TBool aHiddenFocus )
       
   224     {
       
   225     FUNC_LOG;
       
   226     /*
       
   227      * Moves focus down after key event. If aHiddenFocus, moves focus 
       
   228      * to the first visible field in the top of the viewable area.
       
   229      */
       
   230     
       
   231     if( aHiddenFocus )
       
   232         {
       
   233         return MoveFocusVisibleL();
       
   234         }
       
   235     else
       
   236         {
       
   237         TInt ind( iFocusedFieldIndex );
       
   238 
       
   239         // start searching next possible focus item
       
   240         TInt maxItemIndex = iFactory.Count() - 1;
       
   241 
       
   242         while ( ind < maxItemIndex )
       
   243             {
       
   244             // only visible and focusable items can be focused
       
   245             CESMRField* field = iFactory.Field( ++ind );
       
   246 
       
   247             if ( field->IsVisible() && !field->IsNonFocusing() )
       
   248                 {
       
   249                 CESMRField* focusedField = iFactory.Field( iFocusedFieldIndex );
       
   250 
       
   251                 TBool canLoseFocus(
       
   252                         focusedField->OkToLoseFocusL( field->FieldId() ) );
       
   253 
       
   254                 // check it its ok for the old focus item to lose focus
       
   255                 if ( canLoseFocus )
       
   256                     {
       
   257                     field->SetPreItemIndex( iFocusedFieldIndex );
       
   258                     iFocusedFieldIndex = ind;
       
   259                     field->SetCurrentItemIndex( iFocusedFieldIndex );
       
   260 
       
   261                     // Remove focus from previous position 
       
   262                     focusedField->SetOutlineFocusL( EFalse );
       
   263                     focusedField->SetFocus( EFalse );
       
   264                     
       
   265                     // Set focus to new position
       
   266                     field->SetOutlineFocusL( ETrue );
       
   267                     field->SetFocus( ETrue );
       
   268 
       
   269                     // Scrollbar and physics update is done here
       
   270                     ScrollControlVisible( iFocusedFieldIndex );
       
   271                     
       
   272                     DrawDeferred();
       
   273                     }
       
   274 
       
   275                 return EKeyWasConsumed;
       
   276                 }
       
   277             }
       
   278         return EKeyWasNotConsumed;
       
   279         }
       
   280     }
       
   281 
       
   282 // ---------------------------------------------------------------------------
       
   283 // CMRFieldContainer::MoveFocusVisibleL
       
   284 // ---------------------------------------------------------------------------
       
   285 //
       
   286 TKeyResponse CMRFieldContainer::MoveFocusVisibleL()
       
   287     {
       
   288     FUNC_LOG;
       
   289     /*
       
   290      * Move focus to first completely visible field in the view, 
       
   291      * if focus was in a field that was not visible in the view.
       
   292      * Use case: After pointer scroll focus is hidden. User presses
       
   293      * arrow keys -> Focus appears to the first visible field on the upper
       
   294      * or bottom part of the viewable area.
       
   295      */
       
   296     
       
   297     TKeyResponse response( EKeyWasNotConsumed );
       
   298 
       
   299     CESMRField* focusedField = FocusedField();
       
   300     CESMRField* visibleField = NULL;
       
   301     TRect view( Parent()->Rect() );
       
   302 
       
   303     // Focus is above the visible view area
       
   304     if ( focusedField->Rect().iBr.iY <= view.iTl.iY )
       
   305         {
       
   306         // Move focus to next visible field
       
   307         TInt lastIndex = iFactory.Count() - 1;
       
   308         TInt ind( iFocusedFieldIndex );
       
   309         while ( ind < lastIndex && !visibleField )
       
   310             {
       
   311             visibleField = iFactory.Field( ++ind );
       
   312             TRect fieldRect = visibleField->Rect();
       
   313             if ( visibleField->IsVisible()
       
   314                  && !visibleField->IsNonFocusing()
       
   315                  && fieldRect.iTl.iY >= view.iTl.iY )
       
   316                 {
       
   317                 // Update previous and current field indexes
       
   318                 visibleField->SetPreItemIndex( iFocusedFieldIndex );
       
   319                 iFocusedFieldIndex = ind;
       
   320                 visibleField->SetCurrentItemIndex( iFocusedFieldIndex );
       
   321                 }
       
   322             else
       
   323                 {
       
   324                 visibleField = NULL;
       
   325                 }
       
   326             }
       
   327         }
       
   328     // Focus is below the visible view area
       
   329     else
       
   330         {
       
   331         // Move focus to previous visible field
       
   332         TInt ind( iFocusedFieldIndex );
       
   333         while ( ind > 0 && !visibleField )
       
   334             {
       
   335             visibleField = iFactory.Field( --ind );
       
   336             TRect fieldRect = visibleField->Rect();
       
   337             if ( visibleField->IsVisible()
       
   338                  && !visibleField->IsNonFocusing()
       
   339                  && fieldRect.iBr.iY <= view.iBr.iY )
       
   340                 {
       
   341                 // Update previous and current field indexes
       
   342                 visibleField->SetPreItemIndex( iFocusedFieldIndex );
       
   343                 iFocusedFieldIndex = ind;
       
   344                 visibleField->SetCurrentItemIndex( iFocusedFieldIndex );
       
   345                 }
       
   346             else
       
   347                 {
       
   348                 visibleField = NULL;
       
   349                 }
       
   350             }
       
   351         }
       
   352 
       
   353     if ( visibleField )
       
   354         {
       
   355         // Remove existing focus
       
   356         focusedField->SetOutlineFocusL( EFalse );
       
   357         focusedField->SetFocus( EFalse );
       
   358         
       
   359         // Set focus to new field
       
   360         visibleField->SetOutlineFocusL( ETrue );
       
   361         visibleField->SetFocus( ETrue );
       
   362 
       
   363         response = EKeyWasConsumed;
       
   364         
       
   365         DrawDeferred();
       
   366         }
       
   367     
       
   368     return response;
       
   369     }
       
   370 
       
   371 // ---------------------------------------------------------------------------
       
   372 // CMRFieldContainer::SetFieldContainerObserver
       
   373 // ---------------------------------------------------------------------------
       
   374 //
       
   375 void CMRFieldContainer::SetFieldContainerObserver( 
       
   376         MMRFieldContainerObserver* aObserver )
       
   377     {
       
   378     FUNC_LOG;
       
   379     iObserver = aObserver;
       
   380     }
       
   381 
       
   382 // ---------------------------------------------------------------------------
       
   383 // CMRFieldContainer::CountComponentControls
       
   384 // ---------------------------------------------------------------------------
       
   385 //
       
   386 TInt CMRFieldContainer::CountComponentControls() const
       
   387     {
       
   388     FUNC_LOG;
       
   389     return iFactory.Count();
       
   390     }
       
   391 
       
   392 // ---------------------------------------------------------------------------
       
   393 // CMRFieldContainer::ComponentControl
       
   394 // ---------------------------------------------------------------------------
       
   395 //
       
   396 CCoeControl* CMRFieldContainer::ComponentControl( TInt aIndex ) const
       
   397     {
       
   398     FUNC_LOG;
       
   399     return iFactory.Field( aIndex );
       
   400     }
       
   401 
       
   402 // ---------------------------------------------------------------------------
       
   403 // CMRFieldContainer::MinimumSize
       
   404 // ---------------------------------------------------------------------------
       
   405 //
       
   406 TSize CMRFieldContainer::MinimumSize()
       
   407     {
       
   408     FUNC_LOG;
       
   409     /*
       
   410      * Returns the minimum size required by the field container
       
   411      */
       
   412     
       
   413     TSize containerSize;
       
   414     
       
   415     const TInt count( iFactory.Count() );
       
   416     
       
   417     for ( TInt i(0); i < count; ++i )
       
   418         {
       
   419         CESMRField* field = iFactory.Field( i );
       
   420         if ( field->IsVisible() )
       
   421             {
       
   422             TRect rect( field->Rect() );
       
   423             containerSize.iHeight += rect.Height();
       
   424             }
       
   425         }
       
   426     
       
   427     containerSize.iWidth = Parent()->Rect().Width();
       
   428     
       
   429     return containerSize;
       
   430     }
       
   431 
       
   432 // ---------------------------------------------------------------------------
       
   433 // CMRFieldContainer::SizeChanged
       
   434 // ---------------------------------------------------------------------------
       
   435 //
       
   436 void CMRFieldContainer::SizeChanged()
       
   437     {
       
   438     FUNC_LOG;
       
   439     
       
   440     // TEST CODE:
       
   441     TRect fieldcontainerRect = Rect();
       
   442     TRect parentRect = Parent()->Rect();
       
   443     
       
   444 
       
   445     // For example when orientation changes, we might need to scroll 
       
   446     // the currently focused control visible again. This handles also
       
   447     // scrollbar and physics updates.
       
   448     ScrollControlVisible( KErrNotFound ); 
       
   449     
       
   450     TPoint tl( Position() );
       
   451 
       
   452     const TInt count( iFactory.Count() );
       
   453 
       
   454     // Loop all the visible fields and set size and position in the list
       
   455     for ( TInt i = 0; i < count; i++ )
       
   456         {
       
   457         CESMRField* field = iFactory.Field( i );
       
   458 
       
   459         if ( field->IsVisible() )
       
   460             {
       
   461             LayoutField( *field, tl );
       
   462 
       
   463             TInt height = field->Size().iHeight;
       
   464             tl.iY += height;
       
   465             }
       
   466         }
       
   467     }
       
   468 
       
   469 // ---------------------------------------------------------------------------
       
   470 // CMRFieldContainer::ControlSizeChanged
       
   471 // ---------------------------------------------------------------------------
       
   472 //
       
   473 void CMRFieldContainer::ControlSizeChanged( CESMRField* aField )
       
   474     {
       
   475     FUNC_LOG;
       
   476     /*
       
   477      * Called whenever a fields size has changed. Requires always 
       
   478      * relayouting. 
       
   479      */
       
   480 
       
   481     if ( !aField )
       
   482         {
       
   483         SizeChanged();
       
   484         }
       
   485     else
       
   486         {
       
   487         // Relayout field if size has changed
       
   488         TSize old( aField->Size() );
       
   489         TSize size( aField->MinimumSize() );
       
   490         if( size != old )
       
   491             {
       
   492             aField->SetSize( size );
       
   493             
       
   494             TPoint tl( aField->Position() );
       
   495             TInt index = IndexByFieldId( iFactory, aField->FieldId() );
       
   496 
       
   497             // Move fields below this particular field
       
   498             tl.iY += size.iHeight;
       
   499             MoveFields( index + 1, tl );
       
   500 
       
   501             // Fields have been re-layouted / moved. This requires resetting
       
   502             // the size of this field container.
       
   503             SetSize( MinimumSize() );
       
   504             
       
   505             // Update also scrollbar and physics
       
   506             iObserver->UpdateScrollBarAndPhysics();
       
   507             
       
   508             if( index == iFocusedFieldIndex )
       
   509                 {
       
   510                 // Scroll this field completely visible, if required.
       
   511                 // This updates also scrollbar and physics if scrolling 
       
   512                 // is done.
       
   513                 ScrollControlVisible( iFocusedFieldIndex );
       
   514                 }
       
   515             
       
   516             DrawDeferred();
       
   517             }
       
   518         }
       
   519     }
       
   520 
       
   521 // ---------------------------------------------------------------------------
       
   522 // CMRFieldContainer::ShowControl
       
   523 // ---------------------------------------------------------------------------
       
   524 //
       
   525 void CMRFieldContainer::ShowControl( TESMREntryFieldId aFieldId )
       
   526     {
       
   527     FUNC_LOG;
       
   528     /*
       
   529      * Inserts field visible and layouts it.
       
   530      */
       
   531     
       
   532     CESMRField* field = iFactory.FieldById( aFieldId );
       
   533 
       
   534     if ( field && !field->IsVisible() )
       
   535         {
       
   536         // Make field visible
       
   537         field->MakeVisible( ETrue );
       
   538         TInt index = IndexByFieldId( iFactory, aFieldId );
       
   539 
       
   540         TPoint tl( Rect().iTl );
       
   541         TInt prevIndex = index - 1;
       
   542 
       
   543         // Get previous visible field position
       
   544         // Index 0 must be included in attendee field case, 
       
   545         // to avoid field collision. But in response field, 
       
   546         // causes misplacing of area.
       
   547         if ( ( prevIndex >= 0 ) && ( aFieldId != EESMRFieldResponseArea ) )
       
   548             {
       
   549             CESMRField* previous = NULL;
       
   550             do
       
   551                 {
       
   552                 previous = iFactory.Field( prevIndex-- );
       
   553                 }
       
   554             while ( prevIndex >= 0 && !previous->IsVisible() );
       
   555 
       
   556             tl.iY = previous->Rect().iBr.iY;
       
   557             }
       
   558 
       
   559         // Layout field
       
   560         LayoutField( *field, tl);
       
   561 
       
   562         // Move following fields
       
   563         tl.iY += field->Size().iHeight;
       
   564         MoveFields( ++index, tl );
       
   565 
       
   566         // Set fieldcontainer size again, because 
       
   567         // the amount of fields has changed.
       
   568         SetSize( MinimumSize() );
       
   569         
       
   570         // Scrollbar and physics require updating.
       
   571         iObserver->UpdateScrollBarAndPhysics();
       
   572         }
       
   573     
       
   574     DrawDeferred();
       
   575     }
       
   576 
       
   577 // ---------------------------------------------------------------------------
       
   578 // CMRFieldContainer::HideControl()
       
   579 // ---------------------------------------------------------------------------
       
   580 //
       
   581 void CMRFieldContainer::HideControl( TESMREntryFieldId aFieldId )
       
   582     {
       
   583     FUNC_LOG;
       
   584     /*
       
   585      * Sets field non-visible and moves other fields accordingly.
       
   586      * Does not delete the field. 
       
   587      */
       
   588     CESMRField* field = iFactory.FieldById( aFieldId );
       
   589 
       
   590     if ( field && field->IsVisible() )
       
   591         {
       
   592         field->MakeVisible( EFalse );
       
   593         TInt index = IndexByFieldId( iFactory, aFieldId );
       
   594         TBool focused = ( index == iFocusedFieldIndex )? ETrue : EFalse;
       
   595 
       
   596         TPoint pos( field->Position() );
       
   597         MoveFields( index, pos );
       
   598 
       
   599         // Set fieldcontainer size again, because 
       
   600         // the amount of fields has changed.
       
   601         SetSize( MinimumSize() );
       
   602         
       
   603         // Scrollbar and physics require updating.
       
   604         iObserver->UpdateScrollBarAndPhysics();
       
   605         
       
   606         if ( focused && !field->IsNonFocusing() )            
       
   607             {
       
   608             // Set focus to next field, or if removed field was the last 
       
   609             // field, then move focus to last visible field
       
   610             TInt lastVisibleFieldIndex( LastVisibleField( aFieldId ) ); 
       
   611             
       
   612             // If field was the last one...
       
   613             if( lastVisibleFieldIndex == index )
       
   614                 {
       
   615                 // ... Set focus to last visible field.
       
   616                 TRAP_IGNORE( DoSetFocusL( lastVisibleFieldIndex ) )
       
   617                 }
       
   618             else
       
   619                 {
       
   620                 // Othwerwise set focus to next field
       
   621                 TRAP_IGNORE( DoSetFocusL( index + 1 ) )
       
   622                 }
       
   623             }
       
   624         }
       
   625     DrawDeferred();
       
   626     }
       
   627 
       
   628 // ---------------------------------------------------------------------------
       
   629 // CMRFieldContainer::IsControlVisible
       
   630 // ---------------------------------------------------------------------------
       
   631 //
       
   632 TBool CMRFieldContainer::IsControlVisible( TESMREntryFieldId aField )
       
   633     {
       
   634     FUNC_LOG;
       
   635     /*
       
   636      * Returns ETrue/EFalse if the field with given field id is 
       
   637      * visible or not.
       
   638      */
       
   639     
       
   640     TBool ret( EFalse );
       
   641 
       
   642     CESMRField* field = iFactory.FieldById( aField );
       
   643     if ( field && field->IsVisible() )
       
   644         {
       
   645         ret = ETrue;
       
   646         }
       
   647 
       
   648     return ret;
       
   649     }
       
   650 
       
   651 // ---------------------------------------------------------------------------
       
   652 // CMRFieldContainer::SetControlFocused
       
   653 // ---------------------------------------------------------------------------
       
   654 //
       
   655 void CMRFieldContainer::SetControlFocusedL( TESMREntryFieldId aField )
       
   656     {
       
   657     FUNC_LOG;
       
   658     /*
       
   659      * Set the field with given field id focused.
       
   660      */
       
   661 
       
   662     // This handles scrollbar and physics updates also.
       
   663     DoSetFocusL( IndexByFieldId( iFactory, aField ) );
       
   664     }
       
   665 
       
   666 // ---------------------------------------------------------------------------
       
   667 // CMRFieldContainer::ListHeight
       
   668 // ---------------------------------------------------------------------------
       
   669 //
       
   670 TInt CMRFieldContainer::ListHeight()
       
   671     {
       
   672     FUNC_LOG;
       
   673     /*
       
   674      * Returns the height of all fields, in other words the height
       
   675      * of the field container.
       
   676      */
       
   677     return MinimumSize().iHeight;
       
   678     }
       
   679 
       
   680 // ---------------------------------------------------------------------------
       
   681 // CMRFieldContainer::IsFocusedControlsBottomVisible
       
   682 // ---------------------------------------------------------------------------
       
   683 //
       
   684 TBool CMRFieldContainer::IsFocusedControlsBottomVisible()
       
   685     {
       
   686     FUNC_LOG;
       
   687     /*
       
   688      * Checks if focused field is completely visible in the viewable area. 
       
   689      */
       
   690     
       
   691     // Fetch the position information about currently focused field:
       
   692     CESMRField* field = iFactory.Field( iFocusedFieldIndex );
       
   693     TBool ret( EFalse );
       
   694     if ( field->Rect().iBr.iY <= Parent()->Rect().iBr.iY )
       
   695        {
       
   696        ret = ETrue;
       
   697        }
       
   698 
       
   699     return ret;
       
   700     }
       
   701 
       
   702 
       
   703 // ---------------------------------------------------------------------------
       
   704 // CMRFieldContainer::ScrollControlVisible
       
   705 // ---------------------------------------------------------------------------
       
   706 //
       
   707 void CMRFieldContainer::ScrollControlVisible( TInt aInd )
       
   708     {
       
   709     FUNC_LOG;
       
   710     /*
       
   711      * Scrolls the field with the given index visible
       
   712      */
       
   713     
       
   714     CESMRField* field = NULL;
       
   715     if ( aInd == KErrNotFound )
       
   716         {
       
   717         field = FocusedField();
       
   718         }
       
   719     else
       
   720         {
       
   721         field = iFactory.Field( aInd );
       
   722         }
       
   723 
       
   724     ASSERT( field );
       
   725     
       
   726     TRect fieldRect( field->Position(), field->Size() );
       
   727     TRect parentRect( Parent()->Rect() );
       
   728     
       
   729     /*
       
   730      * Case 1: Field's height is less than the viewable area height,
       
   731      * let's scroll the whole field visible.
       
   732      */
       
   733     if( fieldRect.Height() < parentRect.Height() )
       
   734         {
       
   735         // Scrolling down, let's move fields up
       
   736         if( fieldRect.iBr.iY > parentRect.iBr.iY )
       
   737             {
       
   738             iObserver->ScrollFieldsUp( 
       
   739                     fieldRect.iBr.iY - parentRect.iBr.iY );
       
   740             }
       
   741         // scrolling up, let's move field down
       
   742         if( fieldRect.iTl.iY < parentRect.iTl.iY )
       
   743             {
       
   744             iObserver->ScrollFieldsDown( 
       
   745                     parentRect.iTl.iY - fieldRect.iTl.iY );
       
   746             }
       
   747         }
       
   748     
       
   749     /*
       
   750      * Case 2: Field's height is more than the viewable area's height.
       
   751      */
       
   752     else
       
   753         {
       
   754         // Field is in view mode
       
   755         if( field->FieldMode() == EESMRFieldModeView )
       
   756             {
       
   757             // Focus to this field is coming from above
       
   758             if( field->PreItemIndex() < field->CurrentItemIndex() )
       
   759                 {
       
   760                 // Let's scroll the top of the field to the 
       
   761                 // top of the viewable area
       
   762                 iObserver->ScrollFieldsUp( 
       
   763                                    fieldRect.iTl.iY - parentRect.iTl.iY );
       
   764                 
       
   765                 }
       
   766             // Focus to this field is coming from below
       
   767             if( field->PreItemIndex() > field->CurrentItemIndex() )
       
   768                 {
       
   769                 // Let's scroll the bottom of the field to the
       
   770                 // bottom of the viewable area
       
   771                 iObserver->ScrollFieldsDown( 
       
   772                                    parentRect.iBr.iY - fieldRect.iBr.iY );
       
   773                 }
       
   774             }
       
   775         
       
   776         // Field is in edit mode
       
   777         if( field->FieldMode() == EESMRFieldModeEdit )
       
   778             {
       
   779             // TODO: CORRECT if broken
       
   780             TInt viewBottom( parentRect.iBr.iY );
       
   781 
       
   782             TInt fieldUpper( 0 );
       
   783             TInt fieldLower( 0 );
       
   784             field->GetCursorLineVerticalPos( fieldUpper, fieldLower );
       
   785 
       
   786             TInt focusFieldVisibleUp( fieldRect.iTl.iY + fieldUpper );
       
   787             TInt focusFieldVisibleBottom( fieldRect.iTl.iY + fieldLower );
       
   788 
       
   789             // desired position below view rect:
       
   790             TInt viewHeight( parentRect.Height() );
       
   791             if ( focusFieldVisibleBottom > viewBottom )
       
   792                 {
       
   793                 // move field focus line bottom to view bottom
       
   794                 TInt px = focusFieldVisibleBottom - viewHeight;
       
   795 
       
   796                 
       
   797                 // if focus on last field: add margin height to
       
   798                 // scroll amount.
       
   799                 if ( iFocusedFieldIndex == iFactory.Count()-1 )
       
   800                     {
       
   801                     px += KVerticalScrollMargin; // TODO: Fix me! K-value must be removed.
       
   802                     }
       
   803                 
       
   804                 // Scrollbar and physics update is done here
       
   805                 iObserver->ScrollFieldsUp( px );
       
   806                 }
       
   807             else
       
   808                 {
       
   809                 // If field top is invisible, move downwards to make top visible.
       
   810                 TInt viewTop( parentRect.iTl.iY );
       
   811 
       
   812                 // recalculate field rect
       
   813                 focusFieldVisibleUp = fieldRect.iTl.iY + fieldUpper;
       
   814                 focusFieldVisibleBottom = fieldRect.iTl.iY + fieldLower;
       
   815 
       
   816                 if ( focusFieldVisibleUp < viewTop )
       
   817                     {
       
   818                     TInt px( viewTop - focusFieldVisibleUp );
       
   819 
       
   820                     // Scrollbar and physics update is done here
       
   821                     iObserver->ScrollFieldsDown( px );
       
   822                     }
       
   823                 }
       
   824             }        
       
   825         }
       
   826     }
       
   827 
       
   828 // ---------------------------------------------------------------------------
       
   829 // CMRFieldContainer::RePositionFields
       
   830 // ---------------------------------------------------------------------------
       
   831 //
       
   832 void CMRFieldContainer::RePositionFields( TInt aAmount )
       
   833     {
       
   834     FUNC_LOG;
       
   835     
       
   836     // Movement downwards
       
   837     if( aAmount >= 0 )
       
   838         {
       
   839         // Also scrollbar and physics update is done here
       
   840         iObserver->ScrollFieldsDown( aAmount );
       
   841         }
       
   842     // Movement upwards
       
   843     else
       
   844         {
       
   845         // Also scrollbar and physics update is done here
       
   846         iObserver->ScrollFieldsUp( -aAmount );
       
   847         }
       
   848     }
       
   849 
       
   850 // ---------------------------------------------------------------------------
       
   851 // CMRFieldContainer::ViewableAreaRect
       
   852 // ---------------------------------------------------------------------------
       
   853 //
       
   854 TRect CMRFieldContainer::ViewableAreaRect()
       
   855     {
       
   856     FUNC_LOG;
       
   857     return Parent()->Rect();
       
   858     }
       
   859 
       
   860 // ---------------------------------------------------------------------------
       
   861 // CMRFieldContainer::MoveFields
       
   862 // ---------------------------------------------------------------------------
       
   863 //
       
   864 void CMRFieldContainer::MoveFields( TInt aIndex, TPoint& aTl )
       
   865     {
       
   866     FUNC_LOG;
       
   867     /*
       
   868      * Moves fields from the given index towards the last item. 
       
   869      * This function does not update scrollbar or physics.
       
   870      */
       
   871     
       
   872     const TInt count( iFactory.Count() );
       
   873     
       
   874     for ( TInt i = aIndex; i < count; ++i )
       
   875         {
       
   876         CESMRField* field = iFactory.Field( i );
       
   877         
       
   878         if ( field->IsVisible() )
       
   879             {
       
   880             field->SetPosition( aTl );
       
   881             
       
   882             aTl.iY += field->Size().iHeight;
       
   883             }
       
   884         }
       
   885     }
       
   886 
       
   887 // ---------------------------------------------------------------------------
       
   888 // CMRFieldContainer::LayoutField
       
   889 // ---------------------------------------------------------------------------
       
   890 //
       
   891 void CMRFieldContainer::LayoutField( CESMRField& aField, const TPoint& aTl )
       
   892     {
       
   893     FUNC_LOG;
       
   894     /*
       
   895      * Layouts given field according to the size required by the field and
       
   896      * given TPoint. This function does not update scrollbar or physics.
       
   897      */
       
   898     
       
   899     TSize size( aField.MinimumSize() );
       
   900     aField.SetPosition( aTl );
       
   901     aField.SetSize( size );
       
   902     }
       
   903 
       
   904 // ---------------------------------------------------------------------------
       
   905 // CMRFieldContainer::IsLastVisibleField
       
   906 // ---------------------------------------------------------------------------
       
   907 //
       
   908 TInt CMRFieldContainer::LastVisibleField( 
       
   909         TESMREntryFieldId aFieldId )
       
   910     {
       
   911     /*
       
   912      * Helper function to find out the last visible field in the list.
       
   913      */
       
   914     
       
   915     TInt lastVisibleFieldIndex( 0 );
       
   916     TInt count( iFactory.Count() );
       
   917     
       
   918     // Go through fields from last field towards the first field
       
   919     for( TInt i( 1 ); i > count; ++i )
       
   920         {
       
   921         // Once last visible field is found...
       
   922         if( iFactory.Field( count - i )->IsVisible() )
       
   923             {
       
   924             // ... Compare it to the given field index ...
       
   925             if( iFactory.Field( count - i )->FieldId() == aFieldId )
       
   926                 {
       
   927                 // ... And if match is found, given fieldId is the 
       
   928                 // the last visible field.
       
   929                 lastVisibleFieldIndex = 
       
   930                     IndexByFieldId( iFactory, aFieldId );
       
   931                 }
       
   932             else
       
   933                 {
       
   934                 // Otherwise return the found last visible field.
       
   935                 lastVisibleFieldIndex = 
       
   936                     IndexByFieldId( iFactory, 
       
   937                                     iFactory.Field( count - i )->FieldId() );
       
   938                 }
       
   939             break;
       
   940             }
       
   941         }
       
   942     
       
   943     return lastVisibleFieldIndex;
       
   944     }
       
   945 
       
   946 // ---------------------------------------------------------------------------
       
   947 // CMRFieldContainer::DoSetFocusL
       
   948 // ---------------------------------------------------------------------------
       
   949 //
       
   950 void CMRFieldContainer::DoSetFocusL( TInt aNewFocusIndex )
       
   951     {
       
   952     FUNC_LOG;
       
   953     /*
       
   954      * Sets the focus according to the given index.
       
   955      */
       
   956     
       
   957     TInt count( iFactory.Count() );
       
   958     aNewFocusIndex = Max( 0, Min( aNewFocusIndex, count - 1 ) );
       
   959 
       
   960     if ( aNewFocusIndex != iFocusedFieldIndex )
       
   961         {
       
   962         // Get current focused field
       
   963         CESMRField* old = iFactory.Field( iFocusedFieldIndex );
       
   964 
       
   965         // Get next focused field
       
   966         CESMRField* field = iFactory.Field( aNewFocusIndex );
       
   967         
       
   968         // Do sanity checks
       
   969         while ( aNewFocusIndex < count && !field->IsVisible() )
       
   970             {
       
   971             field = iFactory.Field( aNewFocusIndex++ );
       
   972             }
       
   973 
       
   974         if ( !field->IsVisible() )
       
   975             {
       
   976             aNewFocusIndex = iFocusedFieldIndex - 1;
       
   977             while ( aNewFocusIndex > 0 && !field->IsVisible() )
       
   978                 {
       
   979                 field = iFactory.Field( aNewFocusIndex-- );
       
   980                 }
       
   981             }
       
   982 
       
   983         ASSERT( field->IsVisible() );
       
   984         
       
   985         // Update current and previous item indexes
       
   986         field->SetPreItemIndex( iFocusedFieldIndex );
       
   987         iFocusedFieldIndex = aNewFocusIndex;
       
   988         field->SetCurrentItemIndex( iFocusedFieldIndex );
       
   989         
       
   990         // Remove focus from old
       
   991         old->SetOutlineFocusL( EFalse );
       
   992         old->SetFocus( EFalse );
       
   993         
       
   994         // update focus index to new index
       
   995         field->SetOutlineFocusL( ETrue );
       
   996         field->SetFocus( ETrue );
       
   997         
       
   998         // This handles also scrollbar and physics updating,
       
   999         // if view scrolling is done.
       
  1000         ScrollControlVisible( iFocusedFieldIndex ); 
       
  1001         
       
  1002         DrawDeferred();
       
  1003         }
       
  1004     }
       
  1005 
       
  1006 
       
  1007 // End of file