meetingrequest/mrgui/src/cmrfieldcontainer.cpp
branchRCL_3
changeset 60 d620048b4810
parent 24 b5fbb9b25d57
--- a/meetingrequest/mrgui/src/cmrfieldcontainer.cpp	Mon Jun 21 15:20:54 2010 +0300
+++ b/meetingrequest/mrgui/src/cmrfieldcontainer.cpp	Thu Jul 15 18:19:25 2010 +0300
@@ -24,6 +24,9 @@
 
 namespace { // codescanner::namespace
 
+// Off screen field x coordinate
+const TInt KOffScreenPositionX =  1000;
+
 /**
  * Vertical scroll margin
  */
@@ -79,8 +82,8 @@
 // CMRFieldContainer::NewL
 // ---------------------------------------------------------------------------
 //
-CMRFieldContainer* CMRFieldContainer::NewL( 
-        MESMRFieldStorage& aFactory, 
+CMRFieldContainer* CMRFieldContainer::NewL(
+        MESMRFieldStorage& aFactory,
         const CCoeControl& aParent )
     {
     FUNC_LOG;
@@ -100,7 +103,7 @@
     FUNC_LOG;
     CCoeControl::SetComponentsToInheritVisibility( ETrue );
     SetContainerWindowL( aParent );
-    
+
     TBool focusSet( EFalse );
     const TInt count( iFactory.Count() );
     for ( TInt i = 0; i < count; i++ )
@@ -114,7 +117,6 @@
 
         // Initialize field
         field->InitializeL();
-        User::LeaveIfError( field->SetParent( this ) );
 
         if ( !focusSet
              && field->IsVisible()
@@ -161,10 +163,10 @@
     {
     FUNC_LOG;
     /*
-     * Moves focus up after key event. If aHiddenFocus, moves focus 
+     * Moves focus up after key event. If aHiddenFocus, moves focus
      * to the first visible field in the bottom of the viewable area.
      */
-     
+
     if( aHiddenFocus )
         {
         return MoveFocusVisibleL();
@@ -194,17 +196,19 @@
                         iFocusedFieldIndex = ind;
                         field->SetCurrentItemIndex( iFocusedFieldIndex );
 
-                        // Remove focus from previous position 
+                        // Remove focus from previous position
                         focusedField->SetOutlineFocusL( EFalse );
                         focusedField->SetFocus( EFalse );
-                        
+                        focusedField->MoveToScreen( EFalse );
+
                         // Set focus to new position
                         field->SetOutlineFocusL( ETrue );
                         field->SetFocus( ETrue );
+                        field->MoveToScreen( ETrue );
 
                         // Scrollbar and physics update is done here
                         ScrollControlVisible( iFocusedFieldIndex );
-                        
+
                         DrawDeferred();
                         }
 
@@ -224,10 +228,10 @@
     {
     FUNC_LOG;
     /*
-     * Moves focus down after key event. If aHiddenFocus, moves focus 
+     * Moves focus down after key event. If aHiddenFocus, moves focus
      * to the first visible field in the top of the viewable area.
      */
-    
+
     if( aHiddenFocus )
         {
         return MoveFocusVisibleL();
@@ -258,17 +262,19 @@
                     iFocusedFieldIndex = ind;
                     field->SetCurrentItemIndex( iFocusedFieldIndex );
 
-                    // Remove focus from previous position 
+                    // Remove focus from previous position
                     focusedField->SetOutlineFocusL( EFalse );
                     focusedField->SetFocus( EFalse );
-                    
+                    focusedField->MoveToScreen( EFalse );
+
                     // Set focus to new position
                     field->SetOutlineFocusL( ETrue );
                     field->SetFocus( ETrue );
+                    field->MoveToScreen( ETrue );
 
                     // Scrollbar and physics update is done here
                     ScrollControlVisible( iFocusedFieldIndex );
-                    
+
                     DrawDeferred();
                     }
 
@@ -287,13 +293,13 @@
     {
     FUNC_LOG;
     /*
-     * Move focus to first completely visible field in the view, 
+     * Move focus to first completely visible field in the view,
      * if focus was in a field that was not visible in the view.
      * Use case: After pointer scroll focus is hidden. User presses
      * arrow keys -> Focus appears to the first visible field on the upper
      * or bottom part of the viewable area.
      */
-    
+
     TKeyResponse response( EKeyWasNotConsumed );
 
     CESMRField* focusedField = FocusedField();
@@ -355,16 +361,16 @@
         // Remove existing focus
         focusedField->SetOutlineFocusL( EFalse );
         focusedField->SetFocus( EFalse );
-        
+
         // Set focus to new field
         visibleField->SetOutlineFocusL( ETrue );
         visibleField->SetFocus( ETrue );
 
         response = EKeyWasConsumed;
-        
+
         DrawDeferred();
         }
-    
+
     return response;
     }
 
@@ -372,7 +378,7 @@
 // CMRFieldContainer::SetFieldContainerObserver
 // ---------------------------------------------------------------------------
 //
-void CMRFieldContainer::SetFieldContainerObserver( 
+void CMRFieldContainer::SetFieldContainerObserver(
         MMRFieldContainerObserver* aObserver )
     {
     FUNC_LOG;
@@ -386,7 +392,16 @@
 TInt CMRFieldContainer::CountComponentControls() const
     {
     FUNC_LOG;
-    return iFactory.Count();
+
+    // If field container is scrolling, container will draw also children
+    TInt count( 0 );
+
+    if ( !iScrolling )
+        {
+        count = iFactory.Count();
+        }
+
+    return count;
     }
 
 // ---------------------------------------------------------------------------
@@ -409,11 +424,12 @@
     /*
      * Returns the minimum size required by the field container
      */
-    
+
     TSize containerSize;
-    
+
+    // Calculate height as the sum of the heights of the visible fields
     const TInt count( iFactory.Count() );
-    
+
     for ( TInt i(0); i < count; ++i )
         {
         CESMRField* field = iFactory.Field( i );
@@ -423,9 +439,9 @@
             containerSize.iHeight += rect.Height();
             }
         }
-    
+
     containerSize.iWidth = Parent()->Rect().Width();
-    
+
     return containerSize;
     }
 
@@ -436,17 +452,12 @@
 void CMRFieldContainer::SizeChanged()
     {
     FUNC_LOG;
-    
-    // TEST CODE:
-    TRect fieldcontainerRect = Rect();
-    TRect parentRect = Parent()->Rect();
-    
 
-    // For example when orientation changes, we might need to scroll 
+    // For example when orientation changes, we might need to scroll
     // the currently focused control visible again. This handles also
     // scrollbar and physics updates.
-    ScrollControlVisible( KErrNotFound ); 
-    
+    ScrollControlVisible( KErrNotFound );
+
     TPoint tl( Position() );
 
     const TInt count( iFactory.Count() );
@@ -458,7 +469,15 @@
 
         if ( field->IsVisible() )
             {
-            LayoutField( *field, tl );
+            TPoint pos( tl );
+
+            // If field is not focused, layout it outside screen
+            if ( i != iFocusedFieldIndex )
+                {
+                pos.iX = KOffScreenPositionX;
+                }
+
+            LayoutField( *field, pos );
 
             TInt height = field->Size().iHeight;
             tl.iY += height;
@@ -466,6 +485,29 @@
         }
     }
 
+
+// ---------------------------------------------------------------------------
+// CMRFieldContainer::HandlePointerEventL
+// ---------------------------------------------------------------------------
+//
+void CMRFieldContainer::HandlePointerEventL( const TPointerEvent &aPointerEvent )
+    {
+    FUNC_LOG;
+
+    // Find out to which field this pointer event is intended to
+    TInt fieldCount( iFactory.Count() );
+
+    for( TInt i = 0; i < fieldCount; ++i )
+        {
+        CCoeControl* field = iFactory.Field( i );
+        if( field->Rect().Contains( aPointerEvent.iPosition ) &&
+                field->IsVisible() )
+            {
+            field->HandlePointerEventL( aPointerEvent );
+            }
+        }
+    }
+
 // ---------------------------------------------------------------------------
 // CMRFieldContainer::ControlSizeChanged
 // ---------------------------------------------------------------------------
@@ -474,8 +516,8 @@
     {
     FUNC_LOG;
     /*
-     * Called whenever a fields size has changed. Requires always 
-     * relayouting. 
+     * Called whenever a fields size has changed. Requires always
+     * relayouting.
      */
 
     if ( !aField )
@@ -490,7 +532,7 @@
         if( size != old )
             {
             aField->SetSize( size );
-            
+
             TPoint tl( aField->Position() );
             TInt index = IndexByFieldId( iFactory, aField->FieldId() );
 
@@ -500,19 +542,19 @@
 
             // Fields have been re-layouted / moved. This requires resetting
             // the size of this field container.
-            SetSize( MinimumSize() );
-            
+            SetSizeWithoutNotification( MinimumSize() );
+
             // Update also scrollbar and physics
             iObserver->UpdateScrollBarAndPhysics();
-            
-            if( index == iFocusedFieldIndex )
+
+            if( index <= iFocusedFieldIndex )
                 {
                 // Scroll this field completely visible, if required.
-                // This updates also scrollbar and physics if scrolling 
+                // This updates also scrollbar and physics if scrolling
                 // is done.
                 ScrollControlVisible( iFocusedFieldIndex );
                 }
-            
+
             DrawDeferred();
             }
         }
@@ -528,7 +570,7 @@
     /*
      * Inserts field visible and layouts it.
      */
-    
+
     CESMRField* field = iFactory.FieldById( aFieldId );
 
     if ( field && !field->IsVisible() )
@@ -541,8 +583,8 @@
         TInt prevIndex = index - 1;
 
         // Get previous visible field position
-        // Index 0 must be included in attendee field case, 
-        // to avoid field collision. But in response field, 
+        // Index 0 must be included in attendee field case,
+        // to avoid field collision. But in response field,
         // causes misplacing of area.
         if ( ( prevIndex >= 0 ) && ( aFieldId != EESMRFieldResponseArea ) )
             {
@@ -558,19 +600,21 @@
 
         // Layout field
         LayoutField( *field, tl);
+        // Move field off screen if it is not focused
+        field->MoveToScreen( index == iFocusedFieldIndex );
 
         // Move following fields
         tl.iY += field->Size().iHeight;
         MoveFields( ++index, tl );
 
-        // Set fieldcontainer size again, because 
+        // Set fieldcontainer size again, because
         // the amount of fields has changed.
-        SetSize( MinimumSize() );
-        
+        SetSizeWithoutNotification( MinimumSize() );
+
         // Scrollbar and physics require updating.
         iObserver->UpdateScrollBarAndPhysics();
         }
-    
+
     DrawDeferred();
     }
 
@@ -583,7 +627,7 @@
     FUNC_LOG;
     /*
      * Sets field non-visible and moves other fields accordingly.
-     * Does not delete the field. 
+     * Does not delete the field.
      */
     CESMRField* field = iFactory.FieldById( aFieldId );
 
@@ -596,19 +640,19 @@
         TPoint pos( field->Position() );
         MoveFields( index, pos );
 
-        // Set fieldcontainer size again, because 
+        // Set fieldcontainer size again, because
         // the amount of fields has changed.
-        SetSize( MinimumSize() );
-        
+        SetSizeWithoutNotification( MinimumSize() );
+
         // Scrollbar and physics require updating.
         iObserver->UpdateScrollBarAndPhysics();
-        
-        if ( focused && !field->IsNonFocusing() )            
+
+        if ( focused && !field->IsNonFocusing() )
             {
-            // Set focus to next field, or if removed field was the last 
+            // Set focus to next field, or if removed field was the last
             // field, then move focus to last visible field
-            TInt lastVisibleFieldIndex( LastVisibleField( aFieldId ) ); 
-            
+            TInt lastVisibleFieldIndex( LastVisibleField( aFieldId ) );
+
             // If field was the last one...
             if( lastVisibleFieldIndex == index )
                 {
@@ -633,10 +677,10 @@
     {
     FUNC_LOG;
     /*
-     * Returns ETrue/EFalse if the field with given field id is 
+     * Returns ETrue/EFalse if the field with given field id is
      * visible or not.
      */
-    
+
     TBool ret( EFalse );
 
     CESMRField* field = iFactory.FieldById( aField );
@@ -685,9 +729,9 @@
     {
     FUNC_LOG;
     /*
-     * Checks if focused field is completely visible in the viewable area. 
+     * Checks if focused field is completely visible in the viewable area.
      */
-    
+
     // Fetch the position information about currently focused field:
     CESMRField* field = iFactory.Field( iFocusedFieldIndex );
     TBool ret( EFalse );
@@ -710,7 +754,7 @@
     /*
      * Scrolls the field with the given index visible
      */
-    
+
     CESMRField* field = NULL;
     if ( aInd == KErrNotFound )
         {
@@ -722,10 +766,10 @@
         }
 
     ASSERT( field );
-    
+
     TRect fieldRect( field->Position(), field->Size() );
     TRect parentRect( Parent()->Rect() );
-    
+
     /*
      * Case 1: Field's height is less than the viewable area height,
      * let's scroll the whole field visible.
@@ -735,17 +779,17 @@
         // Scrolling down, let's move fields up
         if( fieldRect.iBr.iY > parentRect.iBr.iY )
             {
-            iObserver->ScrollFieldsUp( 
+            iObserver->ScrollFieldsUp(
                     fieldRect.iBr.iY - parentRect.iBr.iY );
             }
         // scrolling up, let's move field down
         if( fieldRect.iTl.iY < parentRect.iTl.iY )
             {
-            iObserver->ScrollFieldsDown( 
+            iObserver->ScrollFieldsDown(
                     parentRect.iTl.iY - fieldRect.iTl.iY );
             }
         }
-    
+
     /*
      * Case 2: Field's height is more than the viewable area's height.
      */
@@ -757,22 +801,22 @@
             // Focus to this field is coming from above
             if( field->PreItemIndex() < field->CurrentItemIndex() )
                 {
-                // Let's scroll the top of the field to the 
+                // Let's scroll the top of the field to the
                 // top of the viewable area
-                iObserver->ScrollFieldsUp( 
+                iObserver->ScrollFieldsUp(
                                    fieldRect.iTl.iY - parentRect.iTl.iY );
-                
+
                 }
             // Focus to this field is coming from below
             if( field->PreItemIndex() > field->CurrentItemIndex() )
                 {
                 // Let's scroll the bottom of the field to the
                 // bottom of the viewable area
-                iObserver->ScrollFieldsDown( 
+                iObserver->ScrollFieldsDown(
                                    parentRect.iBr.iY - fieldRect.iBr.iY );
                 }
             }
-        
+
         // Field is in edit mode
         if( field->FieldMode() == EESMRFieldModeEdit )
             {
@@ -792,14 +836,14 @@
                 // move field focus line bottom to view bottom
                 TInt px = focusFieldVisibleBottom - viewHeight;
 
-                
+
                 // if focus on last field: add margin height to
                 // scroll amount.
                 if ( iFocusedFieldIndex == iFactory.Count()-1 )
                     {
                     px += KVerticalScrollMargin;
                     }
-                
+
                 // Scrollbar and physics update is done here
                 iObserver->ScrollFieldsUp( px );
                 }
@@ -820,7 +864,7 @@
                     iObserver->ScrollFieldsDown( px );
                     }
                 }
-            }        
+            }
         }
     }
 
@@ -831,7 +875,7 @@
 void CMRFieldContainer::RePositionFields( TInt aAmount )
     {
     FUNC_LOG;
-    
+
     // Movement downwards
     if( aAmount >= 0 )
         {
@@ -864,20 +908,20 @@
     {
     FUNC_LOG;
     /*
-     * Moves fields from the given index towards the last item. 
+     * Moves fields from the given index towards the last item.
      * This function does not update scrollbar or physics.
      */
-    
+
     const TInt count( iFactory.Count() );
-    
+
     for ( TInt i = aIndex; i < count; ++i )
         {
         CESMRField* field = iFactory.Field( i );
-        
+
         if ( field->IsVisible() )
             {
             field->SetPosition( aTl );
-            
+
             aTl.iY += field->Size().iHeight;
             }
         }
@@ -894,26 +938,25 @@
      * Layouts given field according to the size required by the field and
      * given TPoint. This function does not update scrollbar or physics.
      */
-    
+
     TSize size( aField.MinimumSize() );
-    aField.SetPosition( aTl );
-    aField.SetSize( size );
+    aField.SetExtent( aTl, size );
     }
 
 // ---------------------------------------------------------------------------
 // CMRFieldContainer::IsLastVisibleField
 // ---------------------------------------------------------------------------
 //
-TInt CMRFieldContainer::LastVisibleField( 
+TInt CMRFieldContainer::LastVisibleField(
         TESMREntryFieldId aFieldId )
     {
     /*
      * Helper function to find out the last visible field in the list.
      */
-    
+
     TInt lastVisibleFieldIndex( 0 );
     TInt count( iFactory.Count() );
-    
+
     // Go through fields from last field towards the first field
     for( TInt i( 1 ); i > count; ++i )
         {
@@ -923,22 +966,22 @@
             // ... Compare it to the given field index ...
             if( iFactory.Field( count - i )->FieldId() == aFieldId )
                 {
-                // ... And if match is found, given fieldId is the 
+                // ... And if match is found, given fieldId is the
                 // the last visible field.
-                lastVisibleFieldIndex = 
+                lastVisibleFieldIndex =
                     IndexByFieldId( iFactory, aFieldId );
                 }
             else
                 {
                 // Otherwise return the found last visible field.
-                lastVisibleFieldIndex = 
-                    IndexByFieldId( iFactory, 
+                lastVisibleFieldIndex =
+                    IndexByFieldId( iFactory,
                                     iFactory.Field( count - i )->FieldId() );
                 }
             break;
             }
         }
-    
+
     return lastVisibleFieldIndex;
     }
 
@@ -952,7 +995,7 @@
     /*
      * Sets the focus according to the given index.
      */
-    
+
     TInt count( iFactory.Count() );
     aNewFocusIndex = Max( 0, Min( aNewFocusIndex, count - 1 ) );
 
@@ -963,7 +1006,7 @@
 
         // Get next focused field
         CESMRField* field = iFactory.Field( aNewFocusIndex );
-        
+
         // Do sanity checks
         while ( aNewFocusIndex < count && !field->IsVisible() )
             {
@@ -980,27 +1023,133 @@
             }
 
         ASSERT( field->IsVisible() );
-        
+
         // Update current and previous item indexes
         field->SetPreItemIndex( iFocusedFieldIndex );
         iFocusedFieldIndex = aNewFocusIndex;
         field->SetCurrentItemIndex( iFocusedFieldIndex );
-        
+
         // Remove focus from old
         old->SetOutlineFocusL( EFalse );
         old->SetFocus( EFalse );
-        
+        old->MoveToScreen( EFalse );
+
         // update focus index to new index
         field->SetOutlineFocusL( ETrue );
         field->SetFocus( ETrue );
-        
+        field->MoveToScreen( ETrue );
+
         // This handles also scrollbar and physics updating,
         // if view scrolling is done.
-        ScrollControlVisible( iFocusedFieldIndex ); 
-        
+        ScrollControlVisible( iFocusedFieldIndex );
+
         DrawDeferred();
         }
     }
 
 
+// ---------------------------------------------------------------------------
+// CMRFieldContainer::SetScrolling
+// ---------------------------------------------------------------------------
+//
+void CMRFieldContainer::SetScrolling( TBool aScrolling )
+    {
+    FUNC_LOG;
+
+    iScrolling = aScrolling;
+
+    // Move focused field away from screen if container is scrolling.
+    // Otherwise move it to screen.
+    CESMRField* field = iFactory.Field( iFocusedFieldIndex );
+    field->MoveToScreen( !iScrolling );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMRFieldContainer::Draw
+// ---------------------------------------------------------------------------
+//
+void CMRFieldContainer::Draw( const TRect& aRect ) const
+    {
+    FUNC_LOG;
+
+    // Get visible screen area from parent (list pane)
+    TRect parent( Parent()->Rect() );
+
+    // Current container position used to calculate actual field positions
+    TPoint tl( iPosition );
+
+    // Field index to skip
+    TInt fieldToSkip = KErrNotFound;
+
+    if ( !iScrolling )
+        {
+        // Container is not scrolling. Don't draw focused field from buffer
+        fieldToSkip = iFocusedFieldIndex;
+        }
+
+    // Draw all visible fields which are not on screen
+    TInt count( iFactory.Count() );
+
+    for ( TInt i = 0; i < count; ++i )
+        {
+        CESMRField* field = iFactory.Field( i );
+        if ( field->IsVisible() )
+            {
+            // Calculate actual field rect on screen
+            TRect screenRect( tl, field->Size() );
+
+            // Draw field if it intersects with screen visible area
+            if ( i != fieldToSkip
+                 && screenRect.Intersects( parent ) )
+                {
+                field->Draw( screenRect );
+                }
+            // Move next field top left corner
+            tl.iY += screenRect.Height();
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CMRFieldContainer::ScrollContainer
+// ---------------------------------------------------------------------------
+//
+void CMRFieldContainer::ScrollContainer( const TPoint& aTl )
+    {
+    FUNC_LOG;
+
+    // Set scrolling flag and move focused field off screen
+    SetScrolling( ETrue );
+    // Update control position,
+    // but dont propagate the change to component controls
+    iPosition = aTl;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRFieldContainer::Synchronize
+// ---------------------------------------------------------------------------
+//
+void CMRFieldContainer::Synchronize()
+    {
+    FUNC_LOG;
+
+    // Set actual control positions (y-coordinate) to visible fields
+    TPoint tl( iPosition );
+
+    TInt count( iFactory.Count() );
+
+    for ( TInt i = 0; i < count; ++i )
+        {
+        CESMRField* field = iFactory.Field( i );
+        if ( field->IsVisible() )
+            {
+            TPoint pos( field->Position().iX, tl.iY );
+            tl.iY += field->Size().iHeight;
+            field->SetPosition( pos );
+            }
+        }
+    SetScrolling( EFalse );
+    }
+
 // End of file