--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrgui/src/cmrlistpane.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,1022 @@
+/*
+* Copyright (c) 2009-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: List pane component for UI fields
+*
+*/
+#include "cmrlistpane.h"
+
+#include <eikscrlb.h>
+#include <AknUtils.h>
+#include <touchfeedback.h>
+
+#include "mesmrfieldstorage.h"
+#include "cesmrfield.h"
+
+#include "emailtrace.h"
+
+namespace // codescanner::namespace
+ {
+ /**
+ * Vertical scroll margin
+ */
+ const TInt KVerticalScrollMargin = 3;
+
+ // ---------------------------------------------------------------------------
+ // IndexByFieldId
+ // ---------------------------------------------------------------------------
+ //
+ TInt IndexByFieldId( const MESMRFieldStorage& aFactory,
+ TESMREntryFieldId aFieldId )
+ {
+ TInt index( KErrNotFound );
+ TInt count( aFactory.Count() );
+
+ for ( TInt i = 0; i < count; ++i )
+ {
+ if ( aFactory.Field( i )->FieldId() == aFieldId )
+ {
+ index = i;
+ break;
+ }
+ }
+
+ return index;
+ }
+ }
+
+//----- MEMBER FUNCTIONS ----
+
+// ---------------------------------------------------------------------------
+// CMRListPane::NewL
+// ---------------------------------------------------------------------------
+//
+CMRListPane* CMRListPane::NewL( const CCoeControl& aParent,
+ MESMRFieldStorage& aFactory,
+ TAknDoubleSpanScrollBarModel& aScrollModel )
+ {
+ CMRListPane* self = new (ELeave) CMRListPane( aFactory, aScrollModel );
+ CleanupStack::PushL( self );
+ self->ConstructL( aParent );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::~CMRListPane
+// ---------------------------------------------------------------------------
+//
+CMRListPane::~CMRListPane()
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::CMRListPane
+// ---------------------------------------------------------------------------
+//
+CMRListPane::CMRListPane( MESMRFieldStorage& aFactory,
+ TAknDoubleSpanScrollBarModel& aScrollModel )
+ : iFactory( aFactory ),
+ iScrollModel( aScrollModel )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ConstructL( const CCoeControl& aParent )
+ {
+ SetContainerWindowL( aParent );
+ TBool focusSet = EFalse;
+ const TInt count( iFactory.Count() );
+ for ( TInt i = 0; i < count; i++ )
+ {
+ iFactory.Field(i)->SetContainerWindowL( *this );
+ }
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ CESMRField* field = iFactory.Field( i );
+
+ // Initialize field
+ field->InitializeL();
+ User::LeaveIfError( field->SetParent( this ) );
+
+ if ( !focusSet
+ && field->IsVisible()
+ && !field->IsNonFocusing())
+ {
+ field->SetOutlineFocusL( ETrue );
+ focusSet = ETrue;
+ iFocus = i;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::FocusedItem
+// ---------------------------------------------------------------------------
+//
+CESMRField* CMRListPane::FocusedItem() const
+ {
+ FUNC_LOG;
+ CESMRField* field = NULL;
+ if ( iFactory.Count() > 0 )
+ {
+ field = iFactory.Field( iFocus );
+ }
+ return field;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::CountComponentControls
+// ---------------------------------------------------------------------------
+//
+TInt CMRListPane::CountComponentControls() const
+ {
+ return iFactory.Count();
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ComponentControl
+// ---------------------------------------------------------------------------
+//
+CCoeControl* CMRListPane::ComponentControl( TInt aIndex ) const
+ {
+ return iFactory.Field( aIndex );
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::SizeChanged
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::SizeChanged()
+ {
+ TPoint tl( Position() );
+ TInt scrollSpan = 0;
+ // Loop all the visible fields and set size and position in the list
+ TBool topVisibleFound( EFalse );
+
+ const TInt count( iFactory.Count() );
+ for ( TInt i = 0; i < count; i++ )
+ {
+ CESMRField* field = iFactory.Field( i );
+
+ if ( field->IsVisible() )
+ {
+ LayoutField( *field, tl );
+
+ if ( !topVisibleFound )
+ {
+ iTopVisibleIndex = i;
+ topVisibleFound = ETrue;
+ }
+
+ TInt height = field->Size().iHeight;
+ tl.iY += height;
+ scrollSpan += height;
+ }
+ }
+
+ iScrollModel.SetScrollSpan( scrollSpan );
+ iScrollModel.SetWindowSize( iSize.iHeight );
+ UpdateFocusPosition();
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::OfferKeyEventL
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CMRListPane::OfferKeyEventL( const TKeyEvent &aKeyEvent,
+ TEventCode aType )
+ {
+ TKeyResponse response( EKeyWasNotConsumed );
+
+ // If we have at least one item in the list
+ if ( iFocus < iFactory.Count() )
+ {
+ CESMRField* field = iFactory.Field( iFocus );
+ // First check if the focused item needs the key event
+ response = field->OfferKeyEventL( aKeyEvent, aType );
+
+ if ( aType == EEventKey
+ && response == EKeyWasNotConsumed )
+ {
+ // Check if the focus should be changed
+ switch ( aKeyEvent.iScanCode )
+ {
+ case EStdKeyUpArrow:
+ {
+ response = MoveFocusUpL();
+ break;
+ }
+ case EStdKeyDownArrow:
+ {
+ response = MoveFocusDownL();
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ }
+ return response;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ControlSizeChanged
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ControlSizeChanged( CESMRField* aCtrl )
+ {
+ if ( !aCtrl )
+ {
+ SizeChanged();
+ }
+ else
+ {
+ TPoint tl( aCtrl->Position() );
+ TInt index = IndexByFieldId( iFactory, aCtrl->FieldId() );
+
+ // Relayout aCtrl
+ TSize old( aCtrl->Size() );
+ TSize size( aCtrl->MinimumSize() );
+ if ( aCtrl->IsExpandable() )
+ {
+ size.iHeight = aCtrl->ExpandedHeight();
+ }
+ aCtrl->SetSize( size );
+ iScrollModel.SetScrollSpan( iScrollModel.ScrollSpan()
+ + size.iHeight - old.iHeight );
+
+ // Move other fields
+ ++index;
+ tl.iY += size.iHeight;
+ MoveFields( index, tl );
+ UpdateFocusPosition();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::InsertControl
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::InsertControl( TESMREntryFieldId aField )
+ {
+ CESMRField* field = iFactory.FieldById( aField );
+
+ if ( field && !field->IsVisible() )
+ {
+ // Make field visible
+ field->MakeVisible( ETrue );
+ TInt index = IndexByFieldId( iFactory, aField );
+ if ( index < iTopVisibleIndex )
+ {
+ iTopVisibleIndex = index;
+ }
+
+ TPoint tl( Rect().iTl );
+ TInt prevIndex = index - 1;
+
+ // Get previous visible field position
+ if ( prevIndex >= 0 )
+ {
+ CESMRField* previous = NULL;
+ do
+ {
+ previous = iFactory.Field( prevIndex-- );
+ }
+ while ( prevIndex >= 0 && !previous->IsVisible() );
+
+ tl.iY = previous->Rect().iBr.iY;
+ }
+
+ // Layout field
+ LayoutField( *field, tl );
+ iScrollModel.SetScrollSpan( iScrollModel.ScrollSpan()
+ + field->Size().iHeight );
+
+ // Move following fields
+ tl.iY += field->Size().iHeight;
+ MoveFields( ++index, tl );
+ UpdateFocusPosition();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::InsertControl
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::RemoveControl( TESMREntryFieldId aField )
+ {
+ CESMRField* field = iFactory.FieldById( aField );
+
+ if ( field && field->IsVisible() )
+ {
+ field->MakeVisible( EFalse );
+ iScrollModel.SetScrollSpan( iScrollModel.ScrollSpan() - field->Size().iHeight );
+ TInt index = IndexByFieldId( iFactory, aField );
+ TBool focused = ( index == iFocus )? ETrue : EFalse;
+
+ if ( index == iTopVisibleIndex )
+ {
+ // Find next
+ TInt count( iFactory.Count() );
+ while ( index < count )
+ {
+ if ( iFactory.Field( ++index )->IsVisible() )
+ {
+ iTopVisibleIndex = index;
+ break;
+ }
+ }
+ }
+ else
+ {
+ ++index;
+ }
+ TPoint pos( field->Position() );
+ MoveFields( index, pos );
+ if ( focused && !field->IsNonFocusing() )
+ {
+ TRAP_IGNORE( DoSetFocusL( index ) )
+ }
+ UpdateFocusPosition();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::IsControlVisible
+// ---------------------------------------------------------------------------
+//
+TBool CMRListPane::IsControlVisible( TESMREntryFieldId aField )
+ {
+ TBool visible( EFalse );
+ CESMRField* field = iFactory.FieldById( aField );
+
+ if ( field )
+ {
+ visible = field->IsVisible();
+ }
+
+ return visible;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::SetControlFocusedL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::SetControlFocusedL( TESMREntryFieldId aField )
+ {
+ TInt count = iFactory.Count();
+ for ( TInt i(0); i < count; i++ )
+ {
+ CESMRField* field = iFactory.Field(i);
+
+ if ( field->FieldId() == aField )
+ {
+ if( field->IsVisible() && !field->IsNonFocusing() )
+ {
+ // Remove current focus before setting new one
+ CESMRField* focusedField = FocusedItem();
+ ASSERT( focusedField );
+ focusedField->SetOutlineFocusL( EFalse );
+
+ // Set new focus
+ field->SetOutlineFocusL( ETrue );
+ iFocus = i;
+ break;
+ }
+ else
+ {
+ // Not possible to set focus to non-visible control
+ User::Leave( KErrGeneral );
+ }
+ }
+ }
+ }
+
+// SCROLLING_MOD: These two methods are for CESMRRichTextViewer to
+// be able to control view area
+// ---------------------------------------------------------------------------
+// CMRListPane::MoveListAreaDownL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::MoveListAreaDownL( TInt aAmount )
+ {
+ FUNC_LOG;
+ // Method for CESMRRichTextViewer for moving view area down if the text in
+ // text field does not fit on the screen.
+
+ // Fetch the position info about the first visible field in field set:
+ CESMRField* field;
+ if( iTopVisibleIndex != KErrNotFound )
+ {
+ field = iFactory.Field( iTopVisibleIndex );
+ }
+ else
+ {
+ field = iFactory.Field( iFactory.Count() - 1 );
+ }
+ TRect rect( field->Rect() );
+
+ // check whether the first field is visible, if not, let's
+ // check should we scroll less than needed to get the first
+ // field shown.
+ if ( rect.iTl.iY + aAmount > Rect().iTl.iY )
+ {
+ aAmount = Rect().iTl.iY - rect.iTl.iY + KVerticalScrollMargin;
+ }
+ else if ( rect.iTl.iY == Rect().iTl.iY )
+ {
+ // field already visible, do not scroll.
+ aAmount = 0;
+ }
+
+ // Do the view scrolling if needed:
+ if ( aAmount )
+ {
+ ScrollItemsDown( aAmount );
+ UpdateFocusPosition();
+ //UpdateScrollBar();
+ DrawDeferred();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::MoveListAreaUpL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::MoveListAreaUpL( TInt aAmount )
+ {
+ FUNC_LOG;
+ // Fetch the position information about currently focused field:
+ CESMRField* field = iFactory.Field( iFocus );
+ TRect rect( field->Rect() );
+
+ // check whether the scroll pixels should be less than normal
+ // scroll sequence to let the field bottom to be placed at
+ // the bottom of view rect.
+ if ( rect.iBr.iY - aAmount < Rect().iBr.iY )
+ {
+ aAmount = rect.iBr.iY - Rect().iBr.iY + KVerticalScrollMargin;
+ }
+ else if ( rect.iBr.iY + aAmount == Rect().iBr.iY )
+ {
+ // field already visible, do not scroll.
+ aAmount = 0;
+ }
+
+ // do the scrolling if needed:
+ if ( aAmount > 0 )
+ {
+ // if the focus is on last
+ ScrollItemsUp( aAmount );
+ UpdateFocusPosition();
+ //UpdateScrollBar();
+ DrawDeferred();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ListHeight
+// ---------------------------------------------------------------------------
+//
+TInt CMRListPane::ListHeight()
+ {
+ FUNC_LOG;
+ return iSize.iHeight;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::IsFieldBottomVisible
+// ---------------------------------------------------------------------------
+//
+TBool CMRListPane::IsFieldBottomVisible()
+ {
+ // Fetch the position information about currently focused field:
+ CESMRField* field = iFactory.Field( iFocus );
+ TBool ret( EFalse );
+ if ( field->Rect().iBr.iY <= Rect().iBr.iY )
+ {
+ ret = ETrue;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::MoveFocusUpL
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CMRListPane::MoveFocusUpL()
+ {
+ TInt ind( iFocus );
+
+ // search next visible focus item
+ while ( ind > 0 )
+ {
+ CESMRField* field = iFactory.Field( --ind );
+
+ if ( !field->IsNonFocusing() )
+ {
+ field = iFactory.Field( ind );
+
+ CESMRField* focusedField = iFactory.Field( iFocus );
+ if ( field->IsVisible() )
+ {
+ TBool canLoseFocus(
+ focusedField->OkToLoseFocusL( field->FieldId() ) );
+
+ if ( canLoseFocus )
+ {
+ iFocus = ind;
+
+ // update focus index and scroll the item visible
+ focusedField->SetOutlineFocusL( EFalse );
+ // This call changes the text color of previously
+ // focused field
+ focusedField->SetFocus( EFalse );
+ field->SetOutlineFocusL( ETrue );
+ // This call changes the text color of focused field
+ field->SetFocus( ETrue );
+
+ ScrollItemVisible( iFocus );
+ }
+ return EKeyWasConsumed;
+ }
+ }
+ }
+ return EKeyWasNotConsumed;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::MoveFocusDownL
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CMRListPane::MoveFocusDownL()
+ {
+ TInt ind( iFocus );
+
+ // start searching next possible focus item
+ TInt maxItemIndex = iFactory.Count() - 1;
+
+ while ( ind < maxItemIndex )
+ {
+ // only visible and focusable items can be focused
+ CESMRField* field = iFactory.Field( ++ind );
+
+ if ( field->IsVisible() && !field->IsNonFocusing() )
+ {
+ CESMRField* focusedField = iFactory.Field( iFocus );
+
+ TBool canLoseFocus(
+ focusedField->OkToLoseFocusL( field->FieldId() ) );
+
+ // check it its ok for the old focus item to lose focus
+ if ( canLoseFocus )
+ {
+ iFocus = ind;
+
+ // update focus index and scroll the item visible
+ focusedField->SetOutlineFocusL( EFalse );
+ // This call changes the text color of previously
+ // focused field
+ focusedField->SetFocus( EFalse );
+ field->SetOutlineFocusL( ETrue );
+ // This call changes the text color of focused field
+ field->SetFocus( ETrue );
+
+ ScrollItemVisible( iFocus );
+ }
+ return EKeyWasConsumed;
+ }
+ }
+ return EKeyWasNotConsumed;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::MoveFocusL
+// ---------------------------------------------------------------------------
+//
+TBool CMRListPane::MoveFocusL(TInt aNextFieldIndex)
+ {
+ // start searching next possible focus item
+ TInt maxItemIndex = iFactory.Count() - 1;
+
+ CESMRField* focusedField = iFactory.Field( iFocus );
+
+ // only visible and focusable items can be focused
+ CESMRField* field = iFactory.Field( aNextFieldIndex );
+
+ if ( field->IsVisible() && !field->IsNonFocusing() )
+ {
+ TBool canLoseFocus(
+ focusedField->OkToLoseFocusL( field->FieldId() ) );
+
+ // check it its ok for the old focus item to lose focus
+ if ( canLoseFocus )
+ {
+ // tactile feedback if touch
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+ if ( feedback )
+ {
+ feedback->InstantFeedback( this, ETouchFeedbackBasic );
+ }
+ }
+
+ iFocus = aNextFieldIndex;
+
+ // update focus index and scroll the item visible
+ focusedField->SetOutlineFocusL( EFalse );
+ // This call changes the text color of previously
+ // focused field
+ focusedField->SetFocus( EFalse );
+ field->SetOutlineFocusL( ETrue );
+ // This call changes the text color of focused field
+ field->SetFocus( ETrue );
+ DrawDeferred();
+ }
+ return ETrue; // operation succeed
+ }
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::LayoutField
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::LayoutField( CESMRField& aField,
+ const TPoint& aTl )
+ {
+ TSize size( aField.MinimumSize() );
+ if ( aField.IsExpandable() )
+ {
+ size.iHeight = aField.ExpandedHeight();
+ }
+ aField.SetPosition( aTl );
+ aField.SetSize( size );
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::MoveFields
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::MoveFields( TInt aIndex,
+ TPoint& aTl )
+ {
+ 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;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::DoSetFocusL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::DoSetFocusL( TInt aFocus )
+ {
+ TInt count( iFactory.Count() );
+ aFocus = Max( 0, Min( aFocus, count - 1 ) );
+
+ if ( aFocus != iFocus )
+ {
+ // Get current focused field
+ CESMRField* old = iFactory.Field( iFocus );
+
+ // Get next focused field
+ CESMRField* field = iFactory.Field( aFocus );
+ while ( aFocus < count && !field->IsVisible() )
+ {
+ field = iFactory.Field( aFocus++ );
+ }
+
+ if ( !field->IsVisible() )
+ {
+ aFocus = iFocus - 1;
+ while ( aFocus > 0 && !field->IsVisible() )
+ {
+ field = iFactory.Field( aFocus-- );
+ }
+ }
+
+ ASSERT( field->IsVisible() );
+
+ // Remove focus from old
+ iFocus = aFocus;
+ // update focus index and scroll the item visible
+ old->SetOutlineFocusL( EFalse );
+ // Change the text color of previously focused field
+ old->SetFocus( EFalse );
+ field->SetOutlineFocusL( ETrue );
+ // This call changes the text color of focused field
+ field->SetFocus( ETrue );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ScrollItemVisible
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ScrollItemVisible( TInt aInd )
+ {
+ FUNC_LOG;
+ CESMRField* field = NULL;
+ if ( aInd == KErrNotFound )
+ {
+ field = FocusedItem();
+ }
+ else
+ {
+ field = iFactory.Field( aInd );
+ }
+
+ ASSERT( field );
+
+ TRect rect( field->Rect() );
+
+ // move all items upwards
+ TInt bottomRightY = Rect().iBr.iY;
+
+
+ TInt fieldUpper(0);
+ TInt fieldLower(0);
+ field->GetMinimumVisibleVerticalArea( fieldUpper, fieldLower );
+
+ // desired position below view rect:
+ if ( rect.iTl.iY + fieldLower > Rect().iBr.iY )
+ {
+ // field rect Y position related to view rect:
+ TInt fieldRelYPos = rect.iTl.iY - Size().iHeight;
+ TInt px = fieldRelYPos + fieldLower;
+
+ // if focus on first or last field: add margin height to
+ // scroll amount.
+ if ( iFocus == 0 || iFocus == iFactory.Count()-1 )
+ {
+ px += 2 * KVerticalScrollMargin;
+ }
+
+ ScrollItemsUp( px );
+ }
+
+ // move all items downwards.
+ TInt topLeftY = Rect().iTl.iY;
+
+ if ( rect.iBr.iY - (rect.Height() - fieldUpper ) < topLeftY )
+ {
+ TInt fieldRelYPos = topLeftY - rect.iBr.iY;
+ TInt px = fieldRelYPos + ( rect.Height() - fieldUpper);
+
+ // if focus on first or last field: add margin height to
+ // scroll amount.
+ if ( iFocus == 0 || iFocus == iFactory.Count()-1 )
+ {
+ px += KVerticalScrollMargin;
+ }
+
+ ScrollItemsDown( px );
+ }
+
+ UpdateFocusPosition();//UpdateScrollBar();
+ DrawDeferred();
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdateScrollBar
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::UpdateScrollBar()
+ {
+ FUNC_LOG;
+ // Scroll span is the size of the scrolled list,
+ // including the items that doesn't fit in the screen
+ TInt spanSize( 0 );
+ TInt hidden( 0 );
+ const TInt count(iFactory.Count());
+ for ( TInt i(0); i < count; i++ )
+ {
+ CESMRField* field = iFactory.Field( i );
+ if ( field->IsVisible() )
+ {
+ TRect rect( field->Rect() );
+ spanSize += rect.Height();
+ // Check if the field's top Y-position is hidden.
+ if ( rect.iTl.iY < 0 )
+ {
+ // whole field is hidden
+ if ( rect.iBr.iY < 0 )
+ {
+ hidden += rect.Height();
+ }
+ // partly hidden:
+ else
+ {
+ hidden += Abs( rect.iTl.iY );
+ }
+ }
+ }
+ }
+
+ iScrollModel.SetScrollSpan( spanSize );
+ iScrollModel.SetWindowSize( iSize.iHeight );
+ iScrollModel.SetFocusPosition( hidden );
+
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ScrollItemsUp
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ScrollItemsUp( TInt aPx )
+ {
+ FUNC_LOG;
+ TInt count( iFactory.Count() );
+ for ( TInt i = 0; i < count; ++i )
+ {
+ CESMRField* field = iFactory.Field(i);
+ if ( field->IsVisible() )
+ {
+ TPoint pos( field->Position() );
+ pos.iY -= aPx;
+ if ( i == iTopVisibleIndex && pos.iY < 0 )
+ {
+ iTopVisibleIndex = KErrNotFound;
+ }
+ else if ( iTopVisibleIndex == KErrNotFound && pos.iY >= 0 )
+ {
+ iTopVisibleIndex = i;
+ }
+ field->SetPosition( pos );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ScrollItemsDown
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ScrollItemsDown( TInt aPx )
+ {
+ FUNC_LOG;
+ TInt count( iFactory.Count() );
+ for ( TInt i = 0; i < count; ++i )
+ {
+ CESMRField* field = iFactory.Field( i );
+ if ( field->IsVisible() )
+ {
+ TPoint pos( field->Position() );
+ pos.iY += aPx;
+ if ( pos.iY >= 0 && ( i < iTopVisibleIndex || iTopVisibleIndex == KErrNotFound ) )
+ {
+ iTopVisibleIndex = i;
+ }
+ field->SetPosition( pos );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ScrollView
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ScrollView( TInt aAmount )
+ {
+ FUNC_LOG;
+
+ if ( aAmount > 0 )
+ {
+ // move list up
+ ScrollItemsUp( aAmount );
+ UpdateFocusPosition();
+ DrawDeferred();
+ }
+ else if ( aAmount < 0 )
+ {
+ // move list down
+ ScrollItemsDown( -aAmount );
+ UpdateFocusPosition();
+ DrawDeferred();
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdateFocusPosition
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::UpdateFocusPosition()
+ {
+ TInt focusPos = 0;
+ TInt count = iFactory.Count();
+ for ( TInt i = 0; i < count; ++i )
+ {
+ CESMRField* field = iFactory.Field( i );
+ if ( field->IsVisible() )
+ {
+ TRect rect( field->Rect() );
+ // Check if the field's top is above scroll area origo.
+ if ( rect.iTl.iY < 0 )
+ {
+ // Whole field is above origo
+ if ( rect.iBr.iY < 0 )
+ {
+ focusPos += rect.Height();
+ }
+ // Part of the field is above origo
+ else
+ {
+ focusPos += Abs( rect.iTl.iY );
+ }
+ }
+ else
+ {
+ // Rest of the fields are below scroll area origo
+ break;
+ }
+ }
+ }
+
+ iScrollModel.SetFocusPosition( focusPos );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMRListPane::GetViewCenterPosition
+// -----------------------------------------------------------------------------
+//
+TPoint CMRListPane::GetViewCenterPosition() const
+ {
+ const TInt count( iFactory.Count() );
+ TInt topFieldYPos( 0 );
+ for ( TInt i = 0; i < count; i++ )
+ {
+ CESMRField* field = iFactory.Field( i );
+
+ if ( field->IsVisible() )
+ {
+ topFieldYPos = field->Position().iY;
+ break;
+ }
+ }
+ TInt centerX = iSize.iWidth / 2;
+ TInt visibleHeight = iSize.iHeight;
+
+ TInt centerY = visibleHeight / 2 - topFieldYPos;
+
+
+ return TPoint( centerX, centerY );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CMRListPane::HandlePointerEventL
+// -----------------------------------------------------------------------------
+//
+void CMRListPane::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+ {
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
+ {
+ TInt count = iFactory.Count();
+ for ( TInt i = 0; i < count; ++i )
+ {
+ CESMRField* field = static_cast<CESMRField*>(iFactory.Field( i ) );
+ TRect r = field->Rect();
+ TBool tapped = field->Rect().Contains( aPointerEvent.iPosition );
+ if (tapped && field->IsVisible() && !field->IsFocused() )
+ {
+ MoveFocusL( i );
+ break;
+ }
+ }
+ }
+ // here some fields can further adjust their state (for example, CESMRResponseField has sub-fields)
+ CCoeControl::HandlePointerEventL(aPointerEvent);
+ }
+// End of file
+