phonebookui/Phonebook2/ccapplication/ccapp/ccapputil/src/ccappstatuscontrol.cpp
changeset 0 e686773b3f54
child 3 04ab22b956c2
--- /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 <eikimage.h>
+#include <eiklabel.h>
+#include <AknIconUtils.h>
+#include <aknutils.h>
+#include <avkon.mbg>
+#include <gulicon.h>
+#include <stringloader.h>
+#include <aknsframebackgroundcontrolcontext.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <AknsUtils.h>
+#include <AknsDrawUtils.h>
+#include <touchfeedback.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include <Pbk2PresentationUtils.h>
+
+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<TPtrC>& aTxtArray )
+    {
+    // generate array of line lengths 
+    CArrayFixFlat<TInt>* array = 
+        new(ELeave) CArrayFixFlat<TInt>( 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<TPtrC>* txtArray = 
+                new (ELeave) CArrayFixFlat<TPtrC>(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