--- a/meetingrequest/mrgui/src/cmrlistpane.cpp Mon Mar 15 12:39:10 2010 +0200
+++ b/meetingrequest/mrgui/src/cmrlistpane.cpp Wed Mar 31 21:08:33 2010 +0300
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2009-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 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"
@@ -15,61 +15,64 @@
*
*/
#include "cmrlistpane.h"
+#include "mesmrfieldstorage.h"
+#include "mmrscrollbarobserver.h"
+#include "esmrdef.h"
+#include "cesmrfield.h"
+#include "cmrfieldcontainer.h"
+#include "cmrlistpanephysics.h"
#include <eikscrlb.h>
-#include <AknUtils.h>
-#include <touchfeedback.h>
+#include <aknutils.h>
-#include "mesmrfieldstorage.h"
-#include "cesmrfield.h"
-
+//DEBUG
#include "emailtrace.h"
-namespace // codescanner::namespace
- {
- /**
- * Vertical scroll margin
- */
- const TInt KVerticalScrollMargin = 3;
+namespace { // codescanner::namespace
+
+const TInt KLongTapDelay( 700000 ); // 0,7 sec
+const TInt KLongTapAnimationDelay( 300000 ); // 0,3 sec
- // ---------------------------------------------------------------------------
- // IndexByFieldId
- // ---------------------------------------------------------------------------
- //
- TInt IndexByFieldId( const MESMRFieldStorage& aFactory,
- TESMREntryFieldId aFieldId )
+// ----------------
+// IndexByFieldId
+// ----------------
+//
+TInt IndexByFieldId( const MESMRFieldStorage& aFactory,
+ TESMREntryFieldId aFieldId )
+ {
+ TInt index( KErrNotFound );
+ TInt count( aFactory.Count() );
+
+ for ( TInt i = 0; i < count; ++i )
{
- TInt index( KErrNotFound );
- TInt count( aFactory.Count() );
-
- for ( TInt i = 0; i < count; ++i )
+ if ( aFactory.Field( i )->FieldId() == aFieldId )
{
- if ( aFactory.Field( i )->FieldId() == aFieldId )
- {
- index = i;
- break;
- }
+ index = i;
+ break;
}
-
- return index;
}
+
+ return index;
}
+}
+
//----- MEMBER FUNCTIONS ----
// ---------------------------------------------------------------------------
-// CMRListPane::NewL
+// CMRListPane::CMRListPane
// ---------------------------------------------------------------------------
//
-CMRListPane* CMRListPane::NewL( const CCoeControl& aParent,
- MESMRFieldStorage& aFactory,
- TAknDoubleSpanScrollBarModel& aScrollModel )
+CMRListPane::CMRListPane( MESMRFieldStorage& aFactory,
+ TAknDoubleSpanScrollBarModel& aScrollModel,
+ CAknDoubleSpanScrollBar& aScroll,
+ MMRScrollBarObserver& aScrollBarObserver )
+ : iFactory( aFactory ),
+ iScrollModel( aScrollModel ),
+ iScroll( aScroll ),
+ iScrollBarObserver( aScrollBarObserver )
{
- CMRListPane* self = new (ELeave) CMRListPane( aFactory, aScrollModel );
- CleanupStack::PushL( self );
- self->ConstructL( aParent );
- CleanupStack::Pop( self );
- return self;
+ FUNC_LOG;
}
// ---------------------------------------------------------------------------
@@ -78,17 +81,32 @@
//
CMRListPane::~CMRListPane()
{
+ FUNC_LOG;
+ delete iLongtapDetector;
+ delete iPhysics;
+ delete iFieldContainer;
}
// ---------------------------------------------------------------------------
-// CMRListPane::CMRListPane
+// CMRListPane::NewL
// ---------------------------------------------------------------------------
//
-CMRListPane::CMRListPane( MESMRFieldStorage& aFactory,
- TAknDoubleSpanScrollBarModel& aScrollModel )
- : iFactory( aFactory ),
- iScrollModel( aScrollModel )
+CMRListPane* CMRListPane::NewL( const CCoeControl& aParent,
+ MESMRFieldStorage& aFactory,
+ TAknDoubleSpanScrollBarModel& aScrollModel,
+ CAknDoubleSpanScrollBar& aScroll,
+ MMRScrollBarObserver& aScrollBarObserver )
{
+ FUNC_LOG;
+ CMRListPane* self = new( ELeave )CMRListPane(
+ aFactory,
+ aScrollModel,
+ aScroll,
+ aScrollBarObserver );
+ CleanupStack::PushL( self );
+ self->ConstructL( aParent );
+ CleanupStack::Pop( self );
+ return self;
}
// ---------------------------------------------------------------------------
@@ -97,64 +115,173 @@
//
void CMRListPane::ConstructL( const CCoeControl& aParent )
{
+ FUNC_LOG;
+ CCoeControl::SetComponentsToInheritVisibility( ETrue );
SetContainerWindowL( aParent );
- TBool focusSet = EFalse;
+
+ iLongtapDetector = CAknLongTapDetector::NewL( this );
+ iLongtapDetector->SetLongTapDelay( KLongTapDelay );
+ iLongtapDetector->SetTimeDelayBeforeAnimation( KLongTapAnimationDelay );
+
+ iFieldContainer = CMRFieldContainer::NewL( iFactory, *this );
+ iFieldContainer->SetFieldContainerObserver( this );
+
+ // Physics: Create physics
+ // Give pointer to control that should be able to flick/drag
+ iPhysics = CMRListPanePhysics::NewL( *this, *iFieldContainer, *this );
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::InitializeL()
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::InitializeL()
+ {
+ FUNC_LOG;
const TInt count( iFactory.Count() );
for ( TInt i = 0; i < count; i++ )
{
- iFactory.Field(i)->SetContainerWindowL( *this );
+ iFactory.Field(i)->InitializeL();
}
+ iClickedField = NULL;
+ }
+
- for ( TInt i = 0; i < count; i++ )
- {
- CESMRField* field = iFactory.Field( i );
-
- // Initialize field
- field->InitializeL();
- User::LeaveIfError( field->SetParent( this ) );
+// ---------------------------------------------------------------------------
+// CMRListPane::InternalizeL()
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::InternalizeL( MESMRCalEntry& aEntry )
+ {
+ FUNC_LOG;
+ iFactory.InternalizeL( aEntry );
+
+ // This is called to make sure everything is drawn correctly
+ DrawDeferred();
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ExternalizeL()
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ExternalizeL(
+ MESMRCalEntry& aEntry,
+ TBool aForceValidation )
+ {
+ FUNC_LOG;
+ CESMRField* currentFocus = FocusedField();
+ ASSERT( currentFocus );
+ TESMREntryFieldId id = currentFocus->FieldId();
- if ( !focusSet
- && field->IsVisible()
- && !field->IsNonFocusing())
+ if ( aForceValidation )
+ {
+ // force validate the values:
+ TInt err = iFactory.Validate( id, aForceValidation );
+ // fill the calendar entry with data in fields.
+ iFactory.ExternalizeL( aEntry );
+ }
+ else
+ {
+ TInt err = iFactory.Validate( id );
+ if ( err )
+ {
+ //SetControlFocusedL( id ); Why would we set this focused here?
+ User::Leave( err );
+ }
+ else
{
- field->SetOutlineFocusL( ETrue );
- focusSet = ETrue;
- iFocus = i;
+ // fill the calendar entry with data in fields.
+ iFactory.ExternalizeL( aEntry );
}
- }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::DisableSizeChange()
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::DisableSizeChange(TBool aDisable )
+ {
+ FUNC_LOG;
+ iDisableSizeChanged = aDisable;
}
// ---------------------------------------------------------------------------
+// CMRListPane::InitialScroll
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::InitialScrollL()
+ {
+ FUNC_LOG;
+ // TODO: Fix or remove! L-Function called in non-leaving function!
+ // Suggestion: Move functionality to viewerdialog and use existing
+ // functions in listpane to do the required actions.
+
+ // Check if the ResponseArea exist
+ TESMREntryFieldId id = GetResponseFieldsFieldId();
+
+ if( id == EESMRFieldResponseArea )
+ {
+ // Set the focus on the ResponseArea
+ iFieldContainer->SetControlFocusedL( id );
+ //iFactory.FieldById(id)->SetFocus( ETrue );
+
+ // Scroll the list to put the ResponseArea on the top
+ CESMRField* focusField = FocusedField();
+ TPoint pos( focusField->Position() );
+ ScrollFieldsUp(pos.iY);
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
// CMRListPane::FocusedItem
// ---------------------------------------------------------------------------
//
-CESMRField* CMRListPane::FocusedItem() const
+CESMRField* CMRListPane::FocusedField() const
+ {
+ FUNC_LOG;
+ return iFieldContainer->FocusedField();
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::SetControlFocusedL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::SetControlFocusedL( TESMREntryFieldId aFieldId )
{
FUNC_LOG;
- CESMRField* field = NULL;
- if ( iFactory.Count() > 0 )
- {
- field = iFactory.Field( iFocus );
- }
- return field;
+ iFieldContainer->SetControlFocusedL( aFieldId );
}
-
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ClickedItem
+// ---------------------------------------------------------------------------
+//
+CESMRField* CMRListPane::ClickedField() const
+ {
+ return iClickedField;
+ }
+
// ---------------------------------------------------------------------------
// CMRListPane::CountComponentControls
// ---------------------------------------------------------------------------
//
TInt CMRListPane::CountComponentControls() const
{
- return iFactory.Count();
+ FUNC_LOG;
+ return 1; // iFieldContainer
+
}
// ---------------------------------------------------------------------------
// CMRListPane::ComponentControl
// ---------------------------------------------------------------------------
//
-CCoeControl* CMRListPane::ComponentControl( TInt aIndex ) const
+CCoeControl* CMRListPane::ComponentControl( TInt /*aIndex*/ ) const
{
- return iFactory.Field( aIndex );
+ FUNC_LOG;
+ return iFieldContainer;
}
// ---------------------------------------------------------------------------
@@ -163,35 +290,19 @@
//
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++ )
+ FUNC_LOG;
+ if ( iDisableSizeChanged || Rect() == TRect( 0, 0, 0, 0 ) )
{
- 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;
- }
+ return;
}
+
+ TSize containerSize( iFieldContainer->MinimumSize() );
+ iFieldContainer->SetSize( containerSize );
- iScrollModel.SetScrollSpan( scrollSpan );
- iScrollModel.SetWindowSize( iSize.iHeight );
- UpdateFocusPosition();
+ // Physics:
+ iPhysics->InitPhysics();
+
+ DoUpdateScrollBar();
}
// ---------------------------------------------------------------------------
@@ -201,737 +312,111 @@
TKeyResponse CMRListPane::OfferKeyEventL( const TKeyEvent &aKeyEvent,
TEventCode aType )
{
+ FUNC_LOG;
TKeyResponse response( EKeyWasNotConsumed );
+
+ // First check if the focused item needs the key event
+ response = FocusedField()->OfferKeyEventL( aKeyEvent, aType );
- // If we have at least one item in the list
- if ( iFocus < iFactory.Count() )
+ if ( aType == EEventKey
+ && response == EKeyWasNotConsumed )
{
- 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 )
{
- // Check if the focus should be changed
- switch ( aKeyEvent.iScanCode )
+ case EStdKeyUpArrow:
{
- case EStdKeyUpArrow:
- {
- response = MoveFocusUpL();
- break;
- }
- case EStdKeyDownArrow:
- {
- response = MoveFocusDownL();
- break;
- }
- default:
- {
- break;
- }
+ response = iFieldContainer->MoveFocusUpL( HiddenFocus() );
+
+ // Focus changed via keyboard, iClickedItem is no
+ // longer valid
+ iClickedField = NULL;
+ break;
+ }
+ case EStdKeyDownArrow:
+ {
+ response = iFieldContainer->MoveFocusDownL( HiddenFocus() );
+
+ // Focus changed via keyboard, iClickedItem is no
+ // longer valid
+ iClickedField = NULL;
+ 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
+// CMRListPane::HandleLongTapEventL
// ---------------------------------------------------------------------------
//
-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()
+void CMRListPane::HandleLongTapEventL(
+ const TPoint& aPenEventLocation,
+ const TPoint& /* aPenEventScreenLocation */ )
{
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() ) );
+ iLongTapEventConsumed = EFalse;
+ // Long tap functionality may vary between fields
+ // ==> Command field to execute action related to long tap
+ TInt count( iFactory.Count() );
- // 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 )
+ for ( TInt i = 0; i < count; ++i )
{
CESMRField* field = iFactory.Field( i );
- if ( field->IsVisible() )
+ if ( field->IsVisible()
+ && field->Rect().Contains( aPenEventLocation ) )
{
- field->SetPosition( aTl );
-
- aTl.iY += field->Size().iHeight;
+ field->LongtapDetectedL( aPenEventLocation );
+ iLongTapEventConsumed = ETrue;
+ break;
}
}
}
// ---------------------------------------------------------------------------
-// CMRListPane::DoSetFocusL
+// CMRListPane::DoUpdateScrollBar
// ---------------------------------------------------------------------------
//
-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 )
+void CMRListPane::DoUpdateScrollBar( TInt aFocusPosition )
{
FUNC_LOG;
- CESMRField* field = NULL;
- if ( aInd == KErrNotFound )
+ // Set this lispane's size as scroll bar's window size
+ iScrollModel.SetWindowSize( iSize.iHeight );
+ // Set fieldcontainer's height as scrolbar's scroll span
+ iScrollModel.SetScrollSpan( iFieldContainer->MinimumSize().iHeight );
+
+ // Update scrollbar focus position.
+ if( aFocusPosition == KErrNotFound )
{
- field = FocusedItem();
+ iScrollModel.SetFocusPosition( iPhysics->VerticalScrollIndex() );
}
else
{
- field = iFactory.Field( aInd );
+ iScrollModel.SetFocusPosition( aFocusPosition );
}
- 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;
+ iScroll.SetModel( &iScrollModel );
- // 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();
+ // finally update the new thumb position to view's
+ // iScrollBarThumbPosition member.
+ iScrollBarObserver.ScrollBarPositionChanged(
+ iScroll.ThumbPosition() );
}
// ---------------------------------------------------------------------------
-// CMRListPane::UpdateScrollBar
+// CMRListPane::UpdatedFocusPosition
// ---------------------------------------------------------------------------
//
-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 )
+TInt CMRListPane::UpdatedFocusPosition()
{
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 )
@@ -961,62 +446,300 @@
}
}
}
+
+ return focusPos;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ScrollFieldsUp
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ScrollFieldsUp( TInt aPx )
+ {
+ FUNC_LOG;
+ TPoint point = iFieldContainer->Position();
+ point.iY -= aPx;
- iScrollModel.SetFocusPosition( focusPos );
+ // This initializes Draw also
+ iFieldContainer->SetPosition( point );
+
+ // Non-kinetic scrolling executed. Update
+ // new position to physics.
+ iPhysics->UpdateVerticalScrollIndex( UpdatedFocusPosition() );
+
+ DoUpdateScrollBar( UpdatedFocusPosition() );
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ScrollFieldsDown
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ScrollFieldsDown( TInt aPx )
+ {
+ FUNC_LOG;
+ TPoint point = iFieldContainer->Position();
+ point.iY += aPx;
+
+ // This initializes Draw also
+ iFieldContainer->SetPosition( point );
+ // Non-kinetic scrolling executed. Update
+ // new position to physics.
+ iPhysics->UpdateVerticalScrollIndex( UpdatedFocusPosition() );
+
+ DoUpdateScrollBar( UpdatedFocusPosition() );
}
-// -----------------------------------------------------------------------------
-// CMRListPane::GetViewCenterPosition
-// -----------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdateScrollBarAndPhysics
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::UpdateScrollBarAndPhysics()
+ {
+ // Update physics world size
+ iPhysics->InitPhysics();
+
+ // Update scrollbar
+ DoUpdateScrollBar();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ShowControl
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ShowControl( TESMREntryFieldId aFieldId )
+ {
+ iFieldContainer->ShowControl( aFieldId );
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ShowControl
+// ---------------------------------------------------------------------------
//
-TPoint CMRListPane::GetViewCenterPosition() const
+TBool CMRListPane::IsControlVisible( TESMREntryFieldId aFieldId )
+ {
+ return iFieldContainer->IsControlVisible( aFieldId );
+ }
+// ---------------------------------------------------------------------------
+// CMRListPane::GetResponseFieldsFieldId
+// ---------------------------------------------------------------------------
+//
+TESMREntryFieldId CMRListPane::GetResponseFieldsFieldId()
{
- const TInt count( iFactory.Count() );
- TInt topFieldYPos( 0 );
- for ( TInt i = 0; i < count; i++ )
+ // TODO: Should be removed. This shouldn't be even a public function!
+ CESMRField* rfield = iFactory.FieldById( EESMRFieldResponseArea );
+
+ if ( rfield && rfield->IsVisible() && !rfield->IsNonFocusing() )
+ {
+ return EESMRFieldResponseArea;
+ }
+ else
+ {
+ return iFactory.Field(0)->FieldId();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::ReActivateL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ReActivateL()
+ {
+ FUNC_LOG;
+ TInt count = iFactory.Count();
+
+ for ( TInt i = 0; i < count; ++i )
{
CESMRField* field = iFactory.Field( i );
- if ( field->IsVisible() )
+ if ( !field->IsFieldActivated() )
{
- topFieldYPos = field->Position().iY;
- break;
+ field->SetContainerWindowL( *iFieldContainer );
+ field->SetListObserver( iFieldContainer );
+ }
+ }
+
+ // This "for" circle can not be mixed with the above one, since the
+ // field->ActivateL() will call some functions which will traverse
+ // all the fields, but that time, not all the fields have set the
+ // container window.
+ for ( TInt i = 0; i < count; ++i )
+ {
+ CESMRField* field = iFactory.Field( i );
+ if ( !field->IsFieldActivated() )
+ {
+ field->ActivateL();
}
}
- TInt centerX = iSize.iWidth / 2;
- TInt visibleHeight = iSize.iHeight;
+ }
- TInt centerY = visibleHeight / 2 - topFieldYPos;
+// ---------------------------------------------------------------------------
+// CMRListPane::HandlePointerEventL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::HandlePointerEventL( const TPointerEvent &aPointerEvent )
+ {
+ // Check if touch is enabled or not
+ if( !AknLayoutUtils::PenEnabled() )
+ {
+ return;
+ }
+
+ // Forward all listpane related events to physics api first.
+ if ( iPhysics->HandlePointerEventL( aPointerEvent, iPhysicsActionOngoing ) )
+ {
+ DoUpdateScrollBar();
+ // Physics in action. If long tap detection is active,
+ // it should be cancelled.
+ if( iLongtapDetector->IsActive() )
+ {
+ iLongtapDetector->Cancel();
+ }
+ }
-
- return TPoint( centerX, centerY );
+ if( !iPhysicsActionOngoing )
+ {
+ // Offer pointer event to long tap detector
+ iLongtapDetector->PointerEventL( aPointerEvent );
+
+ SetFocusAfterPointerEventL( aPointerEvent );
+
+ // If longtap event has been handled, then do not handle signal event anymore.
+ if( !iLongTapEventConsumed )
+ {
+ CCoeControl::HandlePointerEventL( aPointerEvent );
+ }
+ else
+ {
+ iLongTapEventConsumed = EFalse;
+ }
+
+ UpdateClickedField( aPointerEvent );
+ }
}
+// ---------------------------------------------------------------------------
+// CMRListPane::ActivateL
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::ActivateL()
+ {
+ FUNC_LOG;
+ // This ActiveteL is required only for setting the initial position
+ // of the field container. After setting the position, physics is
+ // initialized with new values also.
+
+ CCoeControl::ActivateL();
+ iFieldContainer->SetPosition( Position() );
+
+ // Physics:
+ iPhysics->InitPhysics();
+ }
-// -----------------------------------------------------------------------------
-// CMRListPane::HandlePointerEventL
-// -----------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+// CMRListPane::PhysicsEmulationEnded
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::PhysicsEmulationEnded()
+ {
+ FUNC_LOG;
+ DoUpdateScrollBar();
+ iPhysicsActionOngoing = EFalse;
+ Parent()->DrawDeferred();
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::SetFocusAfterPointerEventL
+// ---------------------------------------------------------------------------
//
-void CMRListPane::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+void CMRListPane::SetFocusAfterPointerEventL(
+ const TPointerEvent &aPointerEvent )
{
- if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
+ FUNC_LOG;
+
+ if( aPointerEvent.iType == TPointerEvent::EButton1Down )
+ {
+ TInt count( iFactory.Count() );
+ for( TInt i = 0; i < count; ++i )
+ {
+ CESMRField* field = iFactory.Field( i );
+ if ( field->IsVisible() &&
+ field->Rect().Contains( aPointerEvent.iPosition ) )
+ {
+ CESMRField* focusedField = iFieldContainer->FocusedField();
+
+ if ( field != focusedField )
+ {
+ TBool canLoseFocus(
+ focusedField->OkToLoseFocusL( field->FieldId() ) );
+
+ if ( canLoseFocus )
+ {
+ iFieldContainer->SetControlFocusedL( field->FieldId() );
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRListPane::UpdateClickedField
+// ---------------------------------------------------------------------------
+//
+void CMRListPane::UpdateClickedField( const TPointerEvent &aPointerEvent )
+ {
+ FUNC_LOG;
+ TInt fieldCount( iFactory.Count() );
+
+ for( TInt i = 0; i < fieldCount; ++i )
{
- TInt count = iFactory.Count();
- for ( TInt i = 0; i < count; ++i )
+ if( iFactory.Field( i )->Rect().Contains(
+ aPointerEvent.iPosition ) )
{
- 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() )
+ if( aPointerEvent.iType == TPointerEvent::EButton1Down )
{
- MoveFocusL( i );
- break;
+ iClickedField = iFactory.Field( i );
}
}
}
- // here some fields can further adjust their state (for example, CESMRResponseField has sub-fields)
- CCoeControl::HandlePointerEventL(aPointerEvent);
}
+
+// ---------------------------------------------------------------------------
+// CMRListPane::HiddenFocus
+// ---------------------------------------------------------------------------
+//
+TBool CMRListPane::HiddenFocus()
+ {
+ FUNC_LOG;
+ TBool hiddenFocus( EFalse );
+
+ CESMRField* focusedField( iFieldContainer->FocusedField() );
+ TInt focusedFieldIndex( IndexByFieldId(
+ iFactory, focusedField->FieldId() ) );
+
+ if ( focusedFieldIndex < iFactory.Count() )
+ {
+ TRect focusedFieldRect( focusedField->Rect() );
+ TRect listPaneRect( Rect() );
+
+ TInt fieldTopY( focusedFieldRect.iTl.iY );
+ TInt fieldBottomY( focusedFieldRect.iBr.iY );
+
+ TInt listTopY( listPaneRect.iTl.iY );
+ TInt listBottomY( listPaneRect.iBr.iY );
+
+ if ( ( fieldBottomY > listBottomY ||
+ fieldTopY < listTopY ) &&
+ focusedFieldRect.Height() < listPaneRect.Height() )
+ {
+ hiddenFocus = ETrue;
+ }
+ }
+ return hiddenFocus;
+ }
+
// End of file
-