--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingappbase/msgeditor/viewsrc/MsgFormComponent.cpp Wed Nov 03 09:52:46 2010 +0530
@@ -0,0 +1,620 @@
+/*
+* Copyright (c) 2002-2006 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: MsgFormComponent implementation
+*
+*/
+
+
+
+// ========== INCLUDE FILES ================================
+#include <AknUtils.h> // for AknUtils
+#include <AknDef.h>
+
+#include "MsgFormComponent.h" // for CMsgFormComponent
+#include "MsgControlArray.h" // for CMsgControlArray
+#include "MsgBaseControl.h" // for CMsgBaseControl
+#include "MsgEditorPanic.h" // for CMsgEditor panics
+#include "MsgEditorCommon.h"
+
+// ========== EXTERNAL DATA STRUCTURES =====================
+
+// ========== EXTERNAL FUNCTION PROTOTYPES =================
+
+// ========== CONSTANTS ====================================
+
+// ========== MACROS =======================================
+
+// ========== LOCAL CONSTANTS AND MACROS ===================
+
+const TInt KComponentArrayGranularity = 5;
+const TInt ENoFocus = -1;
+
+// ========== MODULE DATA STRUCTURES =======================
+
+// ========== LOCAL FUNCTION PROTOTYPES ====================
+
+// ========== LOCAL FUNCTIONS ==============================
+
+// ========== MEMBER FUNCTIONS =============================
+
+// ---------------------------------------------------------
+// CMsgFormComponent::CMsgFormComponent
+//
+// Constructor.
+// ---------------------------------------------------------
+//
+CMsgFormComponent::CMsgFormComponent( const TMargins& aMargins ) :
+ iCurrentFocus( ENoFocus ),
+ iMargins( aMargins )
+ {
+ SetComponentsToInheritVisibility( ETrue );
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::~CMsgFormComponent
+//
+// Destructor.
+// ---------------------------------------------------------
+//
+CMsgFormComponent::~CMsgFormComponent()
+ {
+ delete iControls;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::BaseConstructL
+//
+//
+// ---------------------------------------------------------
+//
+void CMsgFormComponent::BaseConstructL( const CCoeControl& aParent )
+ {
+ SetContainerWindowL( aParent );
+ iControls = new ( ELeave ) CMsgControlArray( KComponentArrayGranularity );
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::Component
+//
+// Return a pointer to a control by given control id aControlId. If the
+// control cannot be found returns NULL.
+// ---------------------------------------------------------
+//
+CMsgBaseControl* CMsgFormComponent::Component( TInt aControlId ) const
+ {
+ TInt index = ComponentIndexFromId( aControlId );
+
+ if ( index == KErrNotFound )
+ {
+ return NULL;
+ }
+
+ return (*iControls)[index];
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::ComponentIndexFromId
+//
+// Returns control's array index by given control id aControlId.
+// ---------------------------------------------------------
+//
+TInt CMsgFormComponent::ComponentIndexFromId( TInt aControlId ) const
+ {
+ return iControls->ComponentIndexFromId( aControlId );
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::ControlFromPosition
+// ---------------------------------------------------------
+//
+#ifdef RD_SCALABLE_UI_V2
+CMsgBaseControl* CMsgFormComponent::ControlFromPosition( TPoint aPosition, TBool aEvaluateHitTest ) const
+ {
+ TInt componentCount = iControls->Count();
+
+ for ( TInt index = 0; index < componentCount; index++ )
+ {
+ CMsgBaseControl* current = (*iControls)[index];
+ if ( current->Rect().Contains( aPosition ) &&
+ ( !aEvaluateHitTest ||
+ ( !current->HitTest() ||
+ current->HitTest()->HitRegionContains( aPosition, *current ) ) ) )
+ {
+ return current;
+ }
+ }
+ return NULL;
+ }
+#else
+CMsgBaseControl* CMsgFormComponent::ControlFromPosition( TPoint /*aPosition*/, TBool /*aEvaluateHitTest*/ ) const
+ {
+ return NULL;
+ }
+#endif // RD_SCALABLE_UI_V2
+
+
+// ---------------------------------------------------------
+// CMsgFormComponent::AddControlL
+//
+// Adds a control aControl to the control array to position aIndex and sets
+// control id for the control.
+// ---------------------------------------------------------
+//
+void CMsgFormComponent::AddControlL(
+ CMsgBaseControl* aControl,
+ TInt aControlId,
+ TInt aIndex /* = 0*/ )
+ {
+ aControl->SetControlId( aControlId );
+ DoAddControlL( aControl, aIndex );
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::RemoveControlL
+//
+// Removes a control from array by given control id aControlId and returns
+// pointer to it. If the control cannot be found retuns NULL.
+// ---------------------------------------------------------
+//
+CMsgBaseControl* CMsgFormComponent::RemoveControlL( TInt aControlId )
+ {
+ CMsgBaseControl* control = NULL;
+ TInt index = ComponentIndexFromId( aControlId );
+
+ if ( index != KErrNotFound )
+ {
+ control = (*iControls)[index];
+ control->SetFocus( EFalse );
+ iControls->Delete( index );
+
+ if ( index <= iCurrentFocus )
+ {
+ iCurrentFocus--;
+ }
+
+ if ( iControls->Count() == 0 )
+ {
+ iCurrentFocus = ENoFocus;
+ }
+ else if ( iCurrentFocus < 0 )
+ {
+ iCurrentFocus = 0;
+ }
+ }
+
+ return control;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::Margins
+//
+// Returns margins.
+// ---------------------------------------------------------
+//
+TMargins CMsgFormComponent::Margins() const
+ {
+ return iMargins;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::CurrentLineRect
+//
+// Returns the current control rect.
+// ---------------------------------------------------------
+//
+TRect CMsgFormComponent::CurrentLineRect()
+ {
+ __ASSERT_DEBUG( ( iCurrentFocus < iControls->Count() ) &&
+ ( iCurrentFocus != ENoFocus ), Panic( EMsgFocusLost ) );
+
+ return (*iControls)[iCurrentFocus]->CurrentLineRect();
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::ChangeFocusTo
+//
+// Changes focus to a control whose index is aNewFocus. Returns EFalse if focus
+// cannot be changed.
+// ---------------------------------------------------------
+//
+TBool CMsgFormComponent::ChangeFocusTo( TInt aNewFocus, TDrawNow aDrawNow /*= EDrawNow*/ )
+ {
+ __ASSERT_DEBUG( ( aNewFocus < iControls->Count() ) &&
+ ( aNewFocus >= 0 ), Panic( EMsgFocusLost ) );
+
+ if ( (*iControls)[aNewFocus]->IsNonFocusing() )
+ {
+ return EFalse;
+ }
+
+ if ( aNewFocus != iCurrentFocus )
+ {
+ // Take focus off from the currently focused component
+ SetFocus( EFalse, aDrawNow );
+ iCurrentFocus = aNewFocus;
+ }
+
+ SetFocus( ETrue, aDrawNow );
+
+ return ETrue;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::FocusedControl
+//
+// Returns a pointer to the focused control. If focus not set returns NULL.
+// ---------------------------------------------------------
+//
+CMsgBaseControl* CMsgFormComponent::FocusedControl() const
+ {
+ TInt numberOfControls = iControls->Count();
+
+ if ( ( iCurrentFocus != ENoFocus ) && ( iCurrentFocus < numberOfControls ) )
+ {
+ return (*iControls)[iCurrentFocus];
+ }
+ return NULL;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::FirstFocusableControl
+//
+// Finds the first focusable control and returns index of the found control
+// or KErrNotFound if the focusable control cannot be found.
+// ---------------------------------------------------------
+//
+TInt CMsgFormComponent::FirstFocusableControl( TInt aStart, TMsgFocusDirection aDirection )
+ {
+ TInt components = iControls->Count();
+ TInt newFocus = aStart;
+
+ while ( ( newFocus < components ) && ( newFocus >= 0 ) )
+ {
+ if ( (*iControls)[newFocus]->IsNonFocusing() )
+ {
+ newFocus += aDirection;
+ }
+ else
+ {
+ return newFocus;
+ }
+ }
+
+ return KErrNotFound;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::NotifyControlsForEvent
+//
+// Notifies all the controls about a view event.
+// ---------------------------------------------------------
+//
+void CMsgFormComponent::NotifyControlsForEvent( TMsgViewEvent aEvent, TInt aParam )
+ {
+ TInt componentCount = iControls->Count();
+
+ for ( TInt i = 0; i < componentCount; i++ )
+ {
+ (*iControls)[i]->NotifyViewEvent( aEvent, aParam );
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::CurrentFocus
+//
+// Returns index of currently focused control.
+// ---------------------------------------------------------
+//
+TInt CMsgFormComponent::CurrentFocus() const
+ {
+ return iCurrentFocus;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::ResetControls
+//
+// Reset all controls in this component.
+// ---------------------------------------------------------
+//
+void CMsgFormComponent::ResetControls()
+ {
+ TInt componentCount = iControls->Count();
+
+ for (TInt i = 0; i < componentCount; i++)
+ {
+ (*iControls)[i]->Reset();
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::VirtualHeight
+//
+// Return virtual height of controls.
+// ---------------------------------------------------------
+//
+TInt CMsgFormComponent::VirtualHeight()
+ {
+ TInt numberOfControls = iControls->Count();
+ TInt totalHeight = 0;
+ CMsgBaseControl* ctrl;
+
+ for ( TInt i = 0; i < numberOfControls; i++ )
+ {
+ ctrl = (*iControls)[i];
+ totalHeight += ctrl->VirtualHeight();
+ totalHeight += ctrl->DistanceFromComponentAbove();
+ }
+
+ return totalHeight + iMargins.iTop + iMargins.iBottom;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::VirtualExtension
+//
+// Returns total of pixels above each control' band. This function is
+// needed for the scroll bar for estimating message form's position
+// relative to screen.
+// ---------------------------------------------------------
+//
+TInt CMsgFormComponent::VirtualExtension()
+ {
+ TInt numberOfControls = iControls->Count();
+ TInt pos = 0;
+
+ if ( iCurrentFocus < numberOfControls &&
+ iCurrentFocus != ENoFocus )
+ {
+ TInt offset = MsgEditorCommons::MsgBaseLineOffset();
+
+ CMsgBaseControl* ctrl;
+ for ( TInt i = 0; i <= iCurrentFocus; i++ )
+ {
+ ctrl = (*iControls)[i];
+
+ if ( ctrl->Position().iY > offset )
+ {
+ break;
+ }
+
+ pos += ctrl->DistanceFromComponentAbove();
+
+ if ( ctrl->IsFocused() )
+ {
+ pos += ctrl->VirtualVisibleTop();
+
+ TInt visiblePixels( ctrl->Position().iY + ctrl->Size().iHeight );
+ visiblePixels -= offset;
+
+ if ( ctrl->Position().iY < 0 &&
+ visiblePixels > 0 )
+ {
+ pos += ( ctrl->Size().iHeight - visiblePixels );
+ }
+ }
+ else
+ {
+ pos += ctrl->VirtualHeight();
+
+ TInt visiblePixels( 0 );
+
+ if ( ctrl->Position().iY < 0 )
+ {
+ visiblePixels = ctrl->Position().iY + ctrl->Size().iHeight - offset;
+ }
+ else
+ {
+ visiblePixels = ctrl->Size().iHeight;
+ }
+
+ // If control is partially visible on the screen remove
+ // these pixels.
+ if ( visiblePixels > 0 )
+ {
+ pos -= visiblePixels;
+ }
+ }
+ }
+ }
+ return pos;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::OfferKeyEventL
+//
+// Handles key event by passing the event to a focused control.
+// ---------------------------------------------------------
+//
+TKeyResponse CMsgFormComponent::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
+ {
+ __ASSERT_DEBUG( (iCurrentFocus < iControls->Count() ) &&
+ ( iCurrentFocus != ENoFocus ), Panic( EMsgFocusLost ) );
+
+ return static_cast<CCoeControl*>( (*iControls)[iCurrentFocus] )
+ ->OfferKeyEventL( aKeyEvent, aType );
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::CountComponentControls
+//
+// Returns a number of controls.
+// ---------------------------------------------------------
+//
+TInt CMsgFormComponent::CountComponentControls() const
+ {
+ return iControls->Count();
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::ComponentControl
+//
+// Returns a control of index aIndex.
+// ---------------------------------------------------------
+//
+CCoeControl* CMsgFormComponent::ComponentControl( TInt aIndex ) const
+ {
+ if ( aIndex < iControls->Count() )
+ {
+ return ( (*iControls)[aIndex] );
+ }
+
+ __ASSERT_DEBUG(EFalse, Panic(EMsgIncorrectComponentIndex));
+
+ return NULL;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::SizeChanged
+//
+// Sets new position for all the controls.
+//
+// SetExtent function must be used for setting positions because when this
+// is called the first time, positions are not set yet. Hence, SetPosition
+// cannot be used because it assumes that positions are already set.
+// ---------------------------------------------------------
+//
+void CMsgFormComponent::SizeChanged()
+ {
+ TPoint componentPosition(
+ Position().iX + iMargins.iLeft,
+ Position().iY + iMargins.iTop );
+ CMsgBaseControl* component;
+ TInt components( iControls->Count() );
+ TSize componentSize;
+
+ for ( TInt cc = 0; cc < components; cc++ )
+ {
+ component = (*iControls)[cc];
+ componentPosition.iY += component->DistanceFromComponentAbove();
+ componentSize = component->Size();
+ // SetPosition cannot be used here
+ component->SetExtent( componentPosition, componentSize );
+ componentSize = component->Size();
+ componentPosition.iY += componentSize.iHeight;
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::HandleResourceChange
+// Handles a resource relative event
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CMsgFormComponent::HandleResourceChange( TInt aType )
+ {
+ CEikBorderedControl::HandleResourceChange( aType );
+ if( aType == KEikDynamicLayoutVariantSwitch )
+ {
+ SizeChanged();
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::FocusChanged
+//
+// Sets focus off or on if this form component lost focus or gets focused.
+// ---------------------------------------------------------
+//
+void CMsgFormComponent::FocusChanged( TDrawNow aDrawNow )
+ {
+ if ( iControls->Count() > 0 )
+ {
+ CMsgBaseControl* control = (*iControls)[iCurrentFocus];
+
+ if ( !( control->IsNonFocusing() ) )
+ {
+ control->SetFocus( IsFocused(), aDrawNow );
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::DoAddControlL
+//
+// Adds control aControl to the component array to position aIndex. If aIndex =
+// the number components in the array or EMsgAppendControl, appends the control
+// to end of the array. Panics is aIndex is incorrect.
+// ---------------------------------------------------------
+//
+TInt CMsgFormComponent::DoAddControlL( CMsgBaseControl* aControl, TInt aIndex )
+ {
+ TInt controlId = aControl->ControlId();
+ TInt componentCount = iControls->Count();
+
+ __ASSERT_DEBUG( controlId != 0,
+ Panic( EMsgControlIdNotSet ) );
+ __ASSERT_DEBUG( iControls->ComponentIndexFromId( controlId ) == KErrNotFound,
+ Panic( EMsgControlIdNotUnique ) );
+ __ASSERT_DEBUG( ( aIndex >= EMsgAppendControl ) && ( aIndex <= componentCount ),
+ Panic( EMsgIncorrectComponentIndex ) );
+
+ TInt index = ( aIndex == EMsgAppendControl )
+ ? componentCount
+ : aIndex;
+
+ if ( componentCount == 0 )
+ {
+ iCurrentFocus = 0;
+ }
+ else if ( index <= iCurrentFocus )
+ {
+ iCurrentFocus++;
+ }
+
+ if ( index == componentCount )
+ {
+ iControls->AppendL( aControl );
+ }
+ else if ( ( index >= EMsgFirstControl ) && ( index < componentCount ) )
+ {
+ iControls->InsertL( index, aControl );
+ }
+ else
+ {
+ __ASSERT_DEBUG( EFalse, Panic( EMsgIncorrectComponentIndex ) );
+ }
+
+ return controlId;
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::CountMsgControls
+//
+// Returns the number of components.
+// ---------------------------------------------------------
+//
+TInt CMsgFormComponent::CountMsgControls( ) const
+ {
+ return iControls->Count();
+ }
+
+// ---------------------------------------------------------
+// CMsgFormComponent::MsgControl
+//
+// Return a pointer to a control by given control id aControlId. If the
+// control cannot be found returns NULL.
+// ---------------------------------------------------------
+//
+CMsgBaseControl* CMsgFormComponent::MsgControl( TInt aIndex ) const
+ {
+
+ if( aIndex >= iControls->Count( ) || aIndex < 0 )
+ {
+ return NULL;
+ }
+
+ return (*iControls)[aIndex];
+ }
+
+
+// End of File