diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/akndiscreetpopupdrawer.cpp --- /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 +#include "akndiscreetpopupcontrol.h" +#include +#include +#include +#include +#include + + +#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( 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* lineWidths + = new ( ELeave ) CArrayFixFlat( KMaxNumOfLines ); + CleanupStack::PushL( lineWidths ); + CArrayFixFlat* wrappedArray + = new ( ELeave ) CArrayFixFlat( 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 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 ) ); + + } +