/*
* 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;
CEikStatusPaneBase* iStatusPane;
MTouchFeedback* iFeedback;
};
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 ) );
iFeedback = MTouchFeedback::Instance();
if ( iFeedback &&
iIndicatorContainer->iIndicatorContext ==
CAknIndicatorContainer::EUniversalIndicators )
{
// Tactile feedback is only used for universal indicator pane.
CFeedbackSpec* fbSpec = CFeedbackSpec::New();
if ( fbSpec )
{
fbSpec->AddFeedback( ETouchEventStylusDown,
ETouchFeedbackSensitiveButton );
fbSpec->AddFeedback( ETouchEventStylusUp,
ETouchFeedbackSensitiveButton,
ETouchFeedbackVibra );
iFeedback->SetFeedbackArea( iIndicatorContainer,
0,
iIndicatorContainer->Rect(),
fbSpec );
delete fbSpec;
}
}
}
CAknIndicatorContainerExtension::CAknIndicatorContainerExtension(
CAknIndicatorContainer* aIndicatorContainer )
: iIndicatorContainer( aIndicatorContainer )
{
iSmallStatusPaneLayout = AknStatuspaneUtils::SmallLayoutActive();
iIncallBubbleAllowedInUsual = ETrue;
iIsForeground = static_cast<CAknAppUi*>( CEikonEnv::Static()->EikAppUi() )->IsForeground();
iStatusPane = CEikStatusPaneBase::Current();
}
CAknIndicatorContainerExtension::~CAknIndicatorContainerExtension()
{
delete iPictoInterface;
delete iDataObserver;
CCoeEnv::Static()->RemoveMessageMonitorObserver( *this );
MTouchFeedback* feedback = MTouchFeedback::Instance();
if ( feedback )
{
feedback->RemoveFeedbackForControl( iIndicatorContainer );
}
}
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 );
}
}
// ---------------------------------------------------------------------------
// 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() ) );
if ( iExtension && iExtension->iFeedback )
{
iExtension->iFeedback->ChangeFeedbackArea( this,
0,
Rect() );
}
}
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 iIndicators->Count();
}
TInt CAknIndicatorContainer::CountShownIndicator() const
{
TInt count = iIndicators->Count();
TInt indicatorShown = 0;
for ( TInt i = 0; i< count; i++ )
{
if( iIndicators->At(i)->IndicatorState() && iIndicators->At( i )->Priority() != KIndicatorNotShown )
{
indicatorShown++;
}
}
return indicatorShown;
}
EXPORT_C CCoeControl* CAknIndicatorContainer::ComponentControl(TInt aIndex) const
{
if ( aIndex >= 0 && aIndex < iIndicators->Count() )
{
return iIndicators->At( aIndex );
}
else
{
return NULL;
}
}
EXPORT_C void CAknIndicatorContainer::Draw( const TRect& aRect ) const
{
if ( iExtension->iStatusPane &&
iExtension->iStatusPane->IsTransparent() &&
( iIndicatorContext != EQueryEditorIndicators ) )
{
CWindowGc& gc = SystemGc();
TRgb rgb(TRgb::Color16MA(0));
gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.SetBrushColor(rgb);
gc.Clear(aRect);
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 );
// Pointer events are only handled in the universal indicator container.
if ( iExtension && iIndicatorContext == EUniversalIndicators )
{
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;
}
break;
}
case TPointerEvent::EButton1Up:
{
// Currently the small digital clock pane, universal
// indicator pane and battery pane (in status pane layouts
// where it's adjacent to universal indicator or digital
// clock 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 or battery pane area.
CEikStatusPaneBase* sp = CEikStatusPaneBase::Current();
TBool pointerUpInClockArea( EFalse );
TBool pointerUpInBatteryArea( EFalse );
if ( sp )
{
CCoeControl* clockPane = sp->ContainerControlL(
TUid::Uid( EEikStatusPaneUidDigitalClock ) );
if ( clockPane )
{
TRect clockRect( clockPane->PositionRelativeToScreen(),
clockPane->Size() );
pointerUpInClockArea =
clockRect.Contains( aPointerEvent.iParentPosition );
}
if ( !AknStatuspaneUtils::ExtendedFlatLayoutActive() )
{
CCoeControl* batteryPane = sp->ContainerControlL(
TUid::Uid( EEikStatusPaneUidBattery ) );
if ( batteryPane )
{
TRect batteryRect(
batteryPane->PositionRelativeToScreen(),
batteryPane->Size() );
pointerUpInBatteryArea =
batteryRect.Contains( aPointerEvent.iParentPosition );
}
}
}
// if indicator's rect contains pointer up position
if ( ( iExtension->iFlags & EAknIndicatorsButton1DownInIndicatorPaneRect &&
rect.Contains( aPointerEvent.iPosition ) ) ||
pointerUpInClockArea ||
pointerUpInBatteryArea )
{
if ( iExtension->iFeedback &&
( pointerUpInClockArea || pointerUpInBatteryArea ) )
{
// The pointer down was received in another control,
// so the tactile feedback must be given directly.
iExtension->iFeedback->InstantFeedback(
this,
ETouchFeedbackSensitiveButton,
ETouchFeedbackVibra,
aPointerEvent );
}
CAknSmallIndicator* indicatorNotifier = CAknSmallIndicator::NewLC( TUid::Uid( 0 ) );
indicatorNotifier->HandleIndicatorTapL();
//for indicator popup event
MTouchFeedback* feedback = MTouchFeedback::Instance();
if ( feedback )
{
feedback->InstantFeedback(
this,
ETouchFeedbackPopUp,
ETouchFeedbackVibra,
aPointerEvent );
}
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;
}
// Bubble sorted
for (TInt i = 0; i < ( count - 1 ); i++)
{
TBool swaped = EFalse;
for (TInt j = count - 1; j > i; j--)
{
if ( iIndicators->At( j )->Priority()
< iIndicators->At( j - 1 )->Priority() )
{
CAknIndicator* temp = iIndicators->At( j );
iIndicators->Delete( j );
CleanupStack::PushL( temp );
iIndicators->InsertL( j - 1, temp );
CleanupStack::Pop( temp );
swaped = ETrue;
}
}
if( !swaped )
{
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 == EAknNaviPaneEditorIndicatorGprs ||
uid == EAknNaviPaneEditorIndicatorWlanAvailable ||
uid == EAknNaviPaneEditorIndicatorWlanActive ||
uid == EAknNaviPaneEditorIndicatorWlanActiveSecure ||
(!isLandscape &&
(uid == EAknNaviPaneEditorIndicatorProgressBar ||
uid == EAknNaviPaneEditorIndicatorFileSize ||
uid == EAknNaviPaneEditorIndicatorWaitBar ||
uid == EAknNaviPaneEditorIndicatorSecuredConnection ||
uid == EAknNaviPaneEditorIndicatorWmlWaitGlobe)))
{
// These indicators are not shown in this statuspane layout.
indicator->SetExtent( TPoint( 0, 0 ), TSize( 0, 0 ) );
iIndicatorsShown++;
continue;
}
if ( iLayoutOrientation == EVertical )
{
if (uid == EAknNaviPaneEditorIndicatorProgressBar || uid
== EAknNaviPaneEditorIndicatorFileSize || uid
== EAknNaviPaneEditorIndicatorWaitBar || uid
== EAknNaviPaneEditorIndicatorSecuredConnection || uid
== EAknNaviPaneEditorIndicatorWmlWaitGlobe)
{
indicator->SetExtent(TPoint(0, 0), TSize(0, 0));
iIndicatorsShown++;
continue;
}
// 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;
////////////////////////////////////////////////////////////////////////////
//small status pane
TRect smallStatusPaneRect;
AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStatusPane,
smallStatusPaneRect);
// small statuspane, secure state indicator
TAknWindowLineLayout
smallStatusSecureStateLayout =
AknLayout::Small_status_pane_descendants_and_elements_Line_5();
TAknLayoutRect smallStatusSecureStateLayoutRect;
smallStatusSecureStateLayoutRect.LayoutRect(smallStatusPaneRect,
smallStatusSecureStateLayout);
TRect smallStatusSecureStateRect(
smallStatusSecureStateLayoutRect.Rect());
// small statuspane, wait pane
TAknWindowComponentLayout smallStatusWaitPaneLayout =
AknLayoutScalable_Avkon::status_small_wait_pane(3);
TAknLayoutRect smallStatusWaitPaneLayoutRect;
smallStatusWaitPaneLayoutRect.LayoutRect(smallStatusPaneRect,
smallStatusWaitPaneLayout);
TRect smallStatusWaitPaneRect(
smallStatusWaitPaneLayoutRect.Rect());
// small statuspane, globe
TAknWindowComponentLayout smallStatusWmlGlobeLayout =
AknLayoutScalable_Avkon::status_small_pane_g4(0);
TAknLayoutRect smallStatusWmlGlobeLayoutRect;
smallStatusWmlGlobeLayoutRect.LayoutRect(smallStatusPaneRect,
smallStatusWmlGlobeLayout);
TRect smallStatusWmlGlobeRect(
smallStatusWmlGlobeLayoutRect.Rect());
TInt waitBarIndicatorLeftOffset = smallStatusWaitPaneRect.iTl.iX;
TInt progressBarIndicatorLeftOffset = 0;
TInt wmlWaitGlobeLeftOffset = smallStatusWmlGlobeRect.iTl.iX;
TRect rectForMiddleIndicators(wmlWaitGlobeLeftOffset,
containerRect.iTl.iY, wmlWaitGlobeLeftOffset,
containerRect.iBr.iY);
if (AknLayoutUtils::LayoutMirrored())
{
wmlWaitGlobeLeftOffset = smallStatusPaneRect.iBr.iX
- smallStatusWmlGlobeRect.iBr.iX;
waitBarIndicatorLeftOffset = smallStatusPaneRect.iBr.iX
- smallStatusWaitPaneRect.iBr.iX;
}
if (uid == EAknNaviPaneEditorIndicatorProgressBar)
{
indicatorWidth = smallStatusWaitPaneRect.Width();
indicatorHeight = smallStatusWaitPaneRect.Height();
verticalOffset = (containerRect.Height() - indicatorHeight)/ 2;
leftOffset = progressBarIndicatorLeftOffset;
textIndicatorOffsetNeeded = ETrue;
}
else if (uid == EAknNaviPaneEditorIndicatorFileSize)
{
verticalOffset = verticalOffsetForTextIndicator;
// need left offset in western, right offset in A&H layout.
if (AknLayoutUtils::LayoutMirrored())
{
rightOffset = textIndicatorLeftOffset;
}
else
{
leftOffset = KMinSpaceBetweenIconsInPixels;
}
}
else if (uid == EAknNaviPaneEditorIndicatorWmlWaitGlobe)
{
verticalOffset = (containerRect.Height()
- indicator->IconSize().iHeight) / 2;
indicatorWidth = smallStatusWmlGlobeRect.Width();
}
else if (uid == EAknNaviPaneEditorIndicatorWaitBar)
{
indicatorWidth = smallStatusWaitPaneRect.Width();
indicatorHeight = smallStatusWaitPaneRect.Height();
verticalOffset = (containerRect.Height() - indicatorHeight)/ 2;
leftOffset = waitBarIndicatorLeftOffset;
textIndicatorOffsetNeeded = ETrue;
}
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 (AknLayoutUtils::LayoutMirrored())
{
leftOffset = KMinSpaceBetweenIconsInPixels;
}
else
{
rightOffset = KMinSpaceBetweenIconsInPixels;
}
textIndicatorOffsetNeeded = EFalse;
progressBarIndicatorLeftOffset = 0;
}
////////////////////////////////////////////////////////////////////////
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 )
{
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++;
}
}
// 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 )
{
showIndicator = EFalse;
}
else
{
indicatorLayout =
AknLayoutScalable_Avkon::uni_indicator_pane_g4( 1 );
}
break;
}
case 5:
{
if ( extendedFlatLayout )
{
showIndicator = EFalse;
}
else
{
indicatorLayout =
AknLayoutScalable_Avkon::uni_indicator_pane_g5( 1 );
}
break;
}
case 6:
{
if ( extendedFlatLayout )
{
showIndicator = EFalse;
}
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 )
{
iTicker->Cancel();
delete iTicker;
iTicker = NULL;
}
return;
}
if ( iAnimatedIndicatorsShown > 0 )
{
if ( !iTicker )
{
TRAP_IGNORE( iTicker = CPeriodic::NewL( CActive::EPriorityLow ) );
}
if ( iTicker && !iTicker->IsActive() )
{
iTicker->Start( KAknIndicatorAnimationShortDelay,
KAknIndicatorAnimationInterval,
TCallBack( TickerCallback, this ) );
}
}
else if ( iTicker && iAnimatedIndicatorsShown == 0 )
{
// Cancel animation timer if animated indicators
// are not visible anymore.
iTicker->Cancel();
delete iTicker;
iTicker = NULL;
iSynchronizingValue = 0;
}
}
// End of File