--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/AknIndicatorContainer.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,4109 @@
+/*
+* Copyright (c) 2002-2010 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: Implementation for default status indicator control.
+*
+*/
+
+
+// INCLUDE FILES
+#include <AknsDrawUtils.h>
+#include <AknPictographInterface.h>
+#include <AknPictographDrawerInterface.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include <AknSmallIndicator.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uikon/eikenvinterface.h>
+#endif
+
+#include <AknTasHook.h>
+#include <touchfeedback.h>
+
+
+#include "AknIndicatorObserver.h"
+#include "aknindicatordataobserver.h"
+#include "AknSgcc.h"
+#include "AknIncallStatusBubble.h"
+#include "AknUtils.h"
+#include "aknconsts.h"
+#include "AknIndicator.h"
+#include "AknIndicatorContainer.h"
+#include "aknenv.h"
+#include "AknStatuspaneUtils.h"
+#include "AknIndicatorFader.h"
+#include "aknappui.h"
+#include "AknDef.h"
+#include "layoutmetadata.cdl.h"
+
+// CONSTANTS
+const TInt KAknIndicatorQueueGranularity = 4;
+const TInt KAknIndicatorAnimationInterval = 500000; // micro seconds
+const TInt KAknIndicatorAnimationShortDelay = 400000; // micro seconds
+
+// Indicator pane control flags.
+enum TIndicatorPaneControlFlags
+ {
+ EAknIndicatorsButton1DownInIndicatorPaneRect = 0x00000001
+ };
+
+// ================= PRIVATE CLASS =======================
+
+NONSHARABLE_CLASS( CAknIndicatorContainerExtension ) :
+ public CBase,
+ public MAknPictographAnimatorCallBack,
+ public MCoeMessageMonitorObserver
+ {
+public:
+ /**
+ * Constructor.
+ */
+ static CAknIndicatorContainerExtension* NewL(
+ CAknIndicatorContainer* aIndicatorContainer );
+
+ /**
+ * Destructor.
+ */
+ ~CAknIndicatorContainerExtension();
+
+ TBool SmallStatusPaneLayout();
+ void SetSmallStatusPaneLayout( TBool aIsActive );
+
+ // From base class @c MCoeMessageMonitorObserver.
+
+ /**
+ * Used to receive event from window server
+ * when the visibility of the window changes.
+ *
+ * @param aEvent The window server event.
+ */
+ void MonitorWsMessage( const TWsEvent &aEvent );
+
+private:
+
+ CAknIndicatorContainerExtension(
+ CAknIndicatorContainer* aIndicatorContainer );
+
+ void ConstructL();
+
+ // From MAknPictographAnimatorCallBack
+ void DrawPictographArea();
+
+public:
+
+ CAknIndicatorContainer* iIndicatorContainer;
+ CAknPictographInterface* iPictoInterface;
+ TBool iSmallStatusPaneLayout;
+ TBool iSwitchLayoutInProgress;
+ TBool iIncallBubbleAllowedInIdle;
+ TBool iIncallBubbleAllowedInUsual;
+ TPoint iPositionRelativeToScreen;
+ CAknIndicatorDataObserver* iDataObserver;
+ TInt iFlags;
+ TBool iIncallBubbleDisabled;
+ TBool iIsForeground;
+ TBool iIsActiveIdle;
+ };
+
+
+CAknIndicatorContainerExtension* CAknIndicatorContainerExtension::NewL(
+ CAknIndicatorContainer* aIndicatorContainer )
+ {
+ CAknIndicatorContainerExtension* self = new( ELeave )
+ CAknIndicatorContainerExtension( aIndicatorContainer );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+void CAknIndicatorContainerExtension::ConstructL()
+ {
+ iPictoInterface = CAknPictographInterface::NewL( *iIndicatorContainer, *this );
+ if ( iIndicatorContainer->IndicatorContext() ==
+ CAknIndicatorContainer::EUniversalIndicators )
+ {
+ iDataObserver =
+ new (ELeave) CAknIndicatorDataObserver( iIndicatorContainer );
+ }
+
+ TRAP_IGNORE( CCoeEnv::Static()->AddMessageMonitorObserverL( *this ) );
+ }
+
+
+CAknIndicatorContainerExtension::CAknIndicatorContainerExtension(
+ CAknIndicatorContainer* aIndicatorContainer )
+ : iIndicatorContainer( aIndicatorContainer )
+ {
+ iSmallStatusPaneLayout = AknStatuspaneUtils::SmallLayoutActive();
+ iIncallBubbleAllowedInUsual = ETrue;
+ iIsForeground = static_cast<CAknAppUi*>( CEikonEnv::Static()->EikAppUi() )->IsForeground();
+ iIsActiveIdle = AknStatuspaneUtils::IsActiveIdle();
+ }
+
+
+CAknIndicatorContainerExtension::~CAknIndicatorContainerExtension()
+ {
+ delete iPictoInterface;
+ delete iDataObserver;
+
+ CCoeEnv::Static()->RemoveMessageMonitorObserver( *this );
+ }
+
+
+void CAknIndicatorContainerExtension::DrawPictographArea()
+ {
+ iIndicatorContainer->DrawPictographArea();
+ }
+
+
+TBool CAknIndicatorContainerExtension::SmallStatusPaneLayout()
+ {
+ return iSmallStatusPaneLayout;
+ }
+
+
+void CAknIndicatorContainerExtension::SetSmallStatusPaneLayout(
+ TBool aIsActive )
+ {
+ iSmallStatusPaneLayout = aIsActive;
+ }
+
+void CAknIndicatorContainerExtension::MonitorWsMessage( const TWsEvent& aEvent )
+ {
+ switch ( aEvent.Type() )
+ {
+ case KAknFullOrPartialForegroundGained:
+ iIndicatorContainer->ResetAnimTicker( ETrue );
+ break;
+
+ case KAknFullOrPartialForegroundLost:
+ iIndicatorContainer->ResetAnimTicker( EFalse );
+ break;
+
+ default:
+ break;
+ }
+ }
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::CAknIndicatorContainer
+// Default constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAknIndicatorContainer::CAknIndicatorContainer() :
+ iLayoutOrientation( EVertical ),
+ iPreviousLayoutOrientation( EVertical ),
+ iAlignment( ERight ),
+ iIndicatorContext( EUniversalIndicators ),
+ iSynchronizingValue( 0 )
+ {
+ AKNTASHOOK_ADD( this, "CAknIndicatorContainer" );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::CAknIndicatorContainer
+// Constructor with context type parameter.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAknIndicatorContainer::CAknIndicatorContainer(
+ TBool aIndicatorContext )
+ : iLayoutOrientation( EVertical ),
+ iPreviousLayoutOrientation( EVertical ),
+ iAlignment( ERight ),
+ iIndicatorContext( aIndicatorContext ),
+ iSynchronizingValue( 0 )
+ {
+ AKNTASHOOK_ADD( this, "CAknIndicatorContainer" );
+ }
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::~CAknIndicatorContainer
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAknIndicatorContainer::~CAknIndicatorContainer()
+ {
+ AKNTASHOOK_REMOVE();
+ AknsUtils::DeregisterControlPosition( this );
+
+ if ( iIndicators )
+ {
+ TInt count = iIndicators->Count();
+ for ( TInt ii = 0; ii < count; ii++)
+ {
+ delete iIndicators->At( ii );
+ }
+ delete iIndicators;
+ }
+
+ if ( iTicker )
+ {
+ iTicker->Cancel();
+ delete iTicker;
+ }
+
+ delete iIncallBubble;
+ delete iExtension;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::ConstructL
+// Second-phase constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknIndicatorContainer::ConstructL()
+ {
+ iExtension = CAknIndicatorContainerExtension::NewL( this );
+
+ if ( !iIndicators )
+ {
+ iIndicators =
+ new (ELeave) CAknIndicatorQueue( KAknIndicatorQueueGranularity );
+ }
+
+
+ iTicker = CPeriodic::NewL( CActive::EPriorityLow );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::ConstructFromResourceL
+// Resource constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknIndicatorContainer::ConstructFromResourceL(
+ TResourceReader& aReader )
+ {
+ ConstructL();
+
+ if ( iIndicatorContext != EUniversalIndicators &&
+ iIndicatorContext != ENaviPaneEditorIndicators &&
+ iIndicatorContext != EQueryEditorIndicators )
+ {
+ TInt count = aReader.ReadInt16();
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ CAknIndicator* indicator =
+ new (ELeave) CAknIndicator ( iIndicatorContext );
+ CleanupStack::PushL( indicator );
+ indicator->SetContainerWindowL( *this );
+ indicator->ConstructFromResourceL( aReader, this );
+ iIndicators->AppendL( indicator );
+ CleanupStack::Pop( indicator );
+ indicator = NULL;
+ }
+
+ PrioritizeIndicatorsL();
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::IndicatorContext
+// Returns the indicator context of this container.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknIndicatorContainer::IndicatorContext() const
+ {
+ return iIndicatorContext;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SetIndicatorState
+// Sets the state of an indicator in this container.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknIndicatorContainer::SetIndicatorState( TUid aIndicatorId,
+ TInt aState,
+ TBool aDrawNow )
+ {
+ if ( !IndicatorExists( aIndicatorId ) )
+ {
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ TRAP_IGNORE( CreateIndicatorFromPaneResourceL(
+ aIndicatorId, R_AVKON_STATUS_PANE_INDICATOR_DEFAULT, 0 ) );
+ }
+ else if ( iIndicatorContext == ENaviPaneEditorIndicators ||
+ iIndicatorContext == EQueryEditorIndicators )
+ {
+ TRAP_IGNORE( CreateIndicatorFromPaneResourceL(
+ aIndicatorId, R_AVKON_NAVI_PANE_EDITOR_INDICATORS, 0 ) );
+ }
+ }
+
+ TBool changed = EFalse;
+ TInt count = iIndicators->Count();
+
+ CAknIndicator* indicator = NULL;
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ indicator = iIndicators->At( ii );
+
+ if ( indicator->Uid() == aIndicatorId )
+ {
+ if ( indicator->IndicatorState() != aState )
+ {
+ changed = ETrue;
+ }
+
+ indicator->SetIndicatorState( aState );
+ if ( aState == MAknIndicator::EIndicatorAnimate )
+ {
+ // Synchronizes new animated indicator with previous ones
+ indicator->SetAnimateState( iSynchronizingValue );
+ }
+
+ // In case of GPRS indicator in small status pane it is necessary
+ // to check whether a correct status pane layout is used.
+ if ( aIndicatorId == TUid::Uid( EAknNaviPaneEditorIndicatorGprs ) )
+ {
+ TBool layoutUpdated( EFalse );
+ TRAPD( err, layoutUpdated = UpdateSmallLayoutL() );
+ if ( layoutUpdated && err == KErrNone )
+ {
+ // Needed because this method is not called again.
+ iExtension->iSwitchLayoutInProgress = EFalse;
+ }
+ }
+
+ break;
+ }
+ }
+
+ if ( changed )
+ {
+ TRAP_IGNORE( PrioritizeIndicatorsL() );
+ SizeChanged(); // starts/stops also animation timers if needed
+ }
+
+ // Do not draw in case the indicator state has not changed and
+ // the indicator is not visible, even if aDrawNow is defined,
+ // otherwise flicker will occur.
+ if ( aDrawNow && ( changed || aState ) )
+ {
+ DrawNow();
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::IndicatorState
+// Returns current state of a status indicator in this container.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknIndicatorContainer::IndicatorState( TUid aIndicatorId )
+ {
+ TInt indicatorState( MAknIndicator::EIndicatorOff );
+
+ TInt count = iIndicators->Count();
+ CAknIndicator* indicator = NULL;
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ indicator = iIndicators->At( ii );
+
+ if ( indicator->Uid() == aIndicatorId )
+ {
+ indicatorState = indicator->IndicatorState();
+ break;
+ }
+ }
+
+ return indicatorState;
+ }
+
+
+EXPORT_C void CAknIndicatorContainer::SetIndicatorValueL( TUid aIndicatorId,
+ const TDesC& aString )
+ {
+ if ( ( iIndicatorContext == ENaviPaneEditorIndicators ||
+ iIndicatorContext == EQueryEditorIndicators ) &&
+ !IndicatorExists( aIndicatorId ) )
+ {
+ CreateIndicatorFromPaneResourceL( aIndicatorId, R_AVKON_NAVI_PANE_EDITOR_INDICATORS, 0);
+ }
+
+ TInt count = iIndicators->Count();
+ for(TInt ii = 0; ii < count; ii++)
+ {
+ CAknIndicator* indicator = iIndicators->At(ii);
+ if ( indicator->Uid() == aIndicatorId )
+ {
+ TInt indicatorWidthBefore = indicator->IconSize().iWidth;
+ indicator->SetIndicatorValueL(aString);
+ TInt indicatorWidthAfter = indicator->IconSize().iWidth;
+
+ // Draw the message length indicator if it is visible.
+ if ( indicator->IndicatorState() != EAknIndicatorStateOff )
+ {
+ if ( indicatorWidthBefore != indicatorWidthAfter )
+ {
+ // If indicator width was changed, reposition all indicators.
+ PrioritizeIndicatorsL();
+ SizeChanged();
+ }
+ DrawNow();
+ }
+ break;
+ }
+ }
+ }
+
+void CAknIndicatorContainer::DrawPictographArea()
+ {
+ TInt count = iIndicators->Count();
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( i );
+ // Draw the indicator if it is visible and contains pictographs.
+ if ( indicator->TextIndicator() &&
+ indicator->IndicatorState() != EAknIndicatorStateOff &&
+ indicator->IsVisible() &&
+ iExtension->iPictoInterface->Interface()->ContainsPictographs(
+ *( indicator->iIndicatorText ) ) )
+ {
+ indicator->DrawDeferred();
+ }
+ }
+ }
+
+
+CAknPictographInterface* CAknIndicatorContainer::PictographInterface() const
+ {
+ return iExtension->iPictoInterface;
+ }
+
+
+EXPORT_C void CAknIndicatorContainer::SetIncallBubbleFlags( const TInt& aFlags )
+ {
+ if ( aFlags & CIncallStatusBubble::ESBVisible )
+ {
+ if ( !iIncallBubble )
+ {
+ TRAP_IGNORE( CreateIncallBubbleL() );
+ }
+
+ if ( iIncallBubble )
+ {
+ iIncallBubble->SetFlags( aFlags );
+ }
+ }
+ else
+ {
+ // RAM optimization, delete if not shown.
+ delete iIncallBubble;
+ iIncallBubble = NULL;
+ }
+ HandleStatusPaneSizeChange();
+ }
+
+
+EXPORT_C void CAknIndicatorContainer::HandleStatusPaneSizeChange()
+ {
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+ if ( statusPane && iIncallBubble )
+ {
+ // In CDMA, the Phone app is on foreground during incall lock state
+ // In GSM/WCDMA the Autolock application is on foreground
+
+ // Nowdays Autolock itself takes care of the visibility
+ const TBool showIncallIndicatorInLockState = EFalse;
+
+ TBool showIncallIndicatorInIdle =
+ iExtension->iIncallBubbleAllowedInIdle &&
+ !iExtension->iIncallBubbleDisabled;
+
+ TBool showIncallIndicatorInUsual =
+ iExtension->iIncallBubbleAllowedInUsual &&
+ !iExtension->iIncallBubbleDisabled;
+
+ TBool visible = EFalse;
+
+ TBool usualStatuspane = AknStatuspaneUtils::UsualLayoutActive();
+ TBool idleStatuspane = AknStatuspaneUtils::IdleLayoutActive();
+
+ // Call bubble is never displayed if video telephony is
+ // on the foreground.
+ TInt currentLayoutResId = statusPane->CurrentLayoutResId();
+ TBool vtStatuspane =
+ ( currentLayoutResId == R_AVKON_STATUS_PANE_LAYOUT_VT ||
+ currentLayoutResId == R_AVKON_STATUS_PANE_LAYOUT_VT_MIRRORED );
+
+ if ( statusPane->IsVisible() && iExtension->iIsForeground &&
+ ( ( usualStatuspane && showIncallIndicatorInUsual ) ||
+ ( idleStatuspane && showIncallIndicatorInIdle && !vtStatuspane ) ) )
+ {
+ // Incall bubble window is shown only in the usual layout when status
+ // pane is shown. Exception for this rule: The bubble is shown also
+ // when autolock application is in the front even if the idle
+ // layout is visible.
+ visible = ( iIncallBubble->Flags() & CIncallStatusBubble::ESBVisible );
+ }
+
+ IncallBubbleSizeChanged( showIncallIndicatorInLockState );
+ iIncallBubble->MakeVisible( visible );
+ }
+ }
+
+
+//-----------------------------------------------------------------------------
+// CAknIndicatorContainer::HandleResourceChange
+//-----------------------------------------------------------------------------
+//
+EXPORT_C void CAknIndicatorContainer::HandleResourceChange( TInt aType )
+ {
+ CCoeControl::HandleResourceChange( aType );
+
+ if ( aType == KEikMessageFadeAllWindows && iIncallBubble )
+ {
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+ iIncallBubble->SetFaded( statusPane->IsFaded() );
+ }
+
+ if ( aType == KEikColorResourceChange || aType == KAknsMessageSkinChange )
+ {
+ DrawDeferred();
+ }
+ else if ( aType == KEikDynamicLayoutVariantSwitch )
+ {
+ SizeChanged();
+ DrawDeferred();
+ }
+
+ if ( iIncallBubble )
+ {
+ iIncallBubble->HandleResourceChange( aType );
+ }
+ }
+
+
+//-----------------------------------------------------------------------------
+// CAknIndicatorContainer::SizeChanged
+//-----------------------------------------------------------------------------
+//
+EXPORT_C void CAknIndicatorContainer::SizeChanged()
+ {
+ // No fading if staconpane is active and in few other cases too...
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ SetContainerWindowNonFading(
+ AknStatuspaneUtils::ExtendedStaconPaneActive() ||
+ ( AknStatuspaneUtils::StaconPaneActive() &&
+ !AknStatuspaneUtils::IdleLayoutActive() ) );
+ }
+
+ AknsUtils::RegisterControlPosition( this );
+ if ( iExtension && DrawableWindow() )
+ {
+ iExtension->iPositionRelativeToScreen = PositionRelativeToScreen();
+ }
+
+ // Select right layout modes for indicators.
+ // This is now done always to ensure right layout mode.
+ SetupIndicatorLayoutModes();
+
+ // HandleStatusPaneSizeChange() is called here always to check
+ // incall bubble visibility because status pane size change is
+ // not only case when it changes.
+ HandleStatusPaneSizeChange();
+
+ // Check if layout is mirrored and the context
+ // of the indicators is mirrorable.
+ if ( AknLayoutUtils::LayoutMirrored() &&
+ ( iIndicatorContext == EUniversalIndicators ||
+ iIndicatorContext == ENaviPaneEditorIndicators ||
+ iIndicatorContext == EQueryEditorIndicators ) )
+ {
+ iAlignment = TIndicatorAlignment( ELeft );
+ }
+ else
+ {
+ iAlignment = TIndicatorAlignment( ERight );
+ }
+
+ TRect containerRect( Rect() );
+
+ if ( containerRect.IsEmpty() )
+ {
+ return;
+ }
+
+ // Set faders off by default (only used in stacon)
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ TInt count = iIndicators->Count();
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( ii );
+ if ( indicator )
+ {
+ indicator->SetIndicatorFader( NULL );
+ }
+ }
+ }
+
+ TBool idleLayout = AknStatuspaneUtils::IdleLayoutActive();
+ TBool smallLayout = EFalse;
+ TBool flatLayout = EFalse;
+ TBool extendedFlatLayout = EFalse;
+ TBool staconLayout = EFalse;
+ TBool extendedStaconLayout = EFalse;
+ TBool hdLayout = EFalse;
+ TBool extendedLayout = EFalse;
+
+ if ( AknStatuspaneUtils::SmallLayoutActive() )
+ {
+ smallLayout = ETrue;
+ }
+ else if ( AknStatuspaneUtils::FlatLayoutActive() )
+ {
+ flatLayout = ETrue;
+ extendedFlatLayout = !AknLayoutUtils::PenEnabled() &&
+ AknStatuspaneUtils::ExtendedFlatLayoutActive();
+ hdLayout = AknStatuspaneUtils::HDLayoutActive();
+ }
+ else if ( AknStatuspaneUtils::StaconPaneActive() )
+ {
+ staconLayout = ETrue;
+ extendedStaconLayout = AknStatuspaneUtils::ExtendedStaconPaneActive();
+ }
+ else
+ {
+ hdLayout = AknStatuspaneUtils::HDLayoutActive();
+ extendedLayout = AknStatuspaneUtils::ExtendedLayoutActive();
+ }
+
+ switch ( iIndicatorContext )
+ {
+ case ENaviPaneEditorIndicators:
+ {
+ if ( smallLayout )
+ {
+ SizeChangedInSmallStatusPane();
+ }
+ else if ( staconLayout &&
+ !idleLayout )
+ {
+ SizeChangedInStaconPane();
+ }
+ else if ( hdLayout )
+ {
+ SizeChangedInExtendedStatusPane();
+ }
+ else
+ {
+ SizeChangedInNormalStatusPane();
+ }
+ break;
+ }
+
+ case EUniversalIndicators:
+ {
+ if ( extendedLayout )
+ {
+ if ( idleLayout && !hdLayout )
+ {
+ SizeChangedInIdleExtendedStatusPane();
+ }
+ else
+ {
+ SizeChangedInExtendedStatusPane();
+ }
+ }
+ else if ( flatLayout )
+ {
+ if ( extendedFlatLayout )
+ {
+ // Extended flat status pane layout.
+ SizeChangedInExtendedStatusPane();
+ }
+ else
+ {
+ // Old flat status pane layout.
+ SizeChangedInFlatStatusPane();
+ }
+ }
+ else if ( staconLayout )
+ {
+ if ( extendedStaconLayout )
+ {
+ // Extended stacon layout.
+ SizeChangedInExtendedStatusPane();
+ }
+ else if ( !idleLayout )
+ {
+ // Old stacon layout.
+ SizeChangedInStaconPane();
+ }
+ else
+ {
+ SizeChangedInNormalStatusPane();
+ }
+ }
+ else if ( idleLayout &&
+ Layout_Meta_Data::IsLandscapeOrientation() &&
+ Size().iWidth < Size().iHeight )
+ {
+ // Universal indicator container in idle landscape
+ // using vertical indicators.
+ SizeChangedInIdleVertical();
+ }
+ else
+ {
+ // Normal status pane by default.
+ SizeChangedInNormalStatusPane();
+ }
+ break;
+ }
+
+ default:
+ {
+ if ( hdLayout )
+ {
+ SizeChangedInExtendedStatusPane();
+ }
+ else
+ {
+ // Normal status pane by default.
+ SizeChangedInNormalStatusPane();
+ }
+ break;
+ }
+ }
+ }
+
+EXPORT_C void CAknIndicatorContainer::PositionChanged()
+ {
+ AknsUtils::RegisterControlPosition( this );
+ }
+
+EXPORT_C TInt CAknIndicatorContainer::CountComponentControls() const
+ {
+ return (iIndicatorsShown);
+ }
+
+
+EXPORT_C CCoeControl* CAknIndicatorContainer::ComponentControl(TInt aIndex) const
+ {
+ TInt count = iIndicators->Count();
+
+ TInt ii = 0;
+ for (ii = 0; (ii < count) && (aIndex >= 0); ii++)
+ {
+ if ( iIndicators->At(ii)->IndicatorState() && (iIndicators->At(ii)->Priority() != KIndicatorNotShown))
+ {
+ aIndex--;
+ }
+ }
+
+ if ( ii > 0 )
+ {
+ return iIndicators->At(--ii);
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+
+EXPORT_C void CAknIndicatorContainer::Draw( const TRect& /*aRect*/ ) const
+ {
+ if ( iExtension->iIsActiveIdle )
+ {
+ return;
+ }
+
+ // Don't allow normal background drawing if
+ // background is already drawn with a background drawer.
+ const MCoeControlBackground* backgroundDrawer = FindBackground();
+ if ( backgroundDrawer )
+ {
+ return;
+ }
+
+ CWindowGc& gc = SystemGc();
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
+
+ TRect rect( Rect() );
+ gc.SetPenStyle( CGraphicsContext::ENullPen );
+ gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+
+ //
+ // S60 flat statuspane
+ //
+ if ( AknStatuspaneUtils::FlatLayoutActive() )
+ {
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ if( !AknsDrawUtils::Background( skin, cc, this, gc, rect ) )
+ {
+ gc.SetPenStyle( CGraphicsContext::ENullPen );
+ gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+ gc.SetBrushColor(
+ AKN_LAF_COLOR( KStatusPaneBackgroundGraphicsColorUsual ) );
+ gc.DrawRect( rect );
+ }
+
+ if( iIndicatorsShown &&
+ iExtension &&
+ AknStatuspaneUtils::IdleLayoutActive() &&
+ !AknStatuspaneUtils::ExtendedFlatLayoutActive() &&
+ !AknStatuspaneUtils::HDLayoutActive() )
+ {
+ TRect fadeRect( rect );
+ // Draw fade if there are indicators
+ if ( iLayoutOrientation == EVertical &&
+ Layout_Meta_Data::IsLandscapeOrientation() )
+ {
+ AknsDrawUtils::DrawCachedImage(
+ skin,
+ gc,
+ fadeRect,
+ KAknsIIDQgnGrafIdleFadeLsc );
+ }
+ else if ( iLayoutOrientation == EHorizontal )
+ {
+ AknsDrawUtils::DrawCachedImage(
+ skin,
+ gc,
+ fadeRect,
+ KAknsIIDQgnGrafIdleFade );
+ }
+ }
+ }
+ else if ( iIndicatorContext == ENaviPaneEditorIndicators )
+ {
+ if( !AknsDrawUtils::Background( skin, cc, this, gc, rect ) )
+ {
+ gc.SetPenStyle( CGraphicsContext::ENullPen );
+ gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+ gc.SetBrushColor(
+ AKN_LAF_COLOR( KStatusPaneBackgroundGraphicsColorUsual ) );
+ gc.DrawRect( rect );
+ }
+ }
+ else
+ {
+ gc.SetBrushColor( AKN_LAF_COLOR( 0 ) );
+ AknsDrawUtils::Background( skin, cc, this, gc, rect );
+ }
+
+ return;
+ }
+
+
+ //
+ // S60 staconpane
+ //
+ if (AknStatuspaneUtils::StaconPaneActive() &&
+ (iIndicatorContext == EUniversalIndicators || iIndicatorContext == ENaviPaneEditorIndicators))
+ {
+ if (iIndicatorContext == ENaviPaneEditorIndicators)
+ {
+ if( !AknsDrawUtils::Background( skin, cc, this, gc, rect ) )
+ {
+ gc.SetPenStyle(CGraphicsContext::ENullPen);
+ gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ gc.SetBrushColor(AKN_LAF_COLOR(KStatusPaneBackgroundGraphicsColorUsual) );
+ gc.DrawRect(rect);
+ }
+ }
+
+ else if ( iIndicatorContext == EUniversalIndicators )
+ {
+ if( !AknsDrawUtils::Background( skin, cc, this, gc, rect ) )
+ {
+ gc.SetPenStyle(CGraphicsContext::ENullPen);
+ gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ gc.SetBrushColor(AKN_LAF_COLOR(KStatusPaneBackgroundGraphicsColorUsual) );
+ gc.DrawRect(rect);
+ }
+
+
+ if( iIndicatorsShown &&
+ iExtension &&
+ AknStatuspaneUtils::IdleLayoutActive() &&
+ !AknStatuspaneUtils::ExtendedStaconPaneActive())
+ {
+ TRect fadeRect( rect );
+ if (iLayoutOrientation == EHorizontal)
+ {
+ // Always this fade
+ AknsDrawUtils::DrawCachedImage( skin, gc, fadeRect,
+ KAknsIIDQgnGrafIdleFade );
+ }
+ else
+ {
+ AknsDrawUtils::DrawCachedImage( skin, gc, fadeRect,
+ KAknsIIDQgnGrafIdleFadeLsc );
+
+ }
+ }
+ }
+ else
+ {
+ // Draw background for query editor indicators
+ gc.SetBrushColor(AKN_LAF_COLOR(0));
+ AknsDrawUtils::Background( skin, cc, this, gc, rect );
+ }
+ return;
+ }
+
+ //
+ // Extended S60 statuspane
+ //
+ if (AknStatuspaneUtils::ExtendedLayoutActive())
+ {
+ if( CAknEnv::Static()->TransparencyEnabled() )
+ {
+ AknsDrawUtils::Background( skin, cc, this, gc, rect, KAknsDrawParamNoClearUnderImage );
+ }
+ else
+ {
+ AknsDrawUtils::Background( skin, cc, this, gc, rect );
+ }
+ return;
+ }
+
+ //
+ // Default S60 statuspane
+ //
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ // Draw background for universal indicator pane
+ gc.SetBrushColor(AKN_LAF_COLOR(0)); // Universal indicator background color
+ AknsDrawUtils::Background( skin, cc, this, gc, rect );
+
+ if( (iLayoutOrientation == EHorizontal) && iIndicatorsShown && iExtension && !AknStatuspaneUtils::StaconPaneActive())
+ {
+ if (AknStatuspaneUtils::IdleLayoutActive())
+ {
+ TRect fadeRect( rect );
+ // Draw fade if there are indicators
+ AknsDrawUtils::DrawCachedImage( skin, gc, fadeRect,
+ KAknsIIDQgnGrafIdleFade );
+ }
+ }
+ }
+ if ( iIndicatorContext != EUniversalIndicators )
+ {
+ if ( iIndicatorContext == ENaviPaneEditorIndicators )
+ {
+ AknsDrawUtils::Background( skin, cc, this, gc, rect );
+ }
+ else
+ {
+ // Draw background for query editor indicators
+ gc.SetBrushColor(AKN_LAF_COLOR(0));
+ if( CAknEnv::Static()->TransparencyEnabled() )
+ {
+ AknsDrawUtils::Background( skin, cc, this, gc, rect, KAknsDrawParamNoClearUnderImage );
+ }
+ else
+ {
+ AknsDrawUtils::Background( skin, cc, this, gc, rect );
+ }
+ }
+ }
+ }
+
+EXPORT_C void CAknIndicatorContainer::HandlePointerEventL(
+ const TPointerEvent& aPointerEvent )
+ {
+ CAknControl::HandlePointerEventL( aPointerEvent );
+
+ if ( AknLayoutUtils::PenEnabled() && iExtension )
+ {
+ TRect rect( Rect() );
+
+ // The indicator popup is launched if both the down and up
+ // pointer events happen in the indicator pane area.
+ switch ( aPointerEvent.iType )
+ {
+ case TPointerEvent::EButton1Down:
+ {
+ // if indicator's rect contains pointer down position
+ if ( rect.Contains( aPointerEvent.iPosition ) )
+ {
+ // set flag that down was inside indicator
+ iExtension->iFlags |=
+ EAknIndicatorsButton1DownInIndicatorPaneRect;
+
+ if ( iIndicatorContext == EUniversalIndicators &&
+ iExtension->iFlags & EAknIndicatorsButton1DownInIndicatorPaneRect
+ )
+ {
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+
+ if ( feedback )
+ {
+ feedback->InstantFeedback( this, ETouchFeedbackSensitiveButton );
+ }
+ }
+ }
+ break;
+ }
+
+ case TPointerEvent::EButton1Up:
+ {
+ // Currently the small digital clock pane and universal
+ // indicator pane are regarded as one touch responsive area from
+ // which the universal indicator popup should open on tap,
+ // so upon pointer up event it must be checked here if
+ // the down event happened inside this control, but the up event
+ // inside digital clock pane area.
+ CEikStatusPaneBase* sp = CEikStatusPaneBase::Current();
+ TRect clockRect( 0, 0, 0, 0 );
+
+ if ( sp )
+ {
+ CCoeControl* clockPane = sp->ContainerControlL(
+ TUid::Uid( EEikStatusPaneUidDigitalClock ) );
+ if ( clockPane )
+ {
+ clockRect = TRect( clockPane->PositionRelativeToScreen(),
+ clockPane->Size() );
+ }
+ }
+
+ // if indicator's rect contains pointer up position
+ if ( iIndicatorContext == EUniversalIndicators &&
+ ( ( iExtension->iFlags & EAknIndicatorsButton1DownInIndicatorPaneRect &&
+ rect.Contains( aPointerEvent.iPosition ) ) ||
+ clockRect.Contains( aPointerEvent.iParentPosition ) ) )
+ {
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+ if ( feedback )
+ {
+ feedback->InstantFeedback( this,
+ ETouchFeedbackSensitiveButton,
+ ETouchFeedbackVibra,
+ aPointerEvent );
+ }
+ CAknSmallIndicator* indicatorNotifier = CAknSmallIndicator::NewLC( TUid::Uid( 0 ) );
+ indicatorNotifier->HandleIndicatorTapL();
+ CleanupStack::PopAndDestroy( indicatorNotifier );
+ }
+ // Up happened, reset button down flag
+ iExtension->iFlags &=
+ ( ~EAknIndicatorsButton1DownInIndicatorPaneRect );
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+ }
+
+EXPORT_C void* CAknIndicatorContainer::ExtensionInterface( TUid /*aInterface*/ )
+ {
+ return NULL;
+ }
+
+void CAknIndicatorContainer::Reserved_1()
+ {}
+
+
+void CAknIndicatorContainer::PrioritizeIndicatorsL()
+ {
+ iPreviousLayoutOrientation = iLayoutOrientation;
+
+ TInt count = iIndicators->Count();
+ if (count < 2)
+ {
+ return;
+ }
+
+ CAknIndicator* temp;
+ for(TInt ii = 1; ii < count; ii++)
+ {
+ temp = iIndicators->At(ii);
+ TInt tempPriority = temp->Priority();
+ if (tempPriority >= 0)
+ {
+ for(TInt jj = 0; jj <= ii; jj++)
+ {
+ if (tempPriority < iIndicators->At(jj)->Priority())
+ {
+ iIndicators->Delete( ii );
+ CleanupStack::PushL( temp );
+ iIndicators->InsertL( jj, temp );
+ CleanupStack::Pop( temp );
+ break;
+ }
+ else if ( jj == (ii-1) )
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+
+TInt CAknIndicatorContainer::TickerCallback(TAny* aThis)
+ {
+ return static_cast<CAknIndicatorContainer*>(aThis)->DoTick();
+ }
+
+TInt CAknIndicatorContainer::DoTick()
+ {
+ if (iAnimatedIndicatorsShown > 0)
+ {
+ TInt count = iIndicators->Count();
+
+ TInt ii = 0;
+ for (ii = 0; ii < count; ii++)
+ {
+ if ( iIndicators->At(ii)->IndicatorState() == MAknIndicator::EIndicatorAnimate && (iIndicators->At(ii)->Priority() != KIndicatorNotShown))
+ {
+ iIndicators->At(ii)->Animate();
+ }
+ }
+ iSynchronizingValue += 1;
+ if (iSynchronizingValue >= 185794560) // This number can be divided with 2,4,6,8,10,12,14,16 and 18
+ {
+ iSynchronizingValue = 0;
+ }
+
+ DrawDeferred(); // Must be DrawDeferred (not DrawNow) so that we don't block application thread in high load situations
+ }
+ return ETrue;
+ }
+
+
+void CAknIndicatorContainer::IncallBubbleSizeChanged(
+ TBool /*aAllowIdleStateBubble*/ )
+ {
+ if ( iIncallBubble &&
+ iIncallBubble->Flags() & CIncallStatusBubble::ESBVisible )
+ {
+ TAknWindowLineLayout layout;
+ if ( iIndicatorsShown > 0 )
+ {
+ // Position of incall bubble if universal small indicator(s) present.
+ // This position is also used when the bubble is shown with idle layout
+ // when autolock application is activated and it is front application.
+ layout = AknLayoutScalable_Apps::popup_call_status_window( 0 ).LayoutLine();
+ }
+ else
+ {
+ // Position of incall bubble if universal small indicator pane is empty.
+ layout = AknLayoutScalable_Apps::popup_call_status_window( 1 ).LayoutLine();
+ }
+
+ // screen
+ TRect screenRect( iAvkonAppUi->ApplicationRect() );
+ TAknLayoutRect layoutRect;
+
+ if ( Layout_Meta_Data::IsLandscapeOrientation() )
+ {
+ TInt topVariety = 8; // default to flat landscape statuspane variety
+ if ( AknStatuspaneUtils::StaconPaneActive() )
+ {
+ topVariety = 2;
+ }
+
+ TInt skvariety = 6;
+ if ( AknStatuspaneUtils::StaconPaneActive() )
+ {
+ if ( AknStatuspaneUtils::StaconSoftKeysRight() )
+ {
+ skvariety = 6;
+ }
+ else
+ {
+ skvariety = 8;
+ }
+ }
+ else if ( AknStatuspaneUtils::FlatLayoutActive() ||
+ AknStatuspaneUtils::HDLayoutActive() )
+ {
+ skvariety = 10;
+ }
+
+ if ( iIndicatorsShown > 0 )
+ {
+ // If indicators are shown we use one bigger variety index. But for "10" there is not such.
+ if ( skvariety != 10 )
+ {
+ skvariety++;
+ }
+ }
+
+ layout = AknLayoutScalable_Apps::popup_call_status_window( skvariety ).LayoutLine();
+
+ // To keep the call bubble in indicator pane area,
+ // otherwise it'll get on top of the title pane in A&H layouts.
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ TInt tmp = layout.il;
+ layout.il = layout.ir;
+ layout.ir = tmp;
+ }
+
+ TAknWindowComponentLayout topLayout = AknLayoutScalable_Avkon::area_top_pane( topVariety );
+ layoutRect.LayoutRect( screenRect, topLayout );
+ TRect topLayoutRect( layoutRect.Rect() );
+ layoutRect.LayoutRect( topLayoutRect, layout );
+ }
+ else
+ {
+ // Incall bubble
+ layoutRect.LayoutRect( screenRect, layout );
+ }
+
+ TRect rect( layoutRect.Rect() );
+
+ // SizeChanged of incall indicator is heavyweight, so set size only if
+ // necessary.
+ if ( rect != TRect( iIncallBubble->Position(), iIncallBubble->Size() ) )
+ {
+ iIncallBubble->SetRect( rect );
+ }
+ }
+ }
+
+EXPORT_C void CAknIndicatorContainer::SetIndicatorValue(TUid aIndicatorId, TInt aValue, TInt aMaxValue)
+ {
+ TInt count = iIndicators->Count();
+ for(TInt ii = 0; ii < count; ii++)
+ {
+ CAknIndicator* indicator = iIndicators->At(ii);
+ if ( indicator->Uid() == aIndicatorId )
+ {
+ indicator->SetIndicatorValue(aValue, aMaxValue);
+ // Draw the indicator if it is visible.
+ if ( indicator->IndicatorState() != EAknIndicatorStateOff )
+ {
+ DrawNow();
+ }
+ break;
+ }
+ }
+ }
+
+void CAknIndicatorContainer::SizeChangedInSmallStatusPane()
+ {
+ iLayoutOrientation = EHorizontal; // always horizontal
+
+ // only editor indicators are supported in small statuspane
+ if (iIndicatorContext != ENaviPaneEditorIndicators)
+ {
+ return;
+ }
+
+ // Gprs indicator is a special case. It is drawn
+ // to other spane by the system. Check here that correct
+ // statuspane layout is enabled and switch if needed
+ //
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+ TInt statusPaneCurrentLayoutResourceId = 0;
+ if ( statusPane )
+ {
+ statusPaneCurrentLayoutResourceId = statusPane->CurrentLayoutResId();
+ }
+ TInt last = iIndicators->Count() - 1;
+
+ // Update the status pane layout if needed to correspond the
+ // visibility of the GPRS indicator. If status pane layout is changed
+ // this function will be called again.
+ TBool layoutChanged = EFalse;
+ TRAP_IGNORE( layoutChanged = UpdateSmallLayoutL() );
+ if ( layoutChanged )
+ {
+ return; // this method will be called again
+ }
+
+ TBool layoutMirrored( AknLayoutUtils::LayoutMirrored() );
+
+ TRect containerRect( Rect() );
+
+ // screen
+ TRect screenRect = iAvkonAppUi->ApplicationRect();
+
+ // small statuspane
+ TRect smallStatusPaneRect;
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::EStatusPane, smallStatusPaneRect );
+
+ // small statuspane, wait pane
+ TAknLayoutRect smallStatusWaitPaneLayoutRect;
+ smallStatusWaitPaneLayoutRect.LayoutRect(
+ smallStatusPaneRect, AknLayoutScalable_Avkon::status_small_wait_pane( 0 ) );
+ TRect smallStatusWaitPaneRect( smallStatusWaitPaneLayoutRect.Rect() );
+
+ // small statuspane, globe
+ TAknLayoutRect smallStatusWmlGlobeLayoutRect;
+ smallStatusWmlGlobeLayoutRect.LayoutRect(
+ smallStatusPaneRect, AknLayoutScalable_Avkon::status_small_pane_g4( 0 ) );
+ TRect smallStatusWmlGlobeRect( smallStatusWmlGlobeLayoutRect.Rect() );
+
+ // small statuspane, gprs indicator
+ TAknLayoutRect smallStatusGprsLayoutRect;
+ smallStatusGprsLayoutRect.LayoutRect(
+ smallStatusPaneRect, AknLayoutScalable_Avkon::status_small_pane_g2( 0 ) );
+ TRect smallStatusGprsRect( smallStatusGprsLayoutRect.Rect() );
+
+ // small statuspane, secure state indicator
+ TAknLayoutRect smallStatusSecureStateLayoutRect;
+ smallStatusSecureStateLayoutRect.LayoutRect(
+ smallStatusPaneRect, AknLayoutScalable_Avkon::status_small_pane_g3( 0 ) );
+ TRect smallStatusSecureStateRect( smallStatusSecureStateLayoutRect.Rect() );
+
+
+ // small statuspane, texts
+ TAknTextComponentLayout smallStatusTextLayout;
+ if ( statusPaneCurrentLayoutResourceId ==
+ AVKONENV->StatusPaneResIdForCurrentLayout( R_AVKON_STATUS_PANE_LAYOUT_SMALL ) )
+ {
+ smallStatusTextLayout = AknLayoutScalable_Avkon::status_small_pane_t1( 0 );
+ }
+ else // gprs indicator visible
+ {
+ smallStatusTextLayout = AknLayoutScalable_Avkon::status_small_pane_t1( 1 );
+ }
+
+ TAknLayoutText textLayout;
+ textLayout.LayoutText( smallStatusPaneRect, smallStatusTextLayout );
+ TRect smallStatusTextRect( textLayout.TextRect() );
+
+ TInt textIndicatorLeftOffset = smallStatusTextRect.iTl.iX;
+
+ // Take possible touch pane into account.
+ TInt textIndicatorVerticalOffset =
+ ( containerRect.Height() - smallStatusTextRect.Height() ) / 2;
+
+ TInt waitBarIndicatorLeftOffset = smallStatusWaitPaneRect.iTl.iX;
+ TInt progressBarIndicatorLeftOffset = smallStatusWaitPaneRect.iTl.iX;
+ TInt wmlWaitGlobeLeftOffset = smallStatusWmlGlobeRect.iTl.iX;
+
+ if ( layoutMirrored )
+ {
+ waitBarIndicatorLeftOffset =
+ smallStatusPaneRect.iBr.iX - smallStatusWaitPaneRect.iBr.iX;
+
+ progressBarIndicatorLeftOffset =
+ smallStatusPaneRect.iBr.iX - smallStatusWaitPaneRect.iBr.iX;
+
+ wmlWaitGlobeLeftOffset =
+ smallStatusPaneRect.iBr.iX - smallStatusWmlGlobeRect.iBr.iX;
+ }
+
+
+ if ( statusPaneCurrentLayoutResourceId ==
+ AVKONENV->StatusPaneResIdForCurrentLayout(
+ R_AVKON_STATUS_PANE_LAYOUT_SMALL_WITH_SIGNAL_PANE ) )
+ {
+ // If GPRS indicator is visible then a larger offset is needed
+ // for text indicator because there are no pixels empty in
+ // the right side of the GPRS status icon as the layout spec
+ // requires in this case.
+ if ( textIndicatorLeftOffset < KMinSpaceBetweenIconsInPixels )
+ {
+ textIndicatorLeftOffset = KMinSpaceBetweenIconsInPixels;
+ }
+
+ // This makes the globe indicator position adjusted to
+ // middle if GPRS indicator is in either side
+ if( !layoutMirrored )
+ {
+ wmlWaitGlobeLeftOffset -= smallStatusGprsRect.Width();
+ }
+ }
+
+ // Modify containerRect if alignment is Right.
+ // For Left aligned no need to modify containerRect.
+ if ( iAlignment == TIndicatorAlignment( ERight ) )
+ {
+ containerRect.iBr.iX -= 3; // Right margin of editor indicators
+ containerRect.iTl.iX += 0; // Left margin of editor indicators
+ }
+
+ iIndicatorsShown = 0;
+ iAnimatedIndicatorsShown = 0;
+ TBool textIndicatorOffsetNeeded = ETrue;
+
+ TRect rectForRightSideIndicators( containerRect.iBr.iX,
+ containerRect.iTl.iY,
+ containerRect.iBr.iX,
+ containerRect.iBr.iY );
+
+ TRect rectForLeftSideIndicators( containerRect.iTl.iX,
+ containerRect.iTl.iY,
+ containerRect.iTl.iX,
+ containerRect.iBr.iY );
+
+ TRect rectForMiddleIndicators( wmlWaitGlobeLeftOffset,
+ containerRect.iTl.iY,
+ wmlWaitGlobeLeftOffset,
+ containerRect.iBr.iY );
+
+ for ( TInt ii = 0; ii <= last; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( ii );
+ TInt uid = indicator->Uid().iUid;
+ TInt indicatorPosition = 0;
+
+ // Decide here how indicators are positioned.
+ // Default is right side.
+ indicatorPosition = indicator->IndicatorPosition();
+
+ // Check if indicator is not shown on current layout even it is set ON.
+ if ( !indicator->IndicatorState() ||
+ indicator->Priority() == KIndicatorNotShown )
+ {
+ continue;
+ }
+
+ // Check if this is GPRS indicator, it is never shown here
+ // but is drawn to the signal pane by the system
+ if ( uid == EAknNaviPaneEditorIndicatorGprs )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+
+ // Handle offsets.
+ TAknLayoutRect statusPaneIconSmallRect;
+ statusPaneIconSmallRect.LayoutRect(
+ smallStatusPaneRect, AknLayoutScalable_Avkon::status_small_icon_pane() );
+
+ // Take possible touch pane into account
+ TInt verticalOffset =
+ ( containerRect.Height() - statusPaneIconSmallRect.Rect().Height() ) / 2;
+
+ TInt leftOffset = 0; // default offset
+ TInt rightOffset = 0; // default offset
+
+ TInt indicatorWidth = indicator->IconSize().iWidth; // default width
+ TInt indicatorHeight = indicator->IconSize().iHeight; // default height
+
+ if ( uid == EAknNaviPaneEditorIndicatorMessageInfo ||
+ uid == EAknNaviPaneEditorIndicatorWmlWindowsText ||
+ uid == EAknNaviPaneEditorIndicatorMessageLength )
+ {
+ indicatorHeight = smallStatusTextRect.Height();
+ verticalOffset = textIndicatorVerticalOffset;
+ // First text indicator needs horizontal offset.
+ if ( textIndicatorOffsetNeeded )
+ {
+ leftOffset += textIndicatorLeftOffset;
+ }
+
+ textIndicatorOffsetNeeded = EFalse;
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorFileSize )
+ {
+ verticalOffset = textIndicatorVerticalOffset;
+
+ // Need left offset in western, right offset in A&H layout.
+ if ( layoutMirrored )
+ {
+ rightOffset = textIndicatorLeftOffset;
+ }
+ else
+ {
+ leftOffset = KMinSpaceBetweenIconsInPixels;
+ }
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorSecuredConnection )
+ {
+ verticalOffset =
+ ( containerRect.Height() - smallStatusSecureStateRect.Height() ) / 2;
+
+ // Because icon bitmap does not contain enough space,
+ // increase offset as the layout spec states.
+ if ( layoutMirrored )
+ {
+ leftOffset = KMinSpaceBetweenIconsInPixels;
+ }
+ else
+ {
+ rightOffset = KMinSpaceBetweenIconsInPixels;
+ }
+
+ textIndicatorOffsetNeeded = EFalse;
+ waitBarIndicatorLeftOffset = 0;
+ progressBarIndicatorLeftOffset = 0;
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorWmlWaitGlobe )
+ {
+ verticalOffset =
+ ( containerRect.Height() - indicator->IconSize().iHeight ) / 2;
+ indicatorWidth = smallStatusWmlGlobeRect.Width();
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorProgressBar )
+ {
+ indicatorWidth = smallStatusWaitPaneRect.Width();
+ indicatorHeight = smallStatusWaitPaneRect.Height();
+ verticalOffset = ( containerRect.Height() - indicatorHeight ) / 2;
+ leftOffset = progressBarIndicatorLeftOffset;
+ textIndicatorOffsetNeeded = ETrue;
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorWaitBar )
+ {
+ indicatorWidth = smallStatusWaitPaneRect.Width();
+ indicatorHeight = smallStatusWaitPaneRect.Height();
+ verticalOffset = ( containerRect.Height() - indicatorHeight ) / 2;
+ leftOffset = waitBarIndicatorLeftOffset;
+ textIndicatorOffsetNeeded = ETrue;
+ }
+
+ if ( layoutMirrored )
+ {
+ TInt temp = leftOffset;
+ leftOffset = rightOffset;
+ rightOffset = temp;
+ }
+
+ // Place indicators to the left side.
+ if ( ( indicatorPosition == ELeftSide &&
+ iAlignment == TIndicatorAlignment( ERight ) ) ||
+ ( indicatorPosition == ERightSide &&
+ iAlignment == TIndicatorAlignment( ELeft ) ) )
+ {
+ TRect requiredRect(
+ rectForLeftSideIndicators.iBr.iX,
+ rectForLeftSideIndicators.iTl.iY,
+ rectForLeftSideIndicators.iBr.iX + leftOffset + indicatorWidth + rightOffset,
+ rectForLeftSideIndicators.iBr.iY );
+
+ // check if indicator fits
+ TBool indicatorDoesNotFit =
+ ( requiredRect.Intersects( rectForRightSideIndicators ) ||
+ requiredRect.Intersects( rectForMiddleIndicators ) ||
+ containerRect.iTl.iX > requiredRect.iTl.iX ||
+ containerRect.iBr.iX < requiredRect.iBr.iX );
+
+ if ( indicatorDoesNotFit &&
+ !indicator->DynamicTextIndicator() )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ if ( indicator->DynamicTextIndicator() && indicatorDoesNotFit )
+ {
+ // Dynamic text indicators (not normal text indicators)
+ // can adjust to any size.
+ TInt maxWidthForDynamicTextIndicator =
+ containerRect.iBr.iX - requiredRect.iTl.iX;
+
+ if ( requiredRect.Intersects( rectForRightSideIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ rectForRightSideIndicators.iTl.iX - requiredRect.iTl.iX;
+ }
+
+ if ( requiredRect.Intersects( rectForMiddleIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ rectForMiddleIndicators.iTl.iX - requiredRect.iTl.iX;
+ }
+
+ indicator->SetExtent( TPoint( requiredRect.iTl.iX + leftOffset,
+ verticalOffset ),
+ TSize( maxWidthForDynamicTextIndicator,
+ indicatorHeight ) );
+
+ rectForLeftSideIndicators.iBr.iX =
+ indicator->Position().iX + indicator->Size().iWidth;
+ }
+ else
+ {
+ indicator->SetExtent( TPoint( requiredRect.iTl.iX + leftOffset,
+ verticalOffset ),
+ TSize( indicatorWidth, indicatorHeight ) );
+
+ rectForLeftSideIndicators.iBr.iX = requiredRect.iBr.iX;
+ }
+ }
+ }
+
+
+ // Place indicators to the right side.
+ if ( ( indicatorPosition == ERightSide &&
+ iAlignment == TIndicatorAlignment( ERight ) ) ||
+ ( indicatorPosition == ELeftSide &&
+ iAlignment == TIndicatorAlignment( ELeft ) ) )
+ {
+ TRect requiredRect(
+ rectForRightSideIndicators.iTl.iX - leftOffset - indicatorWidth - rightOffset,
+ rectForRightSideIndicators.iTl.iY,
+ rectForRightSideIndicators.iTl.iX,
+ rectForRightSideIndicators.iBr.iY );
+
+ // Check if indicator fits.
+ TBool indicatorDoesNotFit =
+ ( requiredRect.Intersects( rectForLeftSideIndicators ) ||
+ requiredRect.Intersects( rectForMiddleIndicators ) ||
+ containerRect.iTl.iX > requiredRect.iTl.iX ||
+ containerRect.iBr.iX < requiredRect.iBr.iX );
+
+ if ( indicatorDoesNotFit &&
+ !indicator->DynamicTextIndicator() )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ if ( indicator->DynamicTextIndicator() && indicatorDoesNotFit )
+ {
+ // Dynamic text indicators (not normal text indicators)
+ // can adjust to any size.
+ TInt maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - containerRect.iTl.iX - leftOffset;
+
+ if ( requiredRect.Intersects( rectForLeftSideIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - rectForLeftSideIndicators.iBr.iX;
+ }
+
+ if ( requiredRect.Intersects( rectForMiddleIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - rectForMiddleIndicators.iBr.iX;
+ }
+
+ indicator->SetExtent(
+ TPoint( requiredRect.iBr.iX - maxWidthForDynamicTextIndicator - leftOffset,
+ verticalOffset ),
+ TSize( maxWidthForDynamicTextIndicator,
+ indicatorHeight ) );
+
+ rectForRightSideIndicators.iTl.iX = indicator->Position().iX;
+ }
+ else
+ {
+ indicator->SetExtent( TPoint( requiredRect.iTl.iX + leftOffset,
+ verticalOffset),
+ TSize( indicatorWidth, indicatorHeight ) );
+
+ rectForRightSideIndicators.iTl.iX = requiredRect.iTl.iX;
+ }
+ }
+ }
+
+
+ // Place indicators to the middle, only indicator is wml wait globe.
+ if ( indicatorPosition == EMiddle )
+ {
+ TRect requiredRect(
+ rectForMiddleIndicators.iTl.iX,
+ rectForMiddleIndicators.iTl.iY,
+ rectForMiddleIndicators.iTl.iX + leftOffset + indicatorWidth + rightOffset,
+ rectForMiddleIndicators.iBr.iY);
+
+ // Check if indicator fits.
+ if ( ( requiredRect.Intersects( rectForRightSideIndicators ) ||
+ requiredRect.Intersects( rectForLeftSideIndicators ) ) ||
+ ( rectForMiddleIndicators.Width() != 0 ) )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ indicator->SetExtent( TPoint( rectForMiddleIndicators.iTl.iX + leftOffset,
+ verticalOffset),
+ TSize( indicatorWidth, indicatorHeight) );
+ rectForMiddleIndicators.iTl.iX += rightOffset;
+ rectForMiddleIndicators.iTl.iX += indicatorWidth;
+ }
+ }
+
+ iIndicatorsShown++;
+
+ if ( indicator->IndicatorState() == MAknIndicator::EIndicatorAnimate )
+ {
+ iAnimatedIndicatorsShown++;
+ }
+ } // for
+
+ ResetAnimTicker( iExtension->iIsForeground );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SizeChangedInNormalStatusPane
+// Handles size change events in normal status pane layouts.
+// ---------------------------------------------------------------------------
+//
+void CAknIndicatorContainer::SizeChangedInNormalStatusPane()
+ {
+ TRect containerRect( Rect() );
+
+ TInt height = containerRect.Height();
+ TInt width = containerRect.Width();
+
+ // Find out if pane layout is horizontal or vertical
+ // Following pane uses vertical layout:
+ // - System owned universal small indicator pane
+ // when status pane is in usual layout
+ // Following panes use horizontal layout:
+ // - System owned universal small indicator pane
+ // when status pane is in idle layout
+ // - Navigation pane editor indicator pane
+ // - Query editor indicators
+ iLayoutOrientation = ( height > width ) ? EVertical : EHorizontal;
+
+ TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
+
+ TAknWindowComponentLayout indicatorIconLayout(
+ AknLayoutScalable_Avkon::indicator_pane_g1( isLandscape ) );
+
+ if ( iIndicatorContext != EUniversalIndicators )
+ {
+ // Editor indicators
+ if ( iAlignment == TIndicatorAlignment( ERight ) )
+ {
+ containerRect.iBr.iX -= 4; // Right margin of editor indicators
+ containerRect.iTl.iX += 6; // Left margin of editor indicators
+ }
+ else
+ {
+ containerRect.iBr.iX -= 6; // Right margin of editor indicators
+ containerRect.iTl.iX += 1; // Left margin of editor indicators
+ }
+ }
+ else if ( iLayoutOrientation == EHorizontal )
+ {
+ TAknWindowLineLayout indicatorLayout = AknLayout::Indicator_pane_elements_Line_1();
+ TAknLayoutRect indicatorLayoutRect;
+ indicatorLayoutRect.LayoutRect(containerRect, indicatorLayout);
+ TRect indicatorRect( indicatorLayoutRect.Rect() );
+
+ // Layout adaptation layer does not work correctly. Access the layout data directly in
+ // scalable UI...and calculate...
+ TAknWindowLineLayout layout1( AknLayoutScalable_Avkon::indicator_pane_g1(0).LayoutLine() );
+
+ indicatorLayoutRect.LayoutRect(containerRect, layout1);
+ indicatorRect = indicatorLayoutRect.Rect();
+
+ // variety 1 is only valid in landscape layouts
+ if(Layout_Meta_Data::IsLandscapeOrientation())
+ {
+ TAknWindowLineLayout layout2 = AknLayoutScalable_Avkon::indicator_pane_g1(1).LayoutLine();
+ indicatorLayoutRect.LayoutRect(containerRect, layout2);
+ TRect rect2( indicatorLayoutRect.Rect() );
+ indicatorRect.BoundingRect(rect2);
+ }
+
+ containerRect.iBr.iX = indicatorRect.iBr.iX;
+ containerRect.iTl.iX = indicatorRect.iTl.iX;
+ }
+
+ // Available space for indicators
+ TRect rect( containerRect );
+
+ height = rect.Height();
+ width = rect.Width();
+
+ TInt verticalIndicatorOffset = rect.iTl.iY;
+ TInt verticalOffsetForTextIndicator = verticalIndicatorOffset;
+
+ TAknLayoutText layoutText;
+ layoutText.LayoutText(
+ Rect(),
+ TAknWindowComponentLayout::ComposeText(
+ AknLayoutScalable_Avkon::navi_text_pane( 0 ),
+ AknLayoutScalable_Avkon::navi_text_pane_t1() ) );
+
+ TAknLayoutRect editingIconLayoutRect;
+ editingIconLayoutRect.LayoutRect(
+ Rect(),
+ TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Avkon::navi_icon_pane( 0 ),
+ AknLayoutScalable_Avkon::navi_icon_pane_g1() ) );
+
+ if ( iIndicatorContext != EUniversalIndicators )
+ {
+ if ( iIndicatorContext == ENaviPaneEditorIndicators )
+ {
+ verticalIndicatorOffset += editingIconLayoutRect.Rect().iTl.iY;
+ verticalOffsetForTextIndicator = layoutText.TextRect().iTl.iY;
+ }
+ // In query editor indicators have offset 0
+ }
+ else if ( iLayoutOrientation == EHorizontal )
+ {
+ TAknLayoutRect indicatorLayoutRect;
+ indicatorLayoutRect.LayoutRect( containerRect, indicatorIconLayout );
+ TRect indicatorRect( indicatorLayoutRect.Rect() );
+
+ verticalIndicatorOffset += indicatorRect.iTl.iY;
+ }
+
+ TInt verticalOffset = verticalIndicatorOffset;
+
+ // If layout orientation has been changed since last call,
+ // prioritize indicators again.
+ if ( iLayoutOrientation != iPreviousLayoutOrientation )
+ {
+ // Following leave is ignored.
+ // In case of leave indicators are not maybe shown correctly.
+ TRAP_IGNORE ( PrioritizeIndicatorsL() );
+ }
+
+ iIndicatorsShown = 0;
+ iAnimatedIndicatorsShown = 0;
+ TInt last = iIndicators->Count() - 1;
+
+ TRect rectForRightSideIndicators( containerRect.iBr.iX,
+ containerRect.iTl.iY,
+ containerRect.iBr.iX,
+ containerRect.iBr.iY );
+
+ TRect rectForLeftSideIndicators( containerRect.iTl.iX,
+ containerRect.iTl.iY,
+ containerRect.iTl.iX,
+ containerRect.iBr.iY );
+
+ // Not really supported in this layout.
+ TRect rectForMiddleIndicators( TRect( 0, 0, 0, 0 ) );
+
+
+ for ( TInt ii = 0; ii <= last; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( ii );
+ if ( !indicator->IndicatorState() ||
+ indicator->Priority() == KIndicatorNotShown )
+ {
+ // Indicator is not shown on current layout even it is set ON.
+ continue;
+ }
+
+ TInt uid = indicator->Uid().iUid;
+
+ if ( uid == EAknNaviPaneEditorIndicatorSecuredConnection ||
+ uid == EAknNaviPaneEditorIndicatorProgressBar ||
+ uid == EAknNaviPaneEditorIndicatorWmlWaitGlobe ||
+ uid == EAknNaviPaneEditorIndicatorGprs ||
+ uid == EAknNaviPaneEditorIndicatorFileSize ||
+ uid == EAknNaviPaneEditorIndicatorWaitBar ||
+ uid == EAknNaviPaneEditorIndicatorWlanAvailable ||
+ uid == EAknNaviPaneEditorIndicatorWlanActive ||
+ uid == EAknNaviPaneEditorIndicatorWlanActiveSecure )
+ {
+ // These indicators are not shown in this statuspane layout.
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+
+
+ if ( iLayoutOrientation == EVertical )
+ {
+ // Highest priority indicator is put topmost.
+ if ( height < indicator->IconSize().iHeight )
+ {
+ // Space for indicators is full.
+ // Rest of low priority indicators are not shown.
+ break;
+ }
+ // Position indicators side by side.
+ if ( iAlignment == TIndicatorAlignment( ERight ) )
+ {
+ indicator->SetExtent( rect.iTl, indicator->IconSize() );
+ }
+ // If layout is left aligned, must leave one pixel to the left empty.
+ else
+ {
+ indicator->SetExtent( TPoint( rect.iTl.iX + 1, rect.iTl.iY ),
+ indicator->IconSize() );
+ }
+ rect.iTl.iY += indicator->IconSize().iHeight;
+ height = rect.Height();
+ }
+ else
+ {
+ // Code to set indicator positions starts,
+ // supports dynamic text indicators.
+ verticalOffset = verticalIndicatorOffset;
+
+ // Decide here how indicators are positioned.
+ // Default is right side.
+ TInt indicatorPosition = indicator->IndicatorPosition();
+
+ TInt leftOffset = 0; // default offset
+ TInt rightOffset = 0; // default offset
+
+ TInt indicatorWidth = indicator->IconSize().iWidth; // default width
+ TInt indicatorHeight = indicator->IconSize().iHeight; // default height
+
+ TBool textIndicatorOffsetNeeded = ETrue;
+
+ TInt textIndicatorLeftOffset = KMinSpaceBetweenIconsInPixels;
+
+ if ( uid == EAknNaviPaneEditorIndicatorMessageInfo ||
+ uid == EAknNaviPaneEditorIndicatorWmlWindowsText ||
+ uid == EAknNaviPaneEditorIndicatorMessageLength )
+ {
+ verticalOffset = verticalOffsetForTextIndicator;
+ // First text indicator need horizontal offset.
+ if ( textIndicatorOffsetNeeded )
+ {
+ leftOffset += textIndicatorLeftOffset;
+ }
+
+ textIndicatorOffsetNeeded = EFalse;
+ }
+
+ if ( uid == EAknNaviPaneEditorIndicatorFileSize )
+ {
+ verticalOffset = verticalOffsetForTextIndicator;
+
+ // Need left offset in western, right offset in A&H layout.
+ if( AknLayoutUtils::LayoutMirrored() )
+ {
+ rightOffset = textIndicatorLeftOffset;
+ }
+ else
+ {
+ leftOffset = KMinSpaceBetweenIconsInPixels;
+ }
+ }
+
+ if( AknLayoutUtils::LayoutMirrored() )
+ {
+ TInt temp = leftOffset;
+ leftOffset = rightOffset;
+ rightOffset = temp;
+ }
+
+ // Place indicators to the leftside.
+ if ( ( indicatorPosition == ELeftSide &&
+ iAlignment == TIndicatorAlignment( ERight ) ) ||
+ ( indicatorPosition == ERightSide &&
+ iAlignment == TIndicatorAlignment( ELeft ) ) )
+ {
+ TRect requiredRect(
+ rectForLeftSideIndicators.iBr.iX,
+ rectForLeftSideIndicators.iTl.iY,
+ rectForLeftSideIndicators.iBr.iX + leftOffset + indicatorWidth + rightOffset,
+ rectForLeftSideIndicators.iBr.iY );
+
+ // Check if indicator fits.
+ TBool indicatorDoesNotFit =
+ ( requiredRect.Intersects( rectForRightSideIndicators ) ||
+ requiredRect.Intersects( rectForMiddleIndicators ) ||
+ containerRect.iTl.iX > requiredRect.iTl.iX ||
+ containerRect.iBr.iX < requiredRect.iBr.iX );
+
+ if ( indicatorDoesNotFit &&
+ !indicator->DynamicTextIndicator() )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ if ( indicator->DynamicTextIndicator() && indicatorDoesNotFit )
+ {
+ // Dynamic text indicators (not normal text indicators)
+ // can adjust to any size.
+ TInt maxWidthForDynamicTextIndicator =
+ containerRect.iBr.iX - requiredRect.iTl.iX;
+
+ if ( requiredRect.Intersects( rectForRightSideIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ rectForRightSideIndicators.iTl.iX - requiredRect.iTl.iX;
+ }
+
+ if ( requiredRect.Intersects( rectForMiddleIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ rectForMiddleIndicators.iTl.iX - requiredRect.iTl.iX;
+ }
+
+ indicator->SetExtent(
+ TPoint( requiredRect.iTl.iX + leftOffset, verticalOffset ),
+ TSize( maxWidthForDynamicTextIndicator, indicatorHeight ) );
+
+ rectForLeftSideIndicators.iBr.iX =
+ indicator->Position().iX + indicator->Size().iWidth;
+ }
+ else
+ {
+ indicator->SetExtent(
+ TPoint( requiredRect.iTl.iX + leftOffset, verticalOffset ),
+ TSize( indicatorWidth, indicatorHeight ) );
+ rectForLeftSideIndicators.iBr.iX = requiredRect.iBr.iX;
+ }
+ }
+ }
+
+
+ // Place indicators on the right side.
+ if ( ( indicatorPosition == ERightSide &&
+ iAlignment == TIndicatorAlignment( ERight ) ) ||
+ ( indicatorPosition == ELeftSide &&
+ iAlignment == TIndicatorAlignment( ELeft ) ) )
+ {
+ TRect requiredRect(
+ rectForRightSideIndicators.iTl.iX - leftOffset - indicatorWidth - rightOffset,
+ rectForRightSideIndicators.iTl.iY,
+ rectForRightSideIndicators.iTl.iX,
+ rectForRightSideIndicators.iBr.iY );
+
+ // Check if indicator fits.
+ TBool indicatorDoesNotFit =
+ ( requiredRect.Intersects( rectForLeftSideIndicators ) ||
+ requiredRect.Intersects( rectForMiddleIndicators ) ||
+ containerRect.iTl.iX > requiredRect.iTl.iX ||
+ containerRect.iBr.iX < requiredRect.iBr.iX );
+
+ if ( indicatorDoesNotFit &&
+ !indicator->DynamicTextIndicator() )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ if ( indicator->DynamicTextIndicator() && indicatorDoesNotFit )
+ {
+ // Dynamic text indicators (not normal text indicators)
+ // can adjust to any size.
+ TInt maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - containerRect.iTl.iX - leftOffset;
+
+ if ( requiredRect.Intersects( rectForLeftSideIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - rectForLeftSideIndicators.iBr.iX;
+ }
+
+ if ( requiredRect.Intersects( rectForMiddleIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - rectForMiddleIndicators.iBr.iX;
+ }
+
+ indicator->SetExtent(
+ TPoint( requiredRect.iBr.iX - maxWidthForDynamicTextIndicator + leftOffset,
+ verticalOffset ),
+ TSize( maxWidthForDynamicTextIndicator, indicatorHeight ) );
+ rectForRightSideIndicators.iTl.iX = indicator->Position().iX;
+ }
+ else
+ {
+ indicator->SetExtent(
+ TPoint( requiredRect.iTl.iX + leftOffset, verticalOffset ),
+ TSize( indicatorWidth, indicatorHeight ) );
+ rectForRightSideIndicators.iTl.iX = requiredRect.iTl.iX;
+ }
+ }
+ }
+
+
+ // Place indicators to the middle if any.
+ if ( indicatorPosition == EMiddle )
+ {
+ // Not supported for now, always set size to zero.
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ }
+ }
+
+
+ iIndicatorsShown++;
+ if ( indicator->IndicatorState() == MAknIndicator::EIndicatorAnimate )
+ {
+ iAnimatedIndicatorsShown++;
+ }
+ }
+
+ // Code for setting indicator positions ends.
+
+ ResetAnimTicker( iExtension->iIsForeground );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SizeChangedInExtendedStatusPane
+// Handles size change events in extended status pane layouts.
+// ---------------------------------------------------------------------------
+//
+void CAknIndicatorContainer::SizeChangedInExtendedStatusPane()
+ {
+ TRect containerRect( Rect() );
+
+ TBool hdLayout( AknStatuspaneUtils::HDLayoutActive() );
+
+ // In landscape layoutdata there is not yet data
+ // so we approximate a bit here...
+ if ( AknStatuspaneUtils::ExtendedStaconPaneActive() )
+ {
+ containerRect.iTl.iY += Rect().Size().iHeight / 9;
+ containerRect.iBr.iY -= Rect().Size().iHeight / 9;
+ }
+
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ iLayoutOrientation = EHorizontal;
+
+ if ( hdLayout )
+ {
+ if ( !AknLayoutUtils::LayoutMirrored() )
+ {
+ iAlignment = TIndicatorAlignment( ELeft );
+ }
+ else
+ {
+ iAlignment = TIndicatorAlignment( ERight );
+ }
+ }
+ }
+
+ // Available space for indicators
+ TRect rect( containerRect );
+
+ // If layout orientation has been changed since last call, prioritize indicators again.
+ if ( iLayoutOrientation != iPreviousLayoutOrientation )
+ {
+ TRAP_IGNORE ( PrioritizeIndicatorsL() );
+ }
+
+ iIndicatorsShown = 0;
+ iAnimatedIndicatorsShown = 0;
+ TInt last = iIndicators->Count() - 1;
+
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ TRect parent( rect );
+
+ // Read the maximum amount of indicators in one row
+ // from the layout data.
+ TAknLayoutScalableParameterLimits limit(
+ AknLayoutScalable_Avkon::cell_indicator_nsta_pane_ParamLimits() );
+ TInt maxIndicatorsShown = limit.LastColumn() + 1;
+
+ TInt indicatorNumberVariety = 0;
+ if ( maxIndicatorsShown == 4 )
+ {
+ indicatorNumberVariety = 1;
+ }
+
+ TAknLayoutRect layoutRect;
+ TAknWindowLineLayout cellLayout;
+ TAknWindowComponentLayout indicatorLayout(
+ AknLayoutScalable_Avkon::cell_indicator_nsta_pane_g2( hdLayout ) );
+
+
+ TInt totalIndicatorsOn( 0 );
+
+ // Need to go through the indicator array two times
+ // to be able to place the indicators in correct order.
+ for ( TInt i = 0; i <= last; i++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( i );
+ if ( indicator->IndicatorState() &&
+ indicator->Priority() != KIndicatorNotShown )
+ {
+ totalIndicatorsOn++;
+ }
+ }
+
+ for ( TInt ii = 0; ii <= last; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( ii );
+ if ( !indicator->IndicatorState() ||
+ indicator->Priority() == KIndicatorNotShown )
+ {
+ // Indicator is not shown on current layout even it is set ON.
+ continue;
+ }
+
+ iIndicatorsShown++;
+
+ if ( iIndicatorsShown > maxIndicatorsShown )
+ {
+ // Maximum number of indicators is already shown.
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ break;
+ }
+ else
+ {
+ TInt columnVariety( iIndicatorsShown - 1 );
+
+ if ( !hdLayout && totalIndicatorsOn < maxIndicatorsShown )
+ {
+ if ( totalIndicatorsOn == 1 )
+ {
+ columnVariety = maxIndicatorsShown - 1;
+ }
+ else
+ {
+ columnVariety = iIndicatorsShown;
+ }
+ }
+
+ // set indicator sizes here, leftmost cell first if we are in
+ // HD status pane layout, otherwise rightmost cell first.
+ cellLayout = AknLayoutScalable_Avkon::cell_indicator_nsta_pane(
+ columnVariety,
+ indicatorNumberVariety ).LayoutLine();
+ layoutRect.LayoutRect( parent, cellLayout );
+ TRect cell( layoutRect.Rect() );
+
+ layoutRect.LayoutRect( cell, indicatorLayout );
+ TRect indicatorRect( layoutRect.Rect() );
+
+ // FIXME: Layout is broken, we fix it here.
+ // Remove this when layout is fixed.
+ if ( indicatorRect.iBr.iX > cell.iBr.iX )
+ {
+ indicatorRect.iBr.iX = cell.iBr.iX;
+ }
+ if ( indicatorRect.iTl.iX < cell.iTl.iX )
+ {
+ indicatorRect.iTl.iX = cell.iTl.iX;
+ }
+ // End of FIXME
+
+ // TBD: When touch is supported, the size may have
+ // to be reconsidered.
+ indicator->SetRect( indicatorRect );
+ }
+
+ if ( indicator->IndicatorState() == MAknIndicator::EIndicatorAnimate )
+ {
+ iAnimatedIndicatorsShown++;
+ }
+ } // for
+
+ ResetAnimTicker( iExtension->iIsForeground );
+ } // if universal indicators.
+ else // Editor indicators.
+ {
+ // Navi and query editor indicators are always horizontally
+ // arranged in extended status pane layouts.
+ iLayoutOrientation = EHorizontal;
+
+ TInt verticalIndicatorOffset = rect.iTl.iY;
+ TInt verticalOffsetForTextIndicator = verticalIndicatorOffset;
+
+ // Text layout.
+ TAknLayoutText layoutText;
+ layoutText.LayoutText(
+ rect, AknLayoutScalable_Avkon::navi_text_pane_t1() );
+
+ // Offsets calculated from layout data.
+ TAknLayoutRect editingIconLayoutRect;
+ editingIconLayoutRect.LayoutRect(
+ rect, AknLayoutScalable_Avkon::navi_icon_pane_g1( 1 ) );
+
+ if ( iIndicatorContext == ENaviPaneEditorIndicators )
+ {
+ verticalIndicatorOffset += editingIconLayoutRect.Rect().iTl.iY;
+ verticalOffsetForTextIndicator = layoutText.TextRect().iTl.iY;
+ }
+ // In query editor indicators have offset 0
+
+ TInt verticalOffset = verticalIndicatorOffset;
+
+ // If layout orientation has been changed since last call, prioritize indicators again.
+ if ( iLayoutOrientation != iPreviousLayoutOrientation )
+ {
+ // Following leave is ignored.
+ // In case of leave indicators are not maybe shown correctly.
+ TRAP_IGNORE ( PrioritizeIndicatorsL() );
+ }
+
+ iIndicatorsShown = 0;
+ iAnimatedIndicatorsShown = 0;
+ TInt last = iIndicators->Count() - 1;
+
+ // Check if the secured connection indicator is on before
+ // reading the layouts because of different positioning
+ // of wait and progress bars with that indicator on.
+ TBool secureConnectionIndicOn( EFalse );
+ for ( TInt i = 0; i <= last; i++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( i );
+
+ if ( indicator->Uid().iUid == EAknNaviPaneEditorIndicatorSecuredConnection &&
+ indicator->IndicatorState() &&
+ indicator->Priority() != KIndicatorNotShown )
+ {
+ secureConnectionIndicOn = ETrue;
+ }
+ }
+
+ // Wait bar layout.
+ TAknWindowComponentLayout smallStatusWaitPaneLayout(
+ AknLayoutScalable_Avkon::status_small_wait_pane(
+ secureConnectionIndicOn ? 2 : 1 ) );
+ TAknLayoutRect smallStatusWaitPaneLayoutRect;
+ smallStatusWaitPaneLayoutRect.LayoutRect(
+ rect, smallStatusWaitPaneLayout );
+ TRect smallStatusWaitPaneRect( smallStatusWaitPaneLayoutRect.Rect() );
+
+ // Globe layout.
+ TAknLayoutRect smallStatusWmlGlobeLayoutRect;
+ smallStatusWmlGlobeLayoutRect.LayoutRect(
+ rect, AknLayoutScalable_Avkon::status_small_pane_g4( 0 ) );
+ TRect smallStatusWmlGlobeRect( smallStatusWmlGlobeLayoutRect.Rect() );
+
+ TInt wmlWaitGlobeLeftOffset =
+ rect.Width() / 2 - smallStatusWmlGlobeRect.Width() / 2;
+
+ TRect rectForRightSideIndicators( rect.iBr.iX,
+ rect.iTl.iY,
+ rect.iBr.iX,
+ rect.iBr.iY );
+
+ TRect rectForLeftSideIndicators( rect.iTl.iX,
+ rect.iTl.iY,
+ rect.iTl.iX,
+ rect.iBr.iY );
+
+ TRect rectForMiddleIndicators( 0, 0, 0, 0 ); // Not used in portrait.
+ if ( hdLayout )
+ {
+ rectForMiddleIndicators = TRect( wmlWaitGlobeLeftOffset,
+ rect.iTl.iY,
+ wmlWaitGlobeLeftOffset,
+ rect.iBr.iY );
+ }
+
+ for ( TInt ii = 0; ii <= last; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( ii );
+
+ // Check if indicator is not shown on current layout even it is set ON.
+ if ( !indicator->IndicatorState() ||
+ indicator->Priority() == KIndicatorNotShown )
+ {
+ continue;
+ }
+
+ TInt uid = indicator->Uid().iUid;
+ TInt indicatorPosition = indicator->IndicatorPosition();
+
+ // Handle indicators that are not shown in this layout here.
+
+ // Check if this is gprs indicator, it is never shown here but is drawn
+ // to the signal pane by the system
+ if ( uid == EAknNaviPaneEditorIndicatorGprs )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else if ( ( !hdLayout &&
+ ( uid == EAknNaviPaneEditorIndicatorSecuredConnection ||
+ uid == EAknNaviPaneEditorIndicatorProgressBar ||
+ uid == EAknNaviPaneEditorIndicatorWmlWaitGlobe ||
+ uid == EAknNaviPaneEditorIndicatorGprs ||
+ uid == EAknNaviPaneEditorIndicatorFileSize ||
+ uid == EAknNaviPaneEditorIndicatorWaitBar ) ) ||
+ ( hdLayout &&
+ ( uid == EAknNaviPaneEditorIndicatorWlanAvailable ||
+ uid == EAknNaviPaneEditorIndicatorWlanActive ||
+ uid == EAknNaviPaneEditorIndicatorWlanActiveSecure ) ) )
+ {
+ // These indicators are not shown in this statuspane layout
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+
+ // End of layout exceptions
+
+ // Calculate offsets.
+ TInt leftOffset = 0; // default offset
+ TInt rightOffset = 0; // default offset
+
+ TSize indicatorSize = indicator->IconSize();
+ TInt indicatorWidth = indicatorSize.iWidth; // default width
+ TInt indicatorHeight = indicatorSize.iHeight; // default height
+
+
+ switch ( uid )
+ {
+ case EAknNaviPaneEditorIndicatorMessageInfo:
+ case EAknNaviPaneEditorIndicatorWmlWindowsText:
+ case EAknNaviPaneEditorIndicatorMessageLength:
+ {
+ verticalOffset = verticalOffsetForTextIndicator;
+ break;
+ }
+
+ case EAknNaviPaneEditorIndicatorFileSize:
+ {
+ verticalOffset = verticalOffsetForTextIndicator;
+ leftOffset = KMinSpaceBetweenIconsInPixels;
+ break;
+ }
+
+ case EAknNaviPaneEditorIndicatorSecuredConnection:
+ case EAknNaviPaneEditorIndicatorWlanAvailable:
+ case EAknNaviPaneEditorIndicatorWlanActive:
+ case EAknNaviPaneEditorIndicatorWlanActiveSecure:
+ {
+ // Because icon bitmap does not contain enough space,
+ // increase offset as the layout spec states.
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ leftOffset = KMinSpaceBetweenIconsInPixels;
+ }
+ else
+ {
+ rightOffset = KMinSpaceBetweenIconsInPixels;
+ }
+ break;
+ }
+
+ case EAknNaviPaneEditorIndicatorWmlWaitGlobe:
+ {
+ verticalOffset = ( rect.Height() - indicator->IconSize().iHeight ) / 2;
+ indicatorWidth = smallStatusWmlGlobeRect.Width();
+ break;
+ }
+
+ case EAknNaviPaneEditorIndicatorProgressBar:
+ {
+ indicatorWidth = smallStatusWaitPaneRect.Width();
+ indicatorHeight = smallStatusWaitPaneRect.Height();
+ leftOffset = KMinSpaceBetweenIconsInPixels;
+ break;
+ }
+
+ case EAknNaviPaneEditorIndicatorWaitBar:
+ {
+ indicatorWidth = smallStatusWaitPaneRect.Width();
+ indicatorHeight = smallStatusWaitPaneRect.Height();
+ leftOffset = KMinSpaceBetweenIconsInPixels;
+ break;
+ }
+
+ default:
+ {
+ // Default offsets.
+ break;
+ }
+ }
+
+ // End of offset calculations.
+
+ // Place indicators to the left side.
+ if ( ( indicatorPosition == ELeftSide &&
+ iAlignment == TIndicatorAlignment( ERight ) ) ||
+ ( indicatorPosition == ERightSide &&
+ iAlignment == TIndicatorAlignment( ELeft ) ) )
+ {
+ TRect requiredRect(
+ rectForLeftSideIndicators.iBr.iX,
+ rectForLeftSideIndicators.iTl.iY,
+ rectForLeftSideIndicators.iBr.iX + leftOffset + indicatorWidth + rightOffset,
+ rectForLeftSideIndicators.iBr.iY );
+
+ // Check if indicator fits
+ TBool indicatorDoesNotFit =
+ requiredRect.Intersects( rectForRightSideIndicators ) ||
+ requiredRect.Intersects( rectForMiddleIndicators ) ||
+ rect.iTl.iX > requiredRect.iTl.iX ||
+ rect.iBr.iX < requiredRect.iBr.iX;
+
+ if ( indicatorDoesNotFit &&
+ !indicator->DynamicTextIndicator() )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ if ( indicator->DynamicTextIndicator() && indicatorDoesNotFit )
+ {
+ // Dynamic text indicators (not normal text indicators) can adjust to any size.
+ TInt maxWidthForDynamicTextIndicator =
+ rect.iBr.iX - requiredRect.iTl.iX;
+ if ( requiredRect.Intersects( rectForRightSideIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ rectForRightSideIndicators.iTl.iX - requiredRect.iTl.iX;
+ }
+ if ( requiredRect.Intersects( rectForMiddleIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ rectForMiddleIndicators.iTl.iX - requiredRect.iTl.iX;
+ }
+
+ indicator->SetExtent(
+ TPoint( requiredRect.iTl.iX + leftOffset,
+ verticalOffset ),
+ TSize( maxWidthForDynamicTextIndicator,
+ indicatorHeight ) );
+
+ // Adjust remaining space.
+ rectForLeftSideIndicators.iBr.iX =
+ indicator->Position().iX + indicator->Size().iWidth;
+ }
+ else
+ {
+ indicator->SetExtent(
+ TPoint( requiredRect.iTl.iX + leftOffset,
+ verticalOffset ),
+ TSize( indicatorWidth,
+ indicatorHeight ) );
+
+ // Adjust remaining space.
+ rectForLeftSideIndicators.iBr.iX = requiredRect.iBr.iX;
+ }
+ }
+ }
+
+
+ // Place indicators on the right side.
+ if ( ( indicatorPosition == ERightSide &&
+ iAlignment == TIndicatorAlignment( ERight ) ) ||
+ ( indicatorPosition == ELeftSide &&
+ iAlignment == TIndicatorAlignment( ELeft ) ) )
+ {
+ TRect requiredRect(
+ rectForRightSideIndicators.iTl.iX - leftOffset - indicatorWidth - rightOffset,
+ rectForRightSideIndicators.iTl.iY,
+ rectForRightSideIndicators.iTl.iX,
+ rectForRightSideIndicators.iBr.iY );
+
+ // Check if indicator fits.
+ TBool indicatorDoesNotFit =
+ ( requiredRect.Intersects( rectForLeftSideIndicators ) ||
+ requiredRect.Intersects( rectForMiddleIndicators ) ||
+ rect.iTl.iX > requiredRect.iTl.iX ||
+ rect.iBr.iX < requiredRect.iBr.iX );
+
+ if ( indicatorDoesNotFit &&
+ !indicator->DynamicTextIndicator() )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ if ( indicator->DynamicTextIndicator() && indicatorDoesNotFit )
+ {
+ // Dynamic text indicators (not normal text indicators)
+ // can adjust to any size.
+ TInt maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - rect.iTl.iX - leftOffset;
+ if ( requiredRect.Intersects( rectForLeftSideIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - rectForLeftSideIndicators.iBr.iX;
+ }
+ if ( requiredRect.Intersects( rectForMiddleIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - rectForMiddleIndicators.iBr.iX;
+ }
+
+ indicator->SetExtent(
+ TPoint( requiredRect.iBr.iX - maxWidthForDynamicTextIndicator - leftOffset,
+ verticalOffset),
+ TSize( maxWidthForDynamicTextIndicator, indicatorHeight ) );
+
+ // Adjust remaining space.
+ rectForRightSideIndicators.iTl.iX = indicator->Position().iX;
+ }
+ else
+ {
+ indicator->SetExtent(
+ TPoint( requiredRect.iTl.iX + leftOffset,
+ verticalOffset),
+ indicatorSize );
+
+ // Adjust remaining space.
+ rectForRightSideIndicators.iTl.iX = requiredRect.iTl.iX;
+ }
+ }
+ }
+
+ // Place indicators to the middle, only indicator
+ // at the moment is the wml wait globe.
+ if ( indicatorPosition == EMiddle )
+ {
+ TRect requiredRect(
+ rectForMiddleIndicators.iTl.iX,
+ rectForMiddleIndicators.iTl.iY,
+ rectForMiddleIndicators.iTl.iX + leftOffset + indicatorWidth + rightOffset,
+ rectForMiddleIndicators.iBr.iY );
+
+ // Check if indicator fits.
+ if ( ( requiredRect.Intersects( rectForRightSideIndicators ) ||
+ requiredRect.Intersects( rectForLeftSideIndicators ) ) ||
+ rectForMiddleIndicators.Width() != 0 )
+ {
+ // No space available in the middle.
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ indicator->SetExtent(
+ TPoint( rectForMiddleIndicators.iTl.iX + leftOffset,
+ verticalOffset ),
+ indicatorSize );
+
+ // Adjust remaining space.
+ rectForMiddleIndicators.iTl.iX += rightOffset + indicatorWidth;
+ }
+ }
+
+ iIndicatorsShown++;
+
+ if ( indicator->IndicatorState() == MAknIndicator::EIndicatorAnimate )
+ {
+ iAnimatedIndicatorsShown++;
+ }
+ } // for
+
+ // Code for setting indicator positions ends.
+
+ ResetAnimTicker( iExtension->iIsForeground );
+ }
+ }
+
+
+void CAknIndicatorContainer::SizeChangedInIdleExtendedStatusPane()
+ {
+ TRect containerRect( Rect() );
+
+ if (iIndicatorContext == EUniversalIndicators)
+ {
+ iLayoutOrientation = EHorizontal;
+ }
+
+ // Available space for indicators
+ TRect rect(containerRect);
+
+ // If layout orientation has been changed since last call, prioritize indicators again.
+ if ( iLayoutOrientation != iPreviousLayoutOrientation )
+ {
+ TRAP_IGNORE ( PrioritizeIndicatorsL() );
+ }
+
+ iIndicatorsShown = 0;
+ iAnimatedIndicatorsShown = 0;
+ TInt last = iIndicators->Count() - 1;
+
+ if (iIndicatorContext == EUniversalIndicators)
+ {
+ TRect parent( rect );
+
+ TAknLayoutScalableParameterLimits limit =
+ AknLayoutScalable_Avkon::cell_indicator_nsta_pane_ParamLimits();
+ TInt maxIndicatorsShownInOneLine = 3; // magic
+
+ TAknLayoutRect layoutRect;
+ TAknWindowLineLayout cellLayout;
+ TAknWindowLineLayout indicatorLayout;
+
+ TInt totalIndicatorsOn = 0;
+
+ // Need to go through the indicator array two times
+ // to be able to place the indicators in correct order.
+ for ( TInt i = 0; i <= last; i++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( i );
+
+ if ( indicator->IndicatorState() &&
+ indicator->Priority() != KIndicatorNotShown )
+ {
+ totalIndicatorsOn++;
+ }
+ }
+
+ for ( TInt ii = 0; ii <= last; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At(ii);
+ if ( !indicator->IndicatorState() || (indicator->Priority() == KIndicatorNotShown))
+ {
+ // Indicator is not shown on current layout even it is set ON.
+ continue;
+ }
+
+ iIndicatorsShown++;
+
+ if (iIndicatorsShown > maxIndicatorsShownInOneLine * 2)
+ {
+ indicator->SetExtent(TPoint(0,0), TSize(0,0));
+ break;
+ }
+ else
+ {
+ TInt indicatorRow = ( iIndicatorsShown - 1 ) / maxIndicatorsShownInOneLine;
+
+ TInt columnVariety =
+ iIndicatorsShown - maxIndicatorsShownInOneLine * indicatorRow - 1;
+
+ if ( ( totalIndicatorsOn < maxIndicatorsShownInOneLine &&
+ indicatorRow == 0 ) ||
+ ( totalIndicatorsOn > maxIndicatorsShownInOneLine &&
+ totalIndicatorsOn < maxIndicatorsShownInOneLine * 2 &&
+ indicatorRow == 1 ) )
+ {
+ if ( totalIndicatorsOn == 1 ||
+ totalIndicatorsOn == maxIndicatorsShownInOneLine + 1 )
+ {
+ columnVariety = maxIndicatorsShownInOneLine - 1;
+ }
+ else
+ {
+ columnVariety =
+ iIndicatorsShown - maxIndicatorsShownInOneLine * indicatorRow;
+ }
+ }
+
+ // set indicator sizes here...rightmost cell first
+ cellLayout = AknLayoutScalable_Avkon::cell_indicator_nsta_pane(
+ columnVariety,
+ 2,
+ indicatorRow ).LayoutLine();
+ layoutRect.LayoutRect( parent, cellLayout );
+ TRect cell( layoutRect.Rect() );
+
+ indicatorLayout =
+ AknLayoutScalable_Avkon::cell_indicator_nsta_pane_g2().LayoutLine();
+ layoutRect.LayoutRect(cell,indicatorLayout);
+ TRect indicatorRect( layoutRect.Rect() );
+
+ // FIXME: Layout is broken, we fix it here. Remove this when layout is fixed.
+ if (indicatorRect.iBr.iX > cell.iBr.iX)
+ indicatorRect.iBr.iX = cell.iBr.iX;
+ if (indicatorRect.iTl.iX < cell.iTl.iX)
+ indicatorRect.iTl.iX = cell.iTl.iX;
+ // End of FIXME
+
+ // TBD: When touch is supported, the size may have to be reconsidered.
+ indicator->SetRect(indicatorRect);
+ }
+
+ if (indicator->IndicatorState() == MAknIndicator::EIndicatorAnimate)
+ {
+ iAnimatedIndicatorsShown++;
+ }
+ } // for
+
+ ResetAnimTicker( iExtension->iIsForeground );
+ } // if universal indicators
+ }
+
+
+void CAknIndicatorContainer::SizeChangedInFlatStatusPane()
+ {
+ TRect containerRect(Rect());
+
+ if (iIndicatorContext == EUniversalIndicators)
+ {
+ iLayoutOrientation = EVertical;
+ }
+
+ // Available space for indicators
+ TRect rect(containerRect);
+
+ // If layout orientation has been changed since last call, prioritize indicators again.
+ if ( iLayoutOrientation != iPreviousLayoutOrientation )
+ {
+ TRAP_IGNORE ( PrioritizeIndicatorsL() );
+ }
+
+ iIndicatorsShown = 0;
+ iAnimatedIndicatorsShown = 0;
+ TInt last = iIndicators->Count() - 1;
+
+ if (iIndicatorContext == EUniversalIndicators)
+ {
+ TAknLayoutRect layoutRect;
+ TAknWindowComponentLayout indicatorLayout;
+ TBool extendedFlatLayout(
+ AknStatuspaneUtils::ExtendedFlatLayoutActive() );
+
+ for (TInt ii = 0; ii <= last; ii++)
+ {
+ CAknIndicator* indicator = iIndicators->At(ii);
+ if ( !indicator->IndicatorState() || (indicator->Priority() == KIndicatorNotShown))
+ {
+ // Indicator is not shown on current layout even it is set ON.
+ continue;
+ }
+
+ iIndicatorsShown++;
+
+ TBool showIndicator( ETrue );
+
+ switch ( iIndicatorsShown )
+ {
+ case 1:
+ {
+ if ( extendedFlatLayout )
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::indicator_nsta_pane_cp_g1( 0 );
+ }
+ else
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::uni_indicator_pane_g1( 1 );
+ }
+ break;
+ }
+ case 2:
+ {
+ if ( extendedFlatLayout )
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::indicator_nsta_pane_cp_g2( 0 );
+ }
+ else
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::uni_indicator_pane_g2( 1 );
+ }
+ break;
+ }
+ case 3:
+ {
+ if ( extendedFlatLayout )
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::indicator_nsta_pane_cp_g3( 0 );
+ }
+ else
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::uni_indicator_pane_g3( 1 );
+ }
+ break;
+ }
+ case 4:
+ {
+ if ( extendedFlatLayout )
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::indicator_nsta_pane_cp_g4( 0 );
+ }
+ else
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::uni_indicator_pane_g4( 1 );
+ }
+ break;
+ }
+ case 5:
+ {
+ if ( extendedFlatLayout )
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::indicator_nsta_pane_cp_g5( 0 );
+ }
+ else
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::uni_indicator_pane_g5( 1 );
+ }
+ break;
+ }
+ case 6:
+ {
+ if ( extendedFlatLayout )
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::indicator_nsta_pane_cp_g6( 0 );
+ }
+ else
+ {
+ indicatorLayout =
+ AknLayoutScalable_Avkon::uni_indicator_pane_g6( 1 );
+ }
+ break;
+ }
+ default:
+ {
+ showIndicator = EFalse;
+ break;
+ }
+ }
+
+ if ( showIndicator )
+ {
+ layoutRect.LayoutRect( containerRect, indicatorLayout );
+ indicator->SetRect( layoutRect.Rect() );
+ }
+ else // Maximum indicator are shown, others are invisible.
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ }
+
+ if (indicator->IndicatorState() == MAknIndicator::EIndicatorAnimate)
+ {
+ iAnimatedIndicatorsShown++;
+ }
+ } // for
+
+ ResetAnimTicker( iExtension->iIsForeground );
+ } // if universal indicators
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SizeChangedInStaconPane
+// Handles size change events in stacon pane layouts.
+// ---------------------------------------------------------------------------
+//
+void CAknIndicatorContainer::SizeChangedInStaconPane()
+ {
+ TRect containerRect( Rect() );
+
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ if ( AknStatuspaneUtils::IdleLayoutActive() )
+ {
+ iLayoutOrientation = EHorizontal;
+ }
+ else
+ {
+ iLayoutOrientation = EVertical;
+ }
+ }
+
+ // Available space for indicators.
+ TRect rect( containerRect );
+
+ // If layout orientation has been changed since last call,
+ // prioritize indicators again.
+ if ( iLayoutOrientation != iPreviousLayoutOrientation )
+ {
+ // Following leave is ignored.
+ // In case of leave indicators are not maybe shown correctly.
+ TRAP_IGNORE ( PrioritizeIndicatorsL() );
+ }
+
+ iIndicatorsShown = 0;
+ iAnimatedIndicatorsShown = 0;
+ TInt last = iIndicators->Count() - 1;
+
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ TRect parent( rect );
+
+ // Layout data for four indicators in stacon pane layout exists,
+ // but for only two indicators are shown.
+ for ( TInt ii = 0; ii <= last; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( ii );
+ if ( !indicator->IndicatorState() ||
+ indicator->Priority() == KIndicatorNotShown )
+ {
+ // Indicator is not shown on current layout even it is set ON.
+ continue;
+ }
+
+ iIndicatorsShown++;
+
+ // No fading is done to indicators until transparent
+ // windows are available, faders always set to NULL for now.
+ CAknIndicatorFader* topFader = NULL;
+ CAknIndicatorFader* bottomFader = NULL;
+
+ if ( AknStatuspaneUtils::StaconSoftKeysRight() )
+ {
+ if ( iIndicatorsShown == 1 )
+ {
+ indicator->SetIndicatorFader( topFader );
+ AknLayoutUtils::LayoutControl(
+ indicator,
+ parent,
+ AknLayoutScalable_Avkon::uni_indicator_pane_stacon_g1() );
+ }
+ else if ( iIndicatorsShown == 2 )
+ {
+ indicator->SetIndicatorFader( bottomFader );
+ AknLayoutUtils::LayoutControl(
+ indicator,
+ parent,
+ AknLayoutScalable_Avkon::uni_indicator_pane_stacon_g2() );
+ }
+ }
+ else if ( AknStatuspaneUtils::StaconSoftKeysLeft() )
+ {
+ // LAF does not contain mirrored lines. We mirror positions here.
+ if ( iIndicatorsShown == 1 )
+ {
+ indicator->SetIndicatorFader( topFader );
+ AknLayoutUtils::LayoutControl(
+ indicator,
+ parent,
+ AknLayoutScalable_Avkon::uni_indicator_pane_stacon_g3() );
+ }
+ else if ( iIndicatorsShown == 2 )
+ {
+ indicator->SetIndicatorFader( bottomFader );
+ AknLayoutUtils::LayoutControl(
+ indicator,
+ parent,
+ AknLayoutScalable_Avkon::uni_indicator_pane_stacon_g4() );
+ }
+ }
+
+ if ( iIndicatorsShown > 2 )
+ {
+ indicator->SetIndicatorFader( NULL );
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ break;
+ }
+
+ if ( indicator->IndicatorState() == MAknIndicator::EIndicatorAnimate )
+ {
+ iAnimatedIndicatorsShown++;
+ }
+ } // for
+
+ ResetAnimTicker( iExtension->iIsForeground );
+ } // if universal indicators
+ // Currently uses small statuspane layouts in navipane indicators because not all exist for stacon yet.
+ else if ( iIndicatorContext == ENaviPaneEditorIndicators )
+ {
+ TBool isMirrored( AknLayoutUtils::LayoutMirrored() );
+
+ iLayoutOrientation = EHorizontal; // always horizontal
+
+ TRect containerRect( Rect() );
+
+ // Check if the secured connection indicator is on before
+ // reading the layouts because of different positioning
+ // of wait and progress bars with that indicator on.
+ TBool secureConnectionIndicOn( EFalse );
+ for ( TInt i = 0; i <= last; i++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( i );
+
+ if ( indicator->Uid().iUid == EAknNaviPaneEditorIndicatorSecuredConnection &&
+ indicator->IndicatorState() &&
+ indicator->Priority() != KIndicatorNotShown )
+ {
+ secureConnectionIndicOn = ETrue;
+ }
+ }
+
+ // screen
+ TRect screenRect;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect );
+
+ // app window
+ TRect applicationWindowRect;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EApplicationWindow,
+ applicationWindowRect );
+
+ // small statuspane
+ TAknLayoutRect smallStatusPaneLayoutRect;
+ smallStatusPaneLayoutRect.LayoutRect(
+ applicationWindowRect,
+ TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Avkon::area_top_pane( 1 ),
+ AknLayoutScalable_Avkon::status_small_pane() ) );
+ TRect smallStatusPaneRect( smallStatusPaneLayoutRect.Rect() );
+
+ // small statuspane, wait pane
+ TAknLayoutRect smallStatusWaitPaneLayoutRect;
+ smallStatusWaitPaneLayoutRect.LayoutRect(
+ smallStatusPaneRect,
+ AknLayoutScalable_Avkon::status_small_wait_pane(
+ secureConnectionIndicOn ? 2 : 1 ) );
+ TRect smallStatusWaitPaneRect( smallStatusWaitPaneLayoutRect.Rect() );
+
+ // small statuspane, globe
+ TAknLayoutRect smallStatusWmlGlobeLayoutRect;
+ smallStatusWmlGlobeLayoutRect.LayoutRect(
+ smallStatusPaneRect,
+ AknLayoutScalable_Avkon::status_small_pane_g4( 0 ) );
+ TRect smallStatusWmlGlobeRect( smallStatusWmlGlobeLayoutRect.Rect() );
+
+ // small statuspane, GPRS indicator
+ TAknLayoutRect smallStatusGprsLayoutRect;
+ smallStatusGprsLayoutRect.LayoutRect(
+ smallStatusPaneRect,
+ AknLayoutScalable_Avkon::status_small_pane_g2( 0 ) );
+ TRect smallStatusGprsRect( smallStatusGprsLayoutRect.Rect() );
+
+ // small statuspane, secure state indicator
+ TAknLayoutRect smallStatusSecureStateLayoutRect;
+ smallStatusSecureStateLayoutRect.LayoutRect(
+ smallStatusPaneRect,
+ AknLayoutScalable_Avkon::status_small_pane_g3( 0 ) );
+ TRect smallStatusSecureStateRect( smallStatusSecureStateLayoutRect.Rect() );
+
+
+ // small statuspane, texts
+ TAknLayoutText textLayout;
+ textLayout.LayoutText(
+ containerRect,
+ AknLayoutScalable_Avkon::status_small_pane_t1( 0 ) );
+ TRect smallStatusTextRect( textLayout.TextRect() );
+
+ TInt textIndicatorLeftOffset = smallStatusTextRect.iTl.iX;
+ TInt textIndicatorVerticalOffset = smallStatusTextRect.iTl.iY;
+
+ TInt wmlWaitGlobeLeftOffset =
+ containerRect.Width() / 2 - smallStatusWmlGlobeRect.Width() / 2;
+
+ // Modify containerRect if alignment is Right.
+ // For Left aligned no need to modify containerRect.
+ if ( iAlignment == TIndicatorAlignment( ERight ) )
+ {
+ containerRect.iBr.iX -= 3; // Right margin of editor indicators
+ containerRect.iTl.iX += 0; // Left margin of editor indicators
+ }
+
+ iIndicatorsShown = 0;
+ iAnimatedIndicatorsShown = 0;
+ TBool textIndicatorOffsetNeeded = ETrue;
+
+ TRect rectForRightSideIndicators( containerRect.iBr.iX,
+ containerRect.iTl.iY,
+ containerRect.iBr.iX,
+ containerRect.iBr.iY );
+
+ TRect rectForLeftSideIndicators( containerRect.iTl.iX,
+ containerRect.iTl.iY,
+ containerRect.iTl.iX,
+ containerRect.iBr.iY );
+
+ TRect rectForMiddleIndicators( wmlWaitGlobeLeftOffset,
+ containerRect.iTl.iY,
+ wmlWaitGlobeLeftOffset,
+ containerRect.iBr.iY );
+
+ for ( TInt ii = 0; ii <= last; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( ii );
+ TInt uid = indicator->Uid().iUid;
+ TInt indicatorPosition = 0;
+
+ // decide here how indicators are positioned. Default is rigth side.
+ indicatorPosition = indicator->IndicatorPosition();
+
+ // Check if indicator is not shown on current layout even it is set ON.
+ if ( !indicator->IndicatorState() ||
+ indicator->Priority() == KIndicatorNotShown )
+ {
+ continue;
+ }
+
+ // Check if this is gprs indicator, it is never shown here but is drawn
+ // to the signal pane by the system
+ if ( uid == EAknNaviPaneEditorIndicatorGprs )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorWlanAvailable ||
+ uid == EAknNaviPaneEditorIndicatorWlanActive ||
+ uid == EAknNaviPaneEditorIndicatorWlanActiveSecure )
+ {
+ // These are not shown in stacon layout navi pane, as
+ // the same indicators are shown on the universal
+ // indicator pane.
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+
+ // handle offsets
+ TAknWindowLineLayout areaTopPaneLayout = AknLayoutScalable_Avkon::area_top_pane( 0 );
+ TAknLayoutRect areaTopPaneLayoutRect;
+ areaTopPaneLayoutRect.LayoutRect( screenRect, areaTopPaneLayout );
+
+ TAknWindowLineLayout statusPaneIconSmallLayout(
+ TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Avkon::area_top_pane( 1 ),
+ TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Avkon::status_small_pane(),
+ AknLayoutScalable_Avkon::status_small_icon_pane() ) ).LayoutLine() );
+
+ // If top pane area's vertical position doesn't start at 0,
+ // the statusPaneIconSmallRect's values will be incorrect and
+ // must be adjusted.
+ TInt offsetFromTop = areaTopPaneLayoutRect.Rect().iTl.iY;
+ TRect normSmallStatusPaneRect( smallStatusPaneRect );
+ normSmallStatusPaneRect.iTl.iY -= offsetFromTop;
+ statusPaneIconSmallLayout.it -= offsetFromTop;
+
+ TAknLayoutRect statusPaneIconSmallLayoutRect;
+ statusPaneIconSmallLayoutRect.LayoutRect(
+ normSmallStatusPaneRect, statusPaneIconSmallLayout );
+
+ TInt verticalOffset = statusPaneIconSmallLayoutRect.Rect().iTl.iY;
+
+ TInt leftOffset = 0; // default offset
+ TInt rightOffset = 0; // default offset
+
+ TInt indicatorWidth = indicator->IconSize().iWidth; // default width
+ TInt indicatorHeight = indicator->IconSize().iHeight; // default height
+
+ if ( uid == EAknNaviPaneEditorIndicatorMessageInfo ||
+ uid == EAknNaviPaneEditorIndicatorWmlWindowsText ||
+ uid == EAknNaviPaneEditorIndicatorMessageLength )
+ {
+ verticalOffset = textIndicatorVerticalOffset;
+ // first text idicator need horizontal offset
+ if ( textIndicatorOffsetNeeded )
+ {
+ leftOffset += textIndicatorLeftOffset;
+ }
+ textIndicatorOffsetNeeded = EFalse;
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorFileSize )
+ {
+ verticalOffset = textIndicatorVerticalOffset;
+
+ // Need left offset in western, right offset in A&H layout.
+ if ( isMirrored )
+ {
+ rightOffset = textIndicatorLeftOffset;
+ }
+ else
+ {
+ leftOffset = KMinSpaceBetweenIconsInPixels;
+ }
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorSecuredConnection )
+ {
+ verticalOffset = smallStatusSecureStateRect.iTl.iY;
+ // Because icon bitmap does not contain enough space,
+ // increase offset as the layout spec states.
+ if ( isMirrored )
+ {
+ leftOffset = KMinSpaceBetweenIconsInPixels;
+ }
+ else
+ {
+ rightOffset = KMinSpaceBetweenIconsInPixels;
+ }
+ textIndicatorOffsetNeeded = EFalse;
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorWmlWaitGlobe )
+ {
+ verticalOffset = (containerRect.Height() - indicator->IconSize().iHeight)/2;
+ indicatorWidth = smallStatusWmlGlobeRect.Width();
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorProgressBar )
+ {
+ verticalOffset = smallStatusWaitPaneRect.iTl.iY;
+ indicatorWidth = smallStatusWaitPaneRect.Width();
+ indicatorHeight = smallStatusWaitPaneRect.Height();
+ leftOffset = 0;
+ textIndicatorOffsetNeeded = ETrue;
+ }
+ else if ( uid == EAknNaviPaneEditorIndicatorWaitBar )
+ {
+ verticalOffset = smallStatusWaitPaneRect.iTl.iY;
+ indicatorWidth = smallStatusWaitPaneRect.Width();
+ indicatorHeight = smallStatusWaitPaneRect.Height();
+ leftOffset = 0;
+ textIndicatorOffsetNeeded = ETrue;
+ }
+
+ if ( isMirrored )
+ {
+ TInt temp = leftOffset;
+ leftOffset = rightOffset;
+ rightOffset = temp;
+ }
+
+ // Place indicators to the left side.
+ if ( ( indicatorPosition == ELeftSide &&
+ iAlignment == TIndicatorAlignment( ERight ) ) ||
+ ( indicatorPosition == ERightSide &&
+ iAlignment == TIndicatorAlignment( ELeft ) ) )
+ {
+ TRect requiredRect(
+ rectForLeftSideIndicators.iBr.iX,
+ rectForLeftSideIndicators.iTl.iY,
+ rectForLeftSideIndicators.iBr.iX + leftOffset + indicatorWidth + rightOffset,
+ rectForLeftSideIndicators.iBr.iY );
+
+ // Check if indicator fits.
+ TBool indicatorDoesNotFit =
+ ( requiredRect.Intersects( rectForRightSideIndicators ) ||
+ requiredRect.Intersects( rectForMiddleIndicators ) ||
+ containerRect.iTl.iX > requiredRect.iTl.iX ||
+ containerRect.iBr.iX < requiredRect.iBr.iX );
+
+ if ( indicatorDoesNotFit &&
+ !indicator->DynamicTextIndicator() )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ if ( indicator->DynamicTextIndicator() && indicatorDoesNotFit )
+ {
+ // Dynamic text indicators (not normal text indicators)
+ // can adjust to any size.
+ TInt maxWidthForDynamicTextIndicator =
+ containerRect.iBr.iX - requiredRect.iTl.iX;
+
+ if ( requiredRect.Intersects( rectForRightSideIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ rectForRightSideIndicators.iTl.iX - requiredRect.iTl.iX;
+ }
+
+ if ( requiredRect.Intersects( rectForMiddleIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ rectForMiddleIndicators.iTl.iX - requiredRect.iTl.iX;
+ }
+
+ indicator->SetExtent(
+ TPoint( requiredRect.iTl.iX + leftOffset, verticalOffset ),
+ TSize( maxWidthForDynamicTextIndicator, indicatorHeight ) );
+
+ rectForLeftSideIndicators.iBr.iX =
+ indicator->Position().iX + indicator->Size().iWidth;
+ }
+ else
+ {
+ indicator->SetExtent(
+ TPoint( requiredRect.iTl.iX + leftOffset, verticalOffset ),
+ TSize( indicatorWidth, indicatorHeight ) );
+
+ rectForLeftSideIndicators.iBr.iX = requiredRect.iBr.iX;
+ }
+ }
+ }
+
+
+ // Place indicators to the right side.
+ if ( ( indicatorPosition == ERightSide &&
+ iAlignment == TIndicatorAlignment( ERight ) ) ||
+ ( indicatorPosition == ELeftSide &&
+ iAlignment == TIndicatorAlignment( ELeft ) ) )
+ {
+ TRect requiredRect(
+ rectForRightSideIndicators.iTl.iX - leftOffset - indicatorWidth - rightOffset,
+ rectForRightSideIndicators.iTl.iY,
+ rectForRightSideIndicators.iTl.iX,
+ rectForRightSideIndicators.iBr.iY );
+
+ // Check if indicator fits.
+ TBool indicatorDoesNotFit =
+ ( requiredRect.Intersects( rectForLeftSideIndicators ) ||
+ requiredRect.Intersects( rectForMiddleIndicators ) ||
+ containerRect.iTl.iX > requiredRect.iTl.iX ||
+ containerRect.iBr.iX < requiredRect.iBr.iX );
+
+ if ( indicatorDoesNotFit &&
+ !indicator->DynamicTextIndicator() )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ if ( indicator->DynamicTextIndicator() &&
+ indicatorDoesNotFit )
+ {
+ // Dynamic text indicators (not normal text indicators)
+ // can adjust to any size.
+ TInt maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - containerRect.iTl.iX - leftOffset;
+
+ if ( requiredRect.Intersects( rectForLeftSideIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - rectForLeftSideIndicators.iBr.iX;
+ }
+ if ( requiredRect.Intersects( rectForMiddleIndicators ) )
+ {
+ maxWidthForDynamicTextIndicator =
+ requiredRect.iBr.iX - rectForMiddleIndicators.iBr.iX;
+ }
+
+ indicator->SetExtent(
+ TPoint( requiredRect.iBr.iX - maxWidthForDynamicTextIndicator + leftOffset,
+ verticalOffset),
+ TSize( maxWidthForDynamicTextIndicator, indicatorHeight ) );
+ rectForRightSideIndicators.iTl.iX = indicator->Position().iX;
+ }
+ else
+ {
+ indicator->SetExtent(
+ TPoint( requiredRect.iTl.iX + leftOffset, verticalOffset ),
+ TSize( indicatorWidth, indicatorHeight ) );
+
+ rectForRightSideIndicators.iTl.iX = requiredRect.iTl.iX;
+ }
+ }
+ }
+
+
+ // place indicators to the middle, only indicator is wml wait globe
+ if ( indicatorPosition == EMiddle )
+ {
+ TRect requiredRect(
+ rectForMiddleIndicators.iTl.iX,
+ rectForMiddleIndicators.iTl.iY,
+ rectForMiddleIndicators.iTl.iX + leftOffset + indicatorWidth + rightOffset,
+ rectForMiddleIndicators.iBr.iY );
+
+ // check if indicator fits
+ if ( requiredRect.Intersects( rectForRightSideIndicators ) ||
+ requiredRect.Intersects( rectForLeftSideIndicators ) ||
+ rectForMiddleIndicators.Width() != 0 )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ iIndicatorsShown++;
+ continue;
+ }
+ else
+ {
+ indicator->SetExtent( TPoint( rectForMiddleIndicators.iTl.iX + leftOffset,
+ verticalOffset ),
+ TSize( indicatorWidth, indicatorHeight ) );
+
+ rectForMiddleIndicators.iTl.iX += ( rightOffset + indicatorWidth );
+ }
+ }
+
+ iIndicatorsShown++;
+
+ if ( indicator->IndicatorState() == MAknIndicator::EIndicatorAnimate )
+ {
+ iAnimatedIndicatorsShown++;
+ }
+ } // for
+ }
+
+ ResetAnimTicker( iExtension->iIsForeground );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SetIncallBubbleAllowedInIdle
+// Allows/disallows showing the small incall status bubble of this container
+// in idle status pane layouts.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknIndicatorContainer::SetIncallBubbleAllowedInIdle(
+ TBool aAllowed )
+ {
+ if ( iExtension )
+ {
+ iExtension->iIncallBubbleAllowedInIdle = aAllowed;
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SetIncallBubbleAllowedInUsual
+// Allows/disallows showing the small incall status bubble of this container
+// in usual status pane layouts.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknIndicatorContainer::SetIncallBubbleAllowedInUsual(
+ TBool aAllowed )
+ {
+ if ( iExtension )
+ {
+ iExtension->iIncallBubbleAllowedInUsual = aAllowed;
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SetIndicatorObserver
+// Sets aIndicatorObserver to observe indicator with aIndicatorUid
+// by looping through indicators to find indicator with aIndicaotrUid
+// and calling SetIndicatorObserver to it with given pointer to observer
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknIndicatorContainer::SetIndicatorObserver(
+ MAknIndicatorObserver* aIndicatorObserver,
+ TUid aIndicatorUid )
+ {
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ TInt count = iIndicators->Count();
+
+ // Loop through indicators and find indicator with given UID.
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( ii );
+
+ // If indicator found, set aIndicatorObserver to observe it.
+ if ( indicator->Uid() == aIndicatorUid )
+ {
+ indicator->SetIndicatorObserver( aIndicatorObserver );
+ break;
+ }
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SetContainerWindowNonFading
+// Allows/disallows fading of this pane.
+// ---------------------------------------------------------------------------
+//
+void CAknIndicatorContainer::SetContainerWindowNonFading( TBool aNonFading )
+ {
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+ if ( statusPane )
+ {
+ CCoeControl* control = NULL;
+ TRAP_IGNORE(
+ control = statusPane->ContainerControlL(
+ TUid::Uid( EEikStatusPaneUidIndic ) ) );
+
+ if ( control )
+ {
+ control->DrawableWindow()->SetNonFading( aNonFading );
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SetupIndicatorLayoutModes
+// Sets the appropriate layout mode to all the indicators inside
+// this container.
+// ---------------------------------------------------------------------------
+//
+void CAknIndicatorContainer::SetupIndicatorLayoutModes()
+ {
+ TInt mode = SelectIndicatorLayoutMode();
+ TInt count = iIndicators->Count();
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ iIndicators->At( ii )->SetLayoutMode(
+ (CAknIndicator::TLayoutMode) mode );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SelectIndicatorLayoutMode
+// Decides the layout mode to be used for indicators inside this container.
+// ---------------------------------------------------------------------------
+//
+TInt CAknIndicatorContainer::SelectIndicatorLayoutMode()
+ {
+ // Usually this can be used to decide mode...
+ TInt mode = ( Rect().Height() > Rect().Width() ) ?
+ CAknIndicator::ELayoutModeUsual :
+ CAknIndicator::ELayoutModeWide;
+
+ // But one exception is idle where we can have vertical indicators using "wide" mode.
+ if ( iIndicatorContext == EUniversalIndicators &&
+ AknStatuspaneUtils::IdleLayoutActive() )
+ {
+ mode = CAknIndicator::ELayoutModeWide;
+
+ // But exception to exception is portraitmode video telephony layout
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+ if ( statusPane )
+ {
+ TInt currentStatusPaneLayoutResId = statusPane->CurrentLayoutResId();
+ if ( currentStatusPaneLayoutResId == R_AVKON_STATUS_PANE_LAYOUT_VT ||
+ currentStatusPaneLayoutResId == R_AVKON_STATUS_PANE_LAYOUT_VT_MIRRORED )
+ {
+ mode = CAknIndicator::ELayoutModeUsual;
+ }
+ }
+ }
+ // Another thing is if universal indicators but not idle
+ else if ( iIndicatorContext == EUniversalIndicators &&
+ !AknStatuspaneUtils::IdleLayoutActive() )
+ {
+ mode = CAknIndicator::ELayoutModeUsual;
+ }
+ else if ( iIndicatorContext == EQueryEditorIndicators )
+ {
+ mode = CAknIndicator::ELayoutModeUsual;
+ }
+
+ return mode;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::SizeChangedInIdleVertical
+// Handles size change events of vertically arranged universal indicator
+// pane in idle status pane layout.
+// ---------------------------------------------------------------------------
+//
+void CAknIndicatorContainer::SizeChangedInIdleVertical()
+ {
+ TRect containerRect( Rect() );
+
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ iLayoutOrientation = EVertical;
+ }
+
+ // Available space for indicators
+ TRect rect( containerRect );
+
+ // If layout orientation has been changed since last call,
+ // prioritize indicators again.
+ if ( iLayoutOrientation != iPreviousLayoutOrientation )
+ {
+ TRAP_IGNORE ( PrioritizeIndicatorsL() );
+ }
+
+ iIndicatorsShown = 0;
+ iAnimatedIndicatorsShown = 0;
+ TInt last = iIndicators->Count() - 1;
+
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ TRect parent( rect );
+ TAknLayoutRect layoutRect;
+
+ layoutRect.LayoutRect(
+ parent, AknLayoutScalable_Avkon::grid_indicator_pane() );
+ parent = layoutRect.Rect();
+
+ TRect indicatorRect( 0,0,0,0 );
+
+ TInt maxNumberOfIndicatorsShown =
+ AknLayoutScalable_Avkon::cell_indicator_pane_ParamLimits().LastRow();
+
+ for ( TInt ii = 0; ii <= last; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( ii );
+ if ( !indicator->IndicatorState() ||
+ indicator->Priority() == KIndicatorNotShown )
+ {
+ // Indicator is not shown on current layout even it is set ON.
+ continue;
+ }
+
+ layoutRect.LayoutRect(
+ parent,
+ AknLayoutScalable_Avkon::cell_indicator_pane( iIndicatorsShown ) );
+ indicatorRect = layoutRect.Rect();
+ indicator->SetRect( indicatorRect );
+
+ iIndicatorsShown++;
+
+ if ( iIndicatorsShown > maxNumberOfIndicatorsShown )
+ {
+ indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
+ break;
+ }
+
+ if ( indicator->IndicatorState() == MAknIndicator::EIndicatorAnimate )
+ {
+ iAnimatedIndicatorsShown++;
+ }
+ } // for
+
+ ResetAnimTicker( iExtension->iIsForeground );
+
+ } // if universal indicators
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::CreateIndicatorFromResourceL
+// Constructs a status indicator from an indicator resource.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUid CAknIndicatorContainer::CreateIndicatorFromResourceL(
+ TInt aIndicatorResourceId,
+ TInt aCustomIndicatorFlags )
+ {
+ CAknIndicator* newIndicator =
+ new (ELeave) CAknIndicator ( iIndicatorContext );
+ CleanupStack::PushL( newIndicator );
+ newIndicator->SetContainerWindowL( *this );
+
+ TResourceReader reader;
+ iCoeEnv->CreateResourceReaderLC( reader, aIndicatorResourceId );
+ newIndicator->ConstructFromResourceL( reader, this );
+ CleanupStack::PopAndDestroy(); // resource reader
+
+ // Always assign a dynamic UID to avoid clash with pre-defined indicators
+ TInt dynamicUid = EAknNaviPaneEditorIndicatorDynamicUidRangeFirst;
+ TInt count = iIndicators->Count();
+
+ // Loop through indicators and try to find a free dynamic UID.
+ while ( dynamicUid <= EAknNaviPaneEditorIndicatorDynamicUidRangeLast )
+ {
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ CAknIndicator* indicator = iIndicators->At( ii );
+ if ( indicator->iUid == dynamicUid )
+ {
+ dynamicUid++;
+ break;
+ }
+ }
+ break;
+ }
+
+ if ( dynamicUid <= EAknNaviPaneEditorIndicatorDynamicUidRangeLast )
+ {
+ newIndicator->iUid = dynamicUid;
+ }
+ else
+ {
+ User::Leave( KErrGeneral ); // All dynamic UIDs already in use.
+ }
+
+
+ // Handle flags here
+ if ( aCustomIndicatorFlags & EMultiColorIndicator )
+ {
+ newIndicator->SetMultiColorMode( ETrue );
+ }
+
+ if ( aCustomIndicatorFlags & EIndicatorPositionInverted )
+ {
+ newIndicator->SetIndicatorPosition( ELeftSide );
+ }
+ else
+ {
+ newIndicator->SetIndicatorPosition( ERightSide );
+ }
+
+ // Finally add the new indicator and prioritize all.
+ TUid uid = TUid::Uid( newIndicator->iUid );
+ iIndicators->AppendL( newIndicator );
+ CleanupStack::Pop( newIndicator );
+ newIndicator = NULL;
+
+ PrioritizeIndicatorsL();
+
+ return uid;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::ReplaceIndicatorIconL
+// Replaces the icon of an existing indicator.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknIndicatorContainer::ReplaceIndicatorIconL(
+ TUid aIndicator,
+ TInt /*aState*/,
+ TInt aLayoutMode,
+ CFbsBitmap* aIconBitmap,
+ CFbsBitmap* aIconMask,
+ TInt aIconIndex )
+ {
+ TInt count = iIndicators->Count();
+ CAknIndicator* indicator = NULL;
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ indicator = iIndicators->At( ii );
+ if ( indicator && indicator->iUid == aIndicator.iUid )
+ {
+ // This ensures all default bitmaps are created.
+ indicator->CreateLoadedIndicatorBitmapsL();
+
+ if ( aIconBitmap &&
+ indicator->iIndicatorBitmaps[aLayoutMode]->At( aIconIndex ) )
+ {
+ delete indicator->iIndicatorBitmaps[aLayoutMode]->At( aIconIndex );
+ indicator->iIndicatorBitmaps[aLayoutMode]->At( aIconIndex ) = aIconBitmap;
+ }
+
+ if ( aIconMask &&
+ indicator->iIndicatorBitmaps[aLayoutMode]->At( aIconIndex + 1 ) )
+ {
+ delete indicator->iIndicatorBitmaps[aLayoutMode]->At( aIconIndex + 1 );
+ indicator->iIndicatorBitmaps[aLayoutMode]->At( aIconIndex + 1 ) = aIconMask;
+ }
+
+ break;
+ }
+ }
+
+ if ( indicator &&
+ indicator->IndicatorState() ||
+ indicator->Priority() != KIndicatorNotShown )
+ {
+ SizeChanged();
+ DrawDeferred();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::CreateIndicatorFromPaneResourceL
+// Creates a status indicator from an indicator pane resource.
+// ---------------------------------------------------------------------------
+//
+void CAknIndicatorContainer::CreateIndicatorFromPaneResourceL(
+ TUid aUid,
+ TInt aIndicatorPaneResourceId,
+ TInt aCustomIndicatorFlags )
+ {
+ TResourceReader res;
+ iEikonEnv->CreateResourceReaderLC( res, aIndicatorPaneResourceId );
+
+ TInt indicatorCount = res.ReadInt16();
+ for ( TInt ii = 0; ii < indicatorCount; ii++ )
+ {
+ TInt foundUid = res.ReadInt16();
+ if ( foundUid == aUid.iUid )
+ {
+ res.Rewind( sizeof( TInt16 ) );
+ CAknIndicator* indicator =
+ new (ELeave) CAknIndicator ( iIndicatorContext );
+ CleanupStack::PushL( indicator );
+ indicator->SetContainerWindowL( *this );
+ indicator->ConstructFromResourceL( res, this );
+ iIndicators->AppendL( indicator );
+
+ if ( aCustomIndicatorFlags & EMultiColorIndicator )
+ {
+ indicator->SetMultiColorMode( ETrue );
+ }
+
+ // Editor indicator positions are set separately.
+ if ( iIndicatorContext == EUniversalIndicators )
+ {
+ if ( aCustomIndicatorFlags & EIndicatorPositionInverted )
+ {
+ indicator->SetIndicatorPosition( ELeftSide );
+ }
+ else
+ {
+ indicator->SetIndicatorPosition( ERightSide );
+ }
+ }
+
+ indicator->SetLayoutMode(
+ (CAknIndicator::TLayoutMode) SelectIndicatorLayoutMode() );
+
+ CleanupStack::Pop( indicator );
+ indicator = NULL;
+ break;
+ }
+ else
+ {
+ res.ReadInt16();
+ res.ReadInt16();
+ HBufC* bitmapFile = res.ReadHBufCL(); // bmp filename
+ delete bitmapFile;
+ bitmapFile = NULL;
+ TInt numberOfStates = res.ReadInt16(); // Number of states
+ for ( TInt i = 0; i < numberOfStates; i++ )
+ {
+ res.ReadInt16(); // State id
+ TInt numberOfIcons = res.ReadInt16();
+ for ( TInt j = 0; j < numberOfIcons; j++ )
+ {
+ for ( TInt jj = ELayoutModeUsual; jj <= ELayoutModeWide; jj++ )
+ {
+ res.ReadInt16(); // bitmaps
+ res.ReadInt16(); // mask
+ }
+ }
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // res
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::IndicatorExists
+// Checks if an indicator already exists in the indicator array.
+// ---------------------------------------------------------------------------
+//
+TBool CAknIndicatorContainer::IndicatorExists( TUid aUid ) const
+ {
+ TBool exists( EFalse );
+
+ TInt count = iIndicators->Count();
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ if ( iIndicators->At( ii )->Uid() == aUid )
+ {
+ exists = ETrue;
+ break;
+ }
+ }
+
+ return exists;
+ }
+
+// ---------------------------------------------------------------------------
+// CAknIndicatorContainer::CreateIncallBubbleL
+// Creates the small incall status bubble.
+// ---------------------------------------------------------------------------
+//
+void CAknIndicatorContainer::CreateIncallBubbleL()
+ {
+ // Create incall indicator, use empty rect.
+ // Correct size is set in IncallBubbleSizeChanged.
+ iIncallBubble = CIncallStatusBubble::NewL( TRect() );
+ iIncallBubble->SetFlags( 0 );
+ iIncallBubble->MakeVisible( EFalse );
+ iIncallBubble->SetFaded( CAknSgcClient::IsSystemFaded() );
+ }
+
+
+TBool CAknIndicatorContainer::UpdateSmallLayoutL()
+ {
+ // Needed only if small status pane is in use.
+ if ( AknStatuspaneUtils::SmallLayoutActive() )
+ {
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+
+ if ( statusPane )
+ {
+ TInt statusPaneCurrentLayoutResourceId = statusPane->CurrentLayoutResId();
+ TInt statusPaneRequiredLayoutResourceId =
+ AVKONENV->StatusPaneResIdForCurrentLayout(R_AVKON_STATUS_PANE_LAYOUT_SMALL);
+
+ TInt last = iIndicators->Count() - 1;
+ for (TInt j = 0; j <= last; j++)
+ {
+ CAknIndicator* indicator = iIndicators->At(j);
+ TUid uid = indicator->Uid();
+
+ if ( uid == TUid::Uid(EAknNaviPaneEditorIndicatorGprs) )
+ {
+ if ( indicator->IndicatorState() )
+ {
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ statusPaneRequiredLayoutResourceId =
+ AVKONENV->StatusPaneResIdForCurrentLayout(
+ R_AVKON_STATUS_PANE_LAYOUT_SMALL_WITH_SIGNAL_PANE_MIRRORED);
+ }
+ else
+ {
+ statusPaneRequiredLayoutResourceId =
+ AVKONENV->StatusPaneResIdForCurrentLayout(
+ R_AVKON_STATUS_PANE_LAYOUT_SMALL_WITH_SIGNAL_PANE);
+ }
+ break;
+ }
+ }
+ }
+
+ // switch layout if needed
+ if ( statusPaneCurrentLayoutResourceId != statusPaneRequiredLayoutResourceId )
+ {
+ if (iExtension && !iExtension->iSwitchLayoutInProgress)
+ {
+ iExtension->iSwitchLayoutInProgress = ETrue;
+ statusPane->SwitchLayoutL( statusPaneRequiredLayoutResourceId );
+ return ETrue;
+ }
+ }
+ else
+ {
+ if (iExtension)
+ {
+ iExtension->iSwitchLayoutInProgress = EFalse;
+ }
+ }
+ }
+ }
+
+ // layout not changed
+ return EFalse;
+ }
+
+
+void CAknIndicatorContainer::SetIncallBubbleDisabled( TBool aDisabled )
+ {
+ if ( iExtension )
+ {
+ iExtension->iIncallBubbleDisabled = aDisabled;
+ }
+ }
+
+void CAknIndicatorContainer::ResetAnimTicker( TBool bForeground )
+ {
+ iExtension->iIsForeground = bForeground;
+
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+ TInt curId = R_AVKON_STATUS_PANE_LAYOUT_USUAL;
+ if ( statusPane )
+ {
+ curId = statusPane->CurrentLayoutResId();
+ }
+ // if not foreground, cancel the timer
+ if ( !iExtension->iIsForeground ||
+ R_AVKON_STATUS_PANE_LAYOUT_EMPTY == curId )
+ {
+ if ( iTicker->IsActive() )
+ {
+ iTicker->Cancel();
+ }
+ return;
+ }
+
+ if ( !iTicker->IsActive() && iAnimatedIndicatorsShown > 0 )
+ {
+ iTicker->Start( KAknIndicatorAnimationShortDelay,
+ KAknIndicatorAnimationInterval,
+ TCallBack( TickerCallback, this ) );
+ }
+ else if ( iTicker->IsActive() && iAnimatedIndicatorsShown == 0 )
+ {
+ // Cancel animation timer if animated indicators
+ // are not visible anymore.
+ iTicker->Cancel();
+ iSynchronizingValue = 0;
+ }
+ }
+
+// End of File