diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/akntitle.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uifw/AvKon/src/akntitle.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,2849 @@ +/* +* 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: Implementation for the default control in the +* status pane's title pane. +* +*/ + + +// SYSTEM INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +// USER INCLUDE FILES +#include "aknappui.h" +#include "AknUtils.h" +#include "avkon.hrh" +#include "AknPanic.h" +#include "akntitle.h" +#include "aknconsts.h" +#include "AknStatuspaneUtils.h" +#include "AknTitlePaneLabel.h" +#include "AknTitlePaneObserver.h" +#include "aknnavi.h" +#include "aknnavide.h" + +// Titlepane flags +enum TTitlePaneControlFlags + { + EAknTitlePaneButton1DownInTitleRect = 0x00000001 + }; + +// Scrolling related constants +const TInt KScrollPauseBeforeScroll = 1000000; // 1.0s +const TInt KScrollPauseBeforeFadeOut = 2000000; // 2s +const TInt KScrollPauseBeforeFadeIn = 500000; // 0.5s +const TInt KScrollFadeInFadeOutDuration = 1000000; // 1s + +const TInt KTitleMaxLines = 2; + +NONSHARABLE_CLASS( CAknTitlePaneExtension ) + : public CBase, + public MAknPictographAnimatorCallBack + { +public: + static CAknTitlePaneExtension* NewL( CAknTitlePane& aOwner ); + ~CAknTitlePaneExtension(); + +private: // From MAknPictographAnimatorCallBack + void DrawPictographArea(); + +private: + CAknTitlePaneExtension( CAknTitlePane& aOwner ); + void ConstructL(); + +public: + CAknTitlePane& iOwner; + CEikImage* iTitleImage; + CAknPictographInterface* iPictoInterface; + + TInt iFlags; + + TBool iSmallImageShown; + TBool iScrollEffectEnabled; + TBool iScrollEffectNeeded; + TInt iCurrentNumberOfTextLines; + TInt iLimitedNumberOfTextLines; + + TBool iImageAutoscaling; + TBool iSmallImageAutoscaling; + }; + + +// ---------------------------------------------------------------------------- +// CAknTitlePaneExtension::NewL +// Two-phased constructor. +// ---------------------------------------------------------------------------- +// +CAknTitlePaneExtension* CAknTitlePaneExtension::NewL( CAknTitlePane& aOwner ) + { + CAknTitlePaneExtension* self = + new( ELeave ) CAknTitlePaneExtension( aOwner ); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePaneExtension::~CAknTitlePaneExtension +// Destructor. +// ---------------------------------------------------------------------------- +// +CAknTitlePaneExtension::~CAknTitlePaneExtension() + { + delete iTitleImage; + delete iPictoInterface; + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePaneExtension::CAknTitlePaneExtension +// C++ constructor. +// ---------------------------------------------------------------------------- +// +CAknTitlePaneExtension::CAknTitlePaneExtension( CAknTitlePane& aOwner ) + : iOwner( aOwner ) + { + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePaneExtension::ConstructL +// Second-phase constructor. +// ---------------------------------------------------------------------------- +// +void CAknTitlePaneExtension::ConstructL() + { + iTitleImage = new( ELeave ) CEikImage; + iTitleImage->SetContainerWindowL( iOwner ); + iTitleImage->SetNonFocusing(); + iTitleImage->ActivateL(); + + // Returns NULL if not supported. + iPictoInterface = CAknPictographInterface::NewL( iOwner, *this ); + iScrollEffectEnabled = EFalse; + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePaneExtension::DrawPictographArea +// Draws the pictographs. +// ---------------------------------------------------------------------------- +// +void CAknTitlePaneExtension::DrawPictographArea() + { + iOwner.DrawDeferred(); + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::CAknTitlePane +// Default constructor. +// ---------------------------------------------------------------------------- +// +EXPORT_C CAknTitlePane::CAknTitlePane() + { + AKNTASHOOK_ADD( this, "CAknTitlePane" ); + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::~CAknTitlePane +// Destructor. +// ---------------------------------------------------------------------------- +// +EXPORT_C CAknTitlePane::~CAknTitlePane() + { + AKNTASHOOK_REMOVE(); + AknsUtils::DeregisterControlPosition( this ); + + delete iTitleText; + delete iDefaultTitleText; + delete iTitleLabel; + delete iExtension; + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::ConstructL +// Second-phase constructor. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::ConstructL() + { + CommonConstructL(); + SetTextToDefaultL(); + + if ( AknLayoutUtils::PenEnabled() ) + { + // set flags to default values + iExtension->iFlags = 0; + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::ConstructFromResourceL +// Resource constructor. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::ConstructFromResourceL( TResourceReader& aReader ) + { + CommonConstructL(); + ReadFromResourceFileL( aReader ); + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetTextL +// Sets the title pane text. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::SetTextL( const TDesC& aText ) + { + SetText( aText.AllocL(), EFalse ); + } + + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetText +// Sets the title pane text. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::SetText( HBufC* aText ) + { + SetText( aText, EFalse ); + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetSmallPicture +// Sets the small title pane picture. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::SetSmallPicture( const CFbsBitmap* aBitmap, + const CFbsBitmap* aMaskBitmap, + TBool aVisible ) + { + if ( iExtension->iTitleImage ) + { + // If NULL image is given, previous (existing) image is shown. + if ( aBitmap ) + { + iExtension->iTitleImage->SetPictureOwnedExternally( EFalse ); + iExtension->iTitleImage->SetPicture( aBitmap, aMaskBitmap ); + + if ( iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Bitmap()->SizeInPixels() == TSize( 0, 0 ) ) + { + // Picture is scaled by title pane if the bitmap's + // size is not set. + iExtension->iSmallImageAutoscaling = ETrue; + } + else + { + iExtension->iSmallImageAutoscaling = EFalse; + } + } + + if ( aVisible ) + { + iExtension->iSmallImageShown = ETrue; + iImageShown = EFalse; + } + else + { + iExtension->iSmallImageShown = EFalse; + iImageShown = EFalse; + } + + SizeChanged(); + DrawDeferred(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetPicture +// Sets the large title pane picture (operator logo). +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::SetPicture( const CFbsBitmap* aBitmap, + const CFbsBitmap* aMaskBitmap ) + { + if ( iExtension && iExtension->iTitleImage ) + { + // If NULL image is given, previous (existing) image is shown. + if ( aBitmap ) + { + iExtension->iTitleImage->SetPictureOwnedExternally( EFalse ); + iExtension->iTitleImage->SetPicture( aBitmap, aMaskBitmap ); + + if ( iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Bitmap()->SizeInPixels() == TSize( 0, 0 ) ) + { + // Picture is scaled by title pane if the bitmap's + // size is not set. + iExtension->iImageAutoscaling = ETrue; + } + else + { + iExtension->iImageAutoscaling = EFalse; + } + } + + iImageShown = ETrue; + iExtension->iSmallImageShown = EFalse; + SizeChanged(); + DrawDeferred(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetSmallPictureFromFileL +// Sets the small title pane picture from a file. +// Used by the resource constructor. +// ---------------------------------------------------------------------------- +// +void CAknTitlePane::SetSmallPictureFromFileL( const TDesC& aFileName, + TInt aMainId, + TInt aMaskId ) + { + if ( iExtension && iExtension->iTitleImage ) + { + CEikImage*& img = iExtension->iTitleImage; + delete img; + img = NULL; + + img = new (ELeave) CEikImage; + img->CreatePictureFromFileL( aFileName, aMainId, aMaskId ); + + iImageShown = EFalse; + iExtension->iSmallImageShown = ETrue; + + iExtension->iTitleImage->SetPictureOwnedExternally( EFalse ); + + if ( iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Bitmap()->SizeInPixels() == TSize( 0, 0 ) ) + { + // Picture is scaled by title pane if the bitmap's + // size is not set. + iExtension->iSmallImageAutoscaling = ETrue; + } + else + { + iExtension->iSmallImageAutoscaling = EFalse; + } + + SizeChanged(); + DrawDeferred(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetPictureFromFileL +// Sets the large title pane picture (operator logo) from a file. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::SetPictureFromFileL( const TDesC& aFileName, + TInt aMainId, + TInt aMaskId ) + { + CEikImage*& img = iExtension->iTitleImage; + + delete img; + img = NULL; + + img = new (ELeave) CEikImage; + img->SetContainerWindowL( *this ); + img->SetNonFocusing(); + img->ActivateL(); + img->CreatePictureFromFileL( aFileName, aMainId, aMaskId ); + + iImageShown = ETrue; + iExtension->iSmallImageShown = EFalse; + + if ( iExtension->iTitleImage && + iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Bitmap()->SizeInPixels() == TSize( 0, 0 ) ) + { + iExtension->iImageAutoscaling = ETrue; + } + else + { + iExtension->iImageAutoscaling = EFalse; + } + + SizeChanged(); + DrawDeferred(); + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetFromResourceL +// Sets the title pane content from a resource. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::SetFromResourceL( TResourceReader& aReader ) + { + if ( !iTitleLabel && !iExtension ) // not constructed yet + { + ConstructFromResourceL( aReader ); + } + else // update from resource + { + ReadFromResourceFileL(aReader); + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetTextToDefaultL +// Sets the title pane text to default (application name). +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::SetTextToDefaultL() + { + iExtension->iScrollEffectEnabled = EFalse; + + if ( iDefaultTitleText ) + { + SetTextL( *iDefaultTitleText ); + return; + } + + TBool textSet = EFalse; + RApaLsSession lsSession; + TInt ret = lsSession.Connect(); + if ( ret == KErrNone ) + { + CleanupClosePushL( lsSession ); + TApaAppInfo appInfo; + ret = lsSession.GetAppInfo( appInfo, AppUid() ); + if ( ret == KErrNone ) + { + iDefaultTitleText = appInfo.iCaption.AllocL(); + SetTextL( *iDefaultTitleText ); + textSet = ETrue; + } + CleanupStack::PopAndDestroy( &lsSession); + } + + if ( !textSet ) + { + SetTextL( KTitlePaneDefaultText ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::PrepareContext +// Updates the text color for the window context from skin. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::PrepareContext( CWindowGc& aGc ) const + { + if ( !iImageShown ) + { + TRgb color; + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + TInt error = AknsUtils::GetCachedColor( skin, + color, + KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG1 ); + if ( !error ) + { + aGc.SetPenColor( color ); + } + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SizeChanged +// Handles size change events. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::SizeChanged() + { + // No fading if staconpane is active, because status pane + // and control pane are combined. + SetContainerWindowNonFading( AknStatuspaneUtils::StaconPaneActive() ); + + // If fonts are destroyed with ENV destruction sequence, then abort. + // TBD is a way to detect it right, we use this hack instead for now. + if ( !( iEikonEnv->Alert() ) ) + { + return; + } + + TInt spLayout( AknStatuspaneUtils::CurrentStatusPaneLayoutResId() ); + + if ( AknStatuspaneUtils::StaconPaneActive() ) + { + SizeChangedInStaconPane(); + } + else if ( AknStatuspaneUtils::FlatLayoutActive() ) + { + SizeChangedInFlatStatusPane(); + } + else if ( AknStatuspaneUtils::ExtendedLayoutActive() || + spLayout == R_AVKON_STATUS_PANE_LAYOUT_VT || + spLayout == R_AVKON_STATUS_PANE_LAYOUT_VT_MIRRORED ) + { + // Use the extended title pane layout also for + // the video telephony status pane layout, since + // two-row title text is no longer supported. + SizeChangedInExtendedStatusPane(); + } + else + { + SizeChangedInNormalStatusPane(); + } + + // Update also the navi pane size, because in flat status pane layout + // it draws part of the title pane if narrow navi pane + // layout is in use. + CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current(); + if ( statusPane ) + { + CCoeControl* naviPane = NULL; + + TRAP_IGNORE( + naviPane = statusPane->ContainerControlL( + TUid::Uid( EEikStatusPaneUidNavi ) ) ); + + if ( naviPane ) + { + naviPane->DrawDeferred(); + } + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::PositionChanged +// Handles position change events. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::PositionChanged() + { + AknsUtils::RegisterControlPosition( this ); + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::HandleResourceChange +// Handles resource change events. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::HandleResourceChange( TInt aType ) + { + CCoeControl::HandleResourceChange( aType ); + + if ( aType == KEikDynamicLayoutVariantSwitch || + aType == KEikColorResourceChange || + aType == KAknsMessageSkinChange ) + { + SizeChanged(); + DrawDeferred(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::CountComponentControls +// Returns the amount of component controls. +// ---------------------------------------------------------------------------- +// +EXPORT_C TInt CAknTitlePane::CountComponentControls() const + { + TInt controls( 0 ); + + if ( ( AknStatuspaneUtils::StaconPaneActive() || + AknStatuspaneUtils::FlatLayoutActive() || + AknStatuspaneUtils::ExtendedLayoutActive()) && + !iImageShown ) + { + // Both small image and text can be show simultaneusly + if ( iTitleLabel ) + { + controls++; + } + + if ( iExtension->iSmallImageShown && + iExtension->iTitleImage ) + { + controls++; + } + } + else + { + // Only image or text can be shown simultaneusly + if ( ( iImageShown && + iExtension->iTitleImage ) || + ( !iImageShown && iTitleLabel ) ) + { + controls++; + } + } + + return controls; + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::ComponentControl +// Gets a component control by a control index. +// ---------------------------------------------------------------------------- +// +EXPORT_C CCoeControl* CAknTitlePane::ComponentControl( TInt aIndex ) const + { + CCoeControl* componentControl = NULL; + + if ( ( AknStatuspaneUtils::StaconPaneActive() || + AknStatuspaneUtils::FlatLayoutActive() || + AknStatuspaneUtils::ExtendedLayoutActive() ) && + !iImageShown ) + { + // Both image and text can be show simultaneusly + if ( aIndex == 0 && iExtension->iSmallImageShown ) + { + componentControl = iExtension->iTitleImage; + } + else + { + componentControl = iTitleLabel; + } + } + else + { + // Only image or text can be shown simultaneusly + if ( iImageShown ) + { + componentControl = iExtension->iTitleImage; + } + else + { + componentControl = iTitleLabel; + } + } + + return componentControl; + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::Draw +// Draws the title pane. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::Draw( const TRect& aRect ) const + { + const TUid KActiveIdle2Uid = {0x102750F0}; + + if ( AppUid() == KActiveIdle2Uid ) + { + CWindowGc& gc = SystemGc(); + TRgb rgb(TRgb::Color16MA(0)); + gc.SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); + gc.SetBrushStyle(CGraphicsContext::ESolidBrush); + gc.SetBrushColor(rgb); + gc.Clear( aRect ); + return; + } + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + + TRect rect( Rect() ); + + CWindowGc& gc=SystemGc(); + + if ( AknStatuspaneUtils::StaconPaneActive() || + AknStatuspaneUtils::FlatLayoutActive() ) + { + MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); + + if( !AknsDrawUtils::Background( skin, cc, this, gc, rect ) ) + { + gc.SetPenStyle( CGraphicsContext::ENullPen ); + gc.SetBrushStyle( CGraphicsContext::ESolidBrush ); + gc.SetBrushColor( + AKN_LAF_COLOR( KStatusPaneBackgroundGraphicsColorUsual ) ); + gc.DrawRect( rect ); + } + } + else + { + gc.SetBrushStyle( CGraphicsContext::ESolidBrush ); + gc.SetBrushColor( AKN_LAF_COLOR( KStatusPaneBackgroundColor ) ); + AknsDrawUtils::Background( skin, + AknsDrawUtils::ControlContext( this ), + this, + gc, + rect ); + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::CommonConstructL +// Common second-phase constructor for normal and resource construction. +// ---------------------------------------------------------------------------- +// +void CAknTitlePane::CommonConstructL() + { + iTitleLabel = new (ELeave) CAknTitlePaneLabel; + // we do logical to visual conversion ourselves while wrapping text + iTitleLabel->UseLogicalToVisualConversion( EFalse ); + + iExtension = CAknTitlePaneExtension::NewL( *this ); + + if ( iExtension->iPictoInterface ) + { + iTitleLabel->SetPictographInterface( *iExtension->iPictoInterface ); + } + + iTitleLabel->SetContainerWindowL( *this ); + iTitleLabel->SetNonFocusing(); + iTitleLabel->ActivateL(); + + // Observer is needed with pensupport + iTitlePaneObserver = NULL; + + SetControlContext( this ); + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::AppUid +// Gets the application UID. +// ---------------------------------------------------------------------------- +// +TUid CAknTitlePane::AppUid() const + { + CEikApplication* app = iEikonEnv->EikAppUi()->Application(); + if ( app ) + { + return app->AppDllUid(); + } + else + { + return KNullUid; + } + } + + +NONSHARABLE_CLASS( CTextLayoutManager ) : public CBase + { +public: + enum TLayout + { + ENoLayout, + EOneLineLayout, + ETwoLineLayout + }; + +public: + CTextLayoutManager( const TInt aOneLineLayoutWidth, + const TInt aTwoLineLayoutWidth, + const CFont* aOneLineFont, + const CFont* aTwoLineFont ) + : iOneLineWidth( aOneLineLayoutWidth ), + iTwoLineWidth( aTwoLineLayoutWidth ), + iOneLineFont( aOneLineFont ), + iTwoLineFont( aTwoLineFont ) + {} + + static CTextLayoutManager* NewLC( const TInt aOneLineLayoutWidth, + const TInt aTwoLineLayoutWidth, + const CFont* aOneLineFont, + const CFont* aTwoLineFont ); + void ConstructL(); + ~CTextLayoutManager(); + + void Reset(); + void DoLayoutL( TInt aLineNum, const TDesC& aText ); + const TLayout& Layout() const; + + TInt Lines() const; + const TDesC& Text() const; + +private: + TInt iOneLineWidth; + TInt iTwoLineWidth; + const CFont* iOneLineFont; // not owned + const CFont* iTwoLineFont; // not owned + + CArrayFixFlat* iLineWidthArray; + HBufC* iText; + TLayout iLayout; + + }; + + +CTextLayoutManager* CTextLayoutManager::NewLC( const TInt aOneLineLayoutWidth, + const TInt aTwoLineLayoutWidth, + const CFont* aOneLineFont, + const CFont* aTwoLineFont ) + { + CTextLayoutManager* self = new (ELeave) CTextLayoutManager( + aOneLineLayoutWidth, aTwoLineLayoutWidth, aOneLineFont, aTwoLineFont ); + CleanupStack::PushL( self ); + + self->ConstructL(); + return self; + } + + +void CTextLayoutManager::ConstructL() + { + iLineWidthArray = new (ELeave) CArrayFixFlat( KTitleMaxLines ); + } + + +CTextLayoutManager::~CTextLayoutManager() + { + if ( iLineWidthArray ) + { + iLineWidthArray->Reset(); + } + + delete iLineWidthArray; + delete iText; + } + + +void CTextLayoutManager::Reset() + { + delete iText; + iText = NULL; + + if ( iLineWidthArray ) + { + iLineWidthArray->Reset(); + } + iLayout = ENoLayout; + } + + +void CTextLayoutManager::DoLayoutL( TInt aLineNum, const TDesC& aText ) + { + __ASSERT_DEBUG( aLineNum == 1 || aLineNum == 2, + Panic( EAknPanicNotSupported ) ); + + __ASSERT_DEBUG( iLineWidthArray->Count() == 0, + Panic( EAknPanicSelfCheckFailure ) ); + + const CFont* font = NULL; + + if ( aLineNum == 1 ) + { + iLineWidthArray->AppendL( iOneLineWidth ); + if ( iTwoLineWidth ) + { + // Added only if there exists 2nd line. + iLineWidthArray->AppendL( iTwoLineWidth ); + } + font = iOneLineFont; + iLayout = EOneLineLayout; + } + else + { + iLineWidthArray->AppendL( iOneLineWidth ); + if ( iTwoLineWidth ) + { + // Added only if there exists 2nd line. + iLineWidthArray->AppendL( iTwoLineWidth ); + } + font = iTwoLineFont; + iLayout = ETwoLineLayout; + } + + __ASSERT_DEBUG( iText == NULL, Panic( EAknPanicNullPointer ) ); + + if ( !iText ) + { + // +1 is for line ends + iText = HBufC::NewL( + aText.Length() + KTitleMaxLines * (KAknBidiExtraSpacePerLine + 1) ); + } + + TPtr ptr = iText->Des(); + AknBidiTextUtils::ConvertToVisualAndWrapToStringL( + aText, *iLineWidthArray, *font, ptr, ETrue ); + + } + + +/** + * Return type of layout set in DoLayout operation, either one line + * layout or two line layout. + */ +const CTextLayoutManager::TLayout& CTextLayoutManager::Layout() const + { + return iLayout; + } + + +/** + * Return number of lines by locating \n chars + * in the text. These have been inserted by wrapping + * algorithm. + */ +TInt CTextLayoutManager::Lines() const + { + __ASSERT_DEBUG( iText, Panic( EAknPanicNullPointer ) ); + TInt nLines = 0; + TInt pos = iText->Length(); + + do + { + TPtrC ptrC( iText->Left( pos ) ); + pos = ptrC.LocateReverseF( '\n' ); + } + while ( pos >= 0 && ++nLines ); + return nLines; + } + + +const TDesC& CTextLayoutManager::Text() const + { + __ASSERT_DEBUG( iText, Panic( EAknPanicNullPointer ) ); + return *iText; + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::FormatTitlePaneLabelL +// Formats the title pane text. +// ---------------------------------------------------------------------------- +// +TInt CAknTitlePane::FormatTitlePaneLabelL( const TInt aOneLineLayoutWidth, + const TInt aTwoLineLayoutWidth, + const CFont* aOneLineFont, + const CFont* aTwoLineFont ) + { + if ( !iTitleLabel ) + { + return 0; + } + + if ( Rect().Width() < 1 ) + { + iTitleLabel->SetTextL( *iTitleText ); + return 0; + } + + TPtr ptr( iTitleText->Des() ); + TBuf<1> stripCharacters; + stripCharacters.Append( KPuaCodeLineFeedSymbol ); + AknTextUtils::StripCharacters( ptr, stripCharacters ); + + // Check if 2nd line usage has been limited + TInt oneLineLayoutWidth = aOneLineLayoutWidth; + TInt twoLineLayoutWidth = aTwoLineLayoutWidth; + if ( iExtension && iExtension->iLimitedNumberOfTextLines > 0 && + iExtension->iLimitedNumberOfTextLines < MaxNumberOfVisibleTextRows() ) + { + twoLineLayoutWidth = 0; + } + + // We remove control chars here if one line layout is in use, + // but we don't touch the original text because if we go to + // 2-line layout we would not have the line feeds anymore + // that some text may contain. + HBufC* titleText = iTitleText->AllocLC(); + + if ( twoLineLayoutWidth == 0 ) + { + iTitleLabel->ReplaceControlCharacters( titleText, ETrue ); + } + else + { + iTitleLabel->ReplaceControlCharacters( titleText, EFalse ); + } + + CTextLayoutManager* layoutMgr = CTextLayoutManager::NewLC( + oneLineLayoutWidth, twoLineLayoutWidth, aOneLineFont, aTwoLineFont ); + + layoutMgr->DoLayoutL( 1, *titleText ); + if ( layoutMgr->Lines() > 1 ) + { + layoutMgr->Reset(); + layoutMgr->DoLayoutL( 2, *titleText ); + } + + const CTextLayoutManager::TLayout& layout( layoutMgr->Layout() ); + + TInt lines = + layout == CTextLayoutManager::ETwoLineLayout ? 2 : layoutMgr->Lines(); + + iTitleLabel->SetTextL( layoutMgr->Text() ); + + TBool truncated = iTitleLabel->Text()->Locate( KEllipsis ) != KErrNotFound; + + if ( iExtension ) + { + iExtension->iCurrentNumberOfTextLines = lines; + } + + if ( iExtension ) + { + iExtension->iScrollEffectNeeded = truncated; + } + + CleanupStack::PopAndDestroy( 2, titleText ); // titleText, layoutMgr + return lines; + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::ReadFromResourceFileL +// Updates title pane content from a resource file. +// ---------------------------------------------------------------------------- +// +void CAknTitlePane::ReadFromResourceFileL( TResourceReader& aReader ) + { + if ( iTitleLabel ) + { + iTitleLabel->InvalidateText(); + } + + delete iTitleText; + iTitleText = NULL; + iTitleText = aReader.ReadHBufCL(); + + HBufC* bitmapFile = aReader.ReadHBufCL(); // bmp filename + TInt bitmapId = aReader.ReadInt16(); // bmp id + TInt maskId = aReader.ReadInt16(); // bmp mask id + + if ( !iTitleText ) + { + if ( bitmapFile ) + { + CleanupStack::PushL( bitmapFile ); + if ( bitmapId != KErrNotFound ) + { + SetPictureFromFileL( *bitmapFile, bitmapId, maskId ); + } + else + { + SetTextToDefaultL(); + } + CleanupStack::PopAndDestroy( bitmapFile ); + } + else + { + SetTextToDefaultL(); + } + } + else + { + if ( bitmapFile ) + { + CleanupStack::PushL( bitmapFile ); + if ( bitmapId != KErrNotFound ) + { + SetSmallPictureFromFileL( *bitmapFile, bitmapId, maskId ); + } + else + { + SetTextToDefaultL(); + } + CleanupStack::PopAndDestroy( bitmapFile ); + } + + iImageShown = EFalse; + SizeChanged(); + DrawDeferred(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SizeChangedInNormalStatusPane +// Handles size change events in normal status pane layout. +// ---------------------------------------------------------------------------- +// +void CAknTitlePane::SizeChangedInNormalStatusPane() + { + AknsUtils::RegisterControlPosition( this ); + + TRect rect( Rect() ); + + if ( iTitleLabel && !iImageShown ) + { + __ASSERT_DEBUG( iTitleText, Panic( EAknPanicNullPointer ) ); + + TInt indexW( 0 ); + if ( AknStatuspaneUtils::IdleLayoutActive() ) + { // Is battery pane visible in current layout + indexW = 1; + } + + TAknTextLineLayout oneLineLayout( + AknLayoutScalable_Avkon::title_pane_t1( 0 ).LayoutLine() ); + + const TAknMultiLineTextLayout twoLineLayout( + AKN_LAYOUT_MULTILINE_TEXT_Title_pane_texts_Line_2( indexW, 2 ) ); + + // if text would truncate, then try to use + // smaller font with one line layout + if ( !TextFits( oneLineLayout ) ) + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t2( 1 ).LayoutLine(); + } + + TAknLayoutText oneLineLayoutText; + oneLineLayoutText.LayoutText( rect, oneLineLayout); + TRect oneLineLayoutRect( oneLineLayoutText.TextRect() ); + + TAknLayoutText twoLineLayoutText; + twoLineLayoutText.LayoutText( rect, twoLineLayout); + TRect twoLineLayoutRect( twoLineLayoutText.TextRect() ); + + TInt lines = 0; + + TRAP_IGNORE( + lines = FormatTitlePaneLabelL( + oneLineLayoutRect.Width(), + twoLineLayoutRect.Width(), + AknLayoutUtils::FontFromId( oneLineLayout.FontId() ), + AknLayoutUtils::FontFromId( twoLineLayout.FontId() ) ) + ); // Ignore leave. Only layout of the title pane + // suffers if leave happens. + + if ( lines <= 1 ) + { + AknLayoutUtils::LayoutLabel( iTitleLabel, rect, oneLineLayout ); + } + else + { + AknLayoutUtils::LayoutLabel( iTitleLabel, rect, twoLineLayout ); + } + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + TRgb color; + + TInt error = AknsUtils::GetCachedColor( skin, + color, + KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG1 ); + + if ( !error ) + { + // Ignore error + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( + *iTitleLabel, EColorLabelText, color ) ); + } + + if ( iExtension && + ( iExtension->iScrollEffectEnabled || + iTitleLabel->TextEffect() || + !iTitleLabel->EffectQueueIsEmpty() ) ) + { + TRAP_IGNORE( SetupTitleLabelEffectL() ); + if ( !iTitleLabel->TextEffect() ) + { + if ( lines <= 1 ) + { + AknLayoutUtils::LayoutLabel( iTitleLabel, + rect, + oneLineLayout ); + } + else + { + AknLayoutUtils::LayoutLabel( iTitleLabel, + rect, + twoLineLayout ); + } + // Ignore error + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( + *iTitleLabel, EColorLabelText, color ) ); + } + } + } + else if ( iExtension && iExtension->iTitleImage ) + { + TAknLayoutRect layoutRect; + layoutRect.LayoutRect( rect, AknLayoutScalable_Avkon::title_pane_g1() ); + TRect bmpRect( layoutRect.Rect() ); + TSize bmpSize( bmpRect.Size() ); + + if ( iExtension->iImageAutoscaling && + iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Mask() ) + { + CFbsBitmap* bitmap = + const_cast ( iExtension->iTitleImage->Bitmap() ); + AknIconUtils::SetSize( bitmap, bmpSize ); + } + else if ( !iExtension->iImageAutoscaling && + iExtension->iTitleImage->Bitmap() ) + { + bmpSize = iExtension->iTitleImage->Bitmap()->SizeInPixels(); + } + + TGulAlignment iAlignment; + iAlignment.SetVAlignment( EVCenter ); + if ( AknLayoutUtils::LayoutMirrored() ) + { + iAlignment.SetHAlignment( EHRight ); + } + else + { + iAlignment.SetHAlignment( EHLeft ); + } + + iExtension->iTitleImage->SetAlignment( iAlignment ); + + TInt topMargin = bmpRect.iTl.iY; + TInt leftMargin = bmpRect.iTl.iX; + TInt bottomMargin = rect.iBr.iY - layoutRect.Rect().iBr.iY; + TInt rightMargin = rect.iBr.iX - layoutRect.Rect().iBr.iX; + + iExtension->iTitleImage->SetRect( + iAlignment.InnerRect( + TRect( rect.iTl.iX + leftMargin, + rect.iTl.iY + topMargin, + rect.iBr.iX - rightMargin, + rect.iBr.iY - bottomMargin), + bmpSize ) ); + } + } + + +void CAknTitlePane::SizeChangedInStaconPane() + { + TRect rect( Rect() ); + + AknsUtils::RegisterControlPosition( this ); + TInt leftOrRightSoftKeysVariety = 0; + if ( AknStatuspaneUtils::StaconSoftKeysLeft() ) + { + leftOrRightSoftKeysVariety = 1; + } + + if ( iExtension->iTitleImage && + iExtension->iTitleImage->Bitmap() && + iExtension->iSmallImageShown ) + { + TAknWindowComponentLayout imageLayout( + AknLayoutScalable_Avkon::title_pane_stacon_g1( + leftOrRightSoftKeysVariety ) ); + TAknLayoutRect layoutRect; + layoutRect.LayoutRect( rect, imageLayout ); + + if ( iExtension->iSmallImageAutoscaling && + iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Mask() ) + { + CFbsBitmap* bitmap = + const_cast ( iExtension->iTitleImage->Bitmap() ); + AknIconUtils::SetSize( bitmap, layoutRect.Rect().Size() ); + } + + TGulAlignment alignment; + alignment.SetHAlignment( EHCenter ); + alignment.SetVAlignment( EVCenter ); + iExtension->iTitleImage->SetRect( + alignment.InnerRect( + layoutRect.Rect(), + iExtension->iTitleImage->Bitmap()->SizeInPixels() ) ); + } + + if ( iTitleLabel && !iImageShown ) + { + __ASSERT_DEBUG( iTitleText, Panic( EAknPanicNullPointer ) ); + + // If image is shown, then select shorter text + if ( iExtension->iTitleImage && + iExtension->iTitleImage->Bitmap() && + iExtension->iSmallImageShown ) + { + leftOrRightSoftKeysVariety += 2; + } + + TAknTextLineLayout oneLineLayout( + AknLayoutScalable_Avkon::title_pane_stacon_t1( + leftOrRightSoftKeysVariety ).LayoutLine() ); + TAknLayoutText oneLineLayoutText; + oneLineLayoutText.LayoutText( rect, oneLineLayout ); + TRect oneLineLayoutRect( oneLineLayoutText.TextRect() ); + + const CFont* fontUsed = + AknLayoutUtils::FontFromId( oneLineLayout.FontId() ); + + TRAP_IGNORE( + TInt lines = FormatTitlePaneLabelL( oneLineLayoutRect.Width(), + 0, + fontUsed, + fontUsed ) ); // Ignore leave. + // Only layout of the title pane suffers if leave happens. + + AknLayoutUtils::LayoutLabel( iTitleLabel, rect, oneLineLayout ); + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + TRgb color; + + TInt error = 0; + + if ( AknStatuspaneUtils::IdleLayoutActive() ) + { + error = AknsUtils::GetCachedColor( skin, + color, + KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG38 ); + } + else + { + error = AknsUtils::GetCachedColor( skin, + color, + KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG37 ); + } + + if ( !error ) + { + // Ignore error + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( + *iTitleLabel, EColorLabelText, color ) ); + } + + if ( iExtension && + ( iExtension->iScrollEffectEnabled || + iTitleLabel->TextEffect() || + !iTitleLabel->EffectQueueIsEmpty() ) ) + { + TRAP_IGNORE( SetupTitleLabelEffectL() ); + if ( !iTitleLabel->TextEffect() ) + { + AknLayoutUtils::LayoutLabel( iTitleLabel, rect, oneLineLayout ); + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( + *iTitleLabel, EColorLabelText, color ) ); + } + } + } + else if ( iExtension && iExtension->iTitleImage ) + { + TAknLayoutRect layoutRect; + layoutRect.LayoutRect( + rect, + AknLayoutScalable_Avkon::title_pane_stacon_g2( 0 ) ); + TRect bmpRect( layoutRect.Rect() ); + TSize bmpSize( bmpRect.Size() ); + + if ( iExtension->iImageAutoscaling && + iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Mask() ) + { + CFbsBitmap* bitmap = + const_cast ( iExtension->iTitleImage->Bitmap() ); + AknIconUtils::SetSize( bitmap, bmpSize ); + } + else if ( !iExtension->iImageAutoscaling && + iExtension->iTitleImage->Bitmap() ) + { + bmpSize = iExtension->iTitleImage->Bitmap()->SizeInPixels(); + } + + TGulAlignment iAlignment; + iAlignment.SetVAlignment( EVCenter ); + if ( AknStatuspaneUtils::StaconSoftKeysLeft() ) + { + iAlignment.SetHAlignment( EHRight ); + } + else + { + iAlignment.SetHAlignment( EHLeft ); + } + + iExtension->iTitleImage->SetAlignment( iAlignment ); + + TInt topMargin = bmpRect.iTl.iY; + TInt leftMargin = bmpRect.iTl.iX; + TInt bottomMargin = rect.Height() - ( bmpRect.Height() + topMargin ); + TInt rightMargin = leftMargin; + + iExtension->iTitleImage->SetRect( + iAlignment.InnerRect( + TRect( rect.iTl.iX + leftMargin, + rect.iTl.iY + topMargin, + rect.iBr.iX - rightMargin, + rect.iBr.iY - bottomMargin ), + bmpSize ) ); + } + } + + +void CAknTitlePane::SizeChangedInFlatStatusPane() + { + AknsUtils::RegisterControlPosition( this ); + + TRect rect( Rect() ); + + if ( iExtension->iTitleImage && + iExtension->iTitleImage->Bitmap() && + iExtension->iSmallImageShown ) + { + TBool touchLsc( Layout_Meta_Data::IsLandscapeOrientation() && + AknLayoutUtils::PenEnabled() ); + + TAknLayoutRect layoutRect; + layoutRect.LayoutRect( + rect, + AknLayoutScalable_Avkon::title_pane_g2( touchLsc ? 4 : 0 ) ); + + if ( iExtension->iSmallImageAutoscaling && + iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Mask() ) + { + CFbsBitmap* bitmap = + const_cast ( iExtension->iTitleImage->Bitmap() ); + AknIconUtils::SetSize( bitmap, layoutRect.Rect().Size() ); + } + + TGulAlignment alignment; + alignment.SetHAlignment( EHCenter ); + alignment.SetVAlignment( EVCenter ); + iExtension->iTitleImage->SetRect( alignment.InnerRect( + layoutRect.Rect(), + iExtension->iTitleImage->Bitmap()->SizeInPixels() ) ); + } + + if ( iTitleLabel && !iImageShown ) + { + __ASSERT_DEBUG( iTitleText, Panic( EAknPanicNullPointer ) ); + + TAknTextLineLayout oneLineLayout; + TBool touchLsc( Layout_Meta_Data::IsLandscapeOrientation() && + AknLayoutUtils::PenEnabled() ); + + if ( iExtension->iTitleImage && iExtension->iSmallImageShown ) + { + // if image is shown, use shorter version of text + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( touchLsc ? 11 : 3 ).LayoutLine(); + } + else + { + // if image is not shown, use longer version of text + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( touchLsc ? 10 : 2 ).LayoutLine(); + } + + TAknLayoutText oneLineLayoutText; + oneLineLayoutText.LayoutText( rect, oneLineLayout ); + TRect oneLineLayoutRect( oneLineLayoutText.TextRect() ); + + const CFont* fontUsed = + AknLayoutUtils::FontFromId( oneLineLayout.FontId() ); + + TRAP_IGNORE( + TInt lines = FormatTitlePaneLabelL( + oneLineLayoutRect.Width(), + 0, + fontUsed, + fontUsed ) + ); // Ignore leave. + // Only layout of the title pane suffers if leave happens. + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + TRgb color = 0; + + // Flat statuspane uses same color skinning as stacon pane + AknsUtils::GetCachedColor( skin, + color, + KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG37 ); + + // Ignore error + TRAP_IGNORE(AknLayoutUtils::OverrideControlColorL( + *iTitleLabel, EColorLabelText, color ) ); + + TRAP_IGNORE( SetupTitleLabelEffectL() ); + if ( !iTitleLabel->TextEffect() ) + { + AknLayoutUtils::LayoutLabel( iTitleLabel, rect, oneLineLayout ); + // Ignore error + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( + *iTitleLabel, EColorLabelText, color ) ); + } + } + else if ( iExtension && iExtension->iTitleImage ) + { + TRect bmpRect( rect ); + TSize bmpSize( bmpRect.Size() ); + + if ( !Layout_Meta_Data::IsLandscapeOrientation() ) + { + // Stacon layout is used for this layout too. + TAknLayoutRect layoutRect; + layoutRect.LayoutRect( + rect, + AknLayoutScalable_Avkon::title_pane_stacon_g2( 0 ) ); + bmpRect = layoutRect.Rect(); + bmpSize = bmpRect.Size(); + } + + if ( iExtension->iImageAutoscaling && + iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Mask() ) + { + CFbsBitmap* bitmap = + const_cast ( iExtension->iTitleImage->Bitmap() ); + AknIconUtils::SetSize( bitmap, bmpSize ); + } + else if ( !iExtension->iImageAutoscaling && + iExtension->iTitleImage->Bitmap() ) + { + bmpSize = iExtension->iTitleImage->Bitmap()->SizeInPixels(); + } + + TGulAlignment iAlignment; + iAlignment.SetVAlignment( EVCenter ); + if ( AknLayoutUtils::LayoutMirrored() ) + { + iAlignment.SetHAlignment( EHRight ); + } + else + { + iAlignment.SetHAlignment( EHLeft ); + } + + iExtension->iTitleImage->SetAlignment( iAlignment ); + + TInt topMargin = bmpRect.iTl.iY; + TInt leftMargin = bmpRect.iTl.iX; + TInt bottomMargin = rect.Height() - ( bmpRect.Height() + topMargin ); + TInt rightMargin = leftMargin; + + iExtension->iTitleImage->SetRect( + iAlignment.InnerRect( + TRect( rect.iTl.iX + leftMargin, + rect.iTl.iY + topMargin, + rect.iBr.iX - rightMargin, + rect.iBr.iY - bottomMargin ), + bmpSize ) ); + } + } + + +void CAknTitlePane::SizeChangedInExtendedStatusPane() + { + AknsUtils::RegisterControlPosition( this ); + + TRect rect( Rect() ); + + TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() ); + TBool hdLayout( AknStatuspaneUtils::HDLayoutActive() ); + + if (iExtension->iTitleImage && iExtension->iTitleImage->Bitmap() && iExtension->iSmallImageShown) + { + TAknWindowComponentLayout imageLayout( + AknLayoutScalable_Avkon::title_pane_g2( hdLayout ? 4 : 1) ); + + TAknLayoutRect layoutRect; + layoutRect.LayoutRect( rect, imageLayout ); + + if ( iExtension->iSmallImageAutoscaling && + iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Mask() ) + { + CFbsBitmap* bitmap = + const_cast ( iExtension->iTitleImage->Bitmap() ); + AknIconUtils::SetSize( bitmap, layoutRect.Rect().Size() ); + } + + TGulAlignment alignment; + alignment.SetHAlignment( EHCenter ); + alignment.SetVAlignment( EVCenter ); + iExtension->iTitleImage->SetRect( + alignment.InnerRect( + layoutRect.Rect(), + iExtension->iTitleImage->Bitmap()->SizeInPixels() ) ); + } + + if ( iTitleLabel && !iImageShown ) + { + __ASSERT_DEBUG( iTitleText, Panic( EAknPanicNullPointer ) ); + + TAknTextLineLayout oneLineLayout; + if ( iExtension->iTitleImage && iExtension->iSmallImageShown ) + { + // if image is shown, use shorter version of text + oneLineLayout = AknLayoutScalable_Avkon::title_pane_t1( hdLayout ? 11 : 6 ).LayoutLine(); + if ( !TextFits( oneLineLayout ) ) + { + if ( hdLayout ) + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( 13 ).LayoutLine(); + } + else + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t2( 2 ).LayoutLine(); + } + } + } + else + { + // if image is not shown, use longer version of text + oneLineLayout = AknLayoutScalable_Avkon::title_pane_t1( hdLayout ? 10 : 5 ).LayoutLine(); + if ( !TextFits( oneLineLayout ) ) + { + if ( hdLayout ) + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( 12 ).LayoutLine(); + } + else + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t2( 1 ).LayoutLine(); + } + } + } + + TAknLayoutText oneLineLayoutText; + oneLineLayoutText.LayoutText( rect, oneLineLayout ); + TRect oneLineLayoutRect = oneLineLayoutText.TextRect(); + + const CFont* fontUsed = + AknLayoutUtils::FontFromId( oneLineLayout.FontId() ); + + TRAP_IGNORE( + TInt lines = FormatTitlePaneLabelL( + oneLineLayoutRect.Width(), + 0, + fontUsed, + fontUsed ) + ); // Ignore leave. + // Only layout of the title pane suffers if leave happens. + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + TRgb color = 0; + + // Same color skinning as normal status pane + AknsUtils::GetCachedColor( skin, + color, + KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG1 ); + + // Ignore error + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( + *iTitleLabel, EColorLabelText, color ) ); + + TRAP_IGNORE( SetupTitleLabelEffectL() ); + if ( !iTitleLabel->TextEffect() ) + { + AknLayoutUtils::LayoutLabel( iTitleLabel, rect, oneLineLayout ); + // Ignore error + TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( + *iTitleLabel, EColorLabelText, color ) ); + } + } + else if ( iExtension && iExtension->iTitleImage ) + { + TAknLayoutRect layoutRect; + layoutRect.LayoutRect( + rect, + AknLayoutScalable_Avkon::title_pane_g1( hdLayout ) ); + TRect bmpRect( layoutRect.Rect() ); + TSize bmpSize( bmpRect.Size() ); + + if ( iExtension->iImageAutoscaling && + iExtension->iTitleImage->Bitmap() && + iExtension->iTitleImage->Mask() ) + { + CFbsBitmap* bitmap = + const_cast ( iExtension->iTitleImage->Bitmap() ); + AknIconUtils::SetSize( bitmap, bmpSize ); + } + else if ( !iExtension->iImageAutoscaling && + iExtension->iTitleImage->Bitmap() ) + { + bmpSize = iExtension->iTitleImage->Bitmap()->SizeInPixels(); + } + + TGulAlignment iAlignment; + iAlignment.SetVAlignment( EVCenter ); + if ( AknLayoutUtils::LayoutMirrored() ) + { + iAlignment.SetHAlignment( EHRight ); + } + else + { + iAlignment.SetHAlignment( EHLeft ); + } + + iExtension->iTitleImage->SetAlignment( iAlignment ); + + TInt topMargin = bmpRect.iTl.iY; + TInt leftMargin = bmpRect.iTl.iX; + TInt bottomMargin = rect.Height() - ( bmpRect.Height() + topMargin ); + TInt rightMargin = leftMargin; + + iExtension->iTitleImage->SetRect( + iAlignment.InnerRect( + TRect( rect.iTl.iX + leftMargin, + rect.iTl.iY + topMargin, + rect.iBr.iX - rightMargin, + rect.iBr.iY - bottomMargin ), + bmpSize ) ); + } + } + + +RWindow* CAknTitlePane::StatuspaneContainerWindow() const + { + RWindow* window = NULL; + CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current(); + if ( statusPane ) + { + CCoeControl* control = NULL; + TRAP_IGNORE( control = statusPane->ContainerControlL( + TUid::Uid( EEikStatusPaneUidTitle ) ) ); + if( control ) + { + RDrawableWindow* drawableWindow = control->DrawableWindow(); + if ( drawableWindow ) + { + // Trust that container is always RWindow. + window = static_cast ( drawableWindow ); + } + } + } + + return window; + } + + +void CAknTitlePane::SetupTitleLabelEffectL() + { + if ( iTitleLabel ) + { + iTitleLabel->InitEffectQueueL(); + } + + if ( AknStatuspaneUtils::StaconPaneActive() ) + { + if ( iExtension && + iExtension->iScrollEffectEnabled ) + { + SetupStaconPaneScrollEffectL(); + } + else + { + SetupNoEffectL(); // Default is no effect + } + } + else if ( AknStatuspaneUtils::FlatLayoutActive() ) + { + if ( iExtension && + iExtension->iScrollEffectEnabled ) + { + SetupFlatStatusPaneFadeEffectL(); + SetupFlatStatusPaneScrollEffectL(); + SetupFlatStatusPaneFadeEffectL(); + } + else + { + SetupFlatStatusPaneFadeEffectL(); // Default is fade effect + } + } + else if ( AknStatuspaneUtils::ExtendedLayoutActive() ) + { + if ( iExtension && + iExtension->iScrollEffectEnabled ) + { + SetupExtendedStatusPaneScrollEffectL(); + } + else + { + SetupNoEffectL(); // Default is no effect + } + } + else + { + if ( iExtension && + iExtension->iScrollEffectEnabled ) + { + SetupNormalStatusPaneScrollEffectL(); + } + else + { + SetupNoEffectL(); // Default is no effect + } + } + + if ( iTitleLabel && iTitleLabel->EffectQueueIsEmpty() ) + { + SetupNoEffectL(); + } + + if ( iTitleLabel ) + { + iTitleLabel->ActivateEffectQueue(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetTitlePaneObserver() +// Set's aObserver as title pane observer +// ---------------------------------------------------------------------------- +EXPORT_C void CAknTitlePane::SetTitlePaneObserver( + MAknTitlePaneObserver* aObserver) + { + iTitlePaneObserver = aObserver; + } + + +EXPORT_C void* CAknTitlePane::ExtensionInterface( TUid /*aInterface*/ ) + { + return NULL; + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::HandlePointerEventL() +// Processes TitlePane's pointer event's by informing observer about tapping +// ---------------------------------------------------------------------------- + +EXPORT_C void CAknTitlePane::HandlePointerEventL( + const TPointerEvent& aPointerEvent ) + { + if ( AknLayoutUtils::PenEnabled() ) + { + if ( IsDimmed() ) + { + iExtension->iFlags &= ( ~EAknTitlePaneButton1DownInTitleRect ); + return; + } + + // get rect of SignalPane + TRect rect( Rect() ); + + // Switch by type + switch ( aPointerEvent.iType ) + { + case TPointerEvent::EButton1Down: + { + // if signalPane's rect contains pointer down position + if ( rect.Contains( aPointerEvent.iPosition ) ) + { + // set flag that down was inside titlePane + iExtension->iFlags |= EAknTitlePaneButton1DownInTitleRect; + } + } + break; + + case TPointerEvent::EButton1Up: + { + // if signalPane's rect contains pointer down position + if ( iExtension->iFlags&EAknTitlePaneButton1DownInTitleRect && + rect.Contains( aPointerEvent.iPosition ) ) + { + if ( iTitlePaneObserver ) + { + iTitlePaneObserver->HandleTitlePaneEventL( + MAknTitlePaneObserver::EAknTitlePaneTapped ); + } + } + + // Up happened, reset button down flag + iExtension->iFlags &= ( ~EAknTitlePaneButton1DownInTitleRect ); + } + break; + + default: + break; + } + } + } + + +CEikLabel* CAknTitlePane::TextLabel() + { + return iTitleLabel; + } + + +CEikImage* CAknTitlePane::TitleImage() + { + if ( iExtension && + iExtension->iTitleImage && + iExtension->iTitleImage->Bitmap() && + !iExtension->iSmallImageShown ) + { + return iExtension->iTitleImage; + } + + return NULL; + } + + +void CAknTitlePane::SetContainerWindowNonFading( TBool aNonFading ) + { + CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current(); + if ( statusPane ) + { + CCoeControl* control = NULL; + TRAP_IGNORE( control = + statusPane->ContainerControlL( + TUid::Uid( EEikStatusPaneUidTitle ) ) ); + + if( control ) + { + control->DrawableWindow()->SetNonFading( aNonFading ); + } + } + } + + +void CAknTitlePane::SetupStaconPaneScrollEffectL() + { + if ( !iExtension->iScrollEffectNeeded ) + { + return; + } + + TRect rect( Rect() ); + + // If image is shown, then select shorter text + TInt leftOrRightSoftKeysVariety = 0; + if ( AknStatuspaneUtils::StaconSoftKeysLeft() ) + { + leftOrRightSoftKeysVariety = 1; + } + if ( iExtension->iTitleImage && + iExtension->iTitleImage->Bitmap() && + iExtension->iSmallImageShown ) + { + leftOrRightSoftKeysVariety += 2; + } + + TAknTextLineLayout oneLineLayout( + AknLayoutScalable_Avkon::title_pane_stacon_t1( + leftOrRightSoftKeysVariety ).LayoutLine() ); + TAknLayoutText oneLineLayoutText; + oneLineLayoutText.LayoutText( rect, oneLineLayout ); + TRect oneLineLayoutRect( oneLineLayoutText.TextRect() ); + + TRect effectRect( rect ); + + CAknTitlePaneLabel::SAknTitleLableEffect effect; + + // First show text without effect + effect.iEffectDuration = 0; + effect.iEffect = 0; + effect.iEffectRect = oneLineLayoutRect; + effect.iLabelRect = rect; + effect.iObserver = NULL; + effect.iTitleText = iTitleText; + effect.iTextLayout = oneLineLayoutText; + effect.iTextLayoutLine = oneLineLayout; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectRect = effectRect; + effect.iEffectDuration = KScrollPauseBeforeScroll; + iTitleLabel->AddToEffectQueueL( effect ); + + // Scroll text once + effect.iEffect = CAknTitlePaneLabel::EEffectScrollOnceWithFade; + effect.iEffectRect = oneLineLayoutRect; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectRect = rect; + effect.iEffectDuration = KScrollPauseBeforeFadeOut; + iTitleLabel->AddToEffectQueueL( effect ); + + // Fade out + effect.iEffect = CAknTitlePaneLabel::EEffectFadeOut; + effect.iEffectDuration = KScrollFadeInFadeOutDuration; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectDuration = KScrollPauseBeforeFadeIn; + iTitleLabel->AddToEffectQueueL( effect ); + + // Default + effect.iEffect = CAknTitlePaneLabel::EEffectToggleScrolledTextTruncation; + iTitleLabel->AddToEffectQueueL( effect ); + + // No fade in because we don't do it in other layouts either + + // Finally show text without effect + effect.iEffectDuration = 0; + effect.iEffect = 0; + effect.iEffectRect = oneLineLayoutRect; + iTitleLabel->AddToEffectQueueL( effect ); + } + +void CAknTitlePane::SetupExtendedStatusPaneScrollEffectL() + { + if ( !iExtension->iScrollEffectNeeded ) + { + return; + } + + TRect rect( Rect() ); + TBool hdLayout( AknStatuspaneUtils::HDLayoutActive() ); + + TInt variety = hdLayout ? 10 : 5; + TBool imageShown = EFalse; + + // If image is shown, then select shorter text + if ( iExtension->iTitleImage && + iExtension->iTitleImage->Bitmap() && + iExtension->iSmallImageShown ) + { + variety = hdLayout ? 11 : 6; + imageShown = ETrue; + } + + TAknTextLineLayout oneLineLayout( + AknLayoutScalable_Avkon::title_pane_t1( variety ).LayoutLine() ); + + // if text would truncate, then use smaller font. + // (No smaller font layout with image exist) + if ( !TextFits( oneLineLayout ) ) + { + if ( !imageShown ) + { + if ( hdLayout ) + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( 12 ).LayoutLine(); + } + else + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t2( 1 ).LayoutLine(); + } + } + else + { + if ( hdLayout ) + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( 13 ).LayoutLine(); + } + else + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t2( 2 ).LayoutLine(); + } + } + } + + TAknLayoutText oneLineLayoutText; + oneLineLayoutText.LayoutText( rect, oneLineLayout ); + TRect oneLineLayoutRect( oneLineLayoutText.TextRect() ); + + TRect effectRect( rect ); + + CAknTitlePaneLabel::SAknTitleLableEffect effect; + + // First show text without effect + effect.iEffectDuration = 0; + effect.iEffect = 0; + effect.iEffectRect = oneLineLayoutRect; + effect.iLabelRect = rect; + effect.iObserver = NULL; + effect.iTitleText = iTitleText; + effect.iTextLayout = oneLineLayoutText; + effect.iTextLayoutLine = oneLineLayout; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectRect = effectRect; + effect.iEffectDuration = KScrollPauseBeforeScroll; + iTitleLabel->AddToEffectQueueL( effect ); + + // Scroll text once + effect.iEffect = CAknTitlePaneLabel::EEffectScrollOnceWithFade; + effect.iEffectRect = oneLineLayoutRect; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectRect = rect; + effect.iEffectDuration = KScrollPauseBeforeFadeOut; + iTitleLabel->AddToEffectQueueL( effect ); + + // Fade out + effect.iEffect = CAknTitlePaneLabel::EEffectFadeOut; + effect.iEffectDuration = KScrollFadeInFadeOutDuration; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectDuration = KScrollPauseBeforeFadeIn; + iTitleLabel->AddToEffectQueueL( effect ); + + // Default + effect.iEffect = CAknTitlePaneLabel::EEffectToggleScrolledTextTruncation; + iTitleLabel->AddToEffectQueueL( effect ); + + // No fade in because we don't do it in other layouts either + + // Finally show text without effect + effect.iEffectDuration = 0; + effect.iEffect = 0; + effect.iEffectRect = oneLineLayoutRect; + iTitleLabel->AddToEffectQueueL( effect ); + } + + +void CAknTitlePane::SetupFlatStatusPaneScrollEffectL() + { + if ( !iExtension->iScrollEffectNeeded ) + { + return; + } + + CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current(); + TBool fade = EFalse; + TBool narrowNaviPane = EFalse; + TBool forcedNormalNaviPane = EFalse; + + RWindow* naviwindow = NULL; + RWindow* titlewindow = NULL; + CCoeControl* naviContainerControl = NULL; + CCoeControl* titleContainerControl = NULL; + CAknNavigationControlContainer* naviPane = NULL; + CAknNavigationDecorator* decorator = NULL; + + TPoint naviControlPosition; + TSize naviControlSize; + + if ( statusPane ) + { + naviContainerControl = statusPane->ContainerControlL( + TUid::Uid( EEikStatusPaneUidNavi ) ); + titleContainerControl = statusPane->ContainerControlL( + TUid::Uid( EEikStatusPaneUidTitle ) ); + if ( naviContainerControl && titleContainerControl ) + { + RDrawableWindow* drawableWindow = + naviContainerControl->DrawableWindow(); + if ( drawableWindow ) + { + // Trust that container is always RWindow. + naviwindow = static_cast ( drawableWindow ); + } + + drawableWindow = titleContainerControl->DrawableWindow(); + if ( drawableWindow ) + { + // Trust that container is always RWindow. + titlewindow = static_cast ( drawableWindow ); + } + + + naviControlPosition = naviContainerControl->Position(); + naviControlSize = naviContainerControl->Size(); + } + + CCoeControl* control = NULL; + TRAP_IGNORE( control = + statusPane->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) ) ); + if ( control ) + { + // Control cannot be casted directly because someone may have + // swapped the control. Use this method instead. + control->MopGetObject( naviPane ); + if ( naviPane ) + { + decorator = naviPane->Top( EFalse ); + if ( decorator ) + { + if ( decorator->NaviControlLayoutStyle() == + CAknNavigationDecorator::ENaviControlLayoutNarrow ) + { + naviControlPosition += + CAknNavigationDecorator::DecoratedControlNarrowRect( + decorator->ControlType() ).iTl; + naviControlSize = + CAknNavigationDecorator::DecoratedControlNarrowRect( + decorator->ControlType() ).Size(); + narrowNaviPane = ETrue; + } + if ( decorator->NaviControlLayoutStyle() == CAknNavigationDecorator::ENaviControlLayoutNormal && + decorator->NaviControlLayoutMode() == CAknNavigationDecorator::ENaviControlLayoutModeForced ) + { + forcedNormalNaviPane = ETrue; + } + } + } + } + } + + if ( naviwindow && titlewindow ) + { + // Fade title text only if navipane window is above titlepane + TInt naviWindowOrdinalPosition = naviwindow->OrdinalPosition(); + TInt titleWindowOrdinalPosition = titlewindow->OrdinalPosition(); + fade = naviWindowOrdinalPosition < titleWindowOrdinalPosition; + } + + + TAknTextLineLayout oneLineLayout; + + TBool touchLsc( Layout_Meta_Data::IsLandscapeOrientation() && + AknLayoutUtils::PenEnabled() ); + + if ( iExtension->iTitleImage && iExtension->iSmallImageShown ) + { + // if image is shown, use shorter version of text + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( touchLsc ? 11 : 3 ).LayoutLine(); + } + else + { + // if image is not shown, use longer version of text + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( touchLsc ? 10 : 2 ).LayoutLine(); + } + + TAknLayoutText oneLineLayoutText; + oneLineLayoutText.LayoutText( Rect(), oneLineLayout ); + TRect oneLineLayoutRect( oneLineLayoutText.TextRect() ); + + TRect effectRect( oneLineLayoutText.TextRect() ); + if ( fade ) + { + if ( !AknLayoutUtils::LayoutMirrored() ) + { + effectRect.iBr.iX = + naviControlPosition.iX - titleContainerControl->Position().iX; + } + else + { + effectRect.iTl.iX = naviControlSize.iWidth + naviControlPosition.iX; + } + } + else + { + effectRect = oneLineLayoutText.TextRect(); + } + + // Decide scrolling need + if ( narrowNaviPane || forcedNormalNaviPane ) + { + const CFont* fontUsed = + AknLayoutUtils::FontFromId( oneLineLayout.FontId() ); + CFont::TMeasureTextInput input; + input.iFlags = CFont::TMeasureTextInput::EFVisualOrder; + TInt textLength = fontUsed->MeasureText( *iTitleText, &input ); + + TRect visibleTextRect( effectRect ); + + if ( textLength > visibleTextRect.Width() ) + { + iExtension->iScrollEffectNeeded = ETrue; + } + } + else + { + // No scroll if navipane is not in short mode but fade is on. + if ( fade ) + { + iExtension->iScrollEffectNeeded = EFalse; + } + } + + // This is the earliest place where we really know + // if scrolling is needed or not. + if ( !iExtension->iScrollEffectNeeded ) + { + return; + } + + CAknTitlePaneLabel::SAknTitleLableEffect effect; + + // Initilize effect struct + effect.iEffectDuration = 0; + effect.iEffect = 0; + effect.iEffectRect = Rect(); + effect.iLabelRect = Rect(); + effect.iObserver = static_cast ( naviPane ); + effect.iTitleText = iTitleText; + effect.iTextLayout = oneLineLayoutText; + effect.iTextLayoutLine = oneLineLayout; + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectDuration = KScrollPauseBeforeScroll; + iTitleLabel->AddToEffectQueueL( effect ); + + // Scroll text once + effect.iEffectDuration = 0; + effect.iEffectRect = effectRect; + effect.iEffect = CAknTitlePaneLabel::EEffectScrollOnceWithFade; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectDuration = KScrollPauseBeforeFadeOut; + iTitleLabel->AddToEffectQueueL( effect ); + + // Fade out + effect.iEffect = CAknTitlePaneLabel::EEffectFadeOut; + effect.iEffectDuration = KScrollFadeInFadeOutDuration; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectDuration = KScrollPauseBeforeFadeIn; + iTitleLabel->AddToEffectQueueL( effect ); + + // Default + effect.iEffect = CAknTitlePaneLabel::EEffectToggleScrolledTextTruncation; + iTitleLabel->AddToEffectQueueL( effect ); + + // No fade in because we don't support fade in with + // other effects (fade left or right). + + // Finally text is shown with fade effect if needed + // (setup in its own method). + } + +void CAknTitlePane::SetupNormalStatusPaneScrollEffectL() + { + if ( !iExtension->iScrollEffectNeeded ) + { + return; + } + + TRect rect( Rect() ); + + // Is battery pane visible in current layout + TInt indexW = AknStatuspaneUtils::IdleLayoutActive() ? 1 : 0; + + TAknTextLineLayout oneLineLayout( + AknLayoutScalable_Avkon::title_pane_t1( 0 ).LayoutLine() ); + + const TAknMultiLineTextLayout twoLineLayout( + AKN_LAYOUT_MULTILINE_TEXT_Title_pane_texts_Line_2( indexW, 2 ) ); + + // if text would truncate, then try to use smaller font with one line layout + if ( !TextFits( oneLineLayout ) ) + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t2( 1 ).LayoutLine(); + } + + TAknLayoutText oneLineLayoutText; + oneLineLayoutText.LayoutText(rect, oneLineLayout); + TRect oneLineLayoutRect( oneLineLayoutText.TextRect() ); + + TAknLayoutText twoLineLayoutText; + twoLineLayoutText.LayoutText(rect, twoLineLayout); + TRect twoLineLayoutRect( twoLineLayoutText.TextRect() ); + + CAknTitlePaneLabel::SAknTitleLableEffect effect; + + effect.iEffect = 0; + effect.iEffectDuration = 0; + effect.iLabelRect = rect; + effect.iObserver = NULL; + effect.iTitleText = iTitleText; + effect.iEffectRect = oneLineLayoutRect; + effect.iTextLayout = oneLineLayoutText; + effect.iTextLayoutLine = oneLineLayout; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectDuration = KScrollPauseBeforeScroll; + iTitleLabel->AddToEffectQueueL( effect ); + + // Scroll text once + effect.iEffect = CAknTitlePaneLabel::EEffectScrollOnceWithFade; + effect.iEffectRect = oneLineLayoutRect; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectDuration = KScrollPauseBeforeFadeOut; + iTitleLabel->AddToEffectQueueL( effect ); + + // Fade out + effect.iEffect = CAknTitlePaneLabel::EEffectFadeOut; + effect.iEffectRect = rect; + effect.iEffectDuration = KScrollFadeInFadeOutDuration; + iTitleLabel->AddToEffectQueueL( effect ); + + // Pause + effect.iEffect = CAknTitlePaneLabel::EEffectPause; + effect.iEffectDuration = KScrollPauseBeforeFadeIn; + iTitleLabel->AddToEffectQueueL( effect ); + + // No fade in done, drawing two line text with effects is not supported. + + // Finally show text without effect + effect.iEffect = 0; + if ( iExtension && iExtension->iCurrentNumberOfTextLines == 2 ) + { + effect.iEffectRect = twoLineLayoutRect; + effect.iLabelRect = rect; + effect.iTextLayout = twoLineLayoutText; + effect.iTextLayoutLine = twoLineLayout; + } + else + { + effect.iEffectRect = oneLineLayoutRect; + effect.iLabelRect = rect; + effect.iTextLayout = oneLineLayoutText; + effect.iTextLayoutLine = oneLineLayout; + } + iTitleLabel->AddToEffectQueueL( effect ); + } + + +void CAknTitlePane::SetupFlatStatusPaneFadeEffectL() + { + // For flat statuspane we fade the titletext under navipane + // in situations where navipane is covering part of titlepane. + CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current(); + TBool fade = EFalse; + TBool narrowNaviPane = EFalse; + TBool forcedNormalNaviPane = EFalse; + RWindow* naviwindow = NULL; + RWindow* titlewindow = NULL; + CCoeControl* naviContainerControl = NULL; + CCoeControl* titleContainerControl = NULL; + CAknNavigationControlContainer* naviPane = NULL; + CAknNavigationDecorator* decorator = NULL; + + TPoint naviControlPosition( 0, 0 ); + TSize naviControlSize( 0, 0 ); + TRect rect( Rect() ); + + if ( statusPane ) + { + naviContainerControl = + statusPane->ContainerControlL( TUid::Uid( EEikStatusPaneUidNavi ) ); + titleContainerControl = + statusPane->ContainerControlL( TUid::Uid( EEikStatusPaneUidTitle ) ); + + if ( naviContainerControl && titleContainerControl ) + { + RDrawableWindow* drawableWindow = + naviContainerControl->DrawableWindow(); + + if ( drawableWindow ) + { + // Trust that container is always RWindow. + naviwindow = static_cast ( drawableWindow ); + } + + drawableWindow = titleContainerControl->DrawableWindow(); + if ( drawableWindow ) + { + // Trust that container is always RWindow. + titlewindow = static_cast ( drawableWindow ); + } + + naviControlPosition = naviContainerControl->Position(); + naviControlSize = naviContainerControl->Size(); + } + + CCoeControl* control = NULL; + TRAP_IGNORE( control = + statusPane->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) ) ); + + if ( control ) + { + // Control cannot be casted directly beacause someone + // may have swapped the control. + // Use this workaround instead. + control->MopGetObject( naviPane ); + if ( naviPane ) + { + decorator = naviPane->Top( EFalse ); + if ( decorator ) + { + if ( decorator->NaviControlLayoutStyle() == + CAknNavigationDecorator::ENaviControlLayoutNarrow ) + { + naviControlPosition += + CAknNavigationDecorator::DecoratedControlNarrowRect( + decorator->ControlType() ).iTl; + + naviControlSize = + CAknNavigationDecorator::DecoratedControlNarrowRect( + decorator->ControlType() ).Size(); + + narrowNaviPane = ETrue; + } + if ( decorator->NaviControlLayoutStyle() == CAknNavigationDecorator::ENaviControlLayoutNormal && + decorator->NaviControlLayoutMode() == CAknNavigationDecorator::ENaviControlLayoutModeForced ) + { + forcedNormalNaviPane = ETrue; + } + } + } + } + } + + if ( naviwindow && titlewindow ) + { + // Fade title text only if navipane window is above titlepane + TInt naviWindowOrdinalPosition = naviwindow->OrdinalPosition(); + TInt titleWindowOrdinalPosition = titlewindow->OrdinalPosition(); + fade = titleWindowOrdinalPosition > naviWindowOrdinalPosition; + } + + if ( fade ) + { + TAknTextLineLayout oneLineLayout; + TBool touchLsc( Layout_Meta_Data::IsLandscapeOrientation() && + AknLayoutUtils::PenEnabled() ); + if ( iExtension->iTitleImage && iExtension->iSmallImageShown ) + { + // if image is shown, use shorter version of text + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( touchLsc ? 11 : 3 ).LayoutLine(); + } + else + { + // if image is not shown, use longer version of text + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( touchLsc ? 10 : 2 ).LayoutLine(); + } + + + TAknLayoutText oneLineLayoutText; + oneLineLayoutText.LayoutText(rect, oneLineLayout); + TRect oneLineLayoutRect( oneLineLayoutText.TextRect() ); + + TRect effectRect( rect ); + TInt effectType = 0; + + // In landscape mode fade about 25% of the title, and in portrait + // fade the whole title. + TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() ); + + if ( !AknLayoutUtils::LayoutMirrored() ) + { + effectType = CAknTitlePaneLabel::EEffectFadeToRight; + effectRect.iBr.iX = naviControlPosition.iX - titleContainerControl->Position().iX; + effectRect.iTl.iX = effectRect.iBr.iX - effectRect.iBr.iX / 4; + } + else + { + effectType = CAknTitlePaneLabel::EEffectFadeToLeft; + effectRect.iTl.iX = naviControlPosition.iX + naviControlSize.iWidth; + effectRect.iBr.iX = rect.iBr.iX; + effectRect.iTl.iX -= titleContainerControl->Position().iX; + effectRect.iBr.iX -= effectRect.Size().iWidth * 3 / 4; + } + + CAknTitlePaneLabel::SAknTitleLableEffect effect; + effect.iEffectDuration = 0; + effect.iEffect = effectType; + effect.iEffectRect = effectRect; + effect.iLabelRect = rect; + effect.iObserver = naviPane; + effect.iTitleText = iTitleText; + effect.iTextLayout = oneLineLayoutText; + effect.iTextLayoutLine = oneLineLayout; + iTitleLabel->AddToEffectQueueL( effect ); + + // Decide scrolling need + if ( narrowNaviPane || forcedNormalNaviPane ) + { + const CFont* fontUsed = + AknLayoutUtils::FontFromId( oneLineLayout.FontId() ); + CFont::TMeasureTextInput input; + input.iFlags = CFont::TMeasureTextInput::EFVisualOrder; + TInt textLength = fontUsed->MeasureText( *iTitleText, &input ); + + TRect visibleTextRect( oneLineLayoutRect ); + if ( !AknLayoutUtils::LayoutMirrored() ) + { + visibleTextRect.iBr.iX = effectRect.iTl.iX; + } + else + { + visibleTextRect.iTl.iX = effectRect.iBr.iX; + } + + if ( textLength > visibleTextRect.Width() ) + { + iExtension->iScrollEffectNeeded = ETrue; + } + } + else + { + // No scroll if navipane is not in short mode but fade is on. + if ( fade ) + { + iExtension->iScrollEffectNeeded = EFalse; + } + } + } + else + { + SetupNoEffectL(); + } + } + + +void CAknTitlePane::SetupNoEffectL() + { + TAknLayoutText oneLineLayoutText; + TAknTextLineLayout oneLineLayout; + + TRect rect( Rect() ); + + if ( AknStatuspaneUtils::StaconPaneActive() ) + { + // If image is shown, then select shorter text + TInt leftOrRightSoftKeysVariety = 0; + if ( AknStatuspaneUtils::StaconSoftKeysLeft() ) + { + leftOrRightSoftKeysVariety = 1; + } + if ( iExtension->iTitleImage && + iExtension->iTitleImage->Bitmap() && + iExtension->iSmallImageShown ) + { + leftOrRightSoftKeysVariety += 2; + } + + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_stacon_t1( + leftOrRightSoftKeysVariety ).LayoutLine(); + } + else if ( AknStatuspaneUtils::FlatLayoutActive() ) + { + TBool touchLsc( Layout_Meta_Data::IsLandscapeOrientation() && + AknLayoutUtils::PenEnabled() ); + if ( iExtension->iTitleImage && iExtension->iSmallImageShown ) + { + // if image is shown, use shorter version of text + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( touchLsc ? 11 : 3 ).LayoutLine(); + } + else + { + // if image is not shown, use longer version of text + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( touchLsc ? 10 : 2 ).LayoutLine(); + } + } + else if ( AknStatuspaneUtils::ExtendedLayoutActive() ) + { + if ( iExtension->iTitleImage && iExtension->iSmallImageShown ) + { + // if image is shown, use shorter version of text + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( 6 ).LayoutLine(); + } + else + { + // if image is not shown, use longer version of text + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( 5 ).LayoutLine(); + } + } + else + { + // Is battery pane visible in current layout + TInt indexW = AknStatuspaneUtils::IdleLayoutActive() ? 1 : 0; + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t1( 0 ).LayoutLine(); + + if ( !TextFits( oneLineLayout ) ) + { + oneLineLayout = + AknLayoutScalable_Avkon::title_pane_t2( 1 ).LayoutLine(); + } + + TAknMultiLineTextLayout twoLineLayout( + AKN_LAYOUT_MULTILINE_TEXT_Title_pane_texts_Line_2( indexW, 2 ) ); + + if ( iExtension && iExtension->iCurrentNumberOfTextLines == 2 ) + { + oneLineLayout = twoLineLayout; + } + } + + oneLineLayoutText.LayoutText( rect, oneLineLayout ); + CAknTitlePaneLabel::SAknTitleLableEffect effect; + effect.iEffectDuration = 0; + effect.iEffect = 0; + effect.iEffectRect = rect; + effect.iLabelRect = rect; + effect.iObserver = NULL; + effect.iTitleText = iTitleText; + effect.iTextLayout = oneLineLayoutText; + effect.iTextLayoutLine = oneLineLayout; + iTitleLabel->AddToEffectQueueL( effect ); + } + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetTextL +// Sets the title pane text and scrolling effect. +// CAknTitlePane takes the ownership of aText. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::SetText( HBufC* aText, TBool aScroll ) + { + __ASSERT_ALWAYS( aText, Panic( EAknPanicNullPointer ) ); + + TBool textChanged = !iTitleText || aText != iTitleText || *aText != *iTitleText + || iImageShown || aScroll != iExtension->iScrollEffectEnabled; + + iExtension->iScrollEffectEnabled = aScroll; + if ( iTitleLabel ) + { + iTitleLabel->InvalidateText(); + } + if ( iTitleText != aText ) + { + delete iTitleText; + iTitleText = aText; + } + + if ( textChanged ) + { + iImageShown = EFalse; + SizeChanged(); + DrawDeferred(); + } + } + + +// ---------------------------------------------------------------------------- +// CAknTitlePane::SetTextL +// Sets the title pane text and scrolling effect. +// ---------------------------------------------------------------------------- +// +EXPORT_C void CAknTitlePane::SetTextL( const TDesC& aText, TBool aScroll ) + { + SetText( aText.AllocL(), aScroll ); + } + + +EXPORT_C TInt CAknTitlePane::MaxNumberOfVisibleTextRows() const + { + if ( AknStatuspaneUtils::StaconPaneActive() || + AknStatuspaneUtils::FlatLayoutActive() || + AknStatuspaneUtils::ExtendedLayoutActive() ) + { + return 1; + } + else + { + return 2; + } + } + + +EXPORT_C void CAknTitlePane::SetNumberOfVisibleTextRows( TInt aRows ) + { + if ( iExtension && aRows > 0 && aRows <= MaxNumberOfVisibleTextRows() ) + { + if ( iExtension->iLimitedNumberOfTextLines != aRows ) + { + iExtension->iLimitedNumberOfTextLines = aRows; + SizeChanged(); + DrawDeferred(); + } + } + } + + +// --------------------------------------------------------------------------- +// CAknTitlePane::TextFits +// Checks if the text fits inside the title pane area. +// --------------------------------------------------------------------------- +// +TBool CAknTitlePane::TextFits( TAknTextLineLayout& aTextLayout ) + { + TInt textLength = 0; + TInt maxLength = 0; + + const CFont* fontUsed = AknLayoutUtils::FontFromId( aTextLayout.FontId() ); + CFont::TMeasureTextInput input; + + // We need to check if the title text's directionality + // is from right to left to measure it correctly. + TBool rtl = + TBidiText::TextDirectionality( *iTitleText ) == TBidiText::ERightToLeft; + if ( !rtl ) + { + input.iFlags = CFont::TMeasureTextInput::EFVisualOrder; + } + else + { + input.iFlags = CFont::TMeasureTextInput::EFVisualOrderRightToLeft; + } + textLength = fontUsed->MeasureText( *iTitleText, &input ); + + TAknLayoutText oneLineLayoutText; + oneLineLayoutText.LayoutText( Rect(), aTextLayout ); + maxLength = oneLineLayoutText.TextRect().Width(); + + if ( textLength < maxLength ) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// End of File