diff -r efd4f1afd43e -r d620048b4810 meetingrequest/mrgui/src/cmrfieldcontainer.cpp --- 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