--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/akndiscreetpopupdrawer.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,669 @@
+/*
+* Copyright (c) 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: Discreet popup drawer
+*
+*/
+
+#include <AknBidiTextUtils.h>
+#include "akndiscreetpopupcontrol.h"
+#include <AknIconUtils.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <AknsDrawUtils.h>
+#include <AknUtils.h>
+#include <gulicon.h>
+
+
+#include "akndiscreetpopupdrawer.h"
+
+const TInt KTextBufSize( 255 );
+const TInt KMaxNumOfLines( 2 );
+
+// Help structure for layout data
+class TPopupLayoutData
+ {
+public:
+ TUint16 iWindowVariety;
+ TUint16 iIconVariety;
+ TUint16 i1stRowVariety;
+ TUint16 i2ndRowVariety;
+ };
+
+// Layout data indexes in layout data array
+const TInt KLayoutUnresolved( -1 );
+const TInt KLayout2RowsIcon( 0 );
+const TInt KLayout2Rows( 1 );
+const TInt KLayout1RowIcon( 2 );
+const TInt KLayout1Row( 3 );
+const TInt KLayout2RowsWrappedIcon( 4 );
+const TInt KLayout2RowsWrapped( 5 );
+
+// Layout data array
+static const TPopupLayoutData KPopupLayoutData[] =
+ {
+ { 0, 0, 0, 0 },
+ { 0, 0, 1, 1 },
+ { 0, 1, 2, 0 },
+ { 0, 1, 3, 0 },
+ { 0, 4, 4, 4 },
+ { 0, 0, 5, 5 }
+ };
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::NewL
+// ---------------------------------------------------------------------------
+//
+CAknDiscreetPopupDrawer* CAknDiscreetPopupDrawer::NewL(
+ CAknDiscreetPopupControl* aControl,
+ const TDesC& aTitleText,
+ const TDesC& aBodyText,
+ CGulIcon* aIcon,
+ const TAknsItemID& aSkinId,
+ const TDesC& aBitmapFile,
+ const TInt& aBitmapId,
+ const TInt& aMaskId,
+ const TBool& aAction )
+ {
+ CAknDiscreetPopupDrawer* self =
+ CAknDiscreetPopupDrawer::NewLC( aControl,
+ aTitleText,
+ aBodyText,
+ aIcon,
+ aSkinId,
+ aBitmapFile,
+ aBitmapId,
+ aMaskId,
+ aAction );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::NewLC
+// ---------------------------------------------------------------------------
+//
+CAknDiscreetPopupDrawer* CAknDiscreetPopupDrawer::NewLC(
+ CAknDiscreetPopupControl* aControl,
+ const TDesC& aTitleText,
+ const TDesC& aBodyText,
+ CGulIcon* aIcon,
+ const TAknsItemID& aSkinId,
+ const TDesC& aBitmapFile,
+ const TInt& aBitmapId,
+ const TInt& aMaskId,
+ const TBool& aAction )
+ {
+ CAknDiscreetPopupDrawer* self
+ = new ( ELeave ) CAknDiscreetPopupDrawer( aControl, aIcon, aAction );
+ CleanupStack::PushL( self );
+ self->ConstructL( aTitleText,
+ aBodyText,
+ aSkinId,
+ aBitmapFile,
+ aBitmapId,
+ aMaskId );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::~CAknDiscreetPopupDrawer
+// ---------------------------------------------------------------------------
+//
+CAknDiscreetPopupDrawer::~CAknDiscreetPopupDrawer()
+ {
+ delete iIcon;
+ delete iBodyText;
+ delete iTitleText;
+ }
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::LayoutPopup
+// Sets popup and its components size and position.
+// ---------------------------------------------------------------------------
+//
+TRect CAknDiscreetPopupDrawer::LayoutPopup()
+ {
+ ResolvePopupLayout();
+
+ TPopupLayoutData data( KPopupLayoutData[ iPopupLayoutType ] );
+
+ TRect popupRect;
+ TRect popupBitmapRect;
+
+ GetPopupRect( data.iWindowVariety, popupRect );
+
+ // Calculate sub rects according to popup bitmap rect
+ popupBitmapRect = TRect( 0, 0, popupRect.Width(), popupRect.Height() );
+
+ // Possible icon rect
+ if ( iPopupLayoutType == KLayout2RowsIcon
+ || iPopupLayoutType == KLayout1RowIcon
+ || iPopupLayoutType == KLayout2RowsWrappedIcon )
+ {
+ iIconRect = RectFromLayout( popupBitmapRect,
+ AknLayoutScalable_Avkon::popup_discreet_window_g1(
+ data.iIconVariety ) );
+ if( iIcon && iIcon->Bitmap() )
+ {
+ AknIconUtils::SetSize( iIcon->Bitmap(), iIconRect.Size() );
+ }
+ if( iIcon && iIcon->Mask() )
+ {
+ AknIconUtils::SetSize( iIcon->Mask(), iIconRect.Size() );
+ }
+ }
+
+ // Title text font
+ TextDataFromLayout(
+ iTitleTextData,
+ popupBitmapRect,
+ AknLayoutScalable_Avkon::popup_discreet_window_t1(
+ data.i1stRowVariety ) );
+
+ // Two rows - no wrapping
+ if ( iPopupLayoutType == KLayout2RowsIcon
+ || iPopupLayoutType == KLayout2Rows )
+ {
+ // Body text font
+ TextDataFromLayout(
+ iBodyTextData,
+ popupBitmapRect,
+ AknLayoutScalable_Avkon::popup_discreet_window_t2(
+ data.i2ndRowVariety ) );
+ }
+ // Two wrapped rows
+ else if ( iPopupLayoutType == KLayout2RowsWrappedIcon
+ || iPopupLayoutType == KLayout2RowsWrapped )
+ {
+ // Body text
+ TextDataFromLayout(
+ iBodyTextData,
+ popupBitmapRect,
+ AknLayoutScalable_Avkon::popup_discreet_window_t3(
+ data.i2ndRowVariety ) );
+ // Text should be wrapped if in two-row layout and no bodytext
+ if ( iBodyText->Des() == KNullDesC )
+ {
+ TRAP_IGNORE( WrapTitleTextL() );
+ }
+ }
+
+ return popupRect;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::Draw
+// Draws popup to given graphics context.
+// ---------------------------------------------------------------------------
+//
+void CAknDiscreetPopupDrawer::Draw( CWindowGc& aGc,
+ const TRect& aRect ) const
+ {
+ // draw background of the popup
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ AknsDrawUtils::DrawFrame( skin, aGc, aRect, aRect,
+ KAknsIIDQsnFrPopupPreview, KAknsIIDDefault );
+
+ // Draw the texts
+ TRgb textColor( EikonEnv()->ControlColor( EColorControlText, *iControl ) );
+
+ if ( iAction )
+ {
+ aGc.SetUnderlineStyle( EUnderlineOn );
+ AknsUtils::GetCachedColor( skin,
+ textColor,
+ KAknsIIDQsnHighlightColors,
+ EAknsCIQsnHighlightColorsCG3 );
+ }
+ else
+ {
+ AknsUtils::GetCachedColor( skin,
+ textColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG55 );
+ }
+ aGc.SetPenColor( textColor );
+ DrawTexts( &aGc );
+ aGc.SetUnderlineStyle( EUnderlineOff );
+
+ // draw the icon
+ if ( iIcon && iIcon->Bitmap() && iIcon->Mask() )
+ {
+ aGc.BitBltMasked( iIconRect.iTl,
+ iIcon->Bitmap(),
+ iIcon->Bitmap()->SizeInPixels(),
+ iIcon->Mask(),
+ EFalse );
+
+ }
+ else if( iIcon && iIcon->Bitmap() )
+ {
+ aGc.BitBlt( iIconRect.iTl, iIcon->Bitmap() );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::CAknDiscreetPopupDrawer
+// ---------------------------------------------------------------------------
+//
+CAknDiscreetPopupDrawer::CAknDiscreetPopupDrawer(
+ CAknDiscreetPopupControl* aControl,
+ CGulIcon* aIcon,
+ const TBool& aAction )
+ :
+ iControl( aControl ),
+ iTitleText( NULL ),
+ iBodyText( NULL ),
+ iIcon( aIcon ),
+ iPopupLayoutType( KLayoutUnresolved ),
+ iAction( aAction )
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAknDiscreetPopupDrawer::ConstructL( const TDesC& aTitleText,
+ const TDesC& aBodyText,
+ const TAknsItemID& aSkinId,
+ const TDesC& aBitmapFile,
+ const TInt& aBitmapId,
+ const TInt& aMaskId )
+ {
+ // Body text to title text if title text is empty
+ if ( aTitleText == KNullDesC && aBodyText != KNullDesC )
+ {
+ iTitleText = aBodyText.AllocL();
+ }
+ else
+ {
+ iTitleText = aTitleText.AllocL();
+ iBodyText = aBodyText.AllocL();
+ }
+
+ if ( !iIcon )
+ {
+ iIcon = CreatePopupIconL( aSkinId,
+ aBitmapFile,
+ aBitmapId,
+ aMaskId );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::DrawTexts
+// ---------------------------------------------------------------------------
+//
+void CAknDiscreetPopupDrawer::DrawTexts( CWindowGc* aGc ) const
+ {
+ aGc->SetBrushStyle( CGraphicsContext::ENullBrush );
+
+ DrawBidiEnabledText( aGc, iTitleTextData, *iTitleText );
+
+ if ( iBodyTextData.iTextRect != TRect() )
+ {
+ DrawBidiEnabledText( aGc, iBodyTextData, *iBodyText );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::ResolvePopupLayout
+// Resolves popup layout type.
+// ---------------------------------------------------------------------------
+//
+void CAknDiscreetPopupDrawer::ResolvePopupLayout()
+ {
+ // Layout already resolved, do nothing
+ if ( iPopupLayoutType != KLayoutUnresolved )
+ {
+ return;
+ }
+
+ TBool withIcon( iIcon && iIcon->Bitmap() );
+ TBool twoRowsText(
+ iTitleText->Des() != KNullDesC
+ && iBodyText->Des() != KNullDesC );
+
+ // Two rows of text
+ if ( twoRowsText )
+ {
+ if ( withIcon )
+ {
+ iPopupLayoutType = KLayout2RowsIcon;
+ }
+ else
+ {
+ iPopupLayoutType = KLayout2Rows;
+ }
+ }
+ // One row of text
+ else
+ {
+ if ( withIcon )
+ {
+ iPopupLayoutType = KLayout1RowIcon;
+ }
+ else
+ {
+ iPopupLayoutType = KLayout1Row;
+ }
+
+ // Check if text should be wrapped to two lines
+ if ( TitleTextNeedsWrapping( iPopupLayoutType ) )
+ {
+ if ( withIcon )
+ {
+ iPopupLayoutType = KLayout2RowsWrappedIcon;
+ }
+ else
+ {
+ iPopupLayoutType = KLayout2RowsWrapped;
+ }
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::EikonEnv
+// Provides control eikon env.
+// ---------------------------------------------------------------------------
+//
+CEikonEnv* CAknDiscreetPopupDrawer::EikonEnv() const
+ {
+ if ( iControl )
+ {
+ return static_cast<CEikonEnv*>( iControl->ControlEnv() );
+ }
+ return NULL;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::TitleTextNeedsWrapping
+// Returns ETrue if title text needs wrapping.
+// ---------------------------------------------------------------------------
+//
+TBool CAknDiscreetPopupDrawer::TitleTextNeedsWrapping(
+ const TInt& aLayoutType )
+ {
+ const CFont* textFont( NULL );
+ TRect textRect;
+ TRect popupRect;
+ TPopupLayoutData data( KPopupLayoutData[ aLayoutType ] );
+ GetPopupRect( data.iWindowVariety, popupRect );
+ popupRect.Move( 0, 0 );
+
+ textFont = FontFromLayout(
+ popupRect,
+ AknLayoutScalable_Avkon::popup_discreet_window_t1(
+ data.i1stRowVariety ), textRect );
+ if ( textFont->TextCount( *iTitleText, textRect.Width() )
+ < iTitleText->Length() )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::WrapTitleTextL
+// Wraps long text to two lines.
+// ---------------------------------------------------------------------------
+//
+void CAknDiscreetPopupDrawer::WrapTitleTextL()
+ {
+ CArrayFixFlat<TInt>* lineWidths
+ = new ( ELeave ) CArrayFixFlat<TInt>( KMaxNumOfLines );
+ CleanupStack::PushL( lineWidths );
+ CArrayFixFlat<TPtrC>* wrappedArray
+ = new ( ELeave ) CArrayFixFlat<TPtrC>( KMaxNumOfLines );
+ CleanupStack::PushL( wrappedArray );
+
+ for ( TInt i = 0; i < KMaxNumOfLines; i++ )
+ {
+ lineWidths->AppendL( iTitleTextData.iTextRect.Width() );
+ }
+
+ HBufC* visualBuffer = HBufC::NewLC(
+ iTitleText->Length() + KMaxNumOfLines * KAknBidiExtraSpacePerLine );
+ *visualBuffer = *iTitleText;
+ TPtr ptr( visualBuffer->Des() );
+
+ AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
+ ptr, *lineWidths, *iTitleTextData.iTextFont, *wrappedArray, ETrue );
+
+ if ( wrappedArray->Count() && wrappedArray->At( 1 ) != KNullDesC )
+ {
+ delete iTitleText;
+ iTitleText = NULL;
+ delete iBodyText;
+ iBodyText = NULL;
+ iTitleText = wrappedArray->At( 0 ).AllocL();
+ iBodyText = wrappedArray->At( 1 ).AllocL();
+ }
+
+ CleanupStack::PopAndDestroy( visualBuffer );
+ CleanupStack::PopAndDestroy( wrappedArray );
+ CleanupStack::PopAndDestroy( lineWidths );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::DrawBidiEnabledText
+// ---------------------------------------------------------------------------
+//
+void CAknDiscreetPopupDrawer::DrawBidiEnabledText(
+ CWindowGc* aGc,
+ const TAknDiscreetPopupTextData& aTextData,
+ const TDesC& aText ) const
+ {
+ // Buffer for visually ordered text
+ TBuf<KTextBufSize + KAknBidiExtraSpacePerLine> visualText;
+ TInt clipWidth( aTextData.iTextRect.Width() );
+
+ // Bidi processing - using AknBidiTextUtils.
+ AknBidiTextUtils::ConvertToVisualAndClip(
+ aText, visualText, *aTextData.iTextFont, clipWidth, clipWidth );
+
+ TInt baselineOffset(
+ aTextData.iTextFont->AscentInPixels()
+ + ( aTextData.iTextRect.Height()
+ - aTextData.iTextFont->AscentInPixels() ) / 2 );
+
+ aGc->UseFont( aTextData.iTextFont );
+ aGc->DrawText(
+ visualText,
+ aTextData.iTextRect,
+ baselineOffset,
+ aTextData.iTextAlignment );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::CreatePopupIconL
+// Creates icon of given parameters.
+// ---------------------------------------------------------------------------
+//
+CGulIcon* CAknDiscreetPopupDrawer::CreatePopupIconL( const TAknsItemID& aSkinId,
+ const TDesC& aBitmapFile,
+ const TInt& aBitmapId,
+ const TInt& aMaskId )
+ {
+ if ( !ImageInfoAvailable( aSkinId, aBitmapFile, aBitmapId ) )
+ {
+ return NULL;
+ }
+
+ CGulIcon* icon = NULL;
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ // Only skin id defined
+ if ( aBitmapFile == KNullDesC || aBitmapId == -1 )
+ {
+ if ( aSkinId != KAknsIIDNone && skin )
+ {
+ icon = AknsUtils::CreateGulIconL( skin, aSkinId, EFalse );
+ }
+ }
+ else
+ {
+ // Skin id and bitmap file info defined
+ if ( aSkinId != KAknsIIDNone && skin )
+ {
+ icon = AknsUtils::CreateGulIconL( skin,
+ aSkinId,
+ aBitmapFile,
+ aBitmapId,
+ aMaskId);
+ }
+
+ // Only bitmap file info defined
+ else
+ {
+ CFbsBitmap* bmp;
+ CFbsBitmap* mask;
+ AknIconUtils::CreateIconLC( bmp,
+ mask,
+ aBitmapFile,
+ aBitmapId,
+ aMaskId );
+ icon = CGulIcon::NewL( bmp, mask ); // ownership passed
+ CleanupStack::Pop( mask );
+ CleanupStack::Pop( bmp );
+ }
+ }
+ return icon;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::ImageInfoAvailable
+// ---------------------------------------------------------------------------
+//
+TBool CAknDiscreetPopupDrawer::ImageInfoAvailable( const TAknsItemID& aSkinId,
+ const TDesC& aBitmapFile,
+ const TInt& aBitmapId )
+ {
+ if ( aSkinId != KAknsIIDNone && aSkinId != KAknsIIDDefault )
+ {
+ return ETrue;
+ }
+ if ( aBitmapFile != KNullDesC && aBitmapId > 0 )
+ {
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::RectFromLayout
+// Returns the specified layout rectangle.
+// ---------------------------------------------------------------------------
+//
+TRect CAknDiscreetPopupDrawer::RectFromLayout( const TRect& aParent,
+ const TAknWindowComponentLayout& aComponentLayout )
+ {
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( aParent, aComponentLayout.LayoutLine() );
+ return layoutRect.Rect();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::TextDataFromLayout
+// Fills text data according to text layout.
+// ---------------------------------------------------------------------------
+//
+void CAknDiscreetPopupDrawer::TextDataFromLayout(
+ TAknDiscreetPopupTextData& aTextData,
+ const TRect& aParent,
+ const TAknTextComponentLayout& aComponentLayout )
+ {
+ aTextData.iTextFont =
+ FontFromLayout( aParent, aComponentLayout, aTextData.iTextRect );
+ switch ( aComponentLayout.J() )
+ {
+ case ELayoutAlignRight:
+ {
+ aTextData.iTextAlignment = CGraphicsContext::ERight;
+ break;
+ }
+ case ELayoutAlignLeft:
+ {
+ aTextData.iTextAlignment = CGraphicsContext::ELeft;
+ break;
+ }
+ case ELayoutAlignCenter:
+ {
+ aTextData.iTextAlignment = CGraphicsContext::ECenter;
+ break;
+ }
+ default:
+ {
+ aTextData.iTextAlignment = CGraphicsContext::ECenter;
+ break;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::FontFromLayout
+// Returns the specified text layout font.
+// ---------------------------------------------------------------------------
+//
+const CFont* CAknDiscreetPopupDrawer::FontFromLayout(
+ const TRect& aParent,
+ const TAknTextComponentLayout& aComponentLayout,
+ TRect& aTextRect )
+ {
+ TAknLayoutText layoutRect;
+ layoutRect.LayoutText( aParent, aComponentLayout.LayoutLine() );
+ aTextRect = layoutRect.TextRect();
+ return layoutRect.Font();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknDiscreetPopupDrawer::GetPopupRect
+// Provides popup rect.
+// ---------------------------------------------------------------------------
+//
+void CAknDiscreetPopupDrawer::GetPopupRect(
+ const TInt& aWindowVariety, TRect& aRect )
+ {
+ TRect appRect;
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::EApplicationWindow, appRect);
+
+ // Popup rect
+ aRect = RectFromLayout(
+ appRect,
+ AknLayoutScalable_Avkon::popup_discreet_window(
+ aWindowVariety ) );
+
+ }
+