diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook2/ccapplication/ccapp/ccapputil/src/ccappstatuscontrol.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/ccapplication/ccapp/ccapputil/src/ccappstatuscontrol.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,604 @@ +/* +* Copyright (c) 2009-2009 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: UI status control +* +*/ + + +#include "ccappstatuscontrol.h" +#include "MVPbkContactLink.h" +#include "TPbk2IconId.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +/// Amount of child UI components +const TInt KControlCount = 3; // image & label x 2 +/// Max amount of lines used to show status text. Rest will be clipped +const TInt KStatusTextLines = 2; +const TText KGraphicReplaceCharacter = ' '; + +inline CGulIcon* CreateEmptyIconL() + { + CFbsBitmap* image = NULL; + CFbsBitmap* mask = NULL; + AknIconUtils::CreateIconL( image, mask, + AknIconUtils::AvkonIconFileName(), + EMbmAvkonQgn_prop_empty, + EMbmAvkonQgn_prop_empty_mask ); + return CGulIcon::NewL( image, mask ); + } + +inline void ReSizeIcon( CGulIcon* aIcon, const TSize& aSize ) + { + if( aIcon ) + { + CFbsBitmap* bitmap = aIcon->Bitmap(); + CFbsBitmap* mask = aIcon->Mask(); + if( bitmap ) + { + AknIconUtils::SetSize( bitmap, aSize, EAspectRatioPreservedAndUnusedSpaceRemoved ); + } + if( mask ) + { + AknIconUtils::SetSize( mask, aSize, EAspectRatioPreservedAndUnusedSpaceRemoved ); + } + } + } + +} // namespace + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::NewL +// --------------------------------------------------------------------------- +// +EXPORT_C CCCAppStatusControl* CCCAppStatusControl::NewL( + CSpbContentProvider& aContentProvider, MCCAStatusControlObserver& aObserver ) + { + CCCAppStatusControl* self= new(ELeave) CCCAppStatusControl( aContentProvider, aObserver ); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::CCCAppStatusControl +// --------------------------------------------------------------------------- +// +CCCAppStatusControl::CCCAppStatusControl( + CSpbContentProvider& aContentProvider, MCCAStatusControlObserver& aObserver ) : + iContentProvider( aContentProvider ), + iObserver( aObserver ), + iDefaultResource( KErrNotFound ) + { + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::ConstructL +// --------------------------------------------------------------------------- +// +void CCCAppStatusControl::ConstructL() + { + // Create status icon image + iStatusImage = new( ELeave ) CEikImage; + iStatusImage->SetAlignment( EHCenterVCenter ); + iStatusImage->SetPictureOwnedExternally( ETrue ); + iStatusImage->SetBrushStyle( CGraphicsContext::ENullBrush ); // transparent + iStatusImage->MakeVisible( EFalse ); + + // Create status text label + iStatusLabel1 = new( ELeave ) CEikLabel; + iStatusLabel1->SetAlignment( EHLeftVCenter ); + iStatusLabel1->SetTextL( KNullDesC() ); // CEikLabel will panic without text + iStatusLabel1->MakeVisible( EFalse ); + + iStatusLabel2 = new( ELeave ) CEikLabel; + iStatusLabel2->SetAlignment( EHLeftVCenter ); + iStatusLabel2->SetTextL( KNullDesC() ); // CEikLabel will panic without text + iStatusLabel2->MakeVisible( EFalse ); + + iStatusText = KNullDesC().AllocL(); + + iContentProvider.AddObserverL( *this ); + + iBgContext = CAknsFrameBackgroundControlContext::NewL( + KAknsIIDNone, TRect(), TRect(), EFalse ); + + // normal state by default + iBgContext->SetFrame( KAknsIIDQsnFrButtonNormal ); + iBgContext->SetCenter( KAknsIIDQsnFrButtonCenterNormal ); + + // stylus feedback support + iTouchFeedBack = MTouchFeedback::Instance(); + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::~CCCAppStatusControl +// --------------------------------------------------------------------------- +// +CCCAppStatusControl::~CCCAppStatusControl() + { + if( iTouchFeedBack ) + { + iTouchFeedBack->RemoveFeedbackForControl( this ); + } + iContentProvider.RemoveObserver( *this ); + + delete iStatusImage; + delete iStatusIcon; + delete iStatusLabel1; + delete iStatusLabel2; + delete iStatusText; + delete iDefaultIcon; + delete iBgContext; + delete iLink; + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::SetPressed +// --------------------------------------------------------------------------- +// +void CCCAppStatusControl::SetPressed( TBool aPressed ) + { + if( iPressed != aPressed ) + { + iPressed = aPressed; + if( iPressed ) + { + // pressed + iBgContext->SetFrame( KAknsIIDQsnFrButtonPressed ); + iBgContext->SetCenter( KAknsIIDQsnFrButtonCenterPressed ); + DrawNow(); // respond quickly to user event + } + else + { + // normal + iBgContext->SetFrame( KAknsIIDQsnFrButtonNormal ); + iBgContext->SetCenter( KAknsIIDQsnFrButtonCenterNormal ); + DrawDeferred(); + } + } + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::IsPressed +// --------------------------------------------------------------------------- +// +TBool CCCAppStatusControl::IsPressed() + { + return iPressed; + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::CountComponentControls +// --------------------------------------------------------------------------- +// +EXPORT_C void CCCAppStatusControl::SetContactLinkL( MVPbkContactLink& aLink ) + { + delete iLink; + iLink = NULL; + iLink = aLink.CloneLC(); + CleanupStack::Pop(); // iLink + + delete iStatusText; + iStatusText = NULL; + TPbk2IconId iconId; + CSpbContentProvider::TSpbContentType type = CSpbContentProvider::ETypeNone; + iContentProvider.GetContentL( *iLink, iStatusText, iconId, type ); + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::SetDefaultStatusL +// --------------------------------------------------------------------------- +// +EXPORT_C void CCCAppStatusControl::SetDefaultStatusL( TInt aDefaultResource, + CGulIcon* aDefaultStatusIcon ) + { + iDefaultResource = aDefaultResource; + delete iDefaultIcon; + iDefaultIcon = aDefaultStatusIcon; + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::CountComponentControls +// --------------------------------------------------------------------------- +// +TInt CCCAppStatusControl::CountComponentControls() const + { + return KControlCount; + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::ComponentControl +// --------------------------------------------------------------------------- +// +CCoeControl* CCCAppStatusControl::ComponentControl( TInt aIndex ) const + { + switch( aIndex ) + { + case 0: + { + return iStatusImage; + } + case 1: + { + return iStatusLabel1; + } + case 2: + { + return iStatusLabel2; + } + } + return NULL; + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::SetVariableLayouts +// --------------------------------------------------------------------------- +// +void CCCAppStatusControl::SetVariableLayouts( TInt aOption ) + { + const TRect rect(Rect()); + // set background graphics layout + TAknWindowComponentLayout innerLayout( + AknLayoutScalable_Apps::bg_button_pane_cp033( aOption ) ); + + TAknLayoutRect innerLayoutRect; + innerLayoutRect.LayoutRect( rect, innerLayout.LayoutLine() ); + TRect innerRect( innerLayoutRect.Rect() ); + iBgContext->SetFrameRects( rect, innerRect ); + + // status icon + TAknWindowComponentLayout statusIconLayout( + AknLayoutScalable_Apps::phob2_cc_button_pane_g1( aOption ) ); + + TAknLayoutRect statusIconLayoutRect; + statusIconLayoutRect.LayoutRect( Rect(), statusIconLayout.LayoutLine() ); + TRect statusIconRect( statusIconLayoutRect.Rect() ); + iStatusIconSize = statusIconRect.Size(); + iStatusImage->SetRect( statusIconRect ); + + // status label 1 + AknLayoutUtils::LayoutLabel( + iStatusLabel1, + rect, + AknLayoutScalable_Apps::phob2_cc_button_pane_t1( aOption ) ); + + // resize images for new resolution + ReSizeIcon( iStatusIcon, iStatusIconSize ); + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::SizeChanged +// --------------------------------------------------------------------------- +// +void CCCAppStatusControl::SizeChanged() + { + const TRect rect( Rect() ); + + // update stylus feedback + if( iTouchFeedBack ) + { + iTouchFeedBack->ChangeFeedbackArea( this, 0, rect ); + } + + // status label 2 + AknLayoutUtils::LayoutLabel( + iStatusLabel2, + rect, + AknLayoutScalable_Apps::phob2_cc_button_pane_t2( 0 ) ); + + TInt count(0); + // If this leaves, it means we're out of memory. Nothing we can do. + TRAP_IGNORE( count = RewrapStatusTextL() ); + + TInt option( 1 ); + if( count > 1 ) + { + option = 0; + } + + SetVariableLayouts( option ); + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::HandlePointerEventL +// --------------------------------------------------------------------------- +// +void CCCAppStatusControl::HandlePointerEventL( + const TPointerEvent& aPointerEvent) + { + CCoeControl::HandlePointerEventL( aPointerEvent ); + + if ( aPointerEvent.iType == TPointerEvent::EButton1Down ) + { + SetPressed( ETrue ); + } + else if ( aPointerEvent.iType == TPointerEvent::EButton1Up ) + { + SetPressed( EFalse ); + if( Rect().Contains( aPointerEvent.iPosition ) ) + { + // stylus released inside the button area + iObserver.StatusClickedL(); + } + } + else if( aPointerEvent.iType == TPointerEvent::EDrag ) + { + if( Rect().Contains( aPointerEvent.iPosition ) ) + { + // stylus moved inside the button area + SetPressed( ETrue ); + } + else + { + // stylus moved outside the button area + SetPressed( EFalse ); + } + } + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::SetContainerWindowL +// --------------------------------------------------------------------------- +// +void CCCAppStatusControl::SetContainerWindowL( + const CCoeControl& aContainer ) + { + CCoeControl::SetContainerWindowL( aContainer ); + + // Assign window for child controls too + TInt childCount = CountComponentControls(); + for( TInt i = 0; i < childCount; ++i ) + { + ComponentControl( i )->SetContainerWindowL( *this ); + } + + // stylus feedback can be set only after we have parent control (window owning) + if( iTouchFeedBack ) + { + CFeedbackSpec* spec = CFeedbackSpec::New(); + if( spec ) + { + spec->AddFeedback( ETouchEventStylusDown, ETouchFeedbackBasicButton ); + iTouchFeedBack->SetFeedbackArea( this, 0, Rect(), spec ); + delete spec; + } + } + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::ContentUpdated +// --------------------------------------------------------------------------- +// +void CCCAppStatusControl::ContentUpdated( MVPbkContactLink& aLink, + MSpbContentProviderObserver::TSpbContentEvent aEvent ) + { + TRAP_IGNORE( DoStatusUpdateL( aLink, aEvent ) ); + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::DoStatusUpdateL +// --------------------------------------------------------------------------- +// +void CCCAppStatusControl::DoStatusUpdateL( MVPbkContactLink& aLink, + MSpbContentProviderObserver::TSpbContentEvent aEvent ) + { + if( aEvent == EContentNotAvailable ) + { + DefaultStatusL(); + return; + } + + if( iLink && iLink->IsSame( aLink ) ) + { + delete iStatusText; + iStatusText = NULL; + + TPbk2IconId iconId; + CSpbContentProvider::TSpbContentType type = CSpbContentProvider::ETypeNone; + iContentProvider.GetContentL( aLink, iStatusText, iconId, type ); + + TInt count( RewrapStatusTextL() ); + TInt option( 1 ); + if( count > 1 ) + { + option = 0; + } + SetVariableLayouts( option ); + + CGulIcon* icon = NULL; + TRAP_IGNORE( + { + icon = iContentProvider.CreateServiceIconLC( iconId ); + CleanupStack::Pop( icon ); + } ); + if( !icon ) + { + icon = CreateEmptyIconL(); + } + + delete iStatusIcon; + // iStatusIcon owns bitmaps + iStatusIcon = icon; + ReSizeIcon( iStatusIcon, iStatusIconSize ); + + iStatusImage->SetPicture( iStatusIcon->Bitmap(), iStatusIcon->Mask() ); + iStatusImage->MakeVisible( ETrue ); + DrawDeferred(); + } + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::RewrapStatusTextToArrayL +// --------------------------------------------------------------------------- +// +inline void CCCAppStatusControl::RewrapStatusTextToArrayL( + TDes& aStatusText, + CArrayFix& aTxtArray ) + { + // generate array of line lengths + CArrayFixFlat* array = + new(ELeave) CArrayFixFlat( KStatusTextLines ); + CleanupStack::PushL( array ); + + // check width and font from label 2, because label 2 layout is + // set before this function is called + const TInt width( iStatusLabel2->Size().iWidth ); + array->AppendL( width ); + array->AppendL( width ); + + const CFont* font = iStatusLabel2->Font(); + + // wrap text + AknTextUtils::WrapToArrayAndClipL( + aStatusText, + *array, + *font, + aTxtArray ); + + CleanupStack::PopAndDestroy( array ); + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::RewrapStatusTextL +// --------------------------------------------------------------------------- +// +TInt CCCAppStatusControl::RewrapStatusTextL() + { + TInt txtCount(0); + if( iStatusText ) + { + HBufC* statusTxtBuffer = iStatusText->AllocLC(); + TPtr statusTxt( statusTxtBuffer->Des() ); + + // replace non-allowed characters with ' ' + Pbk2PresentationUtils::ReplaceNonGraphicCharacters( + statusTxt, KGraphicReplaceCharacter ); + AknTextUtils::ReplaceCharacters( + statusTxt, + KAknCommonWhiteSpaceCharacters, + KGraphicReplaceCharacter ); + + // generate array of line lengths + CArrayFixFlat* txtArray = + new (ELeave) CArrayFixFlat(KStatusTextLines); + CleanupStack::PushL( txtArray ); + RewrapStatusTextToArrayL( statusTxt, *txtArray ); + + // assign new text + TPtrC label1(KNullDesC); + TPtrC label2(KNullDesC); + + txtCount = txtArray->Count(); + switch (txtCount) + { + case 1: + { + label1.Set( txtArray->At(0) ); + iStatusLabel1->MakeVisible( ETrue ); + iStatusLabel2->MakeVisible( EFalse ); + break; + } + case 2: + { + label1.Set( txtArray->At(0) ); + label2.Set( txtArray->At(1) ); + iStatusLabel1->MakeVisible( ETrue ); + iStatusLabel2->MakeVisible( ETrue ); + break; + } + default: + { + } + } + + iStatusLabel1->SetTextL( label1 ); + iStatusLabel2->SetTextL( label2 ); + CleanupStack::PopAndDestroy( 2, statusTxtBuffer ); // txtArray + DrawDeferred(); + } + return txtCount; + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::Draw +// --------------------------------------------------------------------------- +// +void CCCAppStatusControl::Draw( const TRect& /*aRect*/ ) const + { + TRect rect( Rect() ); + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + CWindowGc& gc = SystemGc(); + + // draw skinned background + if( !AknsDrawUtils::Background( skin, iBgContext, NULL, + gc, rect, KAknsDrawParamNoClearUnderImage ) ) + { + // if skin fails then draw solid colors + gc.SetBrushColor( iPressed ? KRgbDarkGray : KRgbGray ); + gc.SetBrushStyle( CGraphicsContext::ESolidBrush ); + gc.DrawRect( rect ); + } + } + +// --------------------------------------------------------------------------- +// CCCAppStatusControl::DefaultStatusL +// --------------------------------------------------------------------------- +// +void CCCAppStatusControl::DefaultStatusL() + { + if( iDefaultResource != KErrNotFound ) + { + delete iStatusText; + iStatusText = NULL; + iStatusText = StringLoader::LoadL( iDefaultResource ); + + const TInt count( RewrapStatusTextL() ); + TInt option( 1 ); + if( count > 1 ) + { + option = 0; + } + SetVariableLayouts( option ); + } + + if( iDefaultIcon ) + { + delete iStatusIcon; + iStatusIcon = NULL; + iStatusIcon = CGulIcon::NewL( iDefaultIcon->Bitmap(), iDefaultIcon->Mask() ); + iStatusIcon->SetBitmapsOwnedExternally( ETrue ); // iDefaultIcon owns bitmaps + ReSizeIcon( iStatusIcon, iStatusIconSize ); + + iStatusImage->SetPicture( iDefaultIcon->Bitmap(), iDefaultIcon->Mask() ); + iStatusImage->MakeVisible( ETrue ); + DrawDeferred(); + } + } + +// End of file