--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/AknIncallStatusBubble.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,2010 @@
+/*
+* Copyright (c) 2002-2008 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: Handles incall status bubble drawing.
+*
+*/
+
+
+// SYSTEM INCLUDE FILES
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uikon/eikdefmacros.h>
+#endif
+#include <eikimage.h>
+#include <eikenv.h>
+#include <barsread.h> // Resource reader
+#include <bautils.h> // erase
+#include <avkon.rsg>
+#include <AknsUtils.h>
+#include <AknsDrawUtils.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include <layoutmetadata.cdl.h>
+#include <AknIconUtils.h>
+#include <featmgr.h>
+#include <akniconconfig.h>
+#include <coeaui.h>
+#include <coemain.h>
+#include <coreapplicationuisdomainpskeys.h> // KCoreAppUIsAutolockStatus
+
+#include <AknTasHook.h>
+// USER INCLUDE FILES
+#include "AknIncallStatusBubble.h"
+#include "AknBitmapAnimation.h" // Animation definition
+#include "AknUtils.h"
+#include "aknappui.h"
+#include "AknDef.h"
+#include "aknconsts.h"
+#include "AknStatuspaneUtils.h"
+
+// CONSTANTS
+
+// There does not seem to be any way to query WSERV wheter TRANSPARENCY option has been
+// defined. We use this constant to decide which way we do things.
+// const TBool KTransparentWindowsUsed = EFalse; // Disabled at the moment for performance reasons.
+
+const TUid KPhoneAppUid = { 0x100058B3 };
+const TUid KPhoneViewUid = { 0x10282D81 };
+const TUid KPhoneVievCommand = { 0x2 }; // forces call handling to foreground
+const TUid KVideoCallUid = { 0x101F8681 };
+
+// Note that some icons are masked and some are non-masked.
+
+enum // Grouped by icon layout...
+ {
+ // Layout1
+ EIndexCallstatusQgn_indi_call_active = 0,
+ EIndexCallstatusQgn_indi_call_active_mask,
+ EIndexCallstatusQgn_indi_call_active_2,
+ EIndexCallstatusQgn_indi_call_active_2_mask,
+ EIndexCallstatusQgn_indi_call_active_cyph_off,
+ EIndexCallstatusQgn_indi_call_active_cyph_off_mask,
+ EIndexCallstatusQgn_indi_call_disconn,
+ EIndexCallstatusQgn_indi_call_disconn_mask,
+ EIndexCallstatusQgn_indi_call_disconn_cyph_off,
+ EIndexCallstatusQgn_indi_call_disconn_cyph_off_mask,
+ EIndexCallstatusQgn_indi_call_held,
+ EIndexCallstatusQgn_indi_call_held_mask,
+ EIndexCallstatusQgn_indi_call_held_cyph_off,
+ EIndexCallstatusQgn_indi_call_held_cyph_off_mask,
+ EIndexCallstatusQgn_indi_call_muted_callsta,
+ EIndexCallstatusQgn_indi_call_muted_callsta_mask,
+ EIndexCallstatusQgn_indi_call_video_callsta,
+ EIndexCallstatusQgn_indi_call_video_callsta_mask,
+ EIndexCallstatusQgn_indi_call_video_callsta_1,
+ EIndexCallstatusQgn_indi_call_video_callsta_1_mask,
+ EIndexCallstatusQgn_indi_call_video_callsta_2,
+ EIndexCallstatusQgn_indi_call_video_callsta_2_mask,
+ EIndexCallstatusQgn_indi_call_active_emergency,
+ EIndexCallstatusQgn_indi_call_active_emergency_mask,
+ EIndexCallstatusQgn_indi_call_video_1,
+ EIndexCallstatusQgn_indi_call_video_1_mask,
+ EIndexCallstatusQgn_indi_call_video_disconn,
+ EIndexCallstatusQgn_indi_call_video_disconn_mask,
+ EIndexCallStatusQgn_indi_call_voip_active,
+ EIndexCallStatusQgn_indi_call_voip_active_mask,
+ EIndexCallStatusQgn_indi_call_voip_active_2,
+ EIndexCallStatusQgn_indi_call_voip_active_2_mask,
+ EIndexCallStatusQgn_indi_call_voip_disconn,
+ EIndexCallStatusQgn_indi_call_voip_disconn_mask,
+ EIndexCallStatusQgn_indi_call_voip_held,
+ EIndexCallStatusQgn_indi_call_voip_held_mask,
+ ELayout1End = EIndexCallStatusQgn_indi_call_voip_held_mask,
+
+ // Layout2
+ EIndexCallstatusQgn_graf_bubble_incall,
+ EIndexCallstatusQgn_graf_bubble_incall_mask,
+ EIndexCallstatusQgn_graf_bubble_incall_disconn,
+ EIndexCallstatusQgn_graf_bubble_incall_disconn_mask,
+ ELayout2End = EIndexCallstatusQgn_graf_bubble_incall_disconn_mask,
+
+ // Layout3
+ EIndexCallstatusQgn_indi_call_cyphering_off,
+ EIndexCallstatusQgn_indi_call_cyphering_off_mask, // not used, but AknIconUtils & SVG needs this to exist
+ //ELayout3End = EIndexCallstatusQgn_indi_call_cyphering_off,
+ ELayout3End = EIndexCallstatusQgn_indi_call_cyphering_off_mask,
+
+ // Layout4
+ EIndexCallstatusQgn_indi_call_data,
+ EIndexCallstatusQgn_indi_call_data_mask, // not used, but AknIconUtils & SVG needs this to exist
+ EIndexCallstatusQgn_indi_call_data_hscsd,
+ EIndexCallstatusQgn_indi_call_data_hscsd_mask, // not used, but AknIconUtils & SVG needs this to exist
+ EIndexCallstatusQgn_indi_call_fax,
+ EIndexCallstatusQgn_indi_call_fax_mask, // not used, but AknIconUtils & SVG needs this to exist
+ //ELayout4End = EIndexCallstatusQgn_indi_call_fax,
+ ELayout4End = EIndexCallstatusQgn_indi_call_fax_mask,
+
+ // Layout5
+ EIndexCallstatusQgn_indi_call_line2,
+ EIndexCallstatusQgn_indi_call_line2_mask, // not used, but AknIconUtils & SVG needs this to exist
+ //ELayout5End = EIndexCallstatusQgn_indi_call_line2
+ ELayout5End = EIndexCallstatusQgn_indi_call_line2_mask
+ };
+
+// Cleanup stack helper.
+
+NONSHARABLE_CLASS( CCleanupGuard ) : public CBase
+ {
+ public:
+ inline CCleanupGuard() {}
+ ~CCleanupGuard();
+ public:
+ inline void SetItem1( CBase* aItem ) {iItem1 = aItem;}
+ inline void SetItem2( CBase* aItem ) {iItem2 = aItem;}
+ private:
+ CBase* iItem1;
+ CBase* iItem2;
+ };
+
+CCleanupGuard::~CCleanupGuard()
+ {
+ delete iItem1;
+ delete iItem2;
+ }
+
+// ==== CIncallAnim CLASS ======================
+
+/**
+* Helper class for animation control
+*/
+NONSHARABLE_CLASS( CIncallAnim ) : public CCoeControl
+ {
+ public:
+
+ enum
+ {
+ EDefaultCallAnim,
+ EVoipCallAnim,
+ EVideoCallAnim
+ };
+
+
+ public:
+ void ConstructL( CIncallStatusBubble& aImages );
+ ~CIncallAnim();
+ void MakeVisible( TBool aVisible );
+
+ void ClearAnimation();
+ void SetAnimationL( CIncallStatusBubble& aImages,
+ TInt aCallAnimType = EDefaultCallAnim );
+ void SetAnimationType( TInt aCallAnimType );
+ void CreateBackGroundImageL( const CFbsBitmap* aBubbleBitmap,
+ const CFbsBitmap* aBubbleMask,
+ TRect aBubbleRect );
+
+ private:
+ void UpdateAnimationL( CIncallStatusBubble& aImages,
+ TInt aCallAnimType = EDefaultCallAnim );
+ void SizeChanged();
+ void Draw( const TRect& aRect ) const;
+ private:
+ CAknBitmapAnimation* iIndiAnim;
+ CAknBitmapAnimation* iIndiVoIPAnim;
+ CAknBitmapAnimation* iIndiVideoAnim;
+ CFbsBitmap* iAnimBackGroundImage;
+ mutable TBool iIsRunning;
+ mutable TBool iIsVoIPRunning;
+ mutable TBool iIsVideoRunning;
+ TInt iCallAnimType;
+ };
+
+// Constructor
+void CIncallAnim::ConstructL( CIncallStatusBubble& aImages )
+ {
+ iCallAnimType = EDefaultCallAnim;
+
+ iAnimBackGroundImage = new ( ELeave ) CFbsBitmap();
+
+ SetAnimationL( aImages );
+
+ ActivateL();
+
+ CCoeControl::MakeVisible( EFalse );
+ }
+
+// Destructor
+CIncallAnim::~CIncallAnim()
+ {
+ delete iIndiAnim;
+ delete iIndiVoIPAnim;
+ delete iIndiVideoAnim;
+ delete iAnimBackGroundImage;
+ }
+
+void CIncallAnim::CreateBackGroundImageL(const CFbsBitmap* aBubbleBitmap, const CFbsBitmap* aBubbleMask, TRect aBubbleRect)
+ {
+ if (iAnimBackGroundImage && aBubbleBitmap && aBubbleMask)
+ {
+ CFbsBitmapDevice* destinationDevice = CFbsBitmapDevice::NewL(iAnimBackGroundImage);
+ CleanupStack::PushL(destinationDevice);
+
+ CFbsBitGc* destinationGc;
+ User::LeaveIfError( destinationDevice->CreateContext( destinationGc ) );
+
+ TRect rect = Rect();
+ rect.Move(-aBubbleRect.iTl);
+ destinationGc->BitBltMasked(TPoint(0,0), aBubbleBitmap, rect, aBubbleMask, ETrue);
+
+ delete destinationGc;
+ CleanupStack::PopAndDestroy(destinationDevice);
+ }
+ }
+
+// Position/Size changed
+void CIncallAnim::SizeChanged()
+ {
+ TRect rect( Rect() );
+
+ if ( !iIndiAnim || !iIndiVoIPAnim || !iIndiVideoAnim )
+ {
+ return;
+ }
+
+ if ( Rect().IsEmpty() )
+ return;
+
+ if ( ( rect.Size() != iIndiAnim->Size() ) ||
+ ( rect.Size() != iIndiVoIPAnim->Size() ) ||
+ ( rect.Size() != iIndiVideoAnim->Size() ))
+ {
+ AknIconConfig::TPreferredDisplayMode mode;
+ AknIconConfig::PreferredDisplayMode(mode, AknIconConfig::EImageTypeOffscreen);
+ iAnimBackGroundImage->Create(
+ Size(),
+ mode.iBitmapMode);
+ }
+ iIndiAnim->SetRect( rect );
+ iIndiVoIPAnim->SetRect( rect );
+ iIndiVideoAnim->SetRect( rect );
+ }
+
+// Draws the animation
+void CIncallAnim::Draw( const TRect& /*aRect*/ ) const
+ {
+ CAknBitmapAnimation* ok = NULL;
+ switch (iCallAnimType)
+ {
+ case EDefaultCallAnim:
+ ok = iIndiAnim;
+ break;
+ case EVoipCallAnim:
+ ok = iIndiAnim;
+ break;
+ case EVideoCallAnim:
+ ok = iIndiAnim;
+ break;
+ default:
+ ok = NULL;
+ break;
+ }
+
+ if ( !ok )
+ {
+ return;
+ }
+
+
+ // Background is no more copied from screen because it does not work very well.
+ // Instead we use the image that has been set.
+ if (iAnimBackGroundImage)
+ {
+ // Create frame for background
+ CBitmapFrameData* data = NULL;
+ TRAPD( error , ( data = CBitmapFrameData::NewL() ) );
+ if ( error != KErrNone || data == NULL )
+ {
+ iIsRunning = EFalse;
+ iIsVoIPRunning = EFalse;
+ return;
+ }
+
+ data->SetBitmapsOwnedExternally( ETrue );
+ data->SetBitmap( iAnimBackGroundImage );
+ data->SetInterval( -1 );
+
+ // Set frame to animation
+ CBitmapAnimClientData* animData;
+
+ if ( iCallAnimType == EVoipCallAnim )
+ {
+ animData = iIndiVoIPAnim->BitmapAnimData();
+ }
+ else if ( iCallAnimType == EVideoCallAnim )
+ {
+ animData = iIndiVideoAnim->BitmapAnimData();
+ }
+ else
+ {
+ animData = iIndiAnim->BitmapAnimData();
+ }
+
+ animData->SetBackgroundFrame( data );
+
+ // This is a const function so mutable cast is needed
+ // to change member variables
+ CIncallAnim* mutableThis =
+ MUTABLE_CAST( CIncallAnim* , this );
+
+ // Start animation - we can't do a thing if this fails
+ if ( iCallAnimType == EVoipCallAnim )
+ {
+ TRAP( error , iIndiVoIPAnim->StartAnimationL(EFalse) );
+ mutableThis->iIsVoIPRunning = ETrue;
+ mutableThis->iIsRunning = EFalse;
+ mutableThis->iIsVideoRunning = EFalse;
+ }
+ else if ( iCallAnimType == EVideoCallAnim )
+ {
+ TRAP( error , iIndiVideoAnim->StartAnimationL(EFalse) );
+ mutableThis->iIsVoIPRunning = EFalse;
+ mutableThis->iIsVideoRunning = ETrue;
+ mutableThis->iIsRunning = EFalse;
+ }
+ else
+ {
+ TRAP( error , iIndiAnim->StartAnimationL(EFalse) );
+ mutableThis->iIsVoIPRunning = EFalse;
+ mutableThis->iIsRunning = ETrue;
+ mutableThis->iIsVideoRunning = EFalse;
+ }
+ }
+ }
+
+// Creates new animation frames
+void CIncallAnim::SetAnimationL( CIncallStatusBubble& aImages, TInt aCallAnimType )
+ {
+ iCallAnimType = aCallAnimType;
+
+ // Create new animation
+ iIndiAnim = CAknBitmapAnimation::NewL();
+ iIndiAnim->SetContainerWindowL( *this );
+ iIndiVoIPAnim = CAknBitmapAnimation::NewL();
+ iIndiVoIPAnim->SetContainerWindowL( *this );
+ iIndiVideoAnim = CAknBitmapAnimation::NewL();
+ iIndiVideoAnim->SetContainerWindowL( *this );
+
+ TInt resourceReaderId = 0;
+ resourceReaderId = R_BUBBLEMANAGER_ALERTING_ANIM;
+ TResourceReader rr;
+ iCoeEnv->CreateResourceReaderLC( rr , resourceReaderId );
+ iIndiAnim->ConstructFromResourceL(rr);
+ CleanupStack::PopAndDestroy(); // rr
+
+ resourceReaderId = R_BUBBLEMANAGER_ALERTING_VOIP_ANIM;
+ TResourceReader rr2;
+ iCoeEnv->CreateResourceReaderLC( rr2 , resourceReaderId );
+ iIndiVoIPAnim->ConstructFromResourceL(rr2);
+ CleanupStack::PopAndDestroy(); // rr2
+
+ resourceReaderId = R_BUBBLEMANAGER_ALERTING_VIDEO_ANIM;
+ TResourceReader rr3;
+ iCoeEnv->CreateResourceReaderLC( rr3 , resourceReaderId );
+ iIndiVideoAnim->ConstructFromResourceL(rr3);
+ CleanupStack::PopAndDestroy(); // rr3
+
+ UpdateAnimationL( aImages, EDefaultCallAnim );// Normal CS call.
+ UpdateAnimationL( aImages, EVoipCallAnim ); // VoIP call.
+ UpdateAnimationL( aImages, EVideoCallAnim ); // Video call.
+ }
+
+void CIncallAnim::UpdateAnimationL( CIncallStatusBubble& aImages, TInt aCallAnimType )
+ {
+ // Clear old data:
+ CBitmapAnimClientData* animData;
+ if ( aCallAnimType == EVoipCallAnim )
+ {
+ animData = iIndiVoIPAnim->BitmapAnimData();
+ }
+ else if (iCallAnimType == EVideoCallAnim)
+ {
+ animData = iIndiVideoAnim->BitmapAnimData();
+ }
+ else
+ {
+ animData = iIndiAnim->BitmapAnimData();
+ }
+
+ animData->ResetFrameArray();
+
+ // Create frame 1
+ CEikImage* image1 = new (ELeave) CEikImage;
+ image1->SetPictureOwnedExternally( ETrue );
+ CleanupStack::PushL( image1 );
+
+ if ( aCallAnimType == EVoipCallAnim )
+ {
+ aImages.GetImage(
+ *image1,
+ EIndexCallStatusQgn_indi_call_voip_active,
+ EIndexCallStatusQgn_indi_call_voip_active_mask
+ );
+ }
+ else if (iCallAnimType == EVideoCallAnim)
+ {
+ aImages.GetImage(
+ *image1,
+ EIndexCallstatusQgn_indi_call_video_callsta_1,
+ EIndexCallstatusQgn_indi_call_video_callsta_1_mask
+ );
+ }
+ else
+ {
+ aImages.GetImage(
+ *image1,
+ EIndexCallstatusQgn_indi_call_active,
+ EIndexCallstatusQgn_indi_call_active_mask
+ );
+ }
+
+ CBitmapFrameData* frame1 = CBitmapFrameData::NewL(
+ MUTABLE_CAST( CFbsBitmap*, image1->Bitmap() ),
+ MUTABLE_CAST( CFbsBitmap*, image1->Mask() ) );
+
+ frame1->SetInterval( KErrNotFound );
+ frame1->SetBitmapsOwnedExternally( ETrue );
+ CleanupStack::PushL( frame1 );
+
+ animData->AppendFrameL( frame1 ); // Takes ownership
+
+ CleanupStack::Pop( frame1 );
+ CleanupStack::PopAndDestroy( image1 );
+
+ // Create frame 2
+ CEikImage* image2 = new (ELeave) CEikImage;
+ image2->SetPictureOwnedExternally( ETrue );
+ CleanupStack::PushL( image2 );
+
+ if ( aCallAnimType == EVoipCallAnim )
+ {
+ aImages.GetImage(
+ *image2,
+ EIndexCallStatusQgn_indi_call_voip_active_2,
+ EIndexCallStatusQgn_indi_call_voip_active_2_mask
+ );
+ }
+ else if (iCallAnimType == EVideoCallAnim)
+ {
+ aImages.GetImage(
+ *image2,
+ EIndexCallstatusQgn_indi_call_video_callsta_2,
+ EIndexCallstatusQgn_indi_call_video_callsta_2_mask
+ );
+ }
+ else
+ {
+ aImages.GetImage(
+ *image2,
+ EIndexCallstatusQgn_indi_call_active_2,
+ EIndexCallstatusQgn_indi_call_active_2_mask
+ );
+ }
+
+ CBitmapFrameData* frame2 = CBitmapFrameData::NewL(
+ MUTABLE_CAST( CFbsBitmap*, image2->Bitmap() ),
+ MUTABLE_CAST( CFbsBitmap*, image2->Mask() ) );
+
+ frame2->SetInterval( KErrNotFound );
+ frame2->SetBitmapsOwnedExternally( ETrue );
+ CleanupStack::PushL( frame2 );
+
+ animData->AppendFrameL( frame2 ); // Takes ownership
+
+ CleanupStack::Pop( frame2 );
+ CleanupStack::PopAndDestroy( image2 );
+ }
+
+void CIncallAnim::SetAnimationType( TInt aCallAnimType )
+ {
+ iCallAnimType = aCallAnimType;
+ }
+
+// Clears current animation
+void CIncallAnim::ClearAnimation()
+ {
+ if ( iIndiAnim )
+ {
+ CBitmapAnimClientData* animData = iIndiAnim->BitmapAnimData();
+ animData->ResetFrameArray();
+ }
+ delete iIndiAnim;
+ iIndiAnim = NULL;
+
+ if ( iIndiVoIPAnim )
+ {
+ CBitmapAnimClientData* animData = iIndiVoIPAnim->BitmapAnimData();
+ animData->ResetFrameArray();
+ }
+ delete iIndiVoIPAnim;
+ iIndiVoIPAnim = NULL;
+
+ if ( iIndiVideoAnim )
+ {
+ CBitmapAnimClientData* animData = iIndiVideoAnim->BitmapAnimData();
+ animData->ResetFrameArray();
+ }
+ delete iIndiVideoAnim;
+ iIndiVideoAnim = NULL;
+
+ }
+
+// Make visible
+void CIncallAnim::MakeVisible( TBool aVisible )
+ {
+ if ( IsVisible() && !aVisible && iIndiAnim && iIsRunning )
+ {
+ TInt err = iIndiAnim->CancelAnimation();
+ if ( err == KErrNone )
+ {
+ iIsRunning = EFalse;
+ }
+ }
+
+ if ( IsVisible() && !aVisible && iIndiVoIPAnim && iIsVoIPRunning )
+ {
+ TInt err = iIndiVoIPAnim->CancelAnimation();
+ if ( err == KErrNone )
+ {
+ iIsVoIPRunning = EFalse;
+ }
+ }
+
+ if ( IsVisible() && !aVisible && iIndiVideoAnim && iIsVideoRunning )
+ {
+ TInt err = iIndiVideoAnim->CancelAnimation();
+ if ( err == KErrNone )
+ {
+ iIsVideoRunning = EFalse;
+ }
+ }
+
+ CCoeControl::MakeVisible( aVisible ); // a call to parent's method
+ }
+
+// ==== CIncallAnim CLASS ======================
+
+/**
+* Helper class for muted icon (has its own window)
+*/
+NONSHARABLE_CLASS(CIncallMuted) : public CCoeControl
+ {
+ public:
+ void ConstructL( CCoeControl& aParent );
+ ~CIncallMuted();
+
+ void SetMutedImage(
+ const CFbsBitmap* aBitmap ,
+ const CFbsBitmap* aMask );
+
+ TInt CountComponentControls() const;
+ CCoeControl* ComponentControl(TInt aIndex) const;
+ private:
+ void SizeChanged();
+ void HandlePointerEventL(const TPointerEvent& aPointerEvent);
+
+ private:
+ CEikImage* iMutedImage;
+ CIncallStatusBubble *iIncallStatusBubble;
+ };
+
+// Constructor
+void CIncallMuted::ConstructL( CCoeControl& aParent )
+ {
+ SetContainerWindowL( aParent );
+
+ iIncallStatusBubble = ( CIncallStatusBubble* ) &aParent;
+
+ iMutedImage = new( ELeave ) CEikImage;
+ iMutedImage->SetContainerWindowL( *this );
+ iMutedImage->SetPictureOwnedExternally( ETrue );
+ iMutedImage->MakeVisible( EFalse );
+
+ SetComponentsToInheritVisibility();
+ Window().SetPointerGrab( ETrue );
+ EnableDragEvents();
+ }
+
+// Destructor
+CIncallMuted::~CIncallMuted()
+ {
+ delete iMutedImage;
+ }
+
+// Sets images
+void CIncallMuted::SetMutedImage(
+ const CFbsBitmap* aBitmap ,
+ const CFbsBitmap* aMask )
+ {
+ iMutedImage->SetPicture( aBitmap , aMask );
+ SizeChanged();
+ }
+
+// Count component control
+TInt CIncallMuted::CountComponentControls() const
+ {
+ return 1;
+ }
+
+// Component control
+CCoeControl* CIncallMuted::ComponentControl( TInt /*aIndex*/ ) const
+ {
+ return iMutedImage;
+ }
+
+// New size is checked.
+void CIncallMuted::SizeChanged()
+ {
+ if ( !iMutedImage )
+ {
+ return;
+ }
+
+ iMutedImage->SetRect( Rect() );
+
+ CFbsBitmap* bitmap = (CFbsBitmap*)iMutedImage->Bitmap();
+ if ( bitmap )
+ {
+ AknIconUtils::SetSize( bitmap, Size() );
+ }
+ }
+
+
+void CIncallMuted::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+ {
+ CCoeControl::HandlePointerEventL( aPointerEvent );
+
+ iIncallStatusBubble->HandlePointerEventL( aPointerEvent );
+ }
+
+// ================ CIncallStatusBubble CLASS ===============
+
+// ================= MEMBER FUNCTIONS =======================
+
+// Constructor
+CIncallStatusBubble::CIncallStatusBubble() : iOrder( CompareSkinnedData )
+ {
+ }
+
+// NewL
+CIncallStatusBubble* CIncallStatusBubble::NewL( const TRect& aRect )
+ {
+ CIncallStatusBubble* self = new ( ELeave ) CIncallStatusBubble;
+ CleanupStack::PushL( self );
+ self->ConstructL( aRect );
+ CleanupStack::Pop();
+ AKNTASHOOK_ADDL( self, "CIncallStatusBubble" );
+ return self;
+ }
+
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::ConstructL(const TRect& aRect)
+// EPOC two phased constructor
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::ConstructL( const TRect& aRect )
+ {
+ iMyWindowGroup=RWindowGroup( iCoeEnv->WsSession() );
+ User::LeaveIfError( iMyWindowGroup.Construct( (TUint32)&iMyWindowGroup,
+ EFalse ) );
+ iMyWindowGroup.SetOrdinalPosition( 0, ECoeWinPriorityMedium );
+ CreateWindowL( &iMyWindowGroup );
+
+ // Load bitmaps to an array
+ iBitmaps = new ( ELeave ) CArrayPtrFlat<CFbsBitmap>( 4 );
+ LoadImagesL();
+
+ // Create skinned animation
+ iSmallIndiAnim = new( ELeave ) CIncallAnim;
+ iSmallIndiAnim->SetContainerWindowL( *this );
+ iSmallIndiAnim->ConstructL( *this );
+
+ // call indication
+ iSmallCallIndication = CreateNewEikImageL();
+
+ // bubble icon
+ iBubble = CreateNewEikImageL();
+
+ // type indicatiors
+ iTypeIndication1 = CreateNewEikImageL();
+ iTypeIndication2 = CreateNewEikImageL();
+
+ // skinned muted icon
+ iMutedIcon = new(ELeave) CIncallMuted;
+ iMutedIcon->ConstructL( *this );
+ CEikImage* tmpMutedImage = new(ELeave) CEikImage;
+ CleanupStack::PushL( tmpMutedImage );
+ tmpMutedImage->SetPictureOwnedExternally( ETrue );
+ GetImage(
+ *tmpMutedImage,
+ EIndexCallstatusQgn_indi_call_muted_callsta,
+ EIndexCallstatusQgn_indi_call_muted_callsta_mask
+ );
+ iMutedIcon->SetMutedImage(tmpMutedImage->Bitmap(), tmpMutedImage->Mask());
+ CleanupStack::PopAndDestroy( tmpMutedImage );
+ iMutedIcon->MakeVisible( EFalse );
+
+ // Cyph off image
+ iCyphOffIcon = CreateNewEikImageL();
+ iPressedDown = EFalse;
+ // finnish the job
+ MakeVisible( EFalse );
+ SetRect( aRect );
+ Window().SetPointerGrab( ETrue );
+ EnableDragEvents();
+
+ ActivateL();
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::CreateNewEikImageL
+//
+// ---------------------------------------------------------
+//
+CEikImage* CIncallStatusBubble::CreateNewEikImageL() const
+ {
+ CEikImage* newImage = new( ELeave ) CEikImage;
+ CleanupStack::PushL( newImage );
+ newImage->SetContainerWindowL( *this );
+ newImage->SetPictureOwnedExternally( ETrue );
+ newImage->SetPicture( NULL );
+ newImage->MakeVisible( EFalse );
+ CleanupStack::Pop(); // newImage
+ return newImage;
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::LoadImagesL
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::LoadImagesL()
+ {
+ // These need to be loaded in the same order as defined in the
+ // enumeration in the beginning of this file.
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_active,
+ EMbmCallstatusQgn_indi_call_active_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_active_2,
+ EMbmCallstatusQgn_indi_call_active_2_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_active_cyph_off,
+ EMbmCallstatusQgn_indi_call_active_cyph_off_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_disconn,
+ EMbmCallstatusQgn_indi_call_disconn_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_disconn_cyph_off,
+ EMbmCallstatusQgn_indi_call_disconn_cyph_off_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_held,
+ EMbmCallstatusQgn_indi_call_held_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_held_cyph_off,
+ EMbmCallstatusQgn_indi_call_held_cyph_off_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_muted_callsta,
+ EMbmCallstatusQgn_indi_call_muted_callsta_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_video_callsta,
+ EMbmCallstatusQgn_indi_call_video_callsta_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_video_callsta_1,
+ EMbmCallstatusQgn_indi_call_video_callsta_1_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_video_callsta_2,
+ EMbmCallstatusQgn_indi_call_video_callsta_2_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_active_emergency,
+ EMbmCallstatusQgn_indi_call_active_emergency_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_video_1,
+ EMbmCallstatusQgn_indi_call_video_1_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_video_disconn,
+ EMbmCallstatusQgn_indi_call_video_disconn_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_voip_active,
+ EMbmCallstatusQgn_indi_call_voip_active_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_voip_active_2,
+ EMbmCallstatusQgn_indi_call_voip_active_2_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_voip_disconn,
+ EMbmCallstatusQgn_indi_call_voip_disconn_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_indi_call_voip_held,
+ EMbmCallstatusQgn_indi_call_voip_held_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_graf_bubble_incall,
+ EMbmCallstatusQgn_graf_bubble_incall_mask );
+
+ LoadImageL(
+ EMbmCallstatusQgn_graf_bubble_incall_disconn,
+ EMbmCallstatusQgn_graf_bubble_incall_disconn_mask );
+
+ LoadImageL( EMbmCallstatusQgn_indi_call_cyphering_off );
+
+ LoadImageL( EMbmCallstatusQgn_indi_call_data );
+
+ LoadImageL( EMbmCallstatusQgn_indi_call_data_hscsd );
+
+ LoadImageL( EMbmCallstatusQgn_indi_call_fax );
+
+ LoadImageL( EMbmCallstatusQgn_indi_call_line2 );
+ }
+
+
+// Destructor
+CIncallStatusBubble::~CIncallStatusBubble()
+ {
+ AKNTASHOOK_REMOVE();
+ delete iMutedIcon;
+ delete iSmallCallIndication;
+ delete iSmallIndiAnim;
+ delete iTypeIndication1;
+ delete iTypeIndication2;
+ delete iCyphOffIcon;
+ delete iBubble;
+
+ iSkins.ResetAndDestroy();
+ delete iSkinnedColourBitmap;
+
+ if ( iBitmaps )
+ {
+ iBitmaps->ResetAndDestroy( );
+ delete iBitmaps;
+ }
+
+ iMyWindowGroup.Close();
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::SizeChanged()
+// Called by framework when the view size is changed
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::SizeChanged()
+ {
+ // For performance optimization purposes we do not continue if
+ // we are not visible. Assumed that SetIncallBubbleFlags() causes
+ // this method to be called again.
+ if (!IsVisible() && !(iFlags & ESBVisible))
+ return;
+
+ TRect rect( Rect() );
+ TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
+
+ // Set componets to right places
+
+ TAknWindowLineLayout layout1(
+ AknLayoutScalable_Apps::popup_call_status_window_g1(
+ isLandscape ).LayoutLine() );
+
+ TAknWindowLineLayout layout2(
+ AknLayoutScalable_Apps::popup_call_status_window_g2(
+ isLandscape ).LayoutLine() );
+
+ TAknWindowLineLayout layout3(
+ AknLayoutScalable_Apps::popup_call_status_window_g3( isLandscape ).LayoutLine() );
+
+ TAknWindowLineLayout layout4(
+ AknLayoutScalable_Apps::call_type_pane_g1().LayoutLine() );
+
+ TAknWindowLineLayout layout5(
+ AknLayoutScalable_Apps::call_type_pane_g2().LayoutLine() );
+
+ AknLayoutUtils::LayoutImage( iBubble, rect, layout1 );
+
+ AknLayoutUtils::LayoutControl( iSmallCallIndication, rect, layout2 );
+
+ AknLayoutUtils::LayoutControl( iSmallIndiAnim, rect, layout2 );
+
+ AknLayoutUtils::LayoutControl( iMutedIcon, rect, layout2 );
+
+ TAknLayoutRect callTypeIndicationLayoutRect;
+ callTypeIndicationLayoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Apps::call_type_pane( isLandscape ) );
+ TRect callTypeIndicationRect( callTypeIndicationLayoutRect.Rect() );
+
+ TBool hideTypeIndication = isLandscape && !AknStatuspaneUtils::HDLayoutActive();
+
+ if ( iFlags & ESBVideo )
+ {
+ // video indicator is different size than others
+ AknLayoutUtils::LayoutControl( iTypeIndication1, rect, layout2 );
+ }
+ else
+ {
+ if ( hideTypeIndication )
+ {
+ // Not shown in landscape, because there's not enough space.
+ TRect nullRect( 0, 0, 0, 0 );
+ iTypeIndication1->SetRect( nullRect );
+ iTypeIndication2->SetRect( nullRect );
+ iCyphOffIcon->SetRect( nullRect );
+ }
+ else
+ {
+ AknLayoutUtils::LayoutControl( iTypeIndication1,
+ callTypeIndicationRect,
+ layout4 );
+
+ AknLayoutUtils::LayoutControl( iTypeIndication2,
+ callTypeIndicationRect,
+ layout5 );
+
+ AknLayoutUtils::LayoutControl( iCyphOffIcon,
+ rect,
+ layout3 );
+ }
+ }
+
+ // Bitmaps must be validated (size is set) before they can be used.
+ TAknLayoutRect layoutRect;
+
+ TInt ii;
+
+ // Layout group 1
+ layoutRect.LayoutRect( rect, layout2 );
+ for ( ii = EIndexCallstatusQgn_indi_call_active; ii <= ELayout1End; ii++ )
+ {
+ AknIconUtils::SetSize( iBitmaps->At(ii), layoutRect.Rect().Size() );
+ }
+
+ if ( iSmallCallIndication )
+ {
+ CFbsBitmap* bitmap = (CFbsBitmap*)iSmallCallIndication->Bitmap();
+ if ( bitmap )
+ {
+ AknIconUtils::SetSize( bitmap, iSmallCallIndication->Rect().Size() );
+ }
+ }
+
+
+ // Layout group 2
+ layoutRect.LayoutRect( rect, layout1 );
+ for ( ii = EIndexCallstatusQgn_graf_bubble_incall; ii < ELayout2End; ii++ )
+ {
+ AknIconUtils::SetSize( iBitmaps->At(ii), layoutRect.Rect().Size() );
+ }
+
+ if ( iBubble )
+ {
+ CFbsBitmap* bitmap = (CFbsBitmap*)iBubble->Bitmap();
+ if ( bitmap )
+ {
+ AknIconUtils::SetSize( bitmap, iBubble->Rect().Size() );
+ }
+ }
+
+
+ // Layout group 3
+ layoutRect.LayoutRect( rect, layout3 );
+ for ( ii = EIndexCallstatusQgn_indi_call_cyphering_off; ii <= ELayout3End; ii++ )
+ {
+ if ( hideTypeIndication )
+ {
+ // Not shown in landscape, because there's not enough space.
+ AknIconUtils::SetSize( iBitmaps->At(ii), TSize(0,0) );
+ }
+ else
+ {
+ AknIconUtils::SetSize( iBitmaps->At(ii), layoutRect.Rect().Size() );
+ }
+ }
+
+ if ( iCyphOffIcon )
+ {
+ CFbsBitmap* bitmap = (CFbsBitmap*)iCyphOffIcon->Bitmap();
+ if ( bitmap )
+ {
+ if ( hideTypeIndication )
+ {
+ // Not shown in landscape, because there's not enough space.
+ AknIconUtils::SetSize( bitmap, TSize(0,0) );
+ }
+ else
+ {
+ AknIconUtils::SetSize( bitmap, iCyphOffIcon->Rect().Size() );
+ }
+ }
+ }
+
+
+ // Layout group 4
+ layoutRect.LayoutRect( callTypeIndicationRect, layout4 );
+ for ( ii = EIndexCallstatusQgn_indi_call_data; ii <= ELayout4End; ii++ )
+ {
+ if ( hideTypeIndication )
+ {
+ // Not shown in landscape, because there's not enough space.
+ AknIconUtils::SetSize( iBitmaps->At(ii), TSize(0,0) );
+ }
+ else
+ {
+ AknIconUtils::SetSize( iBitmaps->At(ii), layoutRect.Rect().Size() );
+ }
+ }
+
+ if ( iTypeIndication1 )
+ {
+ CFbsBitmap* bitmap = (CFbsBitmap*)iTypeIndication1->Bitmap();
+ if ( bitmap )
+ {
+ if ( hideTypeIndication )
+ {
+ // Not shown in landscape, because there's not enough space.
+ AknIconUtils::SetSize( bitmap, TSize(0,0) );
+ }
+ else
+ {
+ AknIconUtils::SetSize(bitmap, iTypeIndication1->Rect().Size());
+ }
+ }
+ }
+
+
+ // Layout group 5
+ layoutRect.LayoutRect( callTypeIndicationRect, layout5 );
+ for ( ii = EIndexCallstatusQgn_indi_call_line2; ii <= ELayout5End; ii++ )
+ {
+ if ( hideTypeIndication )
+ {
+ // Not shown in landscape, because there's not enough space.
+ AknIconUtils::SetSize( iBitmaps->At(ii), TSize(0,0) );
+ }
+ else
+ {
+ AknIconUtils::SetSize(iBitmaps->At(ii), layoutRect.Rect().Size());
+ }
+ }
+
+ if ( iTypeIndication2 )
+ {
+ CFbsBitmap* bitmap = (CFbsBitmap*)iTypeIndication2->Bitmap();
+ if ( bitmap )
+ {
+ if ( hideTypeIndication )
+ {
+ // Not shown in landscape, because there's not enough space.
+ AknIconUtils::SetSize( bitmap, TSize(0,0) );
+ }
+ else
+ {
+ AknIconUtils::SetSize(bitmap, iTypeIndication2->Rect().Size());
+ }
+ }
+ }
+
+ Window().SetTransparencyAlphaChannel();
+ Window().SetBackgroundColor( ~0 );
+
+ // Update background of animation
+ if ( iSmallIndiAnim && iBubble && iBubble->Bitmap() && iBubble->Mask() )
+ TRAP_IGNORE( iSmallIndiAnim->CreateBackGroundImageL(
+ iBubble->Bitmap(),
+ iBubble->Mask(),
+ TRect( iBubble->Position(), iBubble->Bitmap()->SizeInPixels() ) ) );
+
+ // Make draw
+ DrawDeferred();
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::CountComponentControls() const
+//
+//
+// ---------------------------------------------------------
+//
+TInt CIncallStatusBubble::CountComponentControls() const
+ {
+ return 7; // bubble, small indi, anim , 2* type icons, cyph off and muted
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::ComponentControl(TInt aIndex) const
+//
+// ---------------------------------------------------------
+//
+CCoeControl* CIncallStatusBubble::ComponentControl(TInt aIndex) const
+ {
+ switch ( aIndex )
+ {
+ case 0:
+ return iBubble;
+ case 1:
+ return iSmallCallIndication;
+ case 2:
+ return iTypeIndication1;
+ case 3:
+ return iTypeIndication2;
+ case 4:
+ return iCyphOffIcon;
+ case 5:
+ return iSmallIndiAnim;
+ case 6:
+ return iMutedIcon;
+ default:
+ return NULL;
+ }
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::Draw
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::Draw(const TRect& /*aRect*/) const
+ {
+ CWindowGc& gc = SystemGc();
+ gc.Clear();
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::SetFlags
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::SetFlags( const TInt& aFlags )
+ {
+ iFlags = aFlags;
+ SelectImages();
+ SizeChanged();
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::Flags
+// Two versions to eliminate compiler warnings
+// ---------------------------------------------------------
+//
+#ifdef __WINS__
+const TInt CIncallStatusBubble::Flags()
+ {
+ return iFlags;
+ }
+#else
+TInt CIncallStatusBubble::Flags()
+ {
+ return iFlags;
+ }
+#endif
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::SetFaded
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::SetFaded(TBool aFaded)
+ {
+ if (!COMPARE_BOOLS(Window().IsFaded(), aFaded))
+ {
+ iMyWindowGroup.SetFaded(
+ aFaded, RWindowTreeNode::EFadeIncludeChildren);
+ }
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::SelectImages
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::SelectImages()
+ {
+ if ( ! ( iFlags & ESBVisible ) )
+ {
+ iSmallCallIndication->MakeVisible( EFalse );
+ iBubble->MakeVisible( EFalse );
+ iSmallIndiAnim->MakeVisible( EFalse );
+ iTypeIndication1->MakeVisible( EFalse );
+ iTypeIndication2->MakeVisible( EFalse );
+ iCyphOffIcon->MakeVisible( EFalse );
+ iMutedIcon->MakeVisible( EFalse );
+ return;
+ }
+
+ TRect rect( Rect() );
+
+ // first set call indication and bubble image
+ TInt indiBitmap = KErrNotFound;
+ TInt indiMask = KErrNotFound;
+ iSmallIndiAnim->MakeVisible( EFalse );
+
+
+ GetImage(
+ *iBubble,
+ EIndexCallstatusQgn_graf_bubble_incall,
+ EIndexCallstatusQgn_graf_bubble_incall_mask );
+ iBubble->MakeVisible( ETrue );
+
+ switch ( iFlags & (ESBAlerting|ESBActive|ESBOnHold|ESBDisconnected ) ) // two last bits
+ {
+ case ESBAlerting:
+ case ESBActive:
+ if ( iFlags & ESBVoIPCall &&
+ FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+ {
+ indiBitmap = EIndexCallStatusQgn_indi_call_voip_active;
+ indiMask = EIndexCallStatusQgn_indi_call_voip_active_mask;
+ }
+
+ else if ( iFlags & ESBVideo )
+ {
+ indiBitmap = EIndexCallstatusQgn_indi_call_video_callsta_1;
+ indiMask = EIndexCallstatusQgn_indi_call_video_callsta_1_mask;
+ }
+
+ else
+ {
+ indiBitmap = EIndexCallstatusQgn_indi_call_active;
+ indiMask = EIndexCallstatusQgn_indi_call_active_mask;
+ }
+ break;
+ case ESBOnHold:
+ if ( iFlags & ESBVoIPCall &&
+ FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+ {
+ indiBitmap = EIndexCallStatusQgn_indi_call_voip_held;
+ indiMask = EIndexCallStatusQgn_indi_call_voip_held_mask;
+ }
+ else
+ {
+ indiBitmap = EIndexCallstatusQgn_indi_call_held;
+ indiMask = EIndexCallstatusQgn_indi_call_held_mask;
+ }
+ break;
+ case ESBDisconnected:
+ if ( iFlags & ESBVoIPCall &&
+ FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+ {
+ indiBitmap = EIndexCallStatusQgn_indi_call_voip_disconn;
+ indiMask = EIndexCallStatusQgn_indi_call_voip_disconn_mask;
+ }
+
+ else if ( iFlags & ESBVideo )
+ {
+ indiBitmap = EIndexCallstatusQgn_indi_call_video_disconn;
+ indiMask = EIndexCallstatusQgn_indi_call_video_disconn_mask;
+ }
+
+ else
+ {
+ indiBitmap = EIndexCallstatusQgn_indi_call_disconn;
+ indiMask = EIndexCallstatusQgn_indi_call_disconn_mask;
+ }
+
+ GetImage(
+ *iBubble,
+ EIndexCallstatusQgn_graf_bubble_incall_disconn,
+ EIndexCallstatusQgn_graf_bubble_incall_disconn_mask );
+ break;
+ default:
+ _LIT(KCallStatus,"CallStatus");
+ User::Panic(KCallStatus , 0 );
+ break;
+ }
+
+ // Cyph off
+ if ( iFlags & ESBNoCiphering )
+ {
+ GetImage(
+ *iCyphOffIcon,
+ EIndexCallstatusQgn_indi_call_cyphering_off );
+ iCyphOffIcon->MakeVisible( ETrue );
+ }
+ else
+ {
+ iCyphOffIcon->MakeVisible( EFalse );
+ }
+
+ // Muted icon
+ if ( iFlags & ESBMuted )
+ {
+ iMutedIcon->MakeVisible( ETrue );
+ }
+ else
+ {
+ iMutedIcon->MakeVisible( EFalse );
+ }
+
+ // Animation
+ if ( (iFlags & (ESBAlerting|ESBActive|ESBOnHold|ESBDisconnected )) == ESBAlerting )
+ {
+ if ( iFlags & ESBVoIPCall &&
+ FeatureManager::FeatureSupported( KFeatureIdCommonVoip ))
+ {
+ iSmallIndiAnim->SetAnimationType( CIncallAnim::EVoipCallAnim ); // We have VoIP call.
+ }
+ else if (iFlags & ESBVideo)
+ {
+ iSmallIndiAnim->SetAnimationType( CIncallAnim::EVideoCallAnim ); // We have Video call.
+ }
+ else
+ {
+ iSmallIndiAnim->SetAnimationType( CIncallAnim::EDefaultCallAnim ); // We have normal CS call.
+ }
+
+ iSmallIndiAnim->MakeVisible( ETrue );
+ }
+ else
+ {
+ iSmallIndiAnim->MakeVisible( EFalse );
+ }
+
+
+ // Emergency call
+ if ( (iFlags & (ESBAlerting|ESBActive|ESBOnHold|ESBDisconnected )) == ESBActive &&
+ (iFlags & ESBEmergency) )
+ {
+ indiBitmap = EIndexCallstatusQgn_indi_call_active_emergency;
+ indiMask = EIndexCallstatusQgn_indi_call_active_emergency_mask;
+ }
+
+
+ if ( indiBitmap != KErrNotFound )
+ {
+ GetImage(
+ *iSmallCallIndication,
+ indiBitmap ,
+ indiMask );
+
+ iSmallCallIndication->MakeVisible( ETrue );
+ }
+
+
+
+ // set type pane
+ TInt picture1 = KErrNotFound;
+ TInt picture2 = KErrNotFound;
+
+ TInt mask1 = KErrNotFound;
+
+ if ( iFlags & ESBFax )
+ {
+ picture1 = EIndexCallstatusQgn_indi_call_fax;
+ }
+ else if ( iFlags & ESBDataHscsd )
+ {
+ picture1 = EIndexCallstatusQgn_indi_call_data_hscsd;
+ }
+ else if ( iFlags & ESBData )
+ {
+ picture1 = EIndexCallstatusQgn_indi_call_data;
+ }
+ else if ( iFlags & ESBVideo )
+ {
+ // type pane is used for video call, it should not be need to use other
+ // other types with video call
+ picture1 = EIndexCallstatusQgn_indi_call_video_callsta;
+ mask1 = EIndexCallstatusQgn_indi_call_video_callsta_mask;
+ }
+
+ if ( iFlags & ESBLine2 )
+ {
+ if ( picture1 == KErrNotFound )
+ {
+ picture1 = EIndexCallstatusQgn_indi_call_line2;
+ }
+ else
+ {
+ picture2 = EIndexCallstatusQgn_indi_call_line2;
+ }
+ }
+
+ if ( picture1 != KErrNotFound )
+ {
+ TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
+
+ GetImage(
+ *iTypeIndication1,
+ picture1,
+ mask1);
+
+ if ( iFlags & ESBVideo )
+ {
+ // video indicator is different size than others
+ AknLayoutUtils::LayoutControl(
+ iTypeIndication1,
+ rect,
+ AknLayoutScalable_Apps::popup_call_status_window_g2(
+ isLandscape ).LayoutLine() );
+
+ // muted icon is never shown with video call
+ iMutedIcon->MakeVisible( EFalse );
+
+ // line2 indication never shown with video call
+ picture2 = KErrNotFound;
+ }
+ else
+ {
+ if ( isLandscape )
+ {
+ // Not shown in landscape.
+ iTypeIndication1->SetRect( TRect( 0, 0, 0, 0 ) );
+ }
+ else
+ {
+ TAknLayoutRect callTypeIndicationRect;
+ callTypeIndicationRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Apps::call_type_pane() );
+ AknLayoutUtils::LayoutControl(
+ iTypeIndication1,
+ callTypeIndicationRect.Rect(),
+ AknLayoutScalable_Apps::call_type_pane_g1().LayoutLine() );
+ }
+ }
+
+ // "Video hold" does not have its own graphics, so we show it differently for now.
+ if ( iFlags & ESBVideo &&
+ ((iFlags & ( ESBAlerting | ESBActive | ESBOnHold | ESBDisconnected )) != ESBOnHold))
+ {
+ iTypeIndication1->MakeVisible( EFalse );
+ }
+ else
+ {
+ iTypeIndication1->MakeVisible( ETrue );
+ }
+
+
+ if ( picture2 != KErrNotFound )
+ {
+ GetImage( *iTypeIndication2,
+ picture2 );
+ iTypeIndication2->MakeVisible( ETrue );
+
+ }
+ else
+ {
+ iTypeIndication2->MakeVisible( EFalse );
+ }
+
+ }
+ else
+ {
+ iTypeIndication1->MakeVisible( EFalse );
+ iTypeIndication2->MakeVisible( EFalse );
+ }
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::SetRect
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::SetRect( const TRect& aRect )
+ {
+ CCoeControl::SetRect( aRect );
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::MapEnumToSkin
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::MapEnumToSkin(
+ const TInt aBmIcon, TAknsItemID& aID )
+ {
+ switch ( aBmIcon )
+ {
+ // Skinned bitmap:
+ case EIndexCallstatusQgn_indi_call_active:
+ aID = KAknsIIDQgnIndiCallActive;
+ break;
+ case EIndexCallstatusQgn_indi_call_disconn:
+ aID = KAknsIIDQgnIndiCallDisconn;
+ break;
+ case EIndexCallstatusQgn_indi_call_held:
+ aID = KAknsIIDQgnIndiCallHeld;
+ break;
+ case EIndexCallstatusQgn_indi_call_active_2:
+ aID = KAknsIIDQgnIndiCallActive2;
+ break;
+ case EIndexCallstatusQgn_indi_call_muted_callsta:
+ aID = KAknsIIDQgnIndiCallMutedCallsta;
+ break;
+ case EIndexCallstatusQgn_graf_bubble_incall:
+ aID = KAknsIIDQgnGrafBubbleIncall;
+ break;
+ case EIndexCallstatusQgn_graf_bubble_incall_disconn:
+ aID = KAknsIIDQgnGrafBubbleIncallDisconn;
+ break;
+ case EIndexCallStatusQgn_indi_call_voip_active:
+ aID = KAknsIIDQgnIndiCallVoipActive;
+ break;
+ case EIndexCallStatusQgn_indi_call_voip_active_2:
+ aID = KAknsIIDQgnIndiCallVoipActive2;
+ break;
+ case EIndexCallStatusQgn_indi_call_voip_disconn:
+ aID = KAknsIIDQgnIndiCallVoipDisconn;
+ break;
+ case EIndexCallStatusQgn_indi_call_voip_held:
+ aID = KAknsIIDQgnIndiCallVoipHeld;
+ break;
+ case EIndexCallstatusQgn_indi_call_video_callsta:
+ aID = KAknsIIDQgnIndiCallVideoCallsta;
+ break;
+ case EIndexCallstatusQgn_indi_call_video_callsta_1:
+ aID = KAknsIIDQgnIndiCallVideoCallsta1;
+ break;
+ case EIndexCallstatusQgn_indi_call_video_callsta_2:
+ aID = KAknsIIDQgnIndiCallVideoCallsta2;
+ break;
+ case EIndexCallstatusQgn_indi_call_video_disconn:
+ aID = KAknsIIDQgnIndiCallVideoCallstaDisconn;
+ break;
+
+ // Colour change:
+ case EIndexCallstatusQgn_indi_call_data:
+ case EIndexCallstatusQgn_indi_call_data_hscsd:
+ case EIndexCallstatusQgn_indi_call_fax:
+ case EIndexCallstatusQgn_indi_call_line2:
+ case EIndexCallstatusQgn_indi_call_cyphering_off:
+ aID = KAknsIIDQsnTextColors;
+ break;
+ default:
+ break;
+ }
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::GetSkinForIcon
+//
+// ---------------------------------------------------------
+//
+CAknsItemData* CIncallStatusBubble::GetSkinForIcon(
+ const TInt aBmIcon )
+ {
+ CAknsItemData* data = NULL;
+
+ TAknsItemID skinId = KAknsIIDNone;
+ MapEnumToSkin( aBmIcon, skinId );
+ if ( skinId == KAknsIIDNone )
+ {
+ return NULL;
+ }
+
+ SSkinnedImage skinnedImage;
+ skinnedImage.iId = skinId;
+
+ TInt index = iSkins.FindInOrder( &skinnedImage, iOrder );
+ if ( index != KErrNotFound )
+ {
+ data = iSkins[ index ]->iItemData;
+ }
+ else
+ {
+ TRAP_IGNORE( data = LoadAndAppendSkinL( skinId ) );
+ }
+ return data;
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::LoadAndAppendSkinL
+//
+// ---------------------------------------------------------
+//
+CAknsItemData* CIncallStatusBubble::LoadAndAppendSkinL(
+ const TAknsItemID& aId )
+ {
+ SSkinnedImage* newImage = new(ELeave) SSkinnedImage;
+ CleanupStack::PushL( newImage );
+
+ newImage->iId = aId;
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ newImage->iItemData = skin->CreateUncachedItemDataL( aId );
+
+ User::LeaveIfError( iSkins.InsertInOrder( newImage, iOrder ) );
+ CleanupStack::Pop( newImage ); // Ownership was given to iSkins array
+
+ return newImage->iItemData;
+ }
+
+// ---------------------------------------------------------------------------
+// CIncallStatusBubble::GetSkin
+// ---------------------------------------------------------------------------
+//
+TBool CIncallStatusBubble::GetSkin( CEikImage& aImage, const TInt aBmIcon )
+ {
+ CAknsItemData* data = GetSkinForIcon( aBmIcon );
+
+ CFbsBitmap* bitmap = NULL;
+ CFbsBitmap* bitmapMask = NULL;
+
+ if ( data )
+ {
+ switch ( data->Type() )
+ {
+ case EAknsITMaskedBitmap:
+ {
+ CAknsMaskedBitmapItemData* maskedBitmapData =
+ static_cast< CAknsMaskedBitmapItemData* >( data );
+ bitmapMask = maskedBitmapData->Mask();
+ }
+ // Flow through
+ case EAknsITBitmap:
+ {
+ CAknsBitmapItemData* bitmapData =
+ static_cast< CAknsBitmapItemData* >( data );
+ bitmap = bitmapData->Bitmap();
+ }
+ break;
+ case EAknsITColorTable:
+ {
+ // If the color for call bubble texts is not defined in the
+ // current skin, use gray.
+ TRgb colour( KRgbGray );
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ AknsUtils::GetCachedColor(
+ skin,
+ colour,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG51 );
+
+ // Load the coloured bitmap if not already loaded.
+ if ( !iSkinnedColourBitmap )
+ {
+ // Color bitmaps are not anymore supported by scalable
+ // skin server, we create our own color bitmap here.
+ TRAP_IGNORE( iSkinnedColourBitmap = CreateSkinnedColourBitmapL() );
+ }
+ // If found, use the full colour bitmap as the image and
+ // use the "real" bitmap" as the mask.
+ if ( iSkinnedColourBitmap )
+ {
+ bitmap = iSkinnedColourBitmap;
+ bitmapMask = iBitmaps->At( aBmIcon );
+ }
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ if ( bitmap )
+ {
+ aImage.SetBitmap( bitmap );
+ aImage.SetMask( bitmapMask ); // Might be NULL
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::CompareSkinnedData
+//
+// ---------------------------------------------------------
+//
+TInt CIncallStatusBubble::CompareSkinnedData(
+ const SSkinnedImage& aSkin1, const SSkinnedImage& aSkin2 )
+ {
+ return aSkin1.iId.iMinor-aSkin2.iId.iMinor ?
+ aSkin1.iId.iMinor-aSkin2.iId.iMinor :
+ aSkin1.iId.iMajor-aSkin2.iId.iMajor;
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::LoadImageL
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::LoadImageL( TInt aBitmapId )
+ {
+ CFbsBitmap* bitmap;
+ CFbsBitmap* mask;
+
+ CCleanupGuard* guard = new( ELeave ) CCleanupGuard;
+ CleanupStack::PushL( guard );
+
+ AknIconUtils::CreateIconL(
+ bitmap, mask, KCallStatusBitmapFile, aBitmapId, aBitmapId ); // use bitmap id for both mask and bitmap because of 1-bit icons
+
+ guard->SetItem1( bitmap );
+ guard->SetItem2( mask );
+
+ iBitmaps->AppendL( mask );
+ guard->SetItem2( NULL ); // mask
+ iBitmaps->AppendL( bitmap );
+ guard->SetItem1( NULL ); // bitmap
+
+ CleanupStack::PopAndDestroy(); // guard
+
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::LoadImageL
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::LoadImageL( TInt aBitmapId, TInt aMaskId )
+ {
+ CFbsBitmap* bitmap;
+ CFbsBitmap* mask;
+
+ CCleanupGuard* guard = new( ELeave ) CCleanupGuard;
+ CleanupStack::PushL( guard );
+
+ AknIconUtils::CreateIconL(
+ bitmap, mask, KCallStatusBitmapFile, aBitmapId, aMaskId );
+
+ guard->SetItem1( bitmap );
+ guard->SetItem2( mask );
+
+ iBitmaps->AppendL( bitmap );
+ guard->SetItem1( NULL ); // bitmap
+ iBitmaps->AppendL( mask );
+ guard->SetItem2( NULL ); // mask
+
+ CleanupStack::PopAndDestroy(); // guard
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::GetImage
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::GetImage(
+ CEikImage& aImage,
+ const TInt& aImageId,
+ const TInt aImageMaskId )
+ {
+ if ( GetSkin( aImage, aImageId ) )
+ {
+ return;
+ }
+
+ aImage.SetBitmap( iBitmaps->At( aImageId ) );
+ if ( aImageMaskId != KErrNotFound )
+ {
+ aImage.SetMask( iBitmaps->At( aImageMaskId ) );
+ }
+ }
+
+// ---------------------------------------------------------
+// CIncallStatusBubble::HandleResourceChange
+//
+// ---------------------------------------------------------
+//
+void CIncallStatusBubble::HandleResourceChange( TInt aType )
+ {
+ if ( aType == KAknsMessageSkinChange ||
+ aType == KEikDynamicLayoutVariantSwitch )
+ {
+ // Clear all handles
+ iSmallCallIndication->SetPicture( NULL );
+ iBubble->SetPicture( NULL );
+ iTypeIndication1->SetPicture( NULL );
+ iTypeIndication2->SetPicture( NULL );
+ iCyphOffIcon->SetPicture( NULL );
+
+ iMutedIcon->SetMutedImage( NULL, NULL );
+
+ iSmallIndiAnim->MakeVisible( EFalse );
+ iSmallIndiAnim->ClearAnimation();
+
+ // Delete old skins
+ iSkins.ResetAndDestroy();
+ delete iSkinnedColourBitmap;
+ iSkinnedColourBitmap = NULL;
+
+ // Update muted icon
+ CEikImage* tmpMutedImage = new CEikImage;
+ if ( tmpMutedImage )
+ {
+ tmpMutedImage->SetPictureOwnedExternally( ETrue );
+ GetImage(
+ *tmpMutedImage,
+ EIndexCallstatusQgn_indi_call_muted_callsta,
+ EIndexCallstatusQgn_indi_call_muted_callsta_mask
+ );
+ iMutedIcon->SetMutedImage(
+ tmpMutedImage->Bitmap(), tmpMutedImage->Mask() );
+ delete tmpMutedImage;
+ }
+
+ // Update animation
+ TInt err = KErrNone;
+ if ( iFlags & ESBVoIPCall &&
+ FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+ {
+ TRAP( err, iSmallIndiAnim->SetAnimationL( *this, CIncallAnim::EVoipCallAnim ) );
+ }
+ else if (iFlags & ESBVideo)
+ {
+ TRAP( err, iSmallIndiAnim->SetAnimationL( *this, CIncallAnim::EVideoCallAnim ) );
+ }
+ else
+ {
+ TRAP( err, iSmallIndiAnim->SetAnimationL( *this, CIncallAnim::EDefaultCallAnim ) );
+ }
+
+ if ( err )
+ {
+ iSmallIndiAnim->ClearAnimation();
+ }
+
+ // Get the other items:
+ SelectImages();
+ SizeChanged();
+ return;
+ }
+
+ CCoeControl::HandleResourceChange(aType);
+ }
+
+
+// ----------------------------------------------------------------------------
+// CIncallStatusBubble::HandlePointerEventL
+// ----------------------------------------------------------------------------
+//
+void CIncallStatusBubble::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+ {
+ // the tap event shall be igored when the keyboard is locked
+ TInt autolockState = EAutolockOff;
+ RProperty::Get( KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus, autolockState );
+ TPoint pdOffset( 3, 3 ); // Move icon to a little for "pressed" effect
+ if ( !Window().IsFaded() &&
+ AknLayoutUtils::PenEnabled() &&
+ autolockState <= EAutolockOff )
+ {
+ if ( ( aPointerEvent.iType == TPointerEvent::EButton1Down ||
+ aPointerEvent.iType == TPointerEvent::EDrag ) &&
+ Rect().Contains( aPointerEvent.iPosition ) )
+ {
+ // Draw down effects.
+ if ( ! iPressedDown )
+ {
+ GetImage(
+ *iBubble,
+ EIndexCallstatusQgn_graf_bubble_incall_disconn,
+ EIndexCallstatusQgn_graf_bubble_incall_disconn_mask );
+
+ TRect newRect = Rect();
+
+ newRect.Move( PositionRelativeToScreen() + pdOffset );
+
+ SetRect( newRect );
+
+ iPressedDown = ! iPressedDown;
+ }
+ }
+ else if ( aPointerEvent.iType == TPointerEvent::EDrag ||
+ aPointerEvent.iType == TPointerEvent::EButton1Up )
+ {
+ // Clear pressed down effects.
+ if ( iPressedDown )
+ {
+ GetImage(
+ *iBubble,
+ EIndexCallstatusQgn_graf_bubble_incall,
+ EIndexCallstatusQgn_graf_bubble_incall_mask );
+
+ TRect newRect = Rect();
+
+ newRect.Move( PositionRelativeToScreen() - pdOffset );
+
+ SetRect( newRect );
+
+ iPressedDown = !iPressedDown;
+ }
+
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Up &&
+ Rect().Contains( aPointerEvent.iPosition ) )
+ {
+
+ CCoeEnv* coeEnv = CCoeEnv::Static();
+ CCoeAppUi* appUi = NULL;
+ if ( coeEnv )
+ {
+ appUi = coeEnv->AppUi();
+ }
+
+ if ( appUi )
+ {
+ if ( ( iFlags & ESBVideo ) && ( iFlags & ESBActive ) )
+ {
+ TVwsViewId viewId( KVideoCallUid, KVideoCallUid );
+ appUi->CreateActivateViewEventL(viewId, KNullUid, KNullDesC8());
+ }
+ else
+ {
+ TVwsViewId diallerView( KPhoneAppUid, KPhoneViewUid );
+ appUi->CreateActivateViewEventL( diallerView, KPhoneVievCommand, KNullDesC8() );
+ }
+ }
+ }
+ }
+ }
+ else if (aPointerEvent.iType == TPointerEvent::EButton1Up)
+ {
+ CEikMenuBar* menuBar = CEikonEnv::Static()->AppUiFactory()->MenuBar();
+ if( menuBar && menuBar->IsVisible() )
+ {
+ //Stops displaying the uifactory's menu bar.
+ menuBar->StopDisplayingMenuBar();
+ }
+ else
+ {
+ //Stops displaying the application's menu bar.
+ CEikonEnv::Static()->EikAppUi()->StopDisplayingMenuBar();
+ }
+ }
+ }
+
+CFbsBitmap* CIncallStatusBubble::CreateSkinnedColourBitmapL()
+ {
+ TSize size( Rect().Size() );
+ if ( size == TSize( 0, 0 ) )
+ {
+ return NULL;
+ }
+
+ TRgb colour( KRgbGray );
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ AknsUtils::GetCachedColor(
+ skin,
+ colour,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG51 );
+
+ CFbsBitmap* destinationBitmap = new (ELeave) CFbsBitmap();
+ CleanupStack::PushL( destinationBitmap );
+ User::LeaveIfNull( destinationBitmap );
+
+ User::LeaveIfError( destinationBitmap->Create( size, EColor16M ) );
+
+ CFbsBitmapDevice* destinationDevice = CFbsBitmapDevice::NewL( destinationBitmap );
+ CleanupStack::PushL( destinationDevice );
+
+ CFbsBitGc* destinationGc;
+ User::LeaveIfError( destinationDevice->CreateContext( destinationGc ) );
+
+ destinationGc->SetPenColor( colour );
+ destinationGc->SetPenStyle( CGraphicsContext::ESolidPen );
+ destinationGc->SetBrushColor( colour );
+ destinationGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
+ destinationGc->DrawRect( TRect( size ) );
+
+ delete destinationGc;
+ CleanupStack::PopAndDestroy( destinationDevice );
+ CleanupStack::Pop( destinationBitmap );
+
+ return destinationBitmap;
+ }
+
+// End of File