diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/AknIncallStatusBubble.cpp --- /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 +#endif +#include +#include +#include // Resource reader +#include // erase +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // KCoreAppUIsAutolockStatus + +#include +// 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( 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